use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use crate::{
deserializers::string_list_deserializer,
entities::{
config::{DatabaseConfig, empty_or_redacted},
logger::{LogConfig, LogLevel, StdioLogMode},
},
};
pub mod args;
#[derive(Debug, Clone, Deserialize)]
pub struct Env {
#[serde(
default = "default_config_paths",
alias = "komodo_cli_config_path"
)]
pub komodo_cli_config_paths: Vec<PathBuf>,
#[serde(
default = "default_config_keywords",
alias = "komodo_cli_config_keyword"
)]
pub komodo_cli_config_keywords: Vec<String>,
#[serde(default = "super::default_merge_nested_config")]
pub komodo_cli_merge_nested_config: bool,
#[serde(default = "super::default_extend_config_arrays")]
pub komodo_cli_extend_config_arrays: bool,
#[serde(default)]
pub komodo_cli_debug_startup: bool,
pub komodo_cli_default_profile: Option<String>,
pub komodo_cli_host: Option<String>,
pub komodo_cli_key: Option<String>,
pub komodo_cli_secret: Option<String>,
pub komodo_cli_table_borders: Option<CliTableBorders>,
pub komodo_cli_backups_folder: Option<PathBuf>,
pub komodo_cli_max_backups: Option<u16>,
#[serde(alias = "komodo_cli_database_copy_uri")]
pub komodo_cli_database_target_uri: Option<String>,
#[serde(alias = "komodo_cli_database_copy_address")]
pub komodo_cli_database_target_address: Option<String>,
#[serde(alias = "komodo_cli_database_copy_username")]
pub komodo_cli_database_target_username: Option<String>,
#[serde(alias = "komodo_cli_database_copy_password")]
pub komodo_cli_database_target_password: Option<String>,
#[serde(alias = "komodo_cli_database_copy_db_name")]
pub komodo_cli_database_target_db_name: Option<String>,
pub komodo_cli_logging_level: Option<LogLevel>,
pub komodo_cli_logging_stdio: Option<StdioLogMode>,
pub komodo_cli_logging_pretty: Option<bool>,
pub komodo_cli_logging_ansi: Option<bool>,
pub komodo_cli_logging_timestamps: Option<bool>,
pub komodo_cli_logging_otlp_endpoint: Option<String>,
pub komodo_cli_logging_opentelemetry_service_name: Option<String>,
pub komodo_cli_logging_opentelemetry_scope_name: Option<String>,
pub komodo_cli_pretty_startup_config: Option<bool>,
pub komodo_host: Option<String>,
#[serde(alias = "komodo_mongo_uri")]
pub komodo_database_uri: Option<String>,
#[serde(alias = "komodo_mongo_uri_file")]
pub komodo_database_uri_file: Option<PathBuf>,
#[serde(alias = "komodo_mongo_address")]
pub komodo_database_address: Option<String>,
#[serde(alias = "komodo_mongo_username")]
pub komodo_database_username: Option<String>,
#[serde(alias = "komodo_mongo_username_file")]
pub komodo_database_username_file: Option<PathBuf>,
#[serde(alias = "komodo_mongo_password")]
pub komodo_database_password: Option<String>,
#[serde(alias = "komodo_mongo_password_file")]
pub komodo_database_password_file: Option<PathBuf>,
#[serde(alias = "komodo_mongo_db_name")]
pub komodo_database_db_name: Option<String>,
}
fn default_config_paths() -> Vec<PathBuf> {
if let Ok(home) = std::env::var("HOME") {
vec![
PathBuf::from(&home).join(".config/komodo"),
PathBuf::from("."),
]
} else {
vec![PathBuf::from(".")]
}
}
fn default_config_keywords() -> Vec<String> {
vec![String::from("*komodo.cli*.*")]
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CliConfig {
#[serde(
alias = "default",
skip_serializing_if = "Option::is_none"
)]
pub default_profile: Option<String>,
#[serde(
default,
alias = "name",
skip_serializing_if = "String::is_empty"
)]
pub config_profile: String,
#[serde(
default,
alias = "aliases",
alias = "alias",
deserialize_with = "string_list_deserializer",
skip_serializing_if = "Vec::is_empty"
)]
pub config_aliases: Vec<String>,
#[serde(default, skip_serializing_if = "String::is_empty")]
pub host: String,
#[serde(alias = "key", skip_serializing_if = "Option::is_none")]
pub cli_key: Option<String>,
#[serde(alias = "secret", skip_serializing_if = "Option::is_none")]
pub cli_secret: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub table_borders: Option<CliTableBorders>,
#[serde(default = "default_backups_folder")]
pub backups_folder: PathBuf,
#[serde(default = "default_max_backups")]
pub max_backups: u16,
#[serde(
default = "default_database_config",
alias = "mongo",
skip_serializing_if = "database_config_is_default"
)]
pub database: DatabaseConfig,
#[serde(
default = "default_database_config",
alias = "database_copy",
skip_serializing_if = "database_config_is_default"
)]
pub database_target: DatabaseConfig,
#[serde(
default = "default_log_config",
skip_serializing_if = "log_config_is_default"
)]
pub cli_logging: LogConfig,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub profile: Vec<CliConfig>,
}
fn default_backups_folder() -> PathBuf {
PathBuf::from("/backups")
}
fn default_max_backups() -> u16 {
14
}
fn default_database_config() -> DatabaseConfig {
DatabaseConfig {
app_name: String::from("komodo_cli"),
..Default::default()
}
}
fn database_config_is_default(db_config: &DatabaseConfig) -> bool {
db_config == &default_database_config()
}
fn default_log_config() -> LogConfig {
LogConfig {
location: false,
..Default::default()
}
}
fn log_config_is_default(log_config: &LogConfig) -> bool {
log_config == &default_log_config()
}
impl Default for CliConfig {
fn default() -> Self {
Self {
default_profile: Default::default(),
config_profile: Default::default(),
config_aliases: Default::default(),
cli_key: Default::default(),
cli_secret: Default::default(),
cli_logging: default_log_config(),
table_borders: Default::default(),
backups_folder: default_backups_folder(),
max_backups: default_max_backups(),
database: default_database_config(),
database_target: default_database_config(),
host: Default::default(),
profile: Default::default(),
}
}
}
impl CliConfig {
pub fn sanitized(&self) -> CliConfig {
CliConfig {
default_profile: self.default_profile.clone(),
config_profile: self.config_profile.clone(),
config_aliases: self.config_aliases.clone(),
cli_key: self
.cli_key
.as_ref()
.map(|cli_key| empty_or_redacted(cli_key)),
cli_secret: self
.cli_secret
.as_ref()
.map(|cli_secret| empty_or_redacted(cli_secret)),
cli_logging: self.cli_logging.clone(),
table_borders: self.table_borders,
backups_folder: self.backups_folder.clone(),
max_backups: self.max_backups,
database_target: self.database_target.sanitized(),
host: self.host.clone(),
database: self.database.sanitized(),
profile: self
.profile
.iter()
.map(CliConfig::sanitized)
.collect(),
}
}
}
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)]
pub enum CliTableBorders {
#[default]
Horizontal,
Vertical,
Outside,
Inside,
All,
}