Skip to main content

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