1use crate::client::CivoClient;
2use crate::client::SimpleResponse;
3use crate::errors::GenericError;
4use crate::errors::HTTPError;
5use crate::network::Subnet;
6use crate::utils;
7use serde::{Deserialize, Serialize};
8#[derive(Deserialize, Serialize, Debug)]
9pub struct Instance {
10 #[serde(default)]
11 pub id: String,
12 #[serde(default)]
13 pub openstack_server_id: String,
14 #[serde(default)]
15 pub hostname: String,
16 #[serde(default)]
17 pub reverse_dns: String,
18 #[serde(default)]
19 pub size: String,
20 #[serde(default)]
21 pub region: String,
22 #[serde(default)]
23 pub network_id: String,
24 #[serde(default)]
25 pub private_ip: String,
26 #[serde(default)]
27 pub public_ip: String,
28 #[serde(default)]
29 pub ipv6: String,
30 #[serde(default)]
31 pub pseudo_ip: String,
32 #[serde(default)]
33 pub template_id: String,
34 #[serde(default)]
35 pub source_type: String,
36 #[serde(default)]
37 pub source_id: String,
38 #[serde(default)]
39 pub snapshot_id: String,
40 #[serde(default)]
41 pub initial_user: String,
42 #[serde(default)]
43 pub initial_password: String,
44 #[serde(default)]
45 pub ssh_key: String,
46 #[serde(default)]
47 pub ssh_key_id: String,
48 #[serde(default)]
49 pub status: String,
50 #[serde(default)]
51 pub notes: String,
52 #[serde(default)]
53 pub firewall_id: String,
54 #[serde(default)]
55 pub tags: Vec<String>,
56 #[serde(default)]
57 pub civostatsd_token: String,
58 #[serde(default)]
59 pub civostatsd_stats: String,
60 #[serde(default)]
61 pub civostatsd_stats_per_minute: Vec<String>,
62 #[serde(default)]
63 pub civostatsd_stats_per_hour: Vec<String>,
64 #[serde(default)]
65 pub openstack_image_id: String,
66 #[serde(default)]
67 pub rescue_password: String,
68 #[serde(default)]
69 pub volume_backed: bool,
70 #[serde(default)]
71 pub cpu_cores: i32,
72 #[serde(default)]
73 pub ram_mb: i32,
74 #[serde(default)]
75 pub disk_gb: i32,
76 #[serde(default)]
77 pub script: String,
78 #[serde(default)]
79 pub created_at: String,
80 #[serde(default)]
81 pub reserved_ip_id: String,
82 #[serde(default)]
83 subnets: Vec<Subnet>,
84}
85#[derive(Deserialize, Serialize, Debug)]
86pub struct InstanceConfig {
87 pub count: i32,
88 pub hostname: String,
89 #[serde(default)]
90 pub reverse_dns: String,
91 pub size: String,
92 pub region: String,
93 pub public_ip: String,
94 pub network_id: String,
95 pub template_id: String,
96 pub source_type: String,
97 pub snapshot_id: String,
98 #[serde(default)]
99 pub subnets: Vec<String>,
100 pub initial_user: String,
101 #[serde(default)]
102 pub ssh_key_id: Option<String>,
103 pub script: String,
104 #[serde(default)]
105 pub tags: String,
106 #[serde(default)]
107 pub tag_list: String,
108 pub firewall_id: String,
109}
110#[derive(Deserialize, Serialize)]
111pub struct InstanceConsole {
112 pub url: String,
113}
114
115pub struct PaginatedInstanceList {
116 pub page: i32,
117 pub per_page: i32,
118 pub pages: i32,
119 pub items: Vec<Instance>,
120}
121
122impl CivoClient {
123 pub async fn new_instance_config(&self) -> Result<InstanceConfig, GenericError> {
130 let default_network = match self.get_default_network().await {
131 Ok(network) => network,
132 Err(error) => return Err(GenericError::new(&error.to_string())),
133 };
134
135 let disk_img = match self.get_disk_by_name("ubuntu-focal").await {
136 Ok(img) => img,
137 Err(error) => return Err(GenericError::new(&error.to_string())),
138 };
139
140 let instance_config = InstanceConfig {
141 count: 1,
142 hostname: utils::random_name(),
143 reverse_dns: "".to_string(),
144 size: "g3.medium".to_string(),
145 region: self.region.to_string(),
146 public_ip: "true".to_string(),
147 network_id: default_network.ID,
148 template_id: disk_img.id,
149 source_type: "".to_string(),
150 snapshot_id: "".to_string(),
151 initial_user: "civo".to_string(),
152 script: "".to_string(),
153 tags: "".to_string(),
154 tag_list: "".to_string(),
155 firewall_id: "".to_string(),
156 subnets: vec!["".to_string()],
157 ssh_key_id: None,
158 };
159
160 Ok(instance_config)
161 }
162
163 pub async fn create_instance(&self, config: InstanceConfig) -> Result<Instance, HTTPError> {
173 let instance_endpoint = self.prepare_client_url("/v2/instances");
174 let resp = self.send_post_request(instance_endpoint, &config).await;
175 match resp {
176 Ok(instance) => Ok(instance.json::<Instance>().await.unwrap()),
177 Err(err) => Err(err),
178 }
179 }
180
181 pub async fn delete_instance(&self, instance_id: &str) -> Result<SimpleResponse, HTTPError> {
191 let instance_endpoint = self.prepare_client_url("/v2/instances/").join(&instance_id);
192 let resp = self
193 .send_delete_request(instance_endpoint.unwrap().as_str())
194 .await;
195 match resp {
196 Ok(simplresp) => Ok(simplresp.json::<SimpleResponse>().await.unwrap()),
197 Err(err) => Err(err),
198 }
199 }
200}