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 let mut key = [0u8; 32];
25 for (i, item) in key.iter_mut().enumerate() {
26 *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}