fakecloud_secretsmanager/
state.rs1use chrono::{DateTime, Utc};
2use parking_lot::RwLock;
3use std::collections::HashMap;
4use std::sync::Arc;
5
6#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
7pub struct Secret {
8 pub name: String,
9 pub arn: String,
10 pub description: Option<String>,
11 pub kms_key_id: Option<String>,
12 pub versions: HashMap<String, SecretVersion>,
13 pub current_version_id: Option<String>,
14 pub tags: Vec<(String, String)>,
15 pub tags_ever_set: bool,
16 pub deleted: bool,
17 pub deletion_date: Option<DateTime<Utc>>,
18 pub created_at: DateTime<Utc>,
19 pub last_changed_at: DateTime<Utc>,
20 pub last_accessed_at: Option<DateTime<Utc>>,
21 pub rotation_enabled: Option<bool>,
22 pub rotation_lambda_arn: Option<String>,
23 pub rotation_rules: Option<RotationRules>,
24 pub last_rotated_at: Option<DateTime<Utc>>,
25 pub resource_policy: Option<String>,
26}
27
28#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
29pub struct RotationRules {
30 pub automatically_after_days: Option<i64>,
31}
32
33#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
34pub struct SecretVersion {
35 pub version_id: String,
36 pub secret_string: Option<String>,
37 pub secret_binary: Option<Vec<u8>>,
38 pub stages: Vec<String>,
39 pub created_at: DateTime<Utc>,
40}
41
42#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
43pub struct SecretsManagerState {
44 pub account_id: String,
45 pub region: String,
46 pub secrets: HashMap<String, Secret>,
47}
48
49impl SecretsManagerState {
50 pub fn new(account_id: &str, region: &str) -> Self {
51 Self {
52 account_id: account_id.to_string(),
53 region: region.to_string(),
54 secrets: HashMap::new(),
55 }
56 }
57
58 pub fn reset(&mut self) {
59 self.secrets.clear();
60 }
61}
62
63pub type SharedSecretsManagerState =
64 Arc<RwLock<fakecloud_core::multi_account::MultiAccountState<SecretsManagerState>>>;
65
66impl fakecloud_core::multi_account::AccountState for SecretsManagerState {
67 fn new_for_account(account_id: &str, region: &str, _endpoint: &str) -> Self {
68 Self::new(account_id, region)
69 }
70}
71
72#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
75pub struct SecretsManagerSnapshot {
76 pub schema_version: u32,
77 #[serde(default)]
78 pub accounts: Option<fakecloud_core::multi_account::MultiAccountState<SecretsManagerState>>,
79 #[serde(default)]
80 pub state: Option<SecretsManagerState>,
81}
82
83pub const SECRETSMANAGER_SNAPSHOT_SCHEMA_VERSION: u32 = 2;
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88
89 #[test]
90 fn new_initializes_empty() {
91 let state = SecretsManagerState::new("123456789012", "us-east-1");
92 assert_eq!(state.account_id, "123456789012");
93 assert_eq!(state.region, "us-east-1");
94 assert!(state.secrets.is_empty());
95 }
96
97 #[test]
98 fn reset_clears_secrets() {
99 let mut state = SecretsManagerState::new("123456789012", "us-east-1");
100 state.secrets.insert(
101 "s1".to_string(),
102 Secret {
103 name: "s1".to_string(),
104 arn: "arn".to_string(),
105 description: None,
106 kms_key_id: None,
107 versions: HashMap::new(),
108 current_version_id: None,
109 tags: vec![],
110 tags_ever_set: false,
111 deleted: false,
112 deletion_date: None,
113 created_at: Utc::now(),
114 last_changed_at: Utc::now(),
115 last_accessed_at: None,
116 rotation_enabled: None,
117 rotation_lambda_arn: None,
118 rotation_rules: None,
119 last_rotated_at: None,
120 resource_policy: None,
121 },
122 );
123 state.reset();
124 assert!(state.secrets.is_empty());
125 }
126}