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