Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

brokkr-utils::config Rust

Structs

brokkr-utils::config::Settings

pub

Derives: Debug, Deserialize, Clone

Represents the main settings structure for the application

Fields

NameTypeDescription
databaseDatabaseDatabase configuration
logLogLogging configuration
pakPAKPAK configuration
agentAgentAgent configuration
brokerBrokerBroker configuration
corsCorsCORS configuration
telemetryTelemetryTelemetry configuration

Methods

new pub
#![allow(unused)]
fn main() {
fn new (file : Option < String >) -> Result < Self , ConfigError >
}

Creates a new Settings instance

Parameters:

NameTypeDescription
file-An optional path to a configuration file

Returns:

Returns a Result containing the Settings instance or a ConfigError

Source
#![allow(unused)]
fn main() {
    pub fn new(file: Option<String>) -> Result<Self, ConfigError> {
        // Start with default settings from the embedded TOML file
        let mut s = Config::builder()
            .add_source(File::from_str(DEFAULT_SETTINGS, config::FileFormat::Toml));

        // If a configuration file is provided, add it as a source
        s = match file {
            Some(x) => s.add_source(File::with_name(x.as_str())),
            None => s,
        };

        // Add environment variables as a source, prefixed with "BROKKR" and using "__" as a separator
        s = s.add_source(Environment::with_prefix("BROKKR").separator("__"));

        // Build the configuration
        let settings = s.build().unwrap();

        // Deserialize the configuration into a Settings instance
        settings.try_deserialize()
    }
}

brokkr-utils::config::Cors

pub

Derives: Debug, Deserialize, Clone

Represents the CORS configuration

Fields

NameTypeDescription
allowed_originsVec < String >Allowed origins for CORS requests
Use “*” to allow all origins (not recommended for production)
Can be set as comma-separated string via env var: “origin1,origin2”
allowed_methodsVec < String >Allowed HTTP methods
Can be set as comma-separated string via env var: “GET,POST,PUT”
allowed_headersVec < String >Allowed HTTP headers
Can be set as comma-separated string via env var: “Authorization,Content-Type”
max_age_secondsu64Max age for preflight cache in seconds

brokkr-utils::config::Broker

pub

Derives: Debug, Deserialize, Clone

Fields

NameTypeDescription
pak_hashOption < String >PAK Hash
diagnostic_cleanup_interval_secondsOption < u64 >Interval for diagnostic cleanup task in seconds (default: 900 = 15 minutes)
diagnostic_max_age_hoursOption < i64 >Maximum age for completed/expired diagnostics before deletion in hours (default: 1)
webhook_encryption_keyOption < String >Webhook encryption key (hex-encoded, 32 bytes for AES-256)
If not provided, a random key will be generated on startup (not recommended for production)
webhook_delivery_interval_secondsOption < u64 >Webhook delivery worker interval in seconds (default: 5)
webhook_delivery_batch_sizeOption < i64 >Webhook delivery batch size (default: 50)
webhook_cleanup_retention_daysOption < i64 >Webhook delivery cleanup retention in days (default: 7)
audit_log_retention_daysOption < i64 >Audit log retention in days (default: 90)
auth_cache_ttl_secondsOption < u64 >Auth cache TTL in seconds (default: 60). Set to 0 to disable caching.

brokkr-utils::config::Agent

pub

Derives: Debug, Deserialize, Clone

Represents the agent configuration

Fields

NameTypeDescription
broker_urlStringBroker URL
polling_intervalu64Polling interval in seconds
kubeconfig_pathOption < String >Kubeconfig path
max_retriesu32Max number of retries
pakStringPAK
agent_nameStringAgent name
cluster_nameStringCluster name
max_event_message_retriesusizeMax number of retries for event messages
event_message_retry_delayu64Delay between event message retries in seconds
health_portOption < u16 >Health check HTTP server port
deployment_health_enabledOption < bool >Whether deployment health checking is enabled
deployment_health_intervalOption < u64 >Interval for deployment health checks in seconds

