tembo/cli/
tembo_config.rs

1use controller::app_service::types::AppService;
2use controller::extensions::types::Extension as ControllerExtension;
3use serde::{Deserialize, Deserializer, Serialize};
4use std::collections::HashMap;
5use tembo_stacks::apps::types::AppType;
6use toml::Value;
7
8#[derive(Serialize, Deserialize, Debug, Clone)]
9pub struct TemboConfig {
10    pub version: String,
11    pub defaults: InstanceSettings,
12}
13
14// Config struct holds to data from the `[config]` section.
15#[derive(Serialize, Deserialize, Debug, Clone)]
16#[serde(deny_unknown_fields)]
17pub struct InstanceSettings {
18    pub environment: String,
19    pub instance_name: String,
20    #[serde(default = "default_cpu")]
21    pub cpu: String,
22    #[serde(default = "default_memory")]
23    pub memory: String,
24    #[serde(default = "default_storage")]
25    pub storage: String,
26    #[serde(default = "default_replicas")]
27    pub replicas: i32,
28    pub stack_type: Option<String>,
29    pub postgres_configurations: Option<HashMap<String, Value>>,
30    #[serde(default = "default_pg_version")]
31    pub pg_version: u8,
32    #[serde(
33        deserialize_with = "deserialize_extensions",
34        default = "default_extensions"
35    )]
36    pub extensions: Option<HashMap<String, Extension>>,
37    pub app_services: Option<Vec<AppType>>,
38    pub controller_app_services: Option<HashMap<String, AppService>>,
39    pub final_extensions: Option<Vec<ControllerExtension>>,
40    pub extra_domains_rw: Option<Vec<String>>,
41    pub ip_allow_list: Option<Vec<String>>,
42    pub stack_file: Option<String>,
43}
44
45#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
46pub struct OverlayInstanceSettings {
47    pub cpu: Option<String>,
48    pub memory: Option<String>,
49    pub storage: Option<String>,
50    pub replicas: Option<i32>,
51    pub stack_type: Option<String>,
52    pub postgres_configurations: Option<HashMap<String, Value>>,
53    pub extensions: Option<HashMap<String, Extension>>,
54    pub extra_domains_rw: Option<Vec<String>>,
55    pub ip_allow_list: Option<Vec<String>>,
56    pub pg_version: Option<u8>,
57    pub stack_file: Option<String>,
58}
59
60// If a trunk project name is not specified, then assume
61// it's the same name as the extension.
62fn deserialize_extensions<'de, D>(
63    deserializer: D,
64) -> Result<Option<HashMap<String, Extension>>, D::Error>
65where
66    D: Deserializer<'de>,
67{
68    let map = Option::<HashMap<String, Extension>>::deserialize(deserializer)?;
69
70    map.map(|mut m| {
71        m.iter_mut().for_each(|(key, ext)| {
72            if ext.trunk_project.is_none() {
73                ext.trunk_project = Some(key.clone());
74            }
75        });
76        m
77    })
78    .map_or(Ok(None), |m| Ok(Some(m)))
79}
80
81/// Default to Postgres 15
82fn default_pg_version() -> u8 {
83    15
84}
85
86fn default_cpu() -> String {
87    "0.25".to_string()
88}
89
90fn default_memory() -> String {
91    "1Gi".to_string()
92}
93
94fn default_storage() -> String {
95    "10Gi".to_string()
96}
97
98fn default_replicas() -> i32 {
99    1
100}
101
102fn default_extensions() -> Option<HashMap<String, Extension>> {
103    Some(HashMap::new())
104}
105
106#[derive(Serialize, Deserialize, Debug, PartialEq, Clone)]
107pub struct Extension {
108    pub version: Option<String>,
109    pub enabled: Option<bool>,
110    pub trunk_project: Option<String>,
111    pub trunk_project_version: Option<String>,
112}
113
114#[derive(Clone)]
115pub struct Library {
116    pub name: String,
117    pub priority: i32,
118}
119
120#[derive(Serialize, Deserialize, Clone)]
121pub struct TrunkProject {
122    pub name: String,
123    pub extensions: Option<Vec<TrunkExtension>>,
124}
125
126#[derive(Serialize, Deserialize, Clone)]
127pub struct TrunkExtension {
128    pub extension_name: String,
129    pub loadable_libraries: Option<Vec<LoadableLibrary>>,
130    pub version: String,
131}
132
133#[derive(Serialize, Deserialize, Clone)]
134pub struct LoadableLibrary {
135    pub library_name: String,
136    pub priority: i32,
137}