civo_rs/
instance.rs

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    /// Creates a new instance configuration
124    ///
125    /// # Returns
126    ///
127    /// Returns a Result containing an `InstanceConfig` on success, or a `GenericError` on failure.
128    /// This method will fail if the call to get the default network or the disk image fails.
129    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    /// Creates a new instance
164    ///
165    /// # Arguments
166    ///
167    /// * `config`: an `InstanceConfig` containing the configuration for the new instance
168    ///
169    /// # Returns
170    ///
171    /// Returns a Result containing an `Instance` on success, or an `HTTPError` on failure.
172    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    /// Deletes an existing instance
182    ///
183    /// # Arguments
184    ///
185    /// * `instance_id`: a string slice containing the id of the instance to be deleted
186    ///
187    /// # Returns
188    ///
189    /// Returns a Result containing a `SimpleResponse` on success, or an `HTTPError` on failure.
190    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}