1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4#[derive(Debug, Clone)]
6pub struct NubisConfig {
7 pub api_key: String,
8 pub base_url: String,
9 pub timeout: Option<std::time::Duration>,
10}
11
12impl Default for NubisConfig {
13 fn default() -> Self {
14 Self {
15 api_key: String::new(),
16 base_url: "https://api.usenubis.com".to_string(),
17 timeout: Some(std::time::Duration::from_secs(30)),
18 }
19 }
20}
21
22#[derive(Debug, Clone, Serialize)]
24pub struct CreateVmRequest {
25 pub project_id: String,
26 pub name: String,
27 pub size: String,
28 pub region: String,
29 pub image: String,
30 #[serde(skip_serializing_if = "Vec::is_empty")]
31 pub ssh_keys: Vec<String>,
32 #[serde(skip_serializing_if = "Option::is_none")]
33 pub ssh_public_key: Option<String>,
34 #[serde(skip_serializing_if = "Option::is_none")]
35 pub ssh_public_key_id: Option<String>,
36 #[serde(skip_serializing_if = "Option::is_none")]
37 pub network_id: Option<String>,
38 #[serde(skip_serializing_if = "Option::is_none")]
39 pub firewall_id: Option<String>,
40 #[serde(skip_serializing_if = "Option::is_none")]
41 pub public_ip: Option<bool>,
42 #[serde(skip_serializing_if = "Option::is_none")]
43 pub tags: Option<HashMap<String, String>>,
44 #[serde(skip_serializing_if = "Option::is_none")]
45 pub enable_password_auth: Option<bool>,
46 #[serde(skip_serializing_if = "Option::is_none")]
47 pub admin_password: Option<String>,
48 #[serde(skip_serializing_if = "Vec::is_empty")]
49 pub ssh_allowed_cidrs: Vec<String>,
50}
51
52#[derive(Debug, Clone, Deserialize)]
54pub struct Vm {
55 pub id: String,
56 pub name: String,
57 pub status: String,
58 pub size: String,
59 pub region: String,
60 pub project_id: String,
61 pub org_id: String,
62 pub provider: String,
63 pub image: String,
64 #[serde(default)]
65 pub public_ip: Option<String>,
66 #[serde(default)]
67 pub private_ip: Option<String>,
68 #[serde(default)]
69 pub created_at: String,
70 #[serde(default)]
71 pub started_at: Option<String>,
72 #[serde(default)]
73 pub last_error: Option<String>,
74 pub provider_id: Option<String>,
76 pub do_droplet_id: Option<i64>,
78 pub do_vpc_uuid: Option<String>,
79 pub do_tags: Option<Vec<String>>,
80 pub raw_base_price_hourly: Option<f64>,
82 pub nubis_final_price_hourly: Option<f64>,
83 pub hourly_cost: Option<f64>,
84 #[serde(flatten)]
85 pub extra: HashMap<String, serde_json::Value>,
86}
87
88#[derive(Debug, Clone, Deserialize)]
90pub struct Project {
91 pub id: String,
92 pub name: String,
93 pub slug: String,
94 pub org_id: String,
95 #[serde(default)]
96 pub created_at: String,
97 #[serde(flatten)]
98 pub extra: HashMap<String, serde_json::Value>,
99}
100
101#[derive(Debug, Clone, Deserialize)]
103pub struct Organization {
104 pub id: String,
105 pub name: String,
106 pub slug: String,
107 #[serde(default)]
108 pub created_at: String,
109 #[serde(flatten)]
110 pub extra: HashMap<String, serde_json::Value>,
111}
112
113#[derive(Debug, Clone, Deserialize)]
115pub struct Region {
116 pub id: String,
117 pub name: String,
118 pub slug: String,
119 #[serde(default)]
120 pub available: bool,
121 #[serde(flatten)]
122 pub extra: HashMap<String, serde_json::Value>,
123}
124
125#[derive(Debug, Clone, Deserialize)]
127pub struct Size {
128 pub id: String,
129 pub slug: String,
130 pub memory: u64,
131 pub vcpus: u32,
132 pub disk: u64,
133 pub transfer: u64,
134 #[serde(default)]
135 pub price_monthly: f64,
136 #[serde(default)]
137 pub price_hourly: f64,
138 #[serde(flatten)]
139 pub extra: HashMap<String, serde_json::Value>,
140}
141
142#[derive(Debug, Clone, Deserialize)]
144pub struct Image {
145 pub id: String,
146 pub name: String,
147 #[serde(skip_serializing_if = "Option::is_none")]
148 pub slug: Option<String>,
149 #[serde(skip_serializing_if = "Option::is_none")]
150 pub distribution: Option<String>,
151 #[serde(flatten)]
152 pub extra: HashMap<String, serde_json::Value>,
153}
154
155#[derive(Debug, Deserialize)]
157pub struct ApiErrorResponse {
158 pub error: ApiError,
159}
160
161#[derive(Debug, Deserialize)]
162pub struct ApiError {
163 pub message: String,
164 #[serde(skip_serializing_if = "Option::is_none")]
165 pub code: Option<String>,
166}