brokkr-utils::config::Database

pub

Derives: Debug, Deserialize, Clone

Represents the database configuration

Fields

NameTypeDescription
urlStringDatabase connection URL
schemaOption < String >Optional schema name for multi-tenant isolation

brokkr-utils::config::Log

pub

Derives: Debug, Deserialize, Clone

Represents the logging configuration

Fields

NameTypeDescription
levelStringLog level (e.g., “info”, “debug”, “warn”, “error”)
formatStringLog format: “text” for human-readable, “json” for structured JSON

brokkr-utils::config::Telemetry

pub

Derives: Debug, Deserialize, Clone

Represents the telemetry (OpenTelemetry) configuration with hierarchical overrides

Fields

NameTypeDescription
enabledboolWhether telemetry is enabled (base default)
otlp_endpointStringOTLP endpoint for trace export (gRPC)
service_nameStringService name for traces
sampling_ratef64Sampling rate (0.0 to 1.0)
brokerTelemetryOverrideBroker-specific overrides
agentTelemetryOverrideAgent-specific overrides

Methods

for_broker pub
#![allow(unused)]
fn main() {
fn for_broker (& self) -> ResolvedTelemetry
}

Get resolved telemetry config for broker (base merged with broker overrides)

Source
#![allow(unused)]
fn main() {
    pub fn for_broker(&self) -> ResolvedTelemetry {
        ResolvedTelemetry {
            enabled: self.broker.enabled.unwrap_or(self.enabled),
            otlp_endpoint: self
                .broker
                .otlp_endpoint
                .clone()
                .unwrap_or_else(|| self.otlp_endpoint.clone()),
            service_name: self
                .broker
                .service_name
                .clone()
                .unwrap_or_else(|| self.service_name.clone()),
            sampling_rate: self.broker.sampling_rate.unwrap_or(self.sampling_rate),
        }
    }
}
for_agent pub
#![allow(unused)]
fn main() {
fn for_agent (& self) -> ResolvedTelemetry
}

Get resolved telemetry config for agent (base merged with agent overrides)

Source
#![allow(unused)]
fn main() {
    pub fn for_agent(&self) -> ResolvedTelemetry {
        ResolvedTelemetry {
            enabled: self.agent.enabled.unwrap_or(self.enabled),
            otlp_endpoint: self
                .agent
                .otlp_endpoint
                .clone()
                .unwrap_or_else(|| self.otlp_endpoint.clone()),
            service_name: self
                .agent
                .service_name
                .clone()
                .unwrap_or_else(|| self.service_name.clone()),
            sampling_rate: self.agent.sampling_rate.unwrap_or(self.sampling_rate),
        }
    }
}

brokkr-utils::config::TelemetryOverride

pub

Derives: Debug, Deserialize, Clone, Default

Component-specific telemetry overrides (all fields optional)

Fields

NameTypeDescription
enabledOption < bool >Override enabled flag
otlp_endpointOption < String >Override OTLP endpoint
service_nameOption < String >Override service name
sampling_rateOption < f64 >Override sampling rate

brokkr-utils::config::ResolvedTelemetry

pub

Derives: Debug, Clone

Resolved telemetry configuration after merging base with overrides

Fields

NameTypeDescription
enabledbool
otlp_endpointString
service_nameString
sampling_ratef64

brokkr-utils::config::PAK

pub

Derives: Debug, Deserialize, Clone

Represents the PAK configuration

Fields

NameTypeDescription
prefixOption < String >PAK prefix
digestOption < String >Digest algorithm for PAK
rngOption < String >RNG type for PAK
short_token_lengthOption < usize >Short token length for PAK
short_token_length_strOption < String >Short token length as a string
short_token_prefixOption < String >Prefix for short tokens
long_token_lengthOption < usize >Long token length for PAK
long_token_length_strOption < String >Long token length as a string

