Skip to main content

nubis_sdk/
types.rs

1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4/// Configuration for the Nubis client
5#[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/// Request to create a new VM
23#[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/// VM representation
53#[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    // Provider ID
75    pub provider_id: Option<String>,
76    // DigitalOcean specific
77    pub do_droplet_id: Option<i64>,
78    pub do_vpc_uuid: Option<String>,
79    pub do_tags: Option<Vec<String>>,
80    // Pricing
81    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/// Project representation
89#[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/// Organization representation
102#[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/// Region representation
114#[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/// Size (VM plan) representation
126#[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/// Image (distribution) representation
143#[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/// API error response
156#[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}