Skip to main content

alien_core/deployment/
domain.rs

1//! Domain, certificate, and DNS metadata for auto-managed public resources.
2
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6/// Certificate status in the certificate lifecycle
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
8#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
9#[serde(rename_all = "kebab-case")]
10pub enum CertificateStatus {
11    Pending,
12    Issued,
13    Renewing,
14    RenewalFailed,
15    Failed,
16    Deleting,
17}
18
19/// DNS record status in the DNS lifecycle
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
21#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
22#[serde(rename_all = "lowercase")]
23pub enum DnsRecordStatus {
24    Pending,
25    Active,
26    Updating,
27    Deleting,
28    Failed,
29}
30
31/// Certificate and DNS metadata for a managed hostname.
32///
33/// Includes decrypted certificate data for issued certificates.
34/// Private keys are deployment-scoped secrets (like environment variables).
35#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
36#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
37#[serde(rename_all = "camelCase")]
38pub struct ManagedDomainInfo {
39    /// Fully qualified domain name.
40    pub fqdn: String,
41    /// Certificate ID (for tracking/logging).
42    pub certificate_id: String,
43    /// Current certificate status
44    pub certificate_status: CertificateStatus,
45    /// Current DNS record status
46    pub dns_status: DnsRecordStatus,
47    /// Last DNS error message. Present when DNS previously failed, even if status
48    /// was reset to pending for retry. Used to surface actionable error context
49    /// in WaitingForDns failure messages.
50    #[serde(skip_serializing_if = "Option::is_none")]
51    pub dns_error: Option<String>,
52    /// Full PEM certificate chain (only present if status is "issued").
53    #[serde(skip_serializing_if = "Option::is_none")]
54    pub certificate_chain: Option<String>,
55    /// Decrypted private key (only present if status is "issued").
56    #[serde(skip_serializing_if = "Option::is_none")]
57    pub private_key: Option<String>,
58    /// ISO 8601 timestamp when certificate was issued (for renewal detection).
59    #[serde(skip_serializing_if = "Option::is_none")]
60    pub issued_at: Option<String>,
61}
62
63/// Certificate and DNS metadata for a public resource.
64///
65/// The direct fields describe the primary generated hostname. `aliases`
66/// contains additional managed hostnames that route directly to the same
67/// resource.
68#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
69#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
70#[serde(rename_all = "camelCase")]
71pub struct ResourceDomainInfo {
72    /// Fully qualified domain name.
73    pub fqdn: String,
74    /// Certificate ID (for tracking/logging).
75    pub certificate_id: String,
76    /// Current certificate status
77    pub certificate_status: CertificateStatus,
78    /// Current DNS record status
79    pub dns_status: DnsRecordStatus,
80    /// Last DNS error message. Present when DNS previously failed, even if status
81    /// was reset to pending for retry. Used to surface actionable error context
82    /// in WaitingForDns failure messages.
83    #[serde(skip_serializing_if = "Option::is_none")]
84    pub dns_error: Option<String>,
85    /// Full PEM certificate chain (only present if status is "issued").
86    #[serde(skip_serializing_if = "Option::is_none")]
87    pub certificate_chain: Option<String>,
88    /// Decrypted private key (only present if status is "issued").
89    #[serde(skip_serializing_if = "Option::is_none")]
90    pub private_key: Option<String>,
91    /// ISO 8601 timestamp when certificate was issued (for renewal detection).
92    #[serde(skip_serializing_if = "Option::is_none")]
93    pub issued_at: Option<String>,
94    /// Additional managed hostnames for the resource.
95    #[serde(default, skip_serializing_if = "Vec::is_empty")]
96    pub aliases: Vec<ManagedDomainInfo>,
97}
98
99/// Domain metadata for auto-managed public resources (no private keys).
100#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
101#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))]
102#[serde(rename_all = "camelCase")]
103pub struct DomainMetadata {
104    /// Base domain for auto-generated domains (e.g., "vpc.direct").
105    pub base_domain: String,
106    /// Deployment public subdomain (e.g., "k8f2j3").
107    pub public_subdomain: String,
108    /// Hosted zone ID for DNS records.
109    pub hosted_zone_id: String,
110    /// Metadata per resource ID.
111    pub resources: HashMap<String, ResourceDomainInfo>,
112}