Methods

short_length_as_str pub
#![allow(unused)]
fn main() {
fn short_length_as_str (& mut self)
}

Convert short token length to string

Source
#![allow(unused)]
fn main() {
    pub fn short_length_as_str(&mut self) {
        self.short_token_length_str = self.short_token_length.map(|v| v.to_string());
    }
}
long_length_as_str pub
#![allow(unused)]
fn main() {
fn long_length_as_str (& mut self)
}

Convert long token length to string

Source
#![allow(unused)]
fn main() {
    pub fn long_length_as_str(&mut self) {
        self.long_token_length_str = self.long_token_length.map(|v| v.to_string());
    }
}

brokkr-utils::config::DynamicConfig

pub

Derives: Debug, Clone

Dynamic configuration values that can be hot-reloaded at runtime.

These settings can be updated without restarting the application. Changes are applied atomically via the RwLock in ReloadableConfig.

Fields

NameTypeDescription
log_levelStringLog level (e.g., “info”, “debug”, “warn”, “error”)
diagnostic_cleanup_interval_secondsu64Interval for diagnostic cleanup task in seconds
diagnostic_max_age_hoursi64Maximum age for completed/expired diagnostics before deletion in hours
webhook_delivery_interval_secondsu64Webhook delivery worker interval in seconds
webhook_delivery_batch_sizei64Webhook delivery batch size
webhook_cleanup_retention_daysi64Webhook delivery cleanup retention in days
cors_allowed_originsVec < String >Allowed origins for CORS requests
cors_max_age_secondsu64Max age for CORS preflight cache in seconds

Methods

from_settings pub
#![allow(unused)]
fn main() {
fn from_settings (settings : & Settings) -> Self
}

Create DynamicConfig from Settings

Source
#![allow(unused)]
fn main() {
    pub fn from_settings(settings: &Settings) -> Self {
        Self {
            log_level: settings.log.level.clone(),
            diagnostic_cleanup_interval_seconds: settings
                .broker
                .diagnostic_cleanup_interval_seconds
                .unwrap_or(900),
            diagnostic_max_age_hours: settings.broker.diagnostic_max_age_hours.unwrap_or(1),
            webhook_delivery_interval_seconds: settings
                .broker
                .webhook_delivery_interval_seconds
                .unwrap_or(5),
            webhook_delivery_batch_size: settings.broker.webhook_delivery_batch_size.unwrap_or(50),
            webhook_cleanup_retention_days: settings
                .broker
                .webhook_cleanup_retention_days
                .unwrap_or(7),
            cors_allowed_origins: settings.cors.allowed_origins.clone(),
            cors_max_age_seconds: settings.cors.max_age_seconds,
        }
    }
}

brokkr-utils::config::ConfigChange

pub

Derives: Debug, Clone

Represents a configuration change detected during reload

Fields

NameTypeDescription
keyStringThe configuration key that changed
old_valueStringThe old value (as string for display)
new_valueStringThe new value (as string for display)

brokkr-utils::config::ReloadableConfig

pub

Derives: Clone

Configuration wrapper that separates static (restart-required) settings from dynamic (hot-reloadable) settings.

Static settings are immutable after creation and require an application restart to change. Dynamic settings can be updated at runtime via the reload() method.

Examples:

use brokkr_utils::config::ReloadableConfig;

let config = ReloadableConfig::new(None)?;

// Read dynamic config (thread-safe)
let log_level = config.log_level();

// Reload config from sources
let changes = config.reload()?;
for change in changes {
    println!("Changed {}: {} -> {}", change.key, change.old_value, change.new_value);
}

Fields

NameTypeDescription
static_configSettingsStatic configuration that requires restart to change
dynamicArc < RwLock < DynamicConfig > >Dynamic configuration that can be hot-reloaded
config_fileOption < String >Optional path to config file for reloading

Methods

