fakecloud_cloudcontrol/
state.rs1use std::collections::BTreeMap;
4use std::sync::Arc;
5
6use chrono::{DateTime, Utc};
7use parking_lot::RwLock;
8use serde::{Deserialize, Serialize};
9
10use fakecloud_core::multi_account::{AccountState, MultiAccountState};
11
12pub const CLOUDCONTROL_SNAPSHOT_SCHEMA_VERSION: u32 = 1;
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct ManagedResource {
20 pub type_name: String,
21 pub identifier: String,
22 pub properties: serde_json::Value,
23 pub attributes: BTreeMap<String, String>,
24 pub created_at: DateTime<Utc>,
25}
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
31pub struct ResourceRequest {
32 pub request_token: String,
33 pub type_name: String,
34 pub identifier: Option<String>,
35 pub operation: String,
37 pub operation_status: String,
40 pub event_time: DateTime<Utc>,
41 pub resource_model: Option<serde_json::Value>,
42 pub status_message: Option<String>,
43 pub error_code: Option<String>,
44 pub client_token: Option<String>,
46 #[serde(default)]
50 pub fingerprint: Option<String>,
51}
52
53#[derive(Debug, Clone, Default, Serialize, Deserialize)]
54pub struct CloudControlState {
55 pub resources: BTreeMap<String, ManagedResource>,
57 pub requests: BTreeMap<String, ResourceRequest>,
59}
60
61impl CloudControlState {
62 pub fn resource_key(type_name: &str, identifier: &str) -> String {
63 format!("{type_name}\u{1f}{identifier}")
64 }
65}
66
67impl AccountState for CloudControlState {
68 fn new_for_account(_account_id: &str, _region: &str, _endpoint: &str) -> Self {
69 Self::default()
70 }
71}
72
73pub type SharedCloudControlState = Arc<RwLock<MultiAccountState<CloudControlState>>>;
74
75#[derive(Debug, Serialize, Deserialize)]
76pub struct CloudControlSnapshot {
77 pub schema_version: u32,
78 pub accounts: MultiAccountState<CloudControlState>,
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn resource_key_is_unit_separated() {
87 let k = CloudControlState::resource_key("AWS::S3::Bucket", "my-bucket");
88 assert!(k.contains('\u{1f}'));
89 assert!(k.starts_with("AWS::S3::Bucket"));
90 assert!(k.ends_with("my-bucket"));
91 }
92}