From 445bd5361607d8dcf78fcab48450a8d10c6753b3 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Mon, 13 May 2024 14:10:09 +0100 Subject: [PATCH] feat: define only non-defaults in toml config templates After implementing the configuration with Figment, it's now possible to omit values if they have a default value. Therefore we don't need to add all options in templates. We only need to add values that are overwriting deffault values. --- packages/configuration/src/lib.rs | 28 ++++++- packages/configuration/src/v1/core.rs | 83 ++++++++++++++++--- .../configuration/src/v1/health_check_api.rs | 9 +- packages/configuration/src/v1/http_tracker.rs | 24 +++++- packages/configuration/src/v1/tracker_api.rs | 35 ++++++-- packages/configuration/src/v1/udp_tracker.rs | 16 +++- .../config/tracker.container.mysql.toml | 31 ------- .../config/tracker.container.sqlite3.toml | 32 ------- .../config/tracker.development.sqlite3.toml | 36 -------- .../config/tracker.e2e.container.sqlite3.toml | 28 ------- .../config/tracker.udp.benchmarking.toml | 32 ------- 11 files changed, 169 insertions(+), 185 deletions(-) diff --git a/packages/configuration/src/lib.rs b/packages/configuration/src/lib.rs index fdc02148..c393623d 100644 --- a/packages/configuration/src/lib.rs +++ b/packages/configuration/src/lib.rs @@ -120,12 +120,22 @@ pub struct AnnouncePolicy { impl Default for AnnouncePolicy { fn default() -> Self { Self { - interval: 120, - interval_min: 120, + interval: Self::default_interval(), + interval_min: Self::default_interval_min(), } } } +impl AnnouncePolicy { + fn default_interval() -> u32 { + 120 + } + + fn default_interval_min() -> u32 { + 120 + } +} + /// Errors that can occur when loading the configuration. #[derive(Error, Debug)] pub enum Error { @@ -166,12 +176,26 @@ impl From for Error { pub struct TslConfig { /// Path to the SSL certificate file. #[serde_as(as = "NoneAsEmptyString")] + #[serde(default = "TslConfig::default_ssl_cert_path")] pub ssl_cert_path: Option, /// Path to the SSL key file. #[serde_as(as = "NoneAsEmptyString")] + #[serde(default = "TslConfig::default_ssl_key_path")] pub ssl_key_path: Option, } +impl TslConfig { + #[allow(clippy::unnecessary_wraps)] + fn default_ssl_cert_path() -> Option { + Some(Utf8PathBuf::new()) + } + + #[allow(clippy::unnecessary_wraps)] + fn default_ssl_key_path() -> Option { + Some(Utf8PathBuf::new()) + } +} + #[derive(Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Clone)] #[serde(rename_all = "lowercase")] pub enum LogLevel { diff --git a/packages/configuration/src/v1/core.rs b/packages/configuration/src/v1/core.rs index ed907419..5d00c67a 100644 --- a/packages/configuration/src/v1/core.rs +++ b/packages/configuration/src/v1/core.rs @@ -10,58 +10,71 @@ use crate::{AnnouncePolicy, LogLevel}; pub struct Core { /// Logging level. Possible values are: `Off`, `Error`, `Warn`, `Info`, /// `Debug` and `Trace`. Default is `Info`. + #[serde(default = "Core::default_log_level")] pub log_level: Option, /// Tracker mode. See [`TrackerMode`] for more information. + #[serde(default = "Core::default_mode")] pub mode: TrackerMode, // Database configuration /// Database driver. Possible values are: `Sqlite3`, and `MySQL`. + #[serde(default = "Core::default_db_driver")] pub db_driver: DatabaseDriver, /// Database connection string. The format depends on the database driver. /// For `Sqlite3`, the format is `path/to/database.db`, for example: /// `./storage/tracker/lib/database/sqlite3.db`. /// For `Mysql`, the format is `mysql://db_user:db_user_password:port/db_name`, for /// example: `root:password@localhost:3306/torrust`. + #[serde(default = "Core::default_db_path")] pub db_path: String, /// See [`AnnouncePolicy::interval`] + #[serde(default = "AnnouncePolicy::default_interval")] pub announce_interval: u32, /// See [`AnnouncePolicy::interval_min`] + #[serde(default = "AnnouncePolicy::default_interval_min")] pub min_announce_interval: u32, /// Weather the tracker is behind a reverse proxy or not. /// If the tracker is behind a reverse proxy, the `X-Forwarded-For` header /// sent from the proxy will be used to get the client's IP address. + #[serde(default = "Core::default_on_reverse_proxy")] pub on_reverse_proxy: bool, /// The external IP address of the tracker. If the client is using a /// loopback IP address, this IP address will be used instead. If the peer /// is using a loopback IP address, the tracker assumes that the peer is /// in the same network as the tracker and will use the tracker's IP /// address instead. + #[serde(default = "Core::default_external_ip")] pub external_ip: Option, /// Weather the tracker should collect statistics about tracker usage. /// If enabled, the tracker will collect statistics like the number of /// connections handled, the number of announce requests handled, etc. /// Refer to the [`Tracker`](https://docs.rs/torrust-tracker) for more /// information about the collected metrics. + #[serde(default = "Core::default_tracker_usage_statistics")] pub tracker_usage_statistics: bool, /// If enabled the tracker will persist the number of completed downloads. /// That's how many times a torrent has been downloaded completely. + #[serde(default = "Core::default_persistent_torrent_completed_stat")] pub persistent_torrent_completed_stat: bool, // Cleanup job configuration /// Maximum time in seconds that a peer can be inactive before being /// considered an inactive peer. If a peer is inactive for more than this /// time, it will be removed from the torrent peer list. + #[serde(default = "Core::default_max_peer_timeout")] pub max_peer_timeout: u32, /// Interval in seconds that the cleanup job will run to remove inactive /// peers from the torrent peer list. + #[serde(default = "Core::default_inactive_peer_cleanup_interval")] pub inactive_peer_cleanup_interval: u64, /// If enabled, the tracker will remove torrents that have no peers. /// The clean up torrent job runs every `inactive_peer_cleanup_interval` /// seconds and it removes inactive peers. Eventually, the peer list of a /// torrent could be empty and the torrent will be removed if this option is /// enabled. + #[serde(default = "Core::default_remove_peerless_torrents")] pub remove_peerless_torrents: bool, } @@ -70,19 +83,67 @@ impl Default for Core { let announce_policy = AnnouncePolicy::default(); Self { - log_level: Some(LogLevel::Info), - mode: TrackerMode::Public, - db_driver: DatabaseDriver::Sqlite3, - db_path: String::from("./storage/tracker/lib/database/sqlite3.db"), + log_level: Self::default_log_level(), + mode: Self::default_mode(), + db_driver: Self::default_db_driver(), + db_path: Self::default_db_path(), announce_interval: announce_policy.interval, min_announce_interval: announce_policy.interval_min, - max_peer_timeout: 900, - on_reverse_proxy: false, - external_ip: Some(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0))), - tracker_usage_statistics: true, - persistent_torrent_completed_stat: false, - inactive_peer_cleanup_interval: 600, - remove_peerless_torrents: true, + max_peer_timeout: Self::default_max_peer_timeout(), + on_reverse_proxy: Self::default_on_reverse_proxy(), + external_ip: Self::default_external_ip(), + tracker_usage_statistics: Self::default_tracker_usage_statistics(), + persistent_torrent_completed_stat: Self::default_persistent_torrent_completed_stat(), + inactive_peer_cleanup_interval: Self::default_inactive_peer_cleanup_interval(), + remove_peerless_torrents: Self::default_remove_peerless_torrents(), } } } + +impl Core { + #[allow(clippy::unnecessary_wraps)] + fn default_log_level() -> Option { + Some(LogLevel::Info) + } + + fn default_mode() -> TrackerMode { + TrackerMode::Public + } + + fn default_db_driver() -> DatabaseDriver { + DatabaseDriver::Sqlite3 + } + + fn default_db_path() -> String { + String::from("./storage/tracker/lib/database/sqlite3.db") + } + + fn default_on_reverse_proxy() -> bool { + false + } + + #[allow(clippy::unnecessary_wraps)] + fn default_external_ip() -> Option { + Some(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0))) + } + + fn default_tracker_usage_statistics() -> bool { + true + } + + fn default_persistent_torrent_completed_stat() -> bool { + false + } + + fn default_max_peer_timeout() -> u32 { + 900 + } + + fn default_inactive_peer_cleanup_interval() -> u64 { + 600 + } + + fn default_remove_peerless_torrents() -> bool { + true + } +} diff --git a/packages/configuration/src/v1/health_check_api.rs b/packages/configuration/src/v1/health_check_api.rs index b8bfd2c1..61178fa8 100644 --- a/packages/configuration/src/v1/health_check_api.rs +++ b/packages/configuration/src/v1/health_check_api.rs @@ -11,13 +11,20 @@ pub struct HealthCheckApi { /// The format is `ip:port`, for example `127.0.0.1:1313`. If you want to /// listen to all interfaces, use `0.0.0.0`. If you want the operating /// system to choose a random port, use port `0`. + #[serde(default = "HealthCheckApi::default_bind_address")] pub bind_address: SocketAddr, } impl Default for HealthCheckApi { fn default() -> Self { Self { - bind_address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 1313), + bind_address: Self::default_bind_address(), } } } + +impl HealthCheckApi { + fn default_bind_address() -> SocketAddr { + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 1313) + } +} diff --git a/packages/configuration/src/v1/http_tracker.rs b/packages/configuration/src/v1/http_tracker.rs index 57b2d83a..b1fe1437 100644 --- a/packages/configuration/src/v1/http_tracker.rs +++ b/packages/configuration/src/v1/http_tracker.rs @@ -10,26 +10,44 @@ use crate::TslConfig; #[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub struct HttpTracker { /// Weather the HTTP tracker is enabled or not. + #[serde(default = "HttpTracker::default_enabled")] pub enabled: bool, /// The address the tracker will bind to. /// The format is `ip:port`, for example `0.0.0.0:6969`. If you want to /// listen to all interfaces, use `0.0.0.0`. If you want the operating /// system to choose a random port, use port `0`. + #[serde(default = "HttpTracker::default_bind_address")] pub bind_address: SocketAddr, /// Weather the HTTP tracker will use SSL or not. + #[serde(default = "HttpTracker::default_ssl_enabled")] pub ssl_enabled: bool, /// TSL config. Only used if `ssl_enabled` is true. #[serde(flatten)] + #[serde(default = "TslConfig::default")] pub tsl_config: TslConfig, } impl Default for HttpTracker { fn default() -> Self { Self { - enabled: false, - bind_address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 7070), - ssl_enabled: false, + enabled: Self::default_enabled(), + bind_address: Self::default_bind_address(), + ssl_enabled: Self::default_ssl_enabled(), tsl_config: TslConfig::default(), } } } + +impl HttpTracker { + fn default_enabled() -> bool { + false + } + + fn default_bind_address() -> SocketAddr { + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 7070) + } + + fn default_ssl_enabled() -> bool { + false + } +} diff --git a/packages/configuration/src/v1/tracker_api.rs b/packages/configuration/src/v1/tracker_api.rs index 5089c496..c2e3e5ee 100644 --- a/packages/configuration/src/v1/tracker_api.rs +++ b/packages/configuration/src/v1/tracker_api.rs @@ -13,40 +13,61 @@ pub type AccessTokens = HashMap; #[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub struct HttpApi { /// Weather the HTTP API is enabled or not. + #[serde(default = "HttpApi::default_enabled")] pub enabled: bool, /// The address the tracker will bind to. /// The format is `ip:port`, for example `0.0.0.0:6969`. If you want to /// listen to all interfaces, use `0.0.0.0`. If you want the operating /// system to choose a random port, use port `0`. + #[serde(default = "HttpApi::default_bind_address")] pub bind_address: SocketAddr, /// Weather the HTTP API will use SSL or not. + #[serde(default = "HttpApi::default_ssl_enabled")] pub ssl_enabled: bool, /// TSL config. Only used if `ssl_enabled` is true. #[serde(flatten)] + #[serde(default = "TslConfig::default")] pub tsl_config: TslConfig, /// Access tokens for the HTTP API. The key is a label identifying the /// token and the value is the token itself. The token is used to /// authenticate the user. All tokens are valid for all endpoints and have /// all permissions. + #[serde(default = "HttpApi::default_access_tokens")] pub access_tokens: AccessTokens, } impl Default for HttpApi { fn default() -> Self { Self { - enabled: true, - bind_address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 1212), - ssl_enabled: false, + enabled: Self::default_enabled(), + bind_address: Self::default_bind_address(), + ssl_enabled: Self::default_ssl_enabled(), tsl_config: TslConfig::default(), - access_tokens: [(String::from("admin"), String::from("MyAccessToken"))] - .iter() - .cloned() - .collect(), + access_tokens: Self::default_access_tokens(), } } } impl HttpApi { + fn default_enabled() -> bool { + true + } + + fn default_bind_address() -> SocketAddr { + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 1212) + } + + fn default_ssl_enabled() -> bool { + false + } + + fn default_access_tokens() -> AccessTokens { + [(String::from("admin"), String::from("MyAccessToken"))] + .iter() + .cloned() + .collect() + } + pub fn override_admin_token(&mut self, api_admin_token: &str) { self.access_tokens.insert("admin".to_string(), api_admin_token.to_string()); } diff --git a/packages/configuration/src/v1/udp_tracker.rs b/packages/configuration/src/v1/udp_tracker.rs index 1f772164..f8387202 100644 --- a/packages/configuration/src/v1/udp_tracker.rs +++ b/packages/configuration/src/v1/udp_tracker.rs @@ -5,18 +5,30 @@ use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone)] pub struct UdpTracker { /// Weather the UDP tracker is enabled or not. + #[serde(default = "UdpTracker::default_enabled")] pub enabled: bool, /// The address the tracker will bind to. /// The format is `ip:port`, for example `0.0.0.0:6969`. If you want to /// listen to all interfaces, use `0.0.0.0`. If you want the operating /// system to choose a random port, use port `0`. + #[serde(default = "UdpTracker::default_bind_address")] pub bind_address: SocketAddr, } impl Default for UdpTracker { fn default() -> Self { Self { - enabled: false, - bind_address: SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 6969), + enabled: Self::default_enabled(), + bind_address: Self::default_bind_address(), } } } + +impl UdpTracker { + fn default_enabled() -> bool { + false + } + + fn default_bind_address() -> SocketAddr { + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 6969) + } +} diff --git a/share/default/config/tracker.container.mysql.toml b/share/default/config/tracker.container.mysql.toml index f2db0622..7678327a 100644 --- a/share/default/config/tracker.container.mysql.toml +++ b/share/default/config/tracker.container.mysql.toml @@ -1,41 +1,10 @@ -announce_interval = 120 db_driver = "MySQL" db_path = "mysql://db_user:db_user_secret_password@mysql:3306/torrust_tracker" -external_ip = "0.0.0.0" -inactive_peer_cleanup_interval = 600 -log_level = "info" -max_peer_timeout = 900 -min_announce_interval = 120 -mode = "public" -on_reverse_proxy = false -persistent_torrent_completed_stat = false -remove_peerless_torrents = true -tracker_usage_statistics = true - -[[udp_trackers]] -bind_address = "0.0.0.0:6969" -enabled = false [[http_trackers]] -bind_address = "0.0.0.0:7070" -enabled = false ssl_cert_path = "/var/lib/torrust/tracker/tls/localhost.crt" -ssl_enabled = false ssl_key_path = "/var/lib/torrust/tracker/tls/localhost.key" [http_api] -bind_address = "0.0.0.0:1212" -enabled = true ssl_cert_path = "/var/lib/torrust/tracker/tls/localhost.crt" -ssl_enabled = false ssl_key_path = "/var/lib/torrust/tracker/tls/localhost.key" - -[http_api.access_tokens] -# Please override the admin token setting the environmental variable: -# `TORRUST_TRACKER__HTTP_API__ACCESS_TOKENS__ADMIN` -# The old variable name is deprecated: -# `TORRUST_TRACKER_API_ADMIN_TOKEN` -admin = "MyAccessToken" - -[health_check_api] -bind_address = "127.0.0.1:1313" diff --git a/share/default/config/tracker.container.sqlite3.toml b/share/default/config/tracker.container.sqlite3.toml index 4a3ba03b..da825928 100644 --- a/share/default/config/tracker.container.sqlite3.toml +++ b/share/default/config/tracker.container.sqlite3.toml @@ -1,41 +1,9 @@ -announce_interval = 120 -db_driver = "Sqlite3" db_path = "/var/lib/torrust/tracker/database/sqlite3.db" -external_ip = "0.0.0.0" -inactive_peer_cleanup_interval = 600 -log_level = "info" -max_peer_timeout = 900 -min_announce_interval = 120 -mode = "public" -on_reverse_proxy = false -persistent_torrent_completed_stat = false -remove_peerless_torrents = true -tracker_usage_statistics = true - -[[udp_trackers]] -bind_address = "0.0.0.0:6969" -enabled = false [[http_trackers]] -bind_address = "0.0.0.0:7070" -enabled = false ssl_cert_path = "/var/lib/torrust/tracker/tls/localhost.crt" -ssl_enabled = false ssl_key_path = "/var/lib/torrust/tracker/tls/localhost.key" [http_api] -bind_address = "0.0.0.0:1212" -enabled = true ssl_cert_path = "/var/lib/torrust/tracker/tls/localhost.crt" -ssl_enabled = false ssl_key_path = "/var/lib/torrust/tracker/tls/localhost.key" - -[http_api.access_tokens] -# Please override the admin token setting the environmental variable: -# `TORRUST_TRACKER__HTTP_API__ACCESS_TOKENS__ADMIN` -# The old variable name is deprecated: -# `TORRUST_TRACKER_API_ADMIN_TOKEN` -admin = "MyAccessToken" - -[health_check_api] -bind_address = "127.0.0.1:1313" diff --git a/share/default/config/tracker.development.sqlite3.toml b/share/default/config/tracker.development.sqlite3.toml index 62e5b478..bf647849 100644 --- a/share/default/config/tracker.development.sqlite3.toml +++ b/share/default/config/tracker.development.sqlite3.toml @@ -1,41 +1,5 @@ -announce_interval = 120 -db_driver = "Sqlite3" -db_path = "./storage/tracker/lib/database/sqlite3.db" -external_ip = "0.0.0.0" -inactive_peer_cleanup_interval = 600 -log_level = "info" -max_peer_timeout = 900 -min_announce_interval = 120 -mode = "public" -on_reverse_proxy = false -persistent_torrent_completed_stat = false -remove_peerless_torrents = true -tracker_usage_statistics = true - [[udp_trackers]] -bind_address = "0.0.0.0:6969" enabled = true [[http_trackers]] -bind_address = "0.0.0.0:7070" -enabled = true -ssl_cert_path = "" -ssl_enabled = false -ssl_key_path = "" - -[http_api] -bind_address = "127.0.0.1:1212" enabled = true -ssl_cert_path = "" -ssl_enabled = false -ssl_key_path = "" - -[http_api.access_tokens] -# Please override the admin token setting the environmental variable: -# `TORRUST_TRACKER__HTTP_API__ACCESS_TOKENS__ADMIN` -# The old variable name is deprecated: -# `TORRUST_TRACKER_API_ADMIN_TOKEN` -admin = "MyAccessToken" - -[health_check_api] -bind_address = "127.0.0.1:1313" diff --git a/share/default/config/tracker.e2e.container.sqlite3.toml b/share/default/config/tracker.e2e.container.sqlite3.toml index 3738704b..e7d8fa27 100644 --- a/share/default/config/tracker.e2e.container.sqlite3.toml +++ b/share/default/config/tracker.e2e.container.sqlite3.toml @@ -1,41 +1,13 @@ -announce_interval = 120 -db_driver = "Sqlite3" db_path = "/var/lib/torrust/tracker/database/sqlite3.db" -external_ip = "0.0.0.0" -inactive_peer_cleanup_interval = 600 -log_level = "info" -max_peer_timeout = 900 -min_announce_interval = 120 -mode = "public" -on_reverse_proxy = false -persistent_torrent_completed_stat = false -remove_peerless_torrents = true -tracker_usage_statistics = true [[udp_trackers]] -bind_address = "0.0.0.0:6969" enabled = true [[http_trackers]] -bind_address = "0.0.0.0:7070" enabled = true ssl_cert_path = "/var/lib/torrust/tracker/tls/localhost.crt" -ssl_enabled = false ssl_key_path = "/var/lib/torrust/tracker/tls/localhost.key" [http_api] -bind_address = "0.0.0.0:1212" -enabled = true ssl_cert_path = "/var/lib/torrust/tracker/tls/localhost.crt" -ssl_enabled = false ssl_key_path = "/var/lib/torrust/tracker/tls/localhost.key" - -[http_api.access_tokens] -# Please override the admin token setting the environmental variable: -# `TORRUST_TRACKER__HTTP_API__ACCESS_TOKENS__ADMIN` -# The old variable name is deprecated: -# `TORRUST_TRACKER_API_ADMIN_TOKEN` -admin = "MyAccessToken" - -[health_check_api] -bind_address = "0.0.0.0:1313" diff --git a/share/default/config/tracker.udp.benchmarking.toml b/share/default/config/tracker.udp.benchmarking.toml index 1e951d8f..00f62628 100644 --- a/share/default/config/tracker.udp.benchmarking.toml +++ b/share/default/config/tracker.udp.benchmarking.toml @@ -1,41 +1,9 @@ -announce_interval = 120 -db_driver = "Sqlite3" -db_path = "./storage/tracker/lib/database/sqlite3.db" -external_ip = "0.0.0.0" -inactive_peer_cleanup_interval = 600 log_level = "error" -max_peer_timeout = 900 -min_announce_interval = 120 -mode = "public" -on_reverse_proxy = false -persistent_torrent_completed_stat = false remove_peerless_torrents = false tracker_usage_statistics = false [[udp_trackers]] -bind_address = "0.0.0.0:6969" enabled = true -[[http_trackers]] -bind_address = "0.0.0.0:7070" -enabled = false -ssl_cert_path = "" -ssl_enabled = false -ssl_key_path = "" - [http_api] -bind_address = "127.0.0.1:1212" enabled = false -ssl_cert_path = "" -ssl_enabled = false -ssl_key_path = "" - -[http_api.access_tokens] -# Please override the admin token setting the environmental variable: -# `TORRUST_TRACKER__HTTP_API__ACCESS_TOKENS__ADMIN` -# The old variable name is deprecated: -# `TORRUST_TRACKER_API_ADMIN_TOKEN` -admin = "MyAccessToken" - -[health_check_api] -bind_address = "127.0.0.1:1313"