Skip to main content

fakecloud_shield/
state.rs

1//! Account-partitioned, serializable state for AWS Shield / Shield Advanced.
2//!
3//! Shield resources are stored as assembled, response-shaped `serde_json::Value`s
4//! keyed by their natural identifiers so a read returns exactly what was written
5//! (round-trip fidelity) and the on-the-wire JSON never carries a field that
6//! isn't in the Smithy model. The subscription, emergency-contact list, DRT
7//! access (role + log buckets) and proactive-engagement status are
8//! account-level singletons; protections, protection groups, per-resource
9//! application-layer automatic-response configs and tags are keyed maps.
10
11use std::collections::BTreeMap;
12use std::sync::Arc;
13
14use parking_lot::RwLock;
15use serde::{Deserialize, Serialize};
16use serde_json::Value;
17
18use fakecloud_core::multi_account::{AccountState, MultiAccountState};
19
20pub const SHIELD_SNAPSHOT_SCHEMA_VERSION: u32 = 1;
21
22/// The account-scoped Shield state for one AWS account.
23#[derive(Debug, Clone, Default, Serialize, Deserialize)]
24pub struct ShieldState {
25    /// Protections keyed by `ProtectionId` (a 36-char id); value is a
26    /// `Protection` shape JSON.
27    #[serde(default)]
28    pub protections: BTreeMap<String, Value>,
29    /// Insertion order of protection ids.
30    #[serde(default)]
31    pub protection_order: Vec<String>,
32    /// Protection groups keyed by `ProtectionGroupId`; value is a
33    /// `ProtectionGroup` shape JSON.
34    #[serde(default)]
35    pub protection_groups: BTreeMap<String, Value>,
36    /// Insertion order of protection-group ids.
37    #[serde(default)]
38    pub protection_group_order: Vec<String>,
39    /// The account's Shield Advanced `Subscription` shape JSON, if subscribed.
40    #[serde(default)]
41    pub subscription: Option<Value>,
42    /// Emergency-contact list (`[{EmailAddress, PhoneNumber?, ContactNotes?}]`).
43    #[serde(default)]
44    pub emergency_contacts: Vec<Value>,
45    /// The DDoS Response Team (DRT) role ARN, if a role has been associated.
46    #[serde(default)]
47    pub drt_role_arn: Option<String>,
48    /// The DRT log-access buckets (`[bucketName]`).
49    #[serde(default)]
50    pub drt_log_buckets: Vec<String>,
51    /// Proactive-engagement status: `ENABLED` / `DISABLED` / `PENDING`.
52    #[serde(default)]
53    pub proactive_engagement_status: Option<String>,
54    /// Tags keyed by resource ARN; value is a `TagList` (`[{Key,Value}]`).
55    #[serde(default)]
56    pub tags: BTreeMap<String, Vec<Value>>,
57}
58
59impl AccountState for ShieldState {
60    fn new_for_account(_account_id: &str, _region: &str, _endpoint: &str) -> Self {
61        Self::default()
62    }
63}
64
65pub type SharedShieldState = Arc<RwLock<MultiAccountState<ShieldState>>>;
66
67#[derive(Debug, Serialize, Deserialize)]
68pub struct ShieldSnapshot {
69    pub schema_version: u32,
70    pub accounts: MultiAccountState<ShieldState>,
71}