new pub
#![allow(unused)]
fn main() {
fn new (file : Option < String >) -> Result < Self , ConfigError >
}

Creates a new ReloadableConfig instance

Parameters:

NameTypeDescription
file-An optional path to a configuration file

Returns:

Returns a Result containing the ReloadableConfig instance or a ConfigError

Source
#![allow(unused)]
fn main() {
    pub fn new(file: Option<String>) -> Result<Self, ConfigError> {
        let settings = Settings::new(file.clone())?;
        let dynamic = DynamicConfig::from_settings(&settings);

        Ok(Self {
            static_config: settings,
            dynamic: Arc::new(RwLock::new(dynamic)),
            config_file: file,
        })
    }
}
from_settings pub
#![allow(unused)]
fn main() {
fn from_settings (settings : Settings , config_file : Option < String >) -> Self
}

Creates a ReloadableConfig from an existing Settings instance

Parameters:

NameTypeDescription
settings-The Settings instance to wrap
config_file-An optional path to the config file for future reloads

Returns:

Returns a ReloadableConfig instance

Source
#![allow(unused)]
fn main() {
    pub fn from_settings(settings: Settings, config_file: Option<String>) -> Self {
        let dynamic = DynamicConfig::from_settings(&settings);

        Self {
            static_config: settings,
            dynamic: Arc::new(RwLock::new(dynamic)),
            config_file,
        }
    }
}
static_config pub
#![allow(unused)]
fn main() {
fn static_config (& self) -> & Settings
}

Get a reference to the static (immutable) settings

These settings require an application restart to change.

Source
#![allow(unused)]
fn main() {
    pub fn static_config(&self) -> &Settings {
        &self.static_config
    }
}
reload pub
#![allow(unused)]
fn main() {
fn reload (& self) -> Result < Vec < ConfigChange > , ConfigError >
}

Reload dynamic configuration from sources (file + environment)

Returns a list of configuration changes that were applied. Thread-safe: blocks writers during reload.

Source
#![allow(unused)]
fn main() {
    pub fn reload(&self) -> Result<Vec<ConfigChange>, ConfigError> {
        // Load fresh settings from sources
        let new_settings = Settings::new(self.config_file.clone())?;
        let new_dynamic = DynamicConfig::from_settings(&new_settings);

        // Acquire write lock and compute changes
        let mut dynamic = self
            .dynamic
            .write()
            .map_err(|e| ConfigError::Message(format!("Failed to acquire write lock: {}", e)))?;

        let mut changes = Vec::new();

        // Check each field for changes
        if dynamic.log_level != new_dynamic.log_level {
            changes.push(ConfigChange {
                key: "log.level".to_string(),
                old_value: dynamic.log_level.clone(),
                new_value: new_dynamic.log_level.clone(),
            });
        }
        if dynamic.diagnostic_cleanup_interval_seconds
            != new_dynamic.diagnostic_cleanup_interval_seconds
        {
            changes.push(ConfigChange {
                key: "broker.diagnostic_cleanup_interval_seconds".to_string(),
                old_value: dynamic.diagnostic_cleanup_interval_seconds.to_string(),
                new_value: new_dynamic.diagnostic_cleanup_interval_seconds.to_string(),
            });
        }
        if dynamic.diagnostic_max_age_hours != new_dynamic.diagnostic_max_age_hours {
            changes.push(ConfigChange {
                key: "broker.diagnostic_max_age_hours".to_string(),
                old_value: dynamic.diagnostic_max_age_hours.to_string(),
                new_value: new_dynamic.diagnostic_max_age_hours.to_string(),
            });
        }
        if dynamic.webhook_delivery_interval_seconds
            != new_dynamic.webhook_delivery_interval_seconds
        {
            changes.push(ConfigChange {
                key: "broker.webhook_delivery_interval_seconds".to_string(),
                old_value: dynamic.webhook_delivery_interval_seconds.to_string(),
                new_value: new_dynamic.webhook_delivery_interval_seconds.to_string(),
            });
        }
        if dynamic.webhook_delivery_batch_size != new_dynamic.webhook_delivery_batch_size {
            changes.push(ConfigChange {
                key: "broker.webhook_delivery_batch_size".to_string(),
                old_value: dynamic.webhook_delivery_batch_size.to_string(),
                new_value: new_dynamic.webhook_delivery_batch_size.to_string(),
            });
        }
        if dynamic.webhook_cleanup_retention_days != new_dynamic.webhook_cleanup_retention_days {
            changes.push(ConfigChange {
                key: "broker.webhook_cleanup_retention_days".to_string(),
                old_value: dynamic.webhook_cleanup_retention_days.to_string(),
                new_value: new_dynamic.webhook_cleanup_retention_days.to_string(),
            });
        }
        if dynamic.cors_allowed_origins != new_dynamic.cors_allowed_origins {
            changes.push(ConfigChange {
                key: "cors.allowed_origins".to_string(),
                old_value: format!("{:?}", dynamic.cors_allowed_origins),
                new_value: format!("{:?}", new_dynamic.cors_allowed_origins),
            });
        }
        if dynamic.cors_max_age_seconds != new_dynamic.cors_max_age_seconds {
            changes.push(ConfigChange {
                key: "cors.max_age_seconds".to_string(),
                old_value: dynamic.cors_max_age_seconds.to_string(),
                new_value: new_dynamic.cors_max_age_seconds.to_string(),
            });
        }

        // Apply the new configuration
        *dynamic = new_dynamic;

        Ok(changes)
    }
}
log_level pub
#![allow(unused)]
fn main() {
fn log_level (& self) -> String
}

