use std::collections::BTreeMap;
use std::sync::Arc;
use chrono::{DateTime, Utc};
use parking_lot::RwLock;
use serde::{Deserialize, Serialize};
use fakecloud_core::multi_account::{AccountState, MultiAccountState};
pub const CLOUDCONTROL_SNAPSHOT_SCHEMA_VERSION: u32 = 1;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ManagedResource {
pub type_name: String,
pub identifier: String,
pub properties: serde_json::Value,
pub attributes: BTreeMap<String, String>,
pub created_at: DateTime<Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ResourceRequest {
pub request_token: String,
pub type_name: String,
pub identifier: Option<String>,
pub operation: String,
pub operation_status: String,
pub event_time: DateTime<Utc>,
pub resource_model: Option<serde_json::Value>,
pub status_message: Option<String>,
pub error_code: Option<String>,
pub client_token: Option<String>,
#[serde(default)]
pub fingerprint: Option<String>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct CloudControlState {
pub resources: BTreeMap<String, ManagedResource>,
pub requests: BTreeMap<String, ResourceRequest>,
}
impl CloudControlState {
pub fn resource_key(type_name: &str, identifier: &str) -> String {
format!("{type_name}\u{1f}{identifier}")
}
}
impl AccountState for CloudControlState {
fn new_for_account(_account_id: &str, _region: &str, _endpoint: &str) -> Self {
Self::default()
}
}
pub type SharedCloudControlState = Arc<RwLock<MultiAccountState<CloudControlState>>>;
#[derive(Debug, Serialize, Deserialize)]
pub struct CloudControlSnapshot {
pub schema_version: u32,
pub accounts: MultiAccountState<CloudControlState>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn resource_key_is_unit_separated() {
let k = CloudControlState::resource_key("AWS::S3::Bucket", "my-bucket");
assert!(k.contains('\u{1f}'));
assert!(k.starts_with("AWS::S3::Bucket"));
assert!(k.ends_with("my-bucket"));
}
}