v0.1.4-pre.011
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-config-desk/src/constants.rs
|
||||
// version: 4
|
||||
// version: 5
|
||||
|
||||
//! Application-owned tracing targets and domains.
|
||||
|
||||
@@ -21,3 +21,5 @@ pub(crate) const TRACING_DOMAIN_WINDOWS: &str = "desktop.window";
|
||||
pub(crate) const TRACING_DOMAIN_DOCUMENTS: &str = "config.documents";
|
||||
/// Structured domain for Config profile selection and provenance inspection.
|
||||
pub(crate) const TRACING_DOMAIN_PROFILES: &str = "config.profiles";
|
||||
/// Structured domain for safe Config environment reports.
|
||||
pub(crate) const TRACING_DOMAIN_ENVIRONMENT: &str = "config.environment";
|
||||
|
||||
119
crates/ksp-app-config-desk/src/environment.rs
Normal file
119
crates/ksp-app-config-desk/src/environment.rs
Normal file
@@ -0,0 +1,119 @@
|
||||
// file: crates/ksp-app-config-desk/src/environment.rs
|
||||
// version: 1
|
||||
|
||||
//! Safe Config environment report projections for Config Desk.
|
||||
|
||||
use ts_rs::TS; // rust-rules: derive-import
|
||||
|
||||
/// Safe desired/effective environment view exposed to the ordinary Config Desk frontend.
|
||||
#[derive(Clone, Debug, serde::Serialize, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export, export_to = "../frontend/ts/bindings/ksp_app_config_desk/environment/ConfigEnvironmentReportDto.ts")]
|
||||
pub(crate) struct ConfigEnvironmentReportDto {
|
||||
/// Supported KSP/KSPB variable name.
|
||||
pub(crate) variable_name: String,
|
||||
/// Namespace family derived from the variable name without inspecting its value.
|
||||
pub(crate) namespace: String,
|
||||
/// `public`, `internal` or `secret`.
|
||||
pub(crate) sensitivity: String,
|
||||
/// Persisted `.env` value using Config's safe/redacted representation.
|
||||
pub(crate) desired_safe_value: std::option::Option<String>,
|
||||
/// Currently effective process-or-`.env` value using Config's safe/redacted representation.
|
||||
pub(crate) effective_safe_value: std::option::Option<String>,
|
||||
/// Winning external source: `process`, `dotenv`, or `none`.
|
||||
pub(crate) effective_source: String,
|
||||
/// Whether the persisted `.env` value is shadowed by the inherited process environment.
|
||||
pub(crate) shadowed_by_process_environment: bool,
|
||||
}
|
||||
|
||||
/// Returns the safe environment report owned by Config.
|
||||
pub(crate) fn report(state: &crate::AppState) -> ksp_core_lib::Result<std::vec::Vec<ConfigEnvironmentReportDto>> {
|
||||
return report_from_management(state.config_management());
|
||||
}
|
||||
|
||||
fn report_from_management(management: &ksp_config_lib::ConfigManagement) -> ksp_core_lib::Result<std::vec::Vec<ConfigEnvironmentReportDto>> {
|
||||
let reports = management.environment_report();
|
||||
let reports = match reports {
|
||||
std::result::Result::Ok(value) => value,
|
||||
std::result::Result::Err(error) => return std::result::Result::Err(error),
|
||||
};
|
||||
let mut result = std::vec::Vec::<ConfigEnvironmentReportDto>::with_capacity(reports.len());
|
||||
let mut process_count = 0usize;
|
||||
let mut dotenv_count = 0usize;
|
||||
let mut shadowed_count = 0usize;
|
||||
let mut secret_count = 0usize;
|
||||
for report in reports {
|
||||
let source = report.effective_source();
|
||||
match source {
|
||||
std::option::Option::Some(ksp_config_lib::ConfigEnvironmentSource::Process) => process_count += 1,
|
||||
std::option::Option::Some(ksp_config_lib::ConfigEnvironmentSource::DotEnv) => dotenv_count += 1,
|
||||
std::option::Option::Some(ksp_config_lib::ConfigEnvironmentSource::Fallback) | std::option::Option::None => {},
|
||||
}
|
||||
if report.shadowed_by_process_environment() {
|
||||
shadowed_count += 1;
|
||||
}
|
||||
if report.sensitivity() == ksp_config_lib::ConfigSensitivity::Secret {
|
||||
secret_count += 1;
|
||||
}
|
||||
result.push(ConfigEnvironmentReportDto {
|
||||
variable_name: report.variable_name().to_owned(),
|
||||
namespace: namespace_label(report.variable_name()).to_owned(),
|
||||
sensitivity: sensitivity_label(report.sensitivity()).to_owned(),
|
||||
desired_safe_value: report.desired_safe_value().map(str::to_owned),
|
||||
effective_safe_value: report.effective_safe_value().map(str::to_owned),
|
||||
effective_source: environment_source_label(source).to_owned(),
|
||||
shadowed_by_process_environment: report.shadowed_by_process_environment(),
|
||||
});
|
||||
}
|
||||
ksp_logging_lib::debug!(
|
||||
target: crate::TRACING_TARGET,
|
||||
domain = crate::TRACING_DOMAIN_ENVIRONMENT,
|
||||
variable_count = result.len(),
|
||||
process_count,
|
||||
dotenv_count,
|
||||
shadowed_count,
|
||||
secret_count,
|
||||
"Config environment report evaluated"
|
||||
);
|
||||
return std::result::Result::Ok(result);
|
||||
}
|
||||
|
||||
const fn environment_source_label(source: std::option::Option<ksp_config_lib::ConfigEnvironmentSource>) -> &'static str {
|
||||
return match source {
|
||||
std::option::Option::Some(ksp_config_lib::ConfigEnvironmentSource::Process) => "process",
|
||||
std::option::Option::Some(ksp_config_lib::ConfigEnvironmentSource::DotEnv) => "dotenv",
|
||||
std::option::Option::Some(ksp_config_lib::ConfigEnvironmentSource::Fallback) => "fallback",
|
||||
std::option::Option::None => "none",
|
||||
};
|
||||
}
|
||||
|
||||
const fn sensitivity_label(sensitivity: ksp_config_lib::ConfigSensitivity) -> &'static str {
|
||||
return match sensitivity {
|
||||
ksp_config_lib::ConfigSensitivity::Public => "public",
|
||||
ksp_config_lib::ConfigSensitivity::Internal => "internal",
|
||||
ksp_config_lib::ConfigSensitivity::Secret => "secret",
|
||||
};
|
||||
}
|
||||
|
||||
fn namespace_label(variable_name: &str) -> &'static str {
|
||||
if variable_name.starts_with("KSPB_SECRET_") {
|
||||
return "KSPB_SECRET";
|
||||
}
|
||||
if variable_name.starts_with("KSPB_PUBLIC_") {
|
||||
return "KSPB_PUBLIC";
|
||||
}
|
||||
if variable_name.starts_with("KSPB_") {
|
||||
return "KSPB";
|
||||
}
|
||||
if variable_name.starts_with("KSP_SECRET_") {
|
||||
return "KSP_SECRET";
|
||||
}
|
||||
if variable_name.starts_with("KSP_PUBLIC_") {
|
||||
return "KSP_PUBLIC";
|
||||
}
|
||||
return "KSP";
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "../unit_tests/environment.rs"]
|
||||
mod tests;
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-config-desk/src/lib.rs
|
||||
// version: 7
|
||||
// version: 8
|
||||
|
||||
//! Tauri desktop application for managing and validating KSP configuration.
|
||||
|
||||
@@ -12,6 +12,7 @@ mod bootstrap;
|
||||
mod constants;
|
||||
mod documents;
|
||||
mod dto_common;
|
||||
mod environment;
|
||||
mod errors;
|
||||
mod frontend_logging;
|
||||
mod profiles;
|
||||
@@ -28,6 +29,7 @@ pub(crate) use self::bootstrap::config_management;
|
||||
pub(crate) use self::bootstrap::initialize_logging;
|
||||
pub(crate) use self::constants::TRACING_DOMAIN_BOOTSTRAP;
|
||||
pub(crate) use self::constants::TRACING_DOMAIN_DOCUMENTS;
|
||||
pub(crate) use self::constants::TRACING_DOMAIN_ENVIRONMENT;
|
||||
pub(crate) use self::constants::TRACING_DOMAIN_FRONTEND;
|
||||
pub(crate) use self::constants::TRACING_DOMAIN_PROFILES;
|
||||
pub(crate) use self::constants::TRACING_DOMAIN_WINDOWS;
|
||||
@@ -41,6 +43,7 @@ pub(crate) use self::documents::ConfigDocumentSaveResultDto;
|
||||
pub(crate) use self::documents::ConfigDocumentSummaryDto;
|
||||
pub(crate) use self::dto_common::AppSnapshotDto;
|
||||
pub(crate) use self::dto_common::CommandErrorDto;
|
||||
pub(crate) use self::environment::ConfigEnvironmentReportDto;
|
||||
pub(crate) use self::errors::ERROR_CODE_APP_STATE_INVALID;
|
||||
pub(crate) use self::errors::ERROR_CODE_APP_STATE_LOCK_FAILED;
|
||||
pub(crate) use self::errors::ERROR_CODE_DOCUMENT_KIND_INVALID;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-config-desk/src/tauri.rs
|
||||
// version: 8
|
||||
// version: 9
|
||||
|
||||
//! Tauri runtime assembly for the KSP configuration desktop application.
|
||||
|
||||
@@ -44,6 +44,7 @@ fn configure_commands(builder: tauri::Builder<tauri::Wry>) -> tauri::Builder<tau
|
||||
save_config_document_source,
|
||||
get_config_profile_documents,
|
||||
get_config_profile_detail,
|
||||
get_environment_report,
|
||||
emit_frontend_log,
|
||||
splash_frontend_ready
|
||||
]);
|
||||
@@ -118,6 +119,17 @@ fn get_config_profile_detail(
|
||||
};
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn get_environment_report(
|
||||
state: tauri::State<'_, crate::AppState>,
|
||||
) -> std::result::Result<std::vec::Vec<crate::ConfigEnvironmentReportDto>, crate::CommandErrorDto> {
|
||||
let result = crate::environment::report(&state);
|
||||
return match result {
|
||||
std::result::Result::Ok(value) => std::result::Result::Ok(value),
|
||||
std::result::Result::Err(error) => std::result::Result::Err(crate::CommandErrorDto::from_error(&error)),
|
||||
};
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn emit_frontend_log(payload: crate::FrontendLogPayloadDto) -> std::result::Result<(), crate::CommandErrorDto> {
|
||||
let result = crate::emit_frontend_log_event(payload);
|
||||
|
||||
Reference in New Issue
Block a user