1use super::artifact::ObservedArtifactV1;
2use super::plan::DeploymentIdentityV1;
3use serde::{Deserialize, Serialize};
4
5#[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#[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#[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#[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#[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#[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#[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#[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#[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#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
148pub struct VerifierReadinessExpectationV1 {
149 pub required: bool,
150 pub expected_role_epochs: Vec<RoleEpochExpectationV1>,
151}
152
153#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
157pub struct VerifierReadinessObservationV1 {
158 pub status: ObservationStatusV1,
159 pub role_epochs: Vec<RoleEpochObservationV1>,
160}
161
162#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
166pub struct RoleEpochExpectationV1 {
167 pub role: String,
168 pub minimum_epoch: u64,
169}
170
171#[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#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
185pub struct DeploymentObservationGapV1 {
186 pub key: String,
187 pub description: String,
188}
189
190#[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}