Skip to main content

canic_host/deployment_truth/model/inventory/
mod.rs

1use super::artifact::ObservedArtifactV1;
2use super::plan::DeploymentIdentityV1;
3use serde::{Deserialize, Serialize};
4
5///
6/// DeploymentInventoryV1
7///
8#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
9pub struct DeploymentInventoryV1 {
10    pub schema_version: u32,
11    pub inventory_id: String,
12    pub observed_at: String,
13    pub observed_identity: Option<DeploymentIdentityV1>,
14    pub observed_root: Option<DeploymentRootObservationV1>,
15    pub local_config: LocalDeploymentConfigV1,
16    pub observed_canisters: Vec<ObservedCanisterV1>,
17    pub observed_pool: Vec<ObservedPoolCanisterV1>,
18    pub observed_artifacts: Vec<ObservedArtifactV1>,
19    pub observed_verifier_readiness: VerifierReadinessObservationV1,
20    pub unresolved_observations: Vec<DeploymentObservationGapV1>,
21}
22
23///
24/// DeploymentRootObservationV1
25///
26#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
27pub struct DeploymentRootObservationV1 {
28    pub deployment_name: String,
29    pub network: String,
30    pub fleet_template: String,
31    pub root_principal: String,
32    pub observed_canister_id: String,
33    pub observation_source: DeploymentRootObservationSourceV1,
34    pub control_class: CanisterControlClassV1,
35    pub controllers: Vec<String>,
36    pub module_hash: Option<String>,
37    pub status: Option<String>,
38    pub role_assignment_source: Option<String>,
39}
40
41///
42/// DeploymentRootObservationSourceV1
43///
44#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
45pub enum DeploymentRootObservationSourceV1 {
46    IcpCanisterStatus,
47    LocalDeploymentState,
48}
49
50impl DeploymentRootObservationSourceV1 {
51    #[must_use]
52    pub const fn label(self) -> &'static str {
53        match self {
54            Self::IcpCanisterStatus => "IcpCanisterStatus",
55            Self::LocalDeploymentState => "LocalDeploymentState",
56        }
57    }
58}
59
60///
61/// ExpectedCanisterV1
62///
63#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
64pub struct ExpectedCanisterV1 {
65    pub role: String,
66    pub canister_id: Option<String>,
67    pub control_class: CanisterControlClassV1,
68}
69
70///
71/// ObservedCanisterV1
72///
73#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
74pub struct ObservedCanisterV1 {
75    pub canister_id: String,
76    pub role: Option<String>,
77    pub control_class: CanisterControlClassV1,
78    pub controllers: Vec<String>,
79    pub module_hash: Option<String>,
80    pub status: Option<String>,
81    pub root_trust_anchor: Option<String>,
82    pub canonical_embedded_config_digest: Option<String>,
83    pub role_assignment_source: Option<String>,
84}
85
86///
87/// CanisterControlClassV1
88///
89#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
90pub enum CanisterControlClassV1 {
91    DeploymentControlled,
92    CanicManagedPool,
93    ExternallyImported,
94    JointlyControlled,
95    UserControlled,
96    UnknownUnsafe,
97}
98
99impl CanisterControlClassV1 {
100    #[must_use]
101    pub const fn label(self) -> &'static str {
102        match self {
103            Self::DeploymentControlled => "DeploymentControlled",
104            Self::CanicManagedPool => "CanicManagedPool",
105            Self::ExternallyImported => "ExternallyImported",
106            Self::JointlyControlled => "JointlyControlled",
107            Self::UserControlled => "UserControlled",
108            Self::UnknownUnsafe => "UnknownUnsafe",
109        }
110    }
111}
112
113///
114/// ExpectedPoolCanisterV1
115///
116#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
117pub struct ExpectedPoolCanisterV1 {
118    pub pool: String,
119    pub canister_id: Option<String>,
120    pub role: Option<String>,
121}
122
123///
124/// ObservedPoolCanisterV1
125///
126#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
127pub struct ObservedPoolCanisterV1 {
128    pub pool: String,
129    pub canister_id: String,
130    pub role: Option<String>,
131    pub control_class: CanisterControlClassV1,
132}
133
134///
135/// LocalDeploymentConfigV1
136///
137#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
138pub struct LocalDeploymentConfigV1 {
139    pub config_path: Option<String>,
140    pub raw_config_sha256: Option<String>,
141    pub canonical_embedded_config_sha256: Option<String>,
142}
143
144///
145/// VerifierReadinessExpectationV1
146///
147#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
148pub struct VerifierReadinessExpectationV1 {
149    pub required: bool,
150    pub expected_role_epochs: Vec<RoleEpochExpectationV1>,
151}
152
153///
154/// VerifierReadinessObservationV1
155///
156#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
157pub struct VerifierReadinessObservationV1 {
158    pub status: ObservationStatusV1,
159    pub role_epochs: Vec<RoleEpochObservationV1>,
160}
161
162///
163/// RoleEpochExpectationV1
164///
165#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
166pub struct RoleEpochExpectationV1 {
167    pub role: String,
168    pub minimum_epoch: u64,
169}
170
171///
172/// RoleEpochObservationV1
173///
174#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
175pub struct RoleEpochObservationV1 {
176    pub role: String,
177    pub observed_epoch: Option<u64>,
178    pub status: ObservationStatusV1,
179}
180
181///
182/// DeploymentObservationGapV1
183///
184#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
185pub struct DeploymentObservationGapV1 {
186    pub key: String,
187    pub description: String,
188}
189
190///
191/// ObservationStatusV1
192///
193#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
194pub enum ObservationStatusV1 {
195    NotObserved,
196    Observed,
197    Missing,
198    Inconclusive,
199}
200
201#[cfg(test)]
202mod tests {
203    use super::*;
204
205    #[test]
206    fn deployment_root_observation_source_owns_text_labels() {
207        assert_eq!(
208            DeploymentRootObservationSourceV1::IcpCanisterStatus.label(),
209            "IcpCanisterStatus"
210        );
211        assert_eq!(
212            DeploymentRootObservationSourceV1::LocalDeploymentState.label(),
213            "LocalDeploymentState"
214        );
215    }
216
217    #[test]
218    fn canister_control_class_owns_text_labels() {
219        assert_eq!(
220            CanisterControlClassV1::DeploymentControlled.label(),
221            "DeploymentControlled"
222        );
223        assert_eq!(
224            CanisterControlClassV1::CanicManagedPool.label(),
225            "CanicManagedPool"
226        );
227        assert_eq!(
228            CanisterControlClassV1::ExternallyImported.label(),
229            "ExternallyImported"
230        );
231        assert_eq!(
232            CanisterControlClassV1::JointlyControlled.label(),
233            "JointlyControlled"
234        );
235        assert_eq!(
236            CanisterControlClassV1::UserControlled.label(),
237            "UserControlled"
238        );
239        assert_eq!(
240            CanisterControlClassV1::UnknownUnsafe.label(),
241            "UnknownUnsafe"
242        );
243    }
244}