Skip to main content

fakecloud_acm/
state.rs

1//! In-memory state for ACM certificates.
2
3use std::collections::BTreeMap;
4use std::sync::Arc;
5
6use chrono::{DateTime, Utc};
7use parking_lot::RwLock;
8use serde::{Deserialize, Serialize};
9
10pub type SharedAcmState = Arc<RwLock<AcmAccounts>>;
11
12#[derive(Debug, Default, Serialize, Deserialize)]
13pub struct AcmAccounts {
14    pub accounts: BTreeMap<String, AccountState>,
15}
16
17impl AcmAccounts {
18    pub fn new() -> Self {
19        Self::default()
20    }
21}
22
23#[derive(Debug, Default, Serialize, Deserialize)]
24pub struct AccountState {
25    /// Keyed by full certificate ARN.
26    pub certificates: BTreeMap<String, StoredCertificate>,
27    pub account_config: AccountConfig,
28}
29
30#[derive(Debug, Clone, Default, Serialize, Deserialize)]
31pub struct AccountConfig {
32    pub expiry_events_days_before_expiry: Option<i32>,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize)]
36pub struct StoredCertificate {
37    pub arn: String,
38    pub domain_name: String,
39    pub subject_alternative_names: Vec<String>,
40    pub status: String,
41    pub cert_type: String,
42    /// Stored when present so we can round-trip it on `GetCertificate`.
43    pub certificate_pem: Option<String>,
44    pub certificate_chain_pem: Option<String>,
45    /// Imported certs only — held in memory but never returned
46    /// (matches real ACM, which never returns the private key).
47    pub private_key_pem: Option<String>,
48    pub idempotency_token: Option<String>,
49    pub serial: String,
50    pub subject: String,
51    pub issuer: String,
52    pub key_algorithm: String,
53    pub signature_algorithm: String,
54    pub created_at: DateTime<Utc>,
55    pub issued_at: Option<DateTime<Utc>>,
56    pub imported_at: Option<DateTime<Utc>>,
57    pub revoked_at: Option<DateTime<Utc>>,
58    pub revocation_reason: Option<String>,
59    /// Last reason recorded by the admin status mutator when the cert
60    /// is flipped to `FAILED` / `VALIDATION_TIMED_OUT`. Surfaced in
61    /// `DescribeCertificate` as `FailureReason` to match real ACM.
62    #[serde(default)]
63    pub failure_reason: Option<String>,
64    pub not_before: DateTime<Utc>,
65    pub not_after: DateTime<Utc>,
66    pub validation_method: Option<String>,
67    pub domain_validation: Vec<DomainValidation>,
68    pub options: CertificateOptions,
69    pub renewal_eligibility: String,
70    pub managed_by: Option<String>,
71    pub certificate_authority_arn: Option<String>,
72    pub tags: BTreeMap<String, String>,
73    pub in_use_by: Vec<String>,
74    /// Number of `DescribeCertificate` reads since the cert was issued.
75    /// Legacy field kept for state-file compatibility; the read-count
76    /// flip was removed in favour of the async auto-issue tick (see
77    /// `AcmService::pending_validation_delay`).
78    #[serde(default)]
79    pub describe_read_count: u32,
80    /// Snapshot of the last managed-renewal round. `None` until either
81    /// the auto-issue tick fires (for DNS) or the admin `/approve`
82    /// endpoint flips an EMAIL cert; refreshed on every successful
83    /// `RenewCertificate`. Surfaced as `RenewalSummary` in
84    /// `DescribeCertificate` for `AMAZON_ISSUED` certs.
85    #[serde(default)]
86    pub renewal_summary: Option<RenewalSummary>,
87}
88
89#[derive(Debug, Clone, Serialize, Deserialize)]
90pub struct RenewalSummary {
91    /// One of `PENDING_AUTO_RENEWAL`, `PENDING_VALIDATION`, `SUCCESS`, `FAILED`.
92    pub renewal_status: String,
93    /// Per-domain validation snapshot at the moment the renewal summary
94    /// was emitted. fakecloud copies the cert's current
95    /// `domain_validation` into this field so callers see consistent
96    /// data between top-level `DomainValidationOptions` and
97    /// `RenewalSummary.DomainValidationOptions`.
98    pub domain_validation: Vec<DomainValidation>,
99    /// Optional renewal failure reason. Real ACM uses
100    /// `RenewalStatusReason` (an enum: `NO_AVAILABLE_CONTACTS`,
101    /// `ADDITIONAL_VERIFICATION_REQUIRED`, etc.); fakecloud just stores
102    /// whatever string the admin endpoint or renew flow recorded.
103    pub renewal_status_reason: Option<String>,
104    pub updated_at: DateTime<Utc>,
105}
106
107#[derive(Debug, Clone, Serialize, Deserialize)]
108pub struct DomainValidation {
109    pub domain_name: String,
110    pub validation_status: String,
111    pub validation_method: String,
112    pub resource_record_name: Option<String>,
113    pub resource_record_type: Option<String>,
114    pub resource_record_value: Option<String>,
115}
116
117#[derive(Debug, Clone, Default, Serialize, Deserialize)]
118pub struct CertificateOptions {
119    pub certificate_transparency_logging_preference: String,
120    pub export: String,
121}