use super::super::*;
use super::artifacts::{
collect_observed_artifacts, observe_canonical_runtime_config_digest, observe_config_sha256,
observe_deployment_manifest_digest,
};
use super::config::observe_local_config_facts;
use super::identity::{InventoryIdentityFacts, local_inventory_identity};
use super::root::{install_state_observations, observed_root_observation};
use crate::install_root::read_named_deployment_install_state_from_root;
use std::path::PathBuf;
use thiserror::Error as ThisError;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct LocalInventoryRequest {
pub deployment_name: String,
pub network: String,
pub workspace_root: PathBuf,
pub icp_root: PathBuf,
pub config_path: Option<PathBuf>,
pub observed_at: String,
}
#[derive(Debug, ThisError)]
pub enum DeploymentTruthError {
#[error("failed to read local deployment state: {0}")]
LocalState(String),
}
pub fn collect_local_deployment_inventory(
request: &LocalInventoryRequest,
) -> Result<DeploymentInventoryV1, DeploymentTruthError> {
let config = deployment_config_path(&request.workspace_root, request.config_path.as_deref());
let mut unresolved_observations = Vec::new();
let local_config_facts = observe_local_config_facts(
&config,
&request.deployment_name,
&mut unresolved_observations,
);
let install_state = read_named_deployment_install_state_from_root(
&request.icp_root,
&request.network,
&request.deployment_name,
)
.map_err(|err| DeploymentTruthError::LocalState(err.to_string()))?;
let raw_config_sha256 = observe_config_sha256(&config, &mut unresolved_observations);
let canonical_runtime_config_digest =
observe_canonical_runtime_config_digest(&config, &mut unresolved_observations);
let deployment_manifest_digest = observe_deployment_manifest_digest(
&request.icp_root,
&request.network,
&mut unresolved_observations,
);
let observed_artifacts = collect_observed_artifacts(
&request.icp_root,
&request.network,
&local_config_facts.roles,
&mut unresolved_observations,
);
let (observed_canisters, observed_pool) = install_state_observations(
install_state.as_ref(),
request,
&local_config_facts.pool_expectations,
&mut unresolved_observations,
);
let observed_root = observed_root_observation(
install_state.as_ref(),
request,
&local_config_facts.fleet_name,
&observed_canisters,
);
let observed_identity = Some(local_inventory_identity(
request,
InventoryIdentityFacts {
root_principal: install_state
.as_ref()
.map(|state| state.root_canister_id.clone()),
deployment_manifest_digest,
canonical_runtime_config_digest: canonical_runtime_config_digest.clone(),
observed_canisters: &observed_canisters,
observed_artifacts: &observed_artifacts,
observed_pool: &observed_pool,
},
));
Ok(DeploymentInventoryV1 {
schema_version: DEPLOYMENT_TRUTH_SCHEMA_VERSION,
inventory_id: format!("local:{}:{}", request.network, request.deployment_name),
observed_at: request.observed_at.clone(),
observed_identity,
observed_root,
local_config: LocalDeploymentConfigV1 {
config_path: Some(config.display().to_string()),
raw_config_sha256,
canonical_embedded_config_sha256: canonical_runtime_config_digest,
},
observed_canisters,
observed_pool,
observed_artifacts,
observed_verifier_readiness: VerifierReadinessObservationV1 {
status: ObservationStatusV1::NotObserved,
role_epochs: Vec::new(),
},
unresolved_observations,
})
}