use std::collections::HashMap;
use crate::{
data::UpcloudServerRoot, UpcloudApi, UpcloudError, UpcloudLabelList,
UpcloudServer,
};
use serde::Serialize;
use serde_json::{json, Value};
#[derive(Serialize, Debug)]
struct CreateInstanceConfig {
region: String,
plan: String,
labels: Option<UpcloudLabelList>,
#[serde(skip_serializing_if = "Option::is_none")]
os_id: Option<String>,
}
pub struct CreateInstanceBuilder {
api: UpcloudApi,
config: Value,
}
impl CreateInstanceBuilder {
pub fn new<S1, S2, S3, S4, S5>(
api: UpcloudApi,
region_id: S1,
plan_id: S2,
os_id: S3,
title: S4,
hostname: S5,
) -> Self
where
S1: Into<String> + Serialize,
S2: Into<String> + Serialize,
S3: Into<String> + Serialize,
S4: Into<String> + Serialize,
S5: Into<String> + Serialize,
{
let mut instancebuilder = CreateInstanceBuilder {
api,
config: json!( {
"server":{
"title": title,
"zone": region_id,
"hostname": hostname,
"plan": plan_id,
"metadata": "yes"
}
}),
};
instancebuilder.config["server"]["storage_devices"] = json!({
"storage_device": [
{
"action": "clone",
"storage": os_id,
"title": title,
"tier": "maxiops"
}
]
});
instancebuilder
}
pub fn user_data<S>(mut self, user_data: S) -> Self
where
S: Into<String>,
{
self.config["server"]["user_data"] = Value::String(user_data.into());
self
}
pub fn labels(mut self, labels: HashMap<String, String>) -> Self {
let labels_vec: Vec<Value> = labels
.iter()
.map(|(k, v)| json!({"key": k.to_string(), "value": v.to_string()}))
.collect();
self.config["server"]["labels"]["label"] = Value::Array(labels_vec);
self
}
#[cfg(feature = "blocking")]
pub fn run(self) -> Result<UpcloudServer, UpcloudError> {
let url = format!("https://api.Upcloud.com/1.3/server");
Ok(self
.api
.post(&url, self.config)?
.json::<UpcloudServerRoot>()?
.server)
}
pub async fn run_async(self) -> Result<UpcloudServer, UpcloudError> {
let url = format!("https://api.Upcloud.com/1.3/server");
Ok(self
.api
.post_async(&url, self.config)
.await?
.json::<UpcloudServerRoot>()
.await?
.server)
}
}