canic_host/deployment_truth/observe/inventory/
mod.rs1use super::super::*;
2use super::artifacts::{
3 collect_observed_artifacts, observe_canonical_runtime_config_digest, observe_config_sha256,
4 observe_deployment_manifest_digest,
5};
6use super::config::observe_local_config_facts;
7use super::identity::{InventoryIdentityFacts, local_inventory_identity};
8use crate::fleet_catalog::{FleetCatalogError, read_fleet_catalog_entry_from_root};
9use crate::network::resolve_canonical_network_id_from_root;
10use std::path::PathBuf;
11use thiserror::Error as ThisError;
12
13#[derive(Clone, Debug, Eq, PartialEq)]
17pub struct LocalInventoryRequest {
18 pub fleet_name: String,
19 pub environment: String,
20 pub artifact_environment: String,
21 pub workspace_root: PathBuf,
22 pub icp_root: PathBuf,
23 pub config_path: Option<PathBuf>,
24 pub observed_at: String,
25}
26
27#[derive(Debug, ThisError)]
31pub enum DeploymentTruthError {
32 #[error("failed to read the canonical-network Fleet catalog: {0}")]
33 FleetCatalog(#[source] FleetCatalogError),
34}
35
36pub fn collect_local_deployment_inventory(
38 request: &LocalInventoryRequest,
39) -> Result<DeploymentInventoryV1, DeploymentTruthError> {
40 let config = deployment_config_path(&request.workspace_root, request.config_path.as_deref());
41 let mut unresolved_observations = Vec::new();
42 let local_config_facts = observe_local_config_facts(&config, &mut unresolved_observations);
43
44 let installed_fleet = read_fleet_catalog_entry_from_root(
45 &request.icp_root,
46 &request.environment,
47 &request.fleet_name,
48 )
49 .map_err(DeploymentTruthError::FleetCatalog)?;
50 let canonical_network_id =
51 resolve_canonical_network_id_from_root(&request.icp_root, &request.environment)
52 .map_err(FleetCatalogError::from)
53 .map_err(DeploymentTruthError::FleetCatalog)?;
54 let raw_config_sha256 = observe_config_sha256(&config, &mut unresolved_observations);
55 let canonical_runtime_config_digest =
56 observe_canonical_runtime_config_digest(&config, &mut unresolved_observations);
57 let deployment_manifest_digest = observe_deployment_manifest_digest(
58 &request.icp_root,
59 &request.artifact_environment,
60 &mut unresolved_observations,
61 );
62 let observed_artifacts = collect_observed_artifacts(
63 &request.icp_root,
64 &request.artifact_environment,
65 &local_config_facts.roles,
66 &mut unresolved_observations,
67 );
68 let observed_canisters = Vec::new();
71 let observed_pool = Vec::new();
72 let observed_root = None;
73 let observed_identity = Some(local_inventory_identity(
74 request,
75 InventoryIdentityFacts {
76 canonical_network_id,
77 fleet_id: installed_fleet.as_ref().map(|fleet| fleet.fleet_id),
78 app: installed_fleet.as_ref().map_or_else(
79 || local_config_facts.app.clone(),
80 |fleet| fleet.app.to_string(),
81 ),
82 root_principal: None,
83 deployment_manifest_digest,
84 canonical_runtime_config_digest: canonical_runtime_config_digest.clone(),
85 observed_canisters: &observed_canisters,
86 observed_artifacts: &observed_artifacts,
87 observed_pool: &observed_pool,
88 },
89 ));
90
91 Ok(DeploymentInventoryV1 {
92 schema_version: DEPLOYMENT_TRUTH_SCHEMA_VERSION,
93 inventory_id: format!("local:{}:{}", request.environment, request.fleet_name),
94 observed_at: request.observed_at.clone(),
95 observed_identity,
96 observed_root,
97 local_config: LocalDeploymentConfigV1 {
98 config_path: Some(config.display().to_string()),
99 raw_config_sha256,
100 canonical_embedded_config_sha256: canonical_runtime_config_digest,
101 },
102 observed_canisters,
103 observed_pool,
104 observed_artifacts,
105 observed_verifier_readiness: VerifierReadinessObservationV1 {
106 status: ObservationStatusV1::NotObserved,
107 role_epochs: Vec::new(),
108 },
109 unresolved_observations,
110 })
111}