use std::sync::Arc;
use serde::{Deserialize, Serialize};
use serde_json as json;
use super::account::{Account, AccountStatus};
use crate::{
client::Client,
keypair::KeypairResource,
lite::BillingResource,
plan::{Billing, PlanResource},
};
pub struct RestoreVirtualMachineOptions {
pub plan: PlanResource,
pub keypair: KeypairResource,
pub billing: Billing,
pub use_credit_card: bool,
pub promocode: Option<String>,
}
pub struct SnapshotOpts {
pub billing: Billing,
pub use_credit_card: bool,
pub promocode: Option<String>,
}
pub struct Snapshot {
client: Arc<Client>,
}
impl Snapshot {
pub fn new(client: Arc<Client>) -> Self {
Self { client }
}
pub async fn list(&self) -> Result<Vec<SnapshotResource>, crate::Error> {
let mut snapshots: Vec<SnapshotResource> = Vec::new();
let account = Account::new(Arc::clone(&self.client));
let accounts = account.list_snapshot().await?;
for account in accounts {
if account.status == AccountStatus::Terminated {
continue;
}
let snapshot = SnapshotResource {
id: account.id,
name: account.extra_details.name,
};
snapshots.push(snapshot);
}
Ok(snapshots)
}
pub async fn create(
&self,
vm_id: u32,
name: String,
description: Option<String>,
opts: &SnapshotOpts,
) -> Result<BillingResource, crate::Error> {
let use_cc = match opts.use_credit_card {
true => "yes",
false => "no",
};
let body = json::json!({
"name": &name,
"description": &description,
"cycle": opts.billing.cycle,
"pay_invoice_with_cc": use_cc,
"promocode": opts.promocode.as_deref(),
});
let response = self
.client
.post(&format!("/accounts/{vm_id}/snapshot"), body)
.await?;
let response: BillingResource = json::from_value(response)?;
Ok(response)
}
pub async fn get(&self, id: u32) -> Result<SnapshotResource, crate::Error> {
let account = Account::new(Arc::clone(&self.client));
let account = account.get_snapshot(id).await?;
let snapshot = SnapshotResource {
id: account.id,
name: account.extra_details.name,
};
Ok(snapshot)
}
pub async fn delete(&self, id: u32) -> Result<(), crate::Error> {
self.client.delete(&format!("/snapshots/{}", id)).await?;
Ok(())
}
pub async fn restore(&self, id: u32) -> Result<(), crate::Error> {
self.client
.put(&format!("/snapshots/accounts/{id}/restore"))
.await?;
Ok(())
}
pub async fn restore_with(
&self,
snapshot_id: u32,
name: String,
description: Option<String>,
username: String,
password: String,
opts: &RestoreVirtualMachineOptions,
) -> Result<BillingResource, crate::Error> {
let use_cc = match opts.use_credit_card {
true => "yes",
false => "no",
};
let body = json::json!({
"ssh_and_console_user": &username,
"console_password": &password,
"vm_name": &name,
"description": &description,
"product_id": opts.plan.id,
"keypair_id": opts.keypair.id,
"cycle": opts.billing.cycle,
"pay_invoice_with_cc": use_cc,
"promocode": opts.promocode,
});
let response = self
.client
.post(&format!("/snapshots/accounts/{snapshot_id}/create"), body)
.await?;
let response: BillingResource = json::from_value(response)?;
Ok(response)
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct SnapshotResource {
pub id: u32,
pub name: String,
}