Skip to content

Commit 2bb7f6d

Browse files
committed
feat: enable overwrite Configuration values using env vars
Enable Figment ability to overwrite all config options with env vars. We are currently overwriting only this value: ```toml [http_api.access_tokens] admin = "MyAccessToken" ``` With the env var `TORRUST_TRACKER_API_ADMIN_TOKEN`. The name we gave to the env var does nto follow Figment convention which is `TORRUST_TRACKER_HTTP_API.ACCESS_TOKENS.ADMIN`. We have to keep both options until we remove the old one in the rest of the code.
1 parent 7eb469a commit 2bb7f6d

File tree

1 file changed

+91
-47
lines changed
  • packages/configuration/src/v1

1 file changed

+91
-47
lines changed

packages/configuration/src/v1/mod.rs

+91-47
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ use std::fs;
239239
use std::net::IpAddr;
240240
use std::str::FromStr;
241241

242-
use figment::providers::{Format, Toml};
242+
use figment::providers::{Env, Format, Toml};
243243
use figment::Figment;
244244
use serde::{Deserialize, Serialize};
245245
use torrust_tracker_primitives::{DatabaseDriver, TrackerMode};
@@ -400,6 +400,16 @@ impl Configuration {
400400
/// Will return `Err` if `path` does not exist or has a bad configuration.
401401
pub fn load_from_file(path: &str) -> Result<Configuration, Error> {
402402
let figment = Figment::new().merge(Toml::file(path));
403+
//.merge(Env::prefixed("TORRUST_TRACKER_"));
404+
405+
// code-review: merging values from env vars makes the test
406+
// "configuration_should_be_loaded_from_a_toml_config_file" fail.
407+
//
408+
// It's because this line in a new test:
409+
//
410+
// jail.set_env("TORRUST_TRACKER_HTTP_API.ACCESS_TOKENS.ADMIN", "NewToken");
411+
//
412+
// It seems env vars are shared between tests.
403413

404414
let config: Configuration = figment.extract()?;
405415

@@ -427,7 +437,9 @@ impl Configuration {
427437
///
428438
/// Will return `Err` if the environment variable does not exist or has a bad configuration.
429439
pub fn load(info: &Info) -> Result<Configuration, Error> {
430-
let figment = Figment::new().merge(Toml::string(&info.tracker_toml));
440+
let figment = Figment::new()
441+
.merge(Toml::string(&info.tracker_toml))
442+
.merge(Env::prefixed("TORRUST_TRACKER_"));
431443

432444
let mut config: Configuration = figment.extract()?;
433445

@@ -463,58 +475,67 @@ impl Configuration {
463475

464476
#[cfg(test)]
465477
mod tests {
466-
use figment::providers::{Format, Toml};
478+
use figment::providers::{Env, Format, Toml};
467479
use figment::Figment;
468480

469481
use crate::v1::Configuration;
470482

483+
#[cfg(test)]
484+
fn default_config_toml() -> String {
485+
let config = r#"log_level = "info"
486+
mode = "public"
487+
db_driver = "Sqlite3"
488+
db_path = "./storage/tracker/lib/database/sqlite3.db"
489+
announce_interval = 120
490+
min_announce_interval = 120
491+
on_reverse_proxy = false
492+
external_ip = "0.0.0.0"
493+
tracker_usage_statistics = true
494+
persistent_torrent_completed_stat = false
495+
max_peer_timeout = 900
496+
inactive_peer_cleanup_interval = 600
497+
remove_peerless_torrents = true
498+
499+
[[udp_trackers]]
500+
enabled = false
501+
bind_address = "0.0.0.0:6969"
502+
503+
[[http_trackers]]
504+
enabled = false
505+
bind_address = "0.0.0.0:7070"
506+
ssl_enabled = false
507+
ssl_cert_path = ""
508+
ssl_key_path = ""
509+
510+
[http_api]
511+
enabled = true
512+
bind_address = "127.0.0.1:1212"
513+
ssl_enabled = false
514+
ssl_cert_path = ""
515+
ssl_key_path = ""
516+
517+
[http_api.access_tokens]
518+
admin = "MyAccessToken"
519+
520+
[health_check_api]
521+
bind_address = "127.0.0.1:1313"
522+
"#
523+
.lines()
524+
.map(str::trim_start)
525+
.collect::<Vec<&str>>()
526+
.join("\n");
527+
config
528+
}
529+
471530
#[test]
472531
fn configuration_should_be_loaded_from_a_toml_config_file() {
473532
figment::Jail::expect_with(|jail| {
474-
jail.create_file(
475-
"Config.toml",
476-
r#"
477-
log_level = "info"
478-
mode = "public"
479-
db_driver = "Sqlite3"
480-
db_path = "./storage/tracker/lib/database/sqlite3.db"
481-
announce_interval = 120
482-
min_announce_interval = 120
483-
on_reverse_proxy = false
484-
external_ip = "0.0.0.0"
485-
tracker_usage_statistics = true
486-
persistent_torrent_completed_stat = false
487-
max_peer_timeout = 900
488-
inactive_peer_cleanup_interval = 600
489-
remove_peerless_torrents = true
490-
491-
[[udp_trackers]]
492-
enabled = false
493-
bind_address = "0.0.0.0:6969"
494-
495-
[[http_trackers]]
496-
enabled = false
497-
bind_address = "0.0.0.0:7070"
498-
ssl_enabled = false
499-
ssl_cert_path = ""
500-
ssl_key_path = ""
501-
502-
[http_api]
503-
enabled = true
504-
bind_address = "127.0.0.1:1212"
505-
ssl_enabled = false
506-
ssl_cert_path = ""
507-
ssl_key_path = ""
508-
509-
[http_api.access_tokens]
510-
admin = "MyAccessToken"
511-
512-
[health_check_api]
513-
bind_address = "127.0.0.1:1313"
514-
"#,
515-
)?;
516-
517-
let figment = Figment::new().merge(Toml::file("Config.toml"));
533+
jail.create_file("Config.toml", &default_config_toml())?;
534+
535+
// todo: replace with Configuration method
536+
let figment = Figment::new()
537+
.merge(Toml::file("Config.toml"))
538+
.merge(Env::prefixed("TORRUST_TRACKER_"));
518539

519540
let config: Configuration = figment.extract()?;
520541

@@ -523,4 +544,27 @@ mod tests {
523544
Ok(())
524545
});
525546
}
547+
548+
#[test]
549+
fn configuration_should_allow_to_overwrite_the_default_tracker_api_token_for_admin() {
550+
figment::Jail::expect_with(|jail| {
551+
jail.create_file("Config.toml", &default_config_toml())?;
552+
553+
jail.set_env("TORRUST_TRACKER_HTTP_API.ACCESS_TOKENS.ADMIN", "NewToken");
554+
555+
// todo: replace with Configuration method
556+
let figment = Figment::new()
557+
.merge(Toml::file("Config.toml"))
558+
.merge(Env::prefixed("TORRUST_TRACKER_"));
559+
560+
let config: Configuration = figment.extract()?;
561+
562+
assert_eq!(
563+
config.http_api.access_tokens.get("admin"),
564+
Some("NewToken".to_owned()).as_ref()
565+
);
566+
567+
Ok(())
568+
});
569+
}
526570
}

0 commit comments

Comments
 (0)