Skip to main content

canic_core/dto/
role.rs

1//! Module: dto::role
2//!
3//! Responsibility: carry the shared role-owned status boundary values.
4//! Does not own: capability derivation, authorization, status lookup, or workflow policy.
5//! Boundary: role-specific status enums compose these passive bounded values.
6
7use crate::{
8    dto::{
9        component_registry::ComponentRuntimeStatusResponse,
10        fleet_activation::FleetActivationStatusResponse,
11        fleet_registry::FleetSubnetRootDrainingReservationResponse,
12        metadata::CanicMetadataResponse, metrics::MetricsKind, page::PageRequest, prelude::*,
13    },
14    log::Level,
15};
16
17/// Closed compiled capability identity exposed by the immutable role overview.
18#[derive(
19    CandidType, Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize,
20)]
21#[remain::sorted]
22pub enum RoleCapability {
23    AutomaticTopup,
24    DelegatedTokenIssuer,
25    DelegatedTokenVerifier,
26    FleetAdmissionProjection,
27    FleetCoordinator,
28    Icrc21,
29    Index,
30    RoleAttestationSigner,
31    RoleAttestationVerifier,
32    Root,
33    RootControlPlane,
34    Runtime,
35    Scaling,
36    Sharding,
37    WasmStore,
38}
39
40/// Immutable role, capability, release, and bootstrap profile-verification response.
41#[derive(CandidType, Clone, Debug, Deserialize)]
42pub struct RoleOverviewResponse {
43    pub role: CanisterRole,
44    pub capabilities: Vec<RoleCapability>,
45    pub protocol_profile_digest: [u8; 32],
46    pub metadata: CanicMetadataResponse,
47    pub bootstrap: BootstrapStatusResponse,
48}
49
50/// Lookup key shared by each role's local durable-operation status variant.
51#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
52pub struct OperationStatusRequest {
53    pub operation_id: [u8; 32],
54}
55
56/// Durable identity returned when one role-owned asynchronous command is accepted.
57#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
58pub struct OperationReceipt {
59    pub operation_id: [u8; 32],
60}
61
62/// Exact Coordinator reservation delivered with one accepted Root-removal intent.
63#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
64pub struct RootRemovalRequest {
65    pub reservation: FleetSubnetRootDrainingReservationResponse,
66}
67
68/// Named response for the protected compiled configuration source.
69#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
70pub struct ConfigStatusResponse {
71    pub toml: String,
72}
73
74/// Named response for the canister's current cycle balance.
75#[derive(CandidType, Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
76pub struct CycleBalanceStatusResponse {
77    pub cycles: u128,
78}
79
80/// Bounded log observation selector used by each role status surface.
81#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq)]
82pub struct LogStatusRequest {
83    pub crate_name: Option<String>,
84    pub topic: Option<String>,
85    pub min_level: Option<Level>,
86    pub page: PageRequest,
87}
88
89/// Bounded metrics observation selector used by each role status surface.
90#[derive(CandidType, Clone, Copy, Debug, Deserialize)]
91pub struct MetricsStatusRequest {
92    pub kind: MetricsKind,
93    pub page: PageRequest,
94}
95
96/// Managed runtime configuration detail projected through the operation lane.
97#[derive(CandidType, Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
98pub struct ComponentRuntimeOperationStatus {
99    pub operation_id: [u8; 32],
100    pub fleet_activation: FleetActivationStatusResponse,
101    pub runtime: ComponentRuntimeStatusResponse,
102}
103
104pub use crate::dto::state::BootstrapStatusResponse;
105
106#[cfg(test)]
107mod tests {
108    use super::*;
109    use candid::{Decode, Encode};
110
111    #[test]
112    fn shared_role_status_requests_round_trip_through_candid() {
113        let operation = OperationStatusRequest {
114            operation_id: [7; 32],
115        };
116        let bytes = Encode!(&operation).expect("encode operation status request");
117        assert_eq!(
118            Decode!(&bytes, OperationStatusRequest).expect("decode operation status request"),
119            operation
120        );
121
122        let receipt = OperationReceipt {
123            operation_id: operation.operation_id,
124        };
125        let bytes = Encode!(&receipt).expect("encode operation receipt");
126        assert_eq!(
127            Decode!(&bytes, OperationReceipt).expect("decode operation receipt"),
128            receipt
129        );
130
131        let logs = LogStatusRequest {
132            crate_name: Some("canic-core".to_string()),
133            topic: Some("Cycles".to_string()),
134            min_level: Some(Level::Warn),
135            page: PageRequest {
136                limit: 25,
137                offset: 50,
138            },
139        };
140        let bytes = Encode!(&logs).expect("encode log status request");
141        assert_eq!(
142            Decode!(&bytes, LogStatusRequest).expect("decode log status request"),
143            logs
144        );
145    }
146}