Get current log level

Source
#![allow(unused)]
fn main() {
    pub fn log_level(&self) -> String {
        self.dynamic
            .read()
            .map(|d| d.log_level.clone())
            .unwrap_or_else(|_| "info".to_string())
    }
}
diagnostic_cleanup_interval_seconds pub
#![allow(unused)]
fn main() {
fn diagnostic_cleanup_interval_seconds (& self) -> u64
}

Get diagnostic cleanup interval in seconds

Source
#![allow(unused)]
fn main() {
    pub fn diagnostic_cleanup_interval_seconds(&self) -> u64 {
        self.dynamic
            .read()
            .map(|d| d.diagnostic_cleanup_interval_seconds)
            .unwrap_or(900)
    }
}
diagnostic_max_age_hours pub
#![allow(unused)]
fn main() {
fn diagnostic_max_age_hours (& self) -> i64
}

Get diagnostic max age in hours

Source
#![allow(unused)]
fn main() {
    pub fn diagnostic_max_age_hours(&self) -> i64 {
        self.dynamic
            .read()
            .map(|d| d.diagnostic_max_age_hours)
            .unwrap_or(1)
    }
}
webhook_delivery_interval_seconds pub
#![allow(unused)]
fn main() {
fn webhook_delivery_interval_seconds (& self) -> u64
}

Get webhook delivery interval in seconds

Source
#![allow(unused)]
fn main() {
    pub fn webhook_delivery_interval_seconds(&self) -> u64 {
        self.dynamic
            .read()
            .map(|d| d.webhook_delivery_interval_seconds)
            .unwrap_or(5)
    }
}
webhook_delivery_batch_size pub
#![allow(unused)]
fn main() {
fn webhook_delivery_batch_size (& self) -> i64
}

Get webhook delivery batch size

Source
#![allow(unused)]
fn main() {
    pub fn webhook_delivery_batch_size(&self) -> i64 {
        self.dynamic
            .read()
            .map(|d| d.webhook_delivery_batch_size)
            .unwrap_or(50)
    }
}
webhook_cleanup_retention_days pub
#![allow(unused)]
fn main() {
fn webhook_cleanup_retention_days (& self) -> i64
}

