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#[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#[derive(Debug, Eq, Error, PartialEq)]
26pub enum AdoptionReportError {
27 #[error("invalid config: {0}")]
28 InvalidConfig(String),
29}
30
31#[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#[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#[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#[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#[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#[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#[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#[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#[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#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
187pub enum AdoptionDeclarationStateV1 {
188 Undeclared,
189 Declared,
190}
191
192#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
196pub enum AdoptionTopologyStateV1 {
197 Unattached,
198 Attached,
199}
200
201#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
205pub enum AdoptionObservationStateV1 {
206 Unobserved,
207 Observed,
208 CandidateMatch,
209 ConflictingMatch,
210}
211
212#[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)]
216pub enum AdoptionAuthorityStateV1 {
217 CanicAuthorized,
218 UserControlled,
219 External,
220 Unknown,
221}
222
223#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
227pub enum AdoptionArtifactStateV1 {
228 CanicBuilt,
229 ExternalWasm,
230 Unknown,
231}
232
233#[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#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
250pub enum AdoptionMatchConfidenceV1 {
251 None,
252 Candidate,
253 ExplicitEvidence,
254 Conflict,
255}
256
257#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
261pub enum AdoptionRecommendationSeverityV1 {
262 Info,
263 Warning,
264 Blocked,
265}
266
267#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
271pub enum AdoptionSuggestedActionEffectV1 {
272 ReadOnly,
273 MutatesState,
274}
275
276#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
280pub enum AdoptionSuggestedActionSupportV1 {
281 SupportedByAdoption,
282 UnsupportedByAdoption,
283}
284
285#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
289pub enum AdoptionOperatorActionRequirementV1 {
290 Required,
291 NotRequired,
292}