You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
298 lines
9.6 KiB
298 lines
9.6 KiB
2 years ago
|
use ureq;
|
||
|
use crate::success;
|
||
|
use crate::external;
|
||
|
use crate::types::{
|
||
|
LunaNodeResponse,
|
||
|
LunaNodeRequest,
|
||
|
Requestable,
|
||
|
};
|
||
|
|
||
|
use serde_json;
|
||
|
use serde::{Serialize, Deserialize};
|
||
|
use serde_with::{
|
||
|
DisplayFromStr,
|
||
|
serde_as,
|
||
|
};
|
||
|
use uuid;
|
||
|
|
||
|
#[serde_as]
|
||
|
#[derive(Serialize, Deserialize, PartialEq, Debug)]
|
||
|
/// Defines a VM (used for requests using the VM section)
|
||
|
pub struct VirtualMachine {
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
/// the UUID of the VM
|
||
|
vm_id: uuid::Uuid, // should be UUIDv4
|
||
|
/// the name of the VM set by the user
|
||
|
name: String, // the name set by the user
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
/// The plan ID, cross-reference with /plan/list/
|
||
|
plan_id: i32, // should be more strict
|
||
|
/// The hostname set by the user
|
||
|
hostname: String, // the hostname set by the user
|
||
|
#[serde(rename="primaryip")]
|
||
|
/// The primary (public) IP address of the VM.
|
||
|
primary_ip: std::net::Ipv4Addr,
|
||
|
#[serde(rename="privateip")]
|
||
|
/// The private IP address of the VM.
|
||
|
private_ip: std::net::Ipv4Addr,
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
/// RAM of the VM in GB
|
||
|
ram: i32, // in GB, may need to be a float
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
/// The number of virtual CPU cores
|
||
|
vcpu: i32, // CPU cores
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
/// The storage amount of the VM in GB
|
||
|
storage: i32, // in GB
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
/// bandwidth in GB/month
|
||
|
bandwidth: i32, // in GB/month
|
||
|
/// The region where the VM is located
|
||
|
region: LNRegion, // could be more strict
|
||
|
/// The status, which should be more strict than a String.
|
||
|
os_status: String, // should be nmore strict
|
||
|
}
|
||
|
|
||
|
#[derive(Serialize, Deserialize, Debug)]
|
||
|
pub struct VMListResponse {
|
||
|
vms: Vec<VirtualMachine>,
|
||
|
#[serde(with="success")]
|
||
|
success: bool, // should be more strict "yes" or "no" as optiobs
|
||
|
}
|
||
|
impl ToString for VMListResponse {
|
||
|
fn to_string(&self) -> String {
|
||
|
"N/A".to_string()
|
||
|
}
|
||
|
}
|
||
|
impl LunaNodeResponse for VMListResponse {}
|
||
|
|
||
|
#[serde_as]
|
||
|
#[derive(Serialize, Deserialize, Debug)]
|
||
|
pub struct VMInfoExtra {
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
/// bandwidth allowed over a month in GB
|
||
|
bandwidth: i32,
|
||
|
/// the hostname set by the user
|
||
|
hostname: String, // sufficiently vague
|
||
|
/// the name set by the user
|
||
|
name: String, // sufficiently vague
|
||
|
/// the status of the operating system; possible values: "active", ... TODO
|
||
|
os_status: String, // should be stricter
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
/// id of the plan being used on the VM
|
||
|
plan_id: i32,
|
||
|
#[serde(rename="primaryip")]
|
||
|
/// primary (floating) IP
|
||
|
primary_ip: std::net::Ipv4Addr,
|
||
|
#[serde(rename="privateip")]
|
||
|
/// the private (non-floating) IP to connect between nodes
|
||
|
private_ip: std::net::Ipv4Addr,
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
/// RAM meassured in MB
|
||
|
ram: i32,
|
||
|
/// the datacentre location the VM is running in
|
||
|
region: LNRegion,
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
/// the storage size of the VM in GB
|
||
|
storage: i32,
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
/// number of virtual CPU cores allocated to the VM
|
||
|
vcpu: i32,
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
/// UUIDv4 of the VM
|
||
|
vm_id: uuid::Uuid,
|
||
|
}
|
||
|
#[derive(Serialize, Deserialize, Debug)]
|
||
|
#[serde(untagged)]
|
||
|
/// A generic IP address type, with two variants: V4, and V6. This is used for generic types returned from the API. For example, a list of IP addresses without the IP type specified.
|
||
|
pub enum IPAddress {
|
||
|
V4(std::net::Ipv4Addr),
|
||
|
V6(std::net::Ipv6Addr),
|
||
|
}
|
||
|
|
||
|
#[derive(Serialize, Deserialize, Debug)]
|
||
|
pub enum IPAddressType {
|
||
|
#[serde(rename="4")]
|
||
|
V4,
|
||
|
#[serde(rename="6")]
|
||
|
V6,
|
||
|
}
|
||
|
|
||
|
#[derive(Serialize, Deserialize, Debug)]
|
||
|
pub struct VMAddress {
|
||
|
addr: IPAddress,
|
||
|
#[serde(with="external")]
|
||
|
external: bool,
|
||
|
version: IPAddressType,
|
||
|
#[serde(rename="reverse")]
|
||
|
/// The reverse DNS assigned to the VM. This is optional.
|
||
|
rdns: Option<String>,
|
||
|
}
|
||
|
|
||
|
#[serde_as]
|
||
|
#[derive(Serialize, Deserialize, Debug)]
|
||
|
pub struct VMInfo {
|
||
|
#[serde(rename="additionalip")]
|
||
|
additional_ip: Vec<VMAddress>,
|
||
|
#[serde(rename="additionalprivateip")]
|
||
|
additional_private_ip: Vec<VMAddress>,
|
||
|
addresses: Vec<VMAddress>,
|
||
|
/// a possibly empty string containing an error message
|
||
|
error_detail: Option<String>,
|
||
|
/// some unkown string that doesn't seem to be a UUID... maybe the checksum?
|
||
|
host_id: String,
|
||
|
/// the name of the VM set at creation by the user
|
||
|
hostname: String,
|
||
|
/// the name of the image being used by the VM
|
||
|
image: String,
|
||
|
/// the primary, external IP of the VM
|
||
|
ip: std::net::Ipv4Addr,
|
||
|
/// a list of IPv6 addresses assigned to the VM
|
||
|
ipv6: Vec<std::net::Ipv6Addr>,
|
||
|
/// Login details from the VM; this could potentially be a bit more strict to support the storing of username and password separately.
|
||
|
/// Also, it's optional. The server may not even report this value at all, not only give a blank one. Fair enough. Seems more secure.
|
||
|
login_details: Option<String>,
|
||
|
/// the operating system (orignal image used to load the machine)
|
||
|
os: String, // sufficiently vague
|
||
|
#[serde(rename="privateip")]
|
||
|
/// the primary private IP assigned to the machine
|
||
|
private_ip: std::net::Ipv4Addr,
|
||
|
/// security groups by id that the VM belongs to; should be a vec of i32, but it might take some custom implementations
|
||
|
security_group_ids: Vec<String>,
|
||
|
/// security groups by name that the VM belongs to
|
||
|
security_groups: Vec<String>,
|
||
|
#[serde(rename="securitygroups")]
|
||
|
/// why is there a second one of these with a different name. This is stupid.
|
||
|
security_groups2: Vec<String>,
|
||
|
/// an HTML status of the machine
|
||
|
status: String,
|
||
|
/// the color of the status; this could be stricter
|
||
|
status_color: String, // could be more strict
|
||
|
/// the non-HTML status, this could potentially be more strict
|
||
|
status_nohtml: String,
|
||
|
/// A raw status-code string; this could for sure be more strict.
|
||
|
status_raw: String,
|
||
|
/// A possibly empty string, idk what task_state is tho
|
||
|
task_state: String, // a possibly empty string
|
||
|
/// A possibly empty string of attached volumes.
|
||
|
volumes: String,
|
||
|
}
|
||
|
|
||
|
#[derive(Serialize, Deserialize, Debug)]
|
||
|
pub struct VMInfoResponse {
|
||
|
extra: VMInfoExtra,
|
||
|
info: VMInfo,
|
||
|
#[serde(with="success")]
|
||
|
success: bool,
|
||
|
}
|
||
|
|
||
|
#[derive(Serialize, Deserialize, Debug)]
|
||
|
pub enum LNPlanCategory {
|
||
|
#[serde(rename="Compute-Optimized")]
|
||
|
ComputeOptimized,
|
||
|
#[serde(rename="General Purpose")]
|
||
|
GeneralPurpose,
|
||
|
#[serde(rename="Memory-Optimized")]
|
||
|
MemoryOptimized,
|
||
|
#[serde(rename="SSD-Cached High-Memory")]
|
||
|
SSDCacheHighMemory,
|
||
|
#[serde(rename="SSD-Cached Standard")]
|
||
|
SSDCacheStandard,
|
||
|
}
|
||
|
|
||
|
#[derive(Serialize, Deserialize, Debug, Hash, Eq, PartialEq)]
|
||
|
#[serde(rename_all = "lowercase")]
|
||
|
pub enum LNRegion {
|
||
|
Montreal,
|
||
|
Roubaix,
|
||
|
Toronto
|
||
|
}
|
||
|
|
||
|
#[serde_as]
|
||
|
#[derive(Serialize, Deserialize, Debug)]
|
||
|
pub struct LNPlan {
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
all_regions: i32, // may need to be more strict?
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
bandwidth: i32, // in Mbps
|
||
|
category: LNPlanCategory,
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
cpu_points: f32, // no idea what this meas
|
||
|
name: String, // plan name, this could potentially be strictly typed as the types of plans don't often change "s.half", "s.1", "m.1", "m.2", etc.
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
plan_id: i32, // can be strictly typed, if needed
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
price: f32, // up to 7 decmial points (f32), and this is the number of US dollars per hour
|
||
|
price_monthly_nice: String, // instead of calculating it on your own, this provides a nice reading of the price for clients
|
||
|
price_nice: String, // same as above, but for the hour
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
ram: i32, // in MB
|
||
|
regions: Vec<LNRegion>, // list of regions by name
|
||
|
regions_nice: String, // list of regions concatonated with commans
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
storage: i32, // per GB
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
vcpu: i32, // number of vCPU cores
|
||
|
}
|
||
|
|
||
|
#[derive(Serialize, Deserialize, Debug)]
|
||
|
pub struct PlanListResponse {
|
||
|
plans: Vec<LNPlan>,
|
||
|
#[serde(with="success")]
|
||
|
success: bool, // should be more strict: "yes" or "no" as options
|
||
|
}
|
||
|
|
||
|
#[serde_as]
|
||
|
#[derive(Serialize, Deserialize, Debug)]
|
||
|
pub struct LNImage {
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
image_id: i32, // id of the image
|
||
|
name: String, // set by the user or LunaNode
|
||
|
region: LNRegion,
|
||
|
status: String, // should be stricter, at least "active", "inactive"(?)
|
||
|
}
|
||
|
|
||
|
#[derive(Serialize, Deserialize, Debug)]
|
||
|
pub struct LNImageDetails {
|
||
|
cache_mode: String, // should be stricter, at least "writeback",
|
||
|
checksum: String, // should be stricter, to check of checksum type
|
||
|
disk_format: String, // should be stricter, at least "iso"
|
||
|
hw_disk_bus: String, // should be stricter, at least "ide",
|
||
|
hw_video_model: String, // could, in theory, be stricter, at least: "cirrus",
|
||
|
hw_vif_model: String, // appropriately vague
|
||
|
#[serde(with="success")]
|
||
|
is_read_only: bool, // "yes"/"no"
|
||
|
libvrt_cpu_mode: String, // should be stricter, at least: "host-model",
|
||
|
metadata: Vec<()>, // vec of what?
|
||
|
name: String, // sufficiently vague
|
||
|
region: LNRegion, // sufficiently typed
|
||
|
size: i32, // in MB, maybe?
|
||
|
status: String, // should be stricter, at least: "active",
|
||
|
time_created: String, // should be a datetime
|
||
|
}
|
||
|
#[derive(Serialize, Deserialize, Debug)]
|
||
|
pub struct LNImageDetailResponse {
|
||
|
#[serde(with="success")]
|
||
|
success: bool,
|
||
|
details: LNImageDetails,
|
||
|
}
|
||
|
|
||
|
#[derive(Serialize, Deserialize, Debug)]
|
||
|
pub struct LNImageListResponse {
|
||
|
images: Vec<LNImage>,
|
||
|
#[serde(with="success")]
|
||
|
success: bool,
|
||
|
}
|
||
|
impl LunaNodeResponse for LNImageListResponse {}
|
||
|
|
||
|
#[serde_as]
|
||
|
#[derive(Serialize, Deserialize, Debug)]
|
||
|
pub struct BillingCreditResponse {
|
||
|
/// Money left in the account in USD
|
||
|
#[serde_as(as="DisplayFromStr")]
|
||
|
credit: f32,
|
||
|
#[serde(with="success")]
|
||
|
success: bool, // this should be stricter
|
||
|
}
|
||
|
impl LunaNodeResponse for BillingCreditResponse {}
|