scouter_settings/
lib.rs

1use base64::prelude::*;
2use scouter_types::StorageType;
3use std::env;
4use tracing::warn;
5
6pub mod auth;
7pub mod database;
8pub mod events;
9pub mod http;
10pub mod polling;
11pub mod storage;
12
13use crate::events::HttpConsumerSettings;
14pub use auth::AuthSettings;
15pub use database::DatabaseSettings;
16pub use events::{KafkaSettings, RabbitMQSettings, RedisSettings};
17pub use http::HTTPConfig;
18pub use polling::PollingSettings;
19pub use storage::ObjectStorageSettings;
20
21fn generate_default_secret() -> String {
22    // Creates a deterministic key for development purposes
23    // Should be replaced with a proper secret in production
24    let mut key = [0u8; 32];
25    for (i, item) in key.iter_mut().enumerate() {
26        // Different pattern than the JWT secret (reversed index)
27        *item = (31 - i) as u8;
28    }
29
30    BASE64_STANDARD.encode(key)
31}
32
33#[derive(Debug, Clone)]
34pub struct ScouterServerConfig {
35    pub polling_settings: PollingSettings,
36    pub database_settings: DatabaseSettings,
37    pub kafka_settings: Option<KafkaSettings>,
38    pub rabbitmq_settings: Option<RabbitMQSettings>,
39    pub redis_settings: Option<RedisSettings>,
40    pub http_consumer_settings: HttpConsumerSettings,
41    pub auth_settings: AuthSettings,
42    pub bootstrap_key: String,
43    pub storage_settings: ObjectStorageSettings,
44}
45
46impl ScouterServerConfig {
47    fn get_storage_type(storage_uri: &str) -> StorageType {
48        let storage_uri_lower = storage_uri.to_lowercase();
49        if storage_uri_lower.starts_with("gs://") {
50            StorageType::Google
51        } else if storage_uri_lower.starts_with("s3://") {
52            StorageType::Aws
53        } else if storage_uri_lower.starts_with("az://") {
54            StorageType::Azure
55        } else {
56            StorageType::Local
57        }
58    }
59}
60
61impl Default for ScouterServerConfig {
62    fn default() -> Self {
63        let polling = PollingSettings::default();
64        let database = DatabaseSettings::default();
65        let kafka = if env::var("KAFKA_BROKERS").is_ok() {
66            Some(KafkaSettings::default())
67        } else {
68            None
69        };
70
71        let rabbitmq = if env::var("RABBITMQ_ADDR").is_ok() {
72            Some(RabbitMQSettings::default())
73        } else {
74            None
75        };
76
77        let redis = if std::env::var("REDIS_ADDR").is_ok() {
78            Some(RedisSettings::default())
79        } else {
80            None
81        };
82        let http_consumer_settings = HttpConsumerSettings::default();
83
84        let auth_settings = AuthSettings {
85            jwt_secret: env::var("SCOUTER_ENCRYPT_SECRET").unwrap_or_else(|_| {
86                warn!(
87                    "Using default secret for encryption 
88                        This is not recommended for production use."
89                );
90                generate_default_secret()
91            }),
92            refresh_secret: env::var("SCOUTER_REFRESH_SECRET").unwrap_or_else(|_| {
93                warn!(
94                    "Using default secret for refreshing. 
95                        This is not recommended for production use."
96                );
97
98                generate_default_secret()
99            }),
100        };
101
102        let bootstrap_key =
103            env::var("SCOUTER_BOOTSTRAP_KEY").unwrap_or_else(|_| generate_default_secret());
104
105        Self {
106            polling_settings: polling,
107            database_settings: database,
108            kafka_settings: kafka,
109            rabbitmq_settings: rabbitmq,
110            redis_settings: redis,
111            auth_settings,
112            bootstrap_key,
113            http_consumer_settings,
114            storage_settings: ObjectStorageSettings::default(),
115        }
116    }
117}
118
119impl ScouterServerConfig {
120    pub fn kafka_enabled(&self) -> bool {
121        self.kafka_settings.is_some()
122    }
123
124    pub fn rabbitmq_enabled(&self) -> bool {
125        self.rabbitmq_settings.is_some()
126    }
127
128    pub fn redis_enabled(&self) -> bool {
129        self.redis_settings.is_some()
130    }
131}