1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct Machine {
7 pub id: String,
8 pub name: String,
9 pub state: MachineState,
10 pub region: String,
11 pub image_ref: ImageRef,
12 pub instance_id: String,
13 pub private_ip: String,
14 pub created_at: DateTime<Utc>,
15 pub updated_at: DateTime<Utc>,
16 pub config: MachineConfig,
17 pub events: Vec<MachineEvent>,
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
21#[serde(rename_all = "lowercase")]
22pub enum MachineState {
23 Created,
24 Starting,
25 Started,
26 Stopping,
27 Stopped,
28 Destroying,
29 Destroyed,
30 Suspending,
31 Suspended,
32}
33
34#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct ImageRef {
36 pub registry: String,
37 pub repository: String,
38 pub tag: String,
39 pub digest: Option<String>,
40}
41
42#[derive(Debug, Clone, Serialize, Deserialize)]
43pub struct MachineConfig {
44 pub image: String,
45 pub guest: GuestConfig,
46 #[serde(skip_serializing_if = "Option::is_none")]
47 pub env: Option<HashMap<String, String>>,
48 #[serde(skip_serializing_if = "Option::is_none")]
49 pub services: Option<Vec<ServiceConfig>>,
50 #[serde(skip_serializing_if = "Option::is_none")]
51 pub checks: Option<HashMap<String, HealthCheck>>,
52 #[serde(skip_serializing_if = "Option::is_none")]
53 pub restart: Option<RestartConfig>,
54 #[serde(skip_serializing_if = "Option::is_none")]
55 pub auto_destroy: Option<bool>,
56 #[serde(skip_serializing_if = "Option::is_none")]
57 pub dns: Option<DnsConfig>,
58 #[serde(skip_serializing_if = "Option::is_none")]
59 pub processes: Option<Vec<ProcessConfig>>,
60 #[serde(skip_serializing_if = "Option::is_none")]
61 pub files: Option<Vec<FileConfig>>,
62 #[serde(skip_serializing_if = "Option::is_none")]
63 pub init: Option<InitConfig>,
64 #[serde(skip_serializing_if = "Option::is_none")]
65 pub mounts: Option<Vec<MountConfig>>,
66 #[serde(skip_serializing_if = "Option::is_none")]
67 pub containers: Option<Vec<ContainerConfig>>,
68}
69
70#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct GuestConfig {
72 pub cpu_kind: String,
73 pub cpus: u32,
74 pub memory_mb: u32,
75 #[serde(skip_serializing_if = "Option::is_none")]
76 pub gpu_kind: Option<String>,
77 #[serde(skip_serializing_if = "Option::is_none")]
78 pub gpus: Option<u32>,
79 #[serde(skip_serializing_if = "Option::is_none")]
80 pub kernel_args: Option<Vec<String>>,
81}
82
83#[derive(Debug, Clone, Serialize, Deserialize)]
84pub struct ServiceConfig {
85 pub ports: Vec<PortConfig>,
86 pub protocol: String,
87 pub internal_port: u16,
88 #[serde(skip_serializing_if = "Option::is_none")]
89 pub autostop: Option<AutostopConfig>,
90 #[serde(skip_serializing_if = "Option::is_none")]
91 pub autostart: Option<AutostartConfig>,
92 #[serde(skip_serializing_if = "Option::is_none")]
93 pub force_instance_description: Option<String>,
94}
95
96#[derive(Debug, Clone, Serialize, Deserialize)]
97pub struct PortConfig {
98 pub port: u16,
99 pub handlers: Vec<String>,
100 #[serde(skip_serializing_if = "Option::is_none")]
101 pub force_https: Option<bool>,
102 #[serde(skip_serializing_if = "Option::is_none")]
103 pub tls_options: Option<TlsOptions>,
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize)]
107pub struct TlsOptions {
108 pub alpn: Vec<String>,
109 pub versions: Vec<String>,
110}
111
112#[derive(Debug, Clone, Serialize, Deserialize)]
113pub struct HealthCheck {
114 #[serde(rename = "type")]
115 pub check_type: String,
116 #[serde(skip_serializing_if = "Option::is_none")]
117 pub port: Option<u16>,
118 #[serde(skip_serializing_if = "Option::is_none")]
119 pub interval: Option<u64>,
120 #[serde(skip_serializing_if = "Option::is_none")]
121 pub timeout: Option<u64>,
122 #[serde(skip_serializing_if = "Option::is_none")]
123 pub grace_period: Option<u64>,
124 #[serde(skip_serializing_if = "Option::is_none")]
125 pub method: Option<String>,
126 #[serde(skip_serializing_if = "Option::is_none")]
127 pub path: Option<String>,
128 #[serde(skip_serializing_if = "Option::is_none")]
129 pub protocol: Option<String>,
130 #[serde(skip_serializing_if = "Option::is_none")]
131 pub tls_server_name: Option<String>,
132 #[serde(skip_serializing_if = "Option::is_none")]
133 pub tls_skip_verify: Option<bool>,
134 #[serde(skip_serializing_if = "Option::is_none")]
135 pub headers: Option<HashMap<String, Vec<String>>>,
136}
137
138#[derive(Debug, Clone, Serialize, Deserialize)]
139pub struct RestartConfig {
140 pub policy: String,
141 #[serde(skip_serializing_if = "Option::is_none")]
142 pub max_retries: Option<u32>,
143}
144
145#[derive(Debug, Clone, Serialize, Deserialize)]
146pub struct DnsConfig {
147 #[serde(skip_serializing_if = "Option::is_none")]
148 pub skip_registration: Option<bool>,
149 #[serde(skip_serializing_if = "Option::is_none")]
150 pub nameservers: Option<Vec<String>>,
151 #[serde(skip_serializing_if = "Option::is_none")]
152 pub searches: Option<Vec<String>>,
153 #[serde(skip_serializing_if = "Option::is_none")]
154 pub options: Option<Vec<String>>,
155}
156
157#[derive(Debug, Clone, Serialize, Deserialize)]
158pub struct ProcessConfig {
159 #[serde(skip_serializing_if = "Option::is_none")]
160 pub entrypoint: Option<Vec<String>>,
161 #[serde(skip_serializing_if = "Option::is_none")]
162 pub cmd: Option<Vec<String>>,
163 #[serde(skip_serializing_if = "Option::is_none")]
164 pub env: Option<HashMap<String, String>>,
165 #[serde(skip_serializing_if = "Option::is_none")]
166 pub exec: Option<Vec<String>>,
167 #[serde(skip_serializing_if = "Option::is_none")]
168 pub user: Option<String>,
169 #[serde(skip_serializing_if = "Option::is_none")]
170 pub secrets: Option<Vec<SecretConfig>>,
171}
172
173#[derive(Debug, Clone, Serialize, Deserialize)]
174pub struct SecretConfig {
175 pub env_var: String,
176 #[serde(skip_serializing_if = "Option::is_none")]
177 pub name: Option<String>,
178}
179
180#[derive(Debug, Clone, Serialize, Deserialize)]
181pub struct FileConfig {
182 pub guest_path: String,
183 #[serde(skip_serializing_if = "Option::is_none")]
184 pub raw_value: Option<String>,
185 #[serde(skip_serializing_if = "Option::is_none")]
186 pub secret_name: Option<String>,
187}
188
189#[derive(Debug, Clone, Serialize, Deserialize)]
190pub struct InitConfig {
191 #[serde(skip_serializing_if = "Option::is_none")]
192 pub exec: Option<Vec<String>>,
193 #[serde(skip_serializing_if = "Option::is_none")]
194 pub entrypoint: Option<Vec<String>>,
195 #[serde(skip_serializing_if = "Option::is_none")]
196 pub cmd: Option<Vec<String>>,
197}
198
199#[derive(Debug, Clone, Serialize, Deserialize)]
200pub struct MountConfig {
201 pub volume: String,
202 pub path: String,
203}
204
205#[derive(Debug, Clone, Serialize, Deserialize)]
206pub struct ContainerConfig {
207 pub name: String,
208 pub image: String,
209 #[serde(skip_serializing_if = "Option::is_none")]
210 pub env: Option<HashMap<String, String>>,
211 #[serde(skip_serializing_if = "Option::is_none")]
212 pub health_checks: Option<Vec<HealthCheck>>,
213 #[serde(skip_serializing_if = "Option::is_none")]
214 pub startup_commands: Option<Vec<String>>,
215 #[serde(skip_serializing_if = "Option::is_none")]
216 pub attached_files: Option<Vec<FileConfig>>,
217 #[serde(skip_serializing_if = "Option::is_none")]
218 pub dependencies: Option<Vec<String>>,
219}
220
221#[derive(Debug, Clone, Serialize, Deserialize)]
222pub struct AutostopConfig {
223 #[serde(skip_serializing_if = "Option::is_none")]
224 pub enabled: Option<bool>,
225 #[serde(skip_serializing_if = "Option::is_none")]
226 pub seconds: Option<u32>,
227}
228
229#[derive(Debug, Clone, Serialize, Deserialize)]
230pub struct AutostartConfig {
231 #[serde(skip_serializing_if = "Option::is_none")]
232 pub enabled: Option<bool>,
233}
234
235#[derive(Debug, Clone, Serialize, Deserialize)]
236pub struct MachineEvent {
237 #[serde(rename = "type")]
238 pub event_type: String,
239 pub status: String,
240 pub source: String,
241 pub timestamp: u64,
242}
243
244#[derive(Debug, Clone, Serialize, Deserialize)]
245pub struct CreateMachineRequest {
246 #[serde(skip_serializing_if = "Option::is_none")]
247 pub name: Option<String>,
248 #[serde(skip_serializing_if = "Option::is_none")]
249 pub region: Option<String>,
250 pub config: MachineConfig,
251 #[serde(skip_serializing_if = "Option::is_none")]
252 pub skip_launch: Option<bool>,
253 #[serde(skip_serializing_if = "Option::is_none")]
254 pub skip_service_registration: Option<bool>,
255 #[serde(skip_serializing_if = "Option::is_none")]
256 pub lease_ttl: Option<u32>,
257}
258
259#[derive(Debug, Clone, Serialize, Deserialize)]
260pub struct UpdateMachineRequest {
261 pub config: MachineConfig,
262 #[serde(skip_serializing_if = "Option::is_none")]
263 pub current_version: Option<String>,
264 #[serde(skip_serializing_if = "Option::is_none")]
265 pub name: Option<String>,
266 #[serde(skip_serializing_if = "Option::is_none")]
267 pub region: Option<String>,
268 #[serde(skip_serializing_if = "Option::is_none")]
269 pub skip_launch: Option<bool>,
270 #[serde(skip_serializing_if = "Option::is_none")]
271 pub skip_service_registration: Option<bool>,
272 #[serde(skip_serializing_if = "Option::is_none")]
273 pub lease_ttl: Option<u32>,
274}
275
276#[derive(Debug, Clone, Serialize, Deserialize)]
277pub struct StopMachineRequest {
278 #[serde(skip_serializing_if = "Option::is_none")]
279 pub signal: Option<String>,
280 #[serde(skip_serializing_if = "Option::is_none")]
281 pub timeout: Option<String>,
282}
283
284#[derive(Debug, Clone, Serialize, Deserialize)]
285pub struct StartMachineResponse {
286 pub previous_state: String,
287 pub migrated: bool,
288 pub new_host: String,
289}
290
291#[derive(Debug, Clone, Serialize, Deserialize)]
292pub struct StopMachineResponse {
293 pub ok: bool,
294}
295
296#[derive(Debug, Clone, Serialize, Deserialize)]
297pub struct WaitMachineQuery {
298 #[serde(skip_serializing_if = "Option::is_none")]
299 pub instance_id: Option<String>,
300 #[serde(skip_serializing_if = "Option::is_none")]
301 pub timeout: Option<u32>,
302 #[serde(skip_serializing_if = "Option::is_none")]
303 pub state: Option<String>,
304}