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)]
129#[serde(deny_unknown_fields)]
130pub struct AdoptionObservedCanisterFindingV1 {
131    pub canister_id: String,
132    pub matched_app: Option<String>,
133    pub matched_role: Option<String>,
134    pub confidence: AdoptionMatchConfidenceV1,
135    pub classifications: Vec<AdoptionClassificationV1>,
136    pub controllers: Vec<String>,
137    pub wasm_evidence: Option<String>,
138    pub fleet_evidence: Option<String>,
139    pub recommendations: Vec<AdoptionRecommendationV1>,
140    pub warnings: Vec<String>,
141}
142
143///
144/// AdoptionRecommendationV1
145///
146#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
147#[serde(deny_unknown_fields)]
148pub struct AdoptionRecommendationV1 {
149    pub kind: String,
150    pub severity: AdoptionRecommendationSeverityV1,
151    pub description: String,
152    pub suggested_action: Option<String>,
153    pub suggested_action_effect: AdoptionSuggestedActionEffectV1,
154    pub suggested_action_support: AdoptionSuggestedActionSupportV1,
155    pub operator_action_requirement: AdoptionOperatorActionRequirementV1,
156}
157
158///
159/// AdoptionPackageMetadataV1
160///
161#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
162pub struct AdoptionPackageMetadataV1 {
163    pub package: String,
164    pub app: Option<String>,
165    pub role: Option<String>,
166}
167
168///
169/// AdoptionClassificationV1
170///
171#[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
172pub enum AdoptionClassificationV1 {
173    Managed,
174    DeclaredOnly,
175    ObservedOnly,
176    AttachedUnobserved,
177    UserControlled,
178    ExternalControllerRequired,
179    ImportedPoolCandidate,
180    EvidenceConflict,
181}
182
183///
184/// AdoptionDeclarationStateV1
185///
186#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
187pub enum AdoptionDeclarationStateV1 {
188    Undeclared,
189    Declared,
190}
191
192///
193/// AdoptionTopologyStateV1
194///
195#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
196pub enum AdoptionTopologyStateV1 {
197    Unattached,
198    Attached,
199}
200
201///
202/// AdoptionObservationStateV1
203///
204#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
205pub enum AdoptionObservationStateV1 {
206    Unobserved,
207    Observed,
208    CandidateMatch,
209    ConflictingMatch,
210}
211
212///
213/// AdoptionAuthorityStateV1
214///
215#[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
216pub enum AdoptionAuthorityStateV1 {
217    CanicAuthorized,
218    UserControlled,
219    External,
220    Unknown,
221}
222
223///
224/// AdoptionArtifactStateV1
225///
226#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
227pub enum AdoptionArtifactStateV1 {
228    CanicBuilt,
229    ExternalWasm,
230    Unknown,
231}
232
233///
234/// AdoptionPackageStateV1
235///
236#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
237pub enum AdoptionPackageStateV1 {
238    UndeclaredRole,
239    NotChecked,
240    Matches,
241    MissingApp,
242    MissingRole,
243    Mismatch,
244}
245
246///
247/// AdoptionMatchConfidenceV1
248///
249#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
250pub enum AdoptionMatchConfidenceV1 {
251    None,
252    Candidate,
253    ExplicitEvidence,
254    Conflict,
255}
256
257///
258/// AdoptionRecommendationSeverityV1
259///
260#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
261pub enum AdoptionRecommendationSeverityV1 {
262    Info,
263    Warning,
264    Blocked,
265}
266
267///
268/// AdoptionSuggestedActionEffectV1
269///
270#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
271pub enum AdoptionSuggestedActionEffectV1 {
272    ReadOnly,
273    MutatesState,
274}
275
276///
277/// AdoptionSuggestedActionSupportV1
278///
279#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
280pub enum AdoptionSuggestedActionSupportV1 {
281    SupportedByAdoption,
282    UnsupportedByAdoption,
283}
284
285///
286/// AdoptionOperatorActionRequirementV1
287///
288#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
289pub enum AdoptionOperatorActionRequirementV1 {
290    Required,
291    NotRequired,
292}