Get webhook cleanup retention in days

Source
#![allow(unused)]
fn main() {
    pub fn webhook_cleanup_retention_days(&self) -> i64 {
        self.dynamic
            .read()
            .map(|d| d.webhook_cleanup_retention_days)
            .unwrap_or(7)
    }
}
cors_allowed_origins pub
#![allow(unused)]
fn main() {
fn cors_allowed_origins (& self) -> Vec < String >
}

Get CORS allowed origins

Source
#![allow(unused)]
fn main() {
    pub fn cors_allowed_origins(&self) -> Vec<String> {
        self.dynamic
            .read()
            .map(|d| d.cors_allowed_origins.clone())
            .unwrap_or_else(|_| vec!["*".to_string()])
    }
}
cors_max_age_seconds pub
#![allow(unused)]
fn main() {
fn cors_max_age_seconds (& self) -> u64
}

Get CORS max age in seconds

Source
#![allow(unused)]
fn main() {
    pub fn cors_max_age_seconds(&self) -> u64 {
        self.dynamic
            .read()
            .map(|d| d.cors_max_age_seconds)
            .unwrap_or(3600)
    }
}
dynamic_snapshot pub
#![allow(unused)]
fn main() {
fn dynamic_snapshot (& self) -> Option < DynamicConfig >
}

Get a snapshot of all dynamic config values

Source
#![allow(unused)]
fn main() {
    pub fn dynamic_snapshot(&self) -> Option<DynamicConfig> {
        self.dynamic.read().ok().map(|d| d.clone())
    }
}

Functions

brokkr-utils::config::deserialize_string_or_vec

private

#![allow(unused)]
fn main() {
fn deserialize_string_or_vec < 'de , D > (deserializer : D) -> Result < Vec < String > , D :: Error > where D : Deserializer < 'de > ,
}

Deserializes a comma-separated string or array into Vec This allows environment variables to be set as “value1,value2,value3” while also supporting proper arrays in config files

Source
#![allow(unused)]
fn main() {
fn deserialize_string_or_vec<'de, D>(deserializer: D) -> Result<Vec<String>, D::Error>
where
    D: Deserializer<'de>,
{
    use serde::de::{self, SeqAccess, Visitor};
    use std::fmt;

    struct StringOrVec;

    impl<'de> Visitor<'de> for StringOrVec {
        type Value = Vec<String>;

        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
            formatter.write_str("a string or sequence of strings")
        }

        fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
        where
            E: de::Error,
        {
            // Split by comma and trim whitespace
            Ok(value.split(',').map(|s| s.trim().to_string()).collect())
        }

        fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
        where
            A: SeqAccess<'de>,
        {
            let mut vec = Vec::new();
            while let Some(item) = seq.next_element::<String>()? {
                vec.push(item);
            }
            Ok(vec)
        }
    }

    deserializer.deserialize_any(StringOrVec)
}
}

brokkr-utils::config::default_log_format

private

#![allow(unused)]
fn main() {
fn default_log_format () -> String
}
Source
#![allow(unused)]
fn main() {
fn default_log_format() -> String {
    "text".to_string()
}
}

brokkr-utils::config::default_otlp_endpoint

private

#![allow(unused)]
fn main() {
fn default_otlp_endpoint () -> String
}
Source
#![allow(unused)]
fn main() {
fn default_otlp_endpoint() -> String {
    "http://localhost:4317".to_string()
}
}

brokkr-utils::config::default_service_name

private

#![allow(unused)]
fn main() {
fn default_service_name () -> String
}
Source
#![allow(unused)]
fn main() {
fn default_service_name() -> String {
    "brokkr".to_string()
}
}

brokkr-utils::config::default_sampling_rate

private

#![allow(unused)]
fn main() {
fn default_sampling_rate () -> f64
}
Source
#![allow(unused)]
fn main() {
fn default_sampling_rate() -> f64 {
    0.1
}
}