Skip to main content

coil_config/
infra.rs

1use serde::{Deserialize, Serialize};
2
3use crate::SecretRef;
4
5#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
6pub struct TlsConfig {
7    pub mode: TlsMode,
8    #[serde(default)]
9    pub challenge: Option<AcmeChallenge>,
10    #[serde(default)]
11    pub provider: Option<TlsProvider>,
12    #[serde(default)]
13    pub account_secret: Option<SecretRef>,
14}
15
16#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
17pub struct DatabaseConfig {
18    #[serde(default = "default_database_driver")]
19    pub driver: DatabaseDriver,
20    #[serde(default = "default_database_url_secret")]
21    pub url: Option<SecretRef>,
22    #[serde(default = "default_database_schema")]
23    pub schema: String,
24    #[serde(default = "default_migrations_table")]
25    pub migrations_table: String,
26    #[serde(default = "default_min_database_connections")]
27    pub min_connections: u16,
28    #[serde(default = "default_max_database_connections")]
29    pub max_connections: u16,
30    #[serde(default = "default_statement_timeout_secs")]
31    pub statement_timeout_secs: u64,
32}
33
34impl Default for DatabaseConfig {
35    fn default() -> Self {
36        Self {
37            driver: default_database_driver(),
38            url: default_database_url_secret(),
39            schema: default_database_schema(),
40            migrations_table: default_migrations_table(),
41            min_connections: default_min_database_connections(),
42            max_connections: default_max_database_connections(),
43            statement_timeout_secs: default_statement_timeout_secs(),
44        }
45    }
46}
47
48#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
49#[serde(rename_all = "snake_case")]
50pub enum DatabaseDriver {
51    Postgres,
52}
53
54#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
55#[serde(rename_all = "kebab-case")]
56pub enum TlsMode {
57    External,
58    Acme,
59    CloudflareOrigin,
60    Manual,
61}
62
63#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
64pub enum AcmeChallenge {
65    #[serde(rename = "http-01")]
66    Http01,
67    #[serde(rename = "tls-alpn-01")]
68    TlsAlpn01,
69    #[serde(rename = "dns-01")]
70    Dns01,
71}
72
73#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
74#[serde(rename_all = "kebab-case")]
75pub enum TlsProvider {
76    CloudflareDns,
77    CloudflareOriginCa,
78    ManualImport,
79}
80
81#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
82pub struct StorageConfig {
83    pub default_class: StorageClass,
84    #[serde(default = "default_storage_deployment")]
85    pub deployment: StorageDeployment,
86    #[serde(default = "default_single_node_escape_hatch")]
87    pub single_node_escape_hatch: SingleNodeStorageMode,
88    #[serde(default)]
89    pub object_store: Option<ObjectStoreKind>,
90    pub local_root: String,
91    #[serde(default)]
92    pub object_store_secret: Option<SecretRef>,
93}
94
95#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
96#[serde(rename_all = "snake_case")]
97pub enum StorageDeployment {
98    Distributed,
99    SingleNode,
100}
101
102#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
103#[serde(rename_all = "snake_case")]
104pub enum SingleNodeStorageMode {
105    Disabled,
106    ExplicitSingleNode,
107}
108
109#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
110#[serde(rename_all = "snake_case")]
111pub enum StorageClass {
112    PublicAsset,
113    PublicUpload,
114    PrivateShared,
115    LocalOnlySensitive,
116}
117
118#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
119#[serde(rename_all = "snake_case")]
120pub enum ObjectStoreKind {
121    S3,
122}
123
124#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
125pub struct CacheConfig {
126    pub l1: CacheL1,
127    #[serde(default)]
128    pub l2: Option<DistributedCache>,
129}
130
131#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
132#[serde(rename_all = "snake_case")]
133pub enum CacheL1 {
134    Moka,
135}
136
137#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
138#[serde(rename_all = "snake_case")]
139pub enum DistributedCache {
140    Redis,
141    Valkey,
142}
143
144#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
145pub struct JobsConfig {
146    pub backend: JobBackend,
147    #[serde(default = "default_retry_limit")]
148    pub retry_limit: u32,
149}
150
151#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
152#[serde(rename_all = "snake_case")]
153pub enum JobBackend {
154    Redis,
155    Valkey,
156}
157
158#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
159pub struct ObservabilityConfig {
160    pub metrics: bool,
161    pub tracing: bool,
162}
163
164#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
165pub struct AssetsConfig {
166    pub publish_manifest: bool,
167    #[serde(default)]
168    pub cdn_base_url: Option<String>,
169}
170
171fn default_retry_limit() -> u32 {
172    5
173}
174
175fn default_database_driver() -> DatabaseDriver {
176    DatabaseDriver::Postgres
177}
178
179fn default_database_url_secret() -> Option<SecretRef> {
180    Some(SecretRef::Env {
181        var: "DATABASE_URL".to_string(),
182    })
183}
184
185fn default_database_schema() -> String {
186    "public".to_string()
187}
188
189fn default_migrations_table() -> String {
190    "_coil_migrations".to_string()
191}
192
193fn default_min_database_connections() -> u16 {
194    4
195}
196
197fn default_max_database_connections() -> u16 {
198    32
199}
200
201fn default_statement_timeout_secs() -> u64 {
202    30
203}
204
205fn default_storage_deployment() -> StorageDeployment {
206    StorageDeployment::Distributed
207}
208
209fn default_single_node_escape_hatch() -> SingleNodeStorageMode {
210    SingleNodeStorageMode::Disabled
211}