Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Accept config to be through file or env vars #352

Merged
merged 2 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 18 additions & 16 deletions config/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,17 +70,19 @@ impl ConfigPrefix {
}

impl Config {
pub fn parse(prefix: ConfigPrefix, filename: &PathBuf) -> Result<Self, String> {
pub fn parse(prefix: ConfigPrefix, filename: Option<&PathBuf>) -> Result<Self, String> {
let config_defaults = include_str!("../default_values.toml");

let mut config_content = std::fs::read_to_string(filename)
.map_err(|e| format!("Failed to read config file: {}", e))?;
let mut figment_config = Figment::new().merge(Toml::string(config_defaults));

config_content = Self::substitute_env_vars(config_content)?;
if let Some(path) = filename {
let mut config_content = std::fs::read_to_string(path)
.map_err(|e| format!("Failed to read config file: {}", e))?;
config_content = Self::substitute_env_vars(config_content)?;
figment_config = figment_config.merge(Toml::string(&config_content));
}

let config: ConfigWrapper = Figment::new()
.merge(Toml::string(config_defaults))
.merge(Toml::string(&config_content))
let config: ConfigWrapper = figment_config
.merge(Env::prefixed(prefix.get_prefix()).split("__"))
.extract()
.map_err(|e| e.to_string())?;
Expand Down Expand Up @@ -386,7 +388,7 @@ mod tests {
fn test_minimal_config() {
Config::parse(
ConfigPrefix::Service,
&PathBuf::from("minimal-config-example.toml"),
Some(PathBuf::from("minimal-config-example.toml")).as_ref(),
)
.unwrap();
}
Expand All @@ -396,7 +398,7 @@ mod tests {
// Generate full config by deserializing the minimal config and let the code fill in the defaults.
let max_config = Config::parse(
ConfigPrefix::Service,
&PathBuf::from("minimal-config-example.toml"),
Some(PathBuf::from("minimal-config-example.toml")).as_ref(),
)
.unwrap();
let max_config_file: Config = toml::from_str(
Expand All @@ -418,7 +420,7 @@ mod tests {

Config::parse(
ConfigPrefix::Service,
&PathBuf::from("minimal-config-example.toml"),
Some(PathBuf::from("minimal-config-example.toml")).as_ref(),
)
.unwrap();

Expand Down Expand Up @@ -458,7 +460,7 @@ mod tests {
// This should fail because the subgraphs.network.query_url field is missing
Config::parse(
ConfigPrefix::Service,
&PathBuf::from(temp_minimal_config_path.path()),
Some(PathBuf::from(temp_minimal_config_path.path())).as_ref(),
)
.unwrap_err();

Expand All @@ -467,7 +469,7 @@ mod tests {

let config = Config::parse(
ConfigPrefix::Service,
&PathBuf::from(temp_minimal_config_path.path()),
Some(PathBuf::from(temp_minimal_config_path.path())).as_ref(),
)
.unwrap();

Expand All @@ -485,7 +487,7 @@ mod tests {

let config = Config::parse(
ConfigPrefix::Service,
&PathBuf::from("minimal-config-example.toml"),
Some(PathBuf::from("minimal-config-example.toml")).as_ref(),
)
.unwrap();

Expand Down Expand Up @@ -569,7 +571,7 @@ mod tests {
// This should fail because the QUERY_URL env variable is not setup
Config::parse(
ConfigPrefix::Service,
&PathBuf::from(temp_minimal_config_path.path()),
Some(PathBuf::from(temp_minimal_config_path.path())).as_ref(),
)
.unwrap_err();

Expand All @@ -578,7 +580,7 @@ mod tests {

let config = Config::parse(
ConfigPrefix::Service,
&PathBuf::from(temp_minimal_config_path.path()),
Some(PathBuf::from(temp_minimal_config_path.path())).as_ref(),
)
.unwrap();

Expand Down Expand Up @@ -663,7 +665,7 @@ mod tests {
// Parse the config with new datbase vars
let config = Config::parse(
ConfigPrefix::Service,
&PathBuf::from(temp_minimal_config_path.path()),
Some(PathBuf::from(temp_minimal_config_path.path())).as_ref(),
)
.unwrap();

Expand Down
2 changes: 1 addition & 1 deletion service/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ pub struct Cli {
/// Path to the configuration file.
/// See https://github.com/graphprotocol/indexer-rs/tree/main/service for examples.
#[arg(long, value_name = "FILE", verbatim_doc_comment)]
pub config: PathBuf,
pub config: Option<PathBuf>,
}
9 changes: 5 additions & 4 deletions service/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,12 @@ pub async fn run() -> anyhow::Result<()> {
// Load the json-rpc service configuration, which is a combination of the
// general configuration options for any indexer service and specific
// options added for JSON-RPC
let config =
MainConfig::parse(indexer_config::ConfigPrefix::Service, &cli.config).map_err(|e| {
let config = MainConfig::parse(indexer_config::ConfigPrefix::Service, cli.config.as_ref())
.map_err(|e| {
error!(
"Invalid configuration file `{}`: {}",
cli.config.display(),
"Invalid configuration file `{}`: {}, if a value is missing you can also use \
--config to fill the rest of the values",
cli.config.unwrap_or_default().display(),
e
);
anyhow!(e)
Expand Down
13 changes: 11 additions & 2 deletions tap-agent/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use indexer_config::{Config as IndexerConfig, ConfigPrefix};
use reqwest::Url;
use std::path::PathBuf;
use std::{collections::HashMap, str::FromStr};
use tracing::error;

use anyhow::Result;
use thegraph_core::{Address, DeploymentId};
Expand All @@ -17,7 +18,7 @@ pub struct Cli {
/// Path to the configuration file.
/// See https://github.com/graphprotocol/indexer-rs/tree/main/tap-agent for examples.
#[arg(long, value_name = "FILE", verbatim_doc_comment)]
pub config: PathBuf,
pub config: Option<PathBuf>,
}

impl From<IndexerConfig> for Config {
Expand Down Expand Up @@ -182,7 +183,15 @@ impl Config {
pub fn from_cli() -> Result<Self> {
let cli = Cli::parse();
let indexer_config =
IndexerConfig::parse(ConfigPrefix::Tap, &cli.config).map_err(|e| anyhow::anyhow!(e))?;
IndexerConfig::parse(ConfigPrefix::Tap, cli.config.as_ref()).map_err(|e| {
error!(
"Invalid configuration file `{}`: {}, if a value is missing you can also use \
--config to fill the rest of the values",
cli.config.unwrap_or_default().display(),
e
);
anyhow::anyhow!(e)
})?;
let config: Config = indexer_config.into();

// Enables tracing under RUST_LOG variable
Expand Down
Loading