Skip to main content

canic_host/adoption/
model.rs

1use crate::deployment_truth::{DeploymentInventoryV1, RoleArtifactManifestV1};
2use serde::{Deserialize, Serialize};
3use std::str::FromStr;
4use thiserror::Error;
5
6pub const ADOPTION_REPORT_SCHEMA_VERSION: u32 = 1;
7
8///
9/// AdoptionReportRequest
10///
11#[derive(Clone, Debug)]
12pub struct AdoptionReportRequest<'a> {
13    pub report_id: &'a str,
14    pub generated_at: &'a str,
15    pub profile: AdoptionProfileV1,
16    pub config_source: &'a str,
17    pub inventory: Option<&'a DeploymentInventoryV1>,
18    pub artifact_manifest: Option<&'a RoleArtifactManifestV1>,
19    pub package_metadata: Vec<AdoptionPackageMetadataV1>,
20}
21
22///
23/// AdoptionReportError
24///
25#[derive(Debug, Eq, Error, PartialEq)]
26pub enum AdoptionReportError {
27    #[error("invalid config: {0}")]
28    InvalidConfig(String),
29}
30
31///
32/// AdoptionProfileV1
33///
34#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
35pub enum AdoptionProfileV1 {
36    Brownfield,
37    Partial,
38    Standalone,
39    LeafOnly,
40    HybridExternalWasm,
41    Minimal,
42}
43
44impl FromStr for AdoptionProfileV1 {
45    type Err = String;
46
47    fn from_str(value: &str) -> Result<Self, Self::Err> {
48        match value {
49            "brownfield" => Ok(Self::Brownfield),
50            "partial" => Ok(Self::Partial),
51            "standalone" => Ok(Self::Standalone),
52            "leaf-only" => Ok(Self::LeafOnly),
53            "hybrid-external-wasm" => Ok(Self::HybridExternalWasm),
54            "minimal" => Ok(Self::Minimal),
55            other => Err(format!("invalid adoption profile: {other}")),
56        }
57    }
58}
59
60///
61/// AdoptionReportV1
62///
63#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
64#[serde(deny_unknown_fields)]
65pub struct AdoptionReportV1 {
66    pub schema_version: u32,
67    pub report_id: String,
68    pub generated_at: String,
69    pub app: String,
70    pub profile: AdoptionProfileV1,
71    pub inputs: AdoptionReportInputsV1,
72    pub summary: AdoptionReportSummaryV1,
73    pub role_findings: Vec<AdoptionRoleFindingV1>,
74    pub observed_canisters: Vec<AdoptionObservedCanisterFindingV1>,
75    pub recommendations: Vec<AdoptionRecommendationV1>,
76    pub blocked_actions: Vec<String>,
77}
78
79///
80/// AdoptionReportInputsV1
81///
82#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
83pub struct AdoptionReportInputsV1 {
84    pub config_present: bool,
85    pub inventory_id: Option<String>,
86    pub artifact_manifest_id: Option<String>,
87    pub package_metadata_count: usize,
88    pub missing_or_stale_evidence: Vec<String>,
89}
90
91///
92/// AdoptionReportSummaryV1
93///
94#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
95pub struct AdoptionReportSummaryV1 {
96    pub managed_configured_roles: usize,
97    pub declared_only_roles: usize,
98    pub attached_unobserved_roles: usize,
99    pub observed_only_canisters: usize,
100    pub user_controlled_canisters: usize,
101    pub external_controller_required: usize,
102    pub evidence_conflicts: usize,
103    pub mutating_actions_performed: usize,
104}
105
106///
107/// AdoptionRoleFindingV1
108///
109#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
110pub struct AdoptionRoleFindingV1 {
111    pub app: String,
112    pub role: String,
113    pub classifications: Vec<AdoptionClassificationV1>,
114    pub declaration_state: AdoptionDeclarationStateV1,
115    pub topology_state: AdoptionTopologyStateV1,
116    pub package_state: AdoptionPackageStateV1,
117    pub observation_state: AdoptionObservationStateV1,
118    pub authority_state: AdoptionAuthorityStateV1,
119    pub artifact_state: AdoptionArtifactStateV1,
120    pub evidence: Vec<String>,
121    pub recommendations: Vec<AdoptionRecommendationV1>,
122    pub warnings: Vec<String>,
123}
124
125///
126/// AdoptionObservedCanisterFindingV1
127///
128#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
129pub struct AdoptionObservedCanisterFindingV1 {
130    pub canister_id: String,
131    pub matched_app: Option<String>,
132    pub matched_role: Option<String>,
133    pub confidence: AdoptionMatchConfidenceV1,
134    pub classifications: Vec<AdoptionClassificationV1>,
135    pub controllers: Vec<String>,
136    pub wasm_evidence: Option<String>,
137    pub deployment_target_evidence: Option<String>,
138    pub recommendations: Vec<AdoptionRecommendationV1>,
139    pub warnings: Vec<String>,
140}
141
142///
143/// AdoptionRecommendationV1
144///
145#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
146#[serde(deny_unknown_fields)]
147pub struct AdoptionRecommendationV1 {
148    pub kind: String,
149    pub severity: AdoptionRecommendationSeverityV1,
150    pub description: String,
151    pub suggested_action: Option<String>,
152    pub suggested_action_effect: AdoptionSuggestedActionEffectV1,
153    pub suggested_action_support: AdoptionSuggestedActionSupportV1,
154    pub operator_action_requirement: AdoptionOperatorActionRequirementV1,
155}
156
157///
158/// AdoptionPackageMetadataV1
159///
160#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
161pub struct AdoptionPackageMetadataV1 {
162    pub package: String,
163    pub app: Option<String>,
164    pub role: Option<String>,
165}
166
167///
168/// AdoptionClassificationV1
169///
170#[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
171pub enum AdoptionClassificationV1 {
172    Managed,
173    DeclaredOnly,
174    ObservedOnly,
175    AttachedUnobserved,
176    UserControlled,
177    ExternalControllerRequired,
178    ImportedPoolCandidate,
179    EvidenceConflict,
180}
181
182///
183/// AdoptionDeclarationStateV1
184///
185#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
186pub enum AdoptionDeclarationStateV1 {
187    Undeclared,
188    Declared,
189}
190
191///
192/// AdoptionTopologyStateV1
193///
194#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
195pub enum AdoptionTopologyStateV1 {
196    Unattached,
197    Attached,
198}
199
200///
201/// AdoptionObservationStateV1
202///
203#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
204pub enum AdoptionObservationStateV1 {
205    Unobserved,
206    Observed,
207    CandidateMatch,
208    ConflictingMatch,
209}
210
211///
212/// AdoptionAuthorityStateV1
213///
214#[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
215pub enum AdoptionAuthorityStateV1 {
216    CanicAuthorized,
217    UserControlled,
218    External,
219    Unknown,
220}
221
222///
223/// AdoptionArtifactStateV1
224///
225#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
226pub enum AdoptionArtifactStateV1 {
227    CanicBuilt,
228    ExternalWasm,
229    Unknown,
230}
231
232///
233/// AdoptionPackageStateV1
234///
235#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
236pub enum AdoptionPackageStateV1 {
237    UndeclaredRole,
238    NotChecked,
239    Matches,
240    MissingApp,
241    MissingRole,
242    Mismatch,
243}
244
245///
246/// AdoptionMatchConfidenceV1
247///
248#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
249pub enum AdoptionMatchConfidenceV1 {
250    None,
251    Candidate,
252    ExplicitEvidence,
253    Conflict,
254}
255
256///
257/// AdoptionRecommendationSeverityV1
258///
259#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
260pub enum AdoptionRecommendationSeverityV1 {
261    Info,
262    Warning,
263    Blocked,
264}
265
266///
267/// AdoptionSuggestedActionEffectV1
268///
269#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
270pub enum AdoptionSuggestedActionEffectV1 {
271    ReadOnly,
272    MutatesState,
273}
274
275///
276/// AdoptionSuggestedActionSupportV1
277///
278#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
279pub enum AdoptionSuggestedActionSupportV1 {
280    SupportedByAdoption,
281    UnsupportedByAdoption,
282}
283
284///
285/// AdoptionOperatorActionRequirementV1
286///
287#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
288pub enum AdoptionOperatorActionRequirementV1 {
289    Required,
290    NotRequired,
291}