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