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.

407 lines
13 KiB

use crate::{
responses::{
IPAddress,
VMListResponse,
BillingCreditResponse,
LNImageListResponse,
VolumeListResponse,
FloatingIpListResponse,
NetworkListResponse,
ZoneListResponse,
ZoneAddResponse,
ZoneRemoveResponse,
RecordListResponse,
DynListResponse,
DynAddResponse,
DynRemoveResponse,
SshKeyResponse,
PlanListResponse,
RegionListResponse,
EmailUsageResponse,
EmailDomainListResponse,
EmailUserListResponse,
EmailUserAddResponse,
EmailUserRemoveResponse,
EmailUserSetPasswordResponse,
MonitorCheckListResponse,
MonitorCheckTypesResponse,
MonitorContactListResponse,
VmStartResponse,
VmStopResponse,
VmRebootResponse,
VmIpListResponse,
},
types::{
LNError,
LunaNodeRequest,
ApiKeys,
},
};
use lunanode_macros::lunanode_request;
use parse_display_derive::Display;
use ureq::post;
use serde::{
Serialize,
Serializer,
Deserialize,
de::DeserializeOwned,
};
use serde_with::serde_as;
use hmac::Hmac;
use sha2::Sha512;
#[derive(Serialize, Deserialize, Debug, clap::Subcommand)]
pub enum SshKeySubArgs {
List(SshKeyRequest),
}
#[derive(Serialize, Deserialize, Debug, clap::Subcommand)]
pub enum DynSubArgs {
List(DynListRequest),
Remove(DynRemoveRequest),
Add(DynAddRequest),
}
#[derive(Serialize, Deserialize, Debug, clap::Subcommand)]
pub enum ZoneSubArgs {
Add(ZoneAddRequest),
List(ZoneListRequest),
Remove(ZoneRemoveRequest),
}
#[derive(Serialize, Deserialize, Debug, clap::Subcommand)]
pub enum EmailDomainSubArgs {
List(EmailDomainListRequest),
}
#[derive(Serialize, Deserialize, Debug, clap::Subcommand)]
pub enum EmailUserSubArgs {
List(EmailUserListRequest),
Add(EmailUserAddRequest),
Remove(EmailUserRemoveRequest),
SetPassword(EmailUserSetPasswordRequest),
}
#[derive(Serialize, Deserialize, Debug, clap::Subcommand)]
pub enum EmailSubArgs {
#[clap(subcommand)]
Domain(EmailDomainSubArgs),
Usage(EmailUsageRequest),
#[clap(subcommand)]
User(EmailUserSubArgs),
}
#[derive(Serialize, Deserialize, Debug, clap::Subcommand)]
#[serde(untagged)]
pub enum FloatingSubArgs {
/// List all images on my account.
List(FloatingIpListRequest),
}
#[derive(Serialize, Deserialize, Debug, clap::Subcommand)]
#[serde(untagged)]
pub enum ImageSubArgs {
/// List all images on my account.
List(ImageListRequest),
}
#[derive(Serialize, Deserialize, Debug, clap::Subcommand)]
#[serde(untagged)]
pub enum RecordSubArgs {
List(RecordListRequest),
}
#[derive(Serialize, Deserialize, Debug, clap::Subcommand)]
#[serde(untagged)]
pub enum VmIpSubArgs {
List(VmIpListRequest),
}
#[derive(Serialize, Deserialize, Debug, clap::Subcommand)]
#[serde(untagged)]
pub enum VmSubArgs {
/// List all VMs on my account.
List(VMListRequest),
/// Restart a VM, given an ID.
Reboot(VmRebootRequest),
/// Stop a VM, given an ID.
Stop(VmStopRequest),
/// Turn on a VM, given an ID.
Start(VmStartRequest),
/// IP subcommands
#[clap(subcommand)]
Ip(VmIpSubArgs),
}
#[derive(Serialize, Deserialize, Debug, clap::Subcommand)]
#[serde(untagged)]
pub enum VolumeSubArgs {
/// List all volumes I'm paying for.
List(VolumeListRequest),
}
#[derive(Serialize, Deserialize, Debug, clap::Subcommand)]
#[serde(untagged)]
pub enum BillingSubArgs {
/// How much money is left in my account.
Credit(BillingCreditRequest),
}
#[derive(Serialize, Deserialize, Debug, clap::Subcommand)]
#[serde(untagged)]
pub enum NetworkSubArgs {
/// Networks on your accounts
List(NetworkListRequest),
}
#[derive(Serialize, Deserialize, Debug, clap::Subcommand)]
pub enum PlanSubArgs {
List(PlanListRequest),
}
#[derive(Serialize, Deserialize, Debug, clap::Subcommand)]
pub enum RegionSubArgs {
List(RegionListRequest),
}
#[derive(Serialize, Deserialize, Debug, clap::Subcommand)]
pub enum MonitorCheckSubArgs {
List(MonitorCheckListRequest),
Types(MonitorCheckTypesRequest),
}
#[derive(Serialize, Deserialize, Debug, clap::Subcommand)]
pub enum MonitorContactSubArgs {
List(MonitorContactListRequest),
}
#[derive(Serialize, Deserialize, Debug, clap::Subcommand)]
pub enum MonitorSubArgs {
#[clap(subcommand)]
Check(MonitorCheckSubArgs),
#[clap(subcommand)]
Contact(MonitorContactSubArgs),
}
#[derive(Serialize, Deserialize, Debug, clap::Parser)]
#[serde(untagged)]
pub enum Args {
#[clap(subcommand)]
/// See `lunanode image help`
Image(ImageSubArgs),
#[clap(subcommand)]
/// See `lunanode ip help`
Floating(FloatingSubArgs),
#[clap(subcommand)]
/// See `lunanode network help`
Network(NetworkSubArgs),
#[clap(subcommand)]
/// See `lunanode vm help`
Vm(VmSubArgs),
#[clap(subcommand)]
/// See `lunanode billing help`
Billing(BillingSubArgs),
#[clap(subcommand)]
/// See `lunanode volume help`
Volume(VolumeSubArgs),
#[clap(subcommand)]
/// See `lunanode zone help`
Zone(ZoneSubArgs),
#[clap(subcommand)]
/// See `lunanode record help`
Record(RecordSubArgs),
#[clap(subcommand)]
/// See `lunanode dyn help`
Dyn(DynSubArgs),
#[clap(subcommand)]
/// See `lunanode sshkey help`
SshKey(SshKeySubArgs),
#[clap(subcommand)]
/// See `lunandoe plan help`
Plan(PlanSubArgs),
#[clap(subcommand)]
/// See `lunanode region help`
Region(RegionSubArgs),
#[clap(subcommand)]
/// See `lunanode email help`
Email(EmailSubArgs),
#[clap(subcommand)]
/// See `lunanode monitor help`
Monitor(MonitorSubArgs),
}
/// Specifies an internal function which can only be called on LunaNodeRequests whoes response type implements Debug. This could be set in the structure itself, and probably should be.
fn print_req<T: LunaNodeRequest>(req: &T) -> Result<(), LNError>
where
<T as LunaNodeRequest>::Response: std::fmt::Debug
{
let ans = req.make_request()?;
println!("{:#?}", ans);
Ok(())
}
impl Args {
pub fn make_request(&self) -> Result<(), LNError> {
match self {
Self::Monitor(MonitorSubArgs::Contact(MonitorContactSubArgs::List(contact_list))) => print_req(contact_list)?,
Self::Monitor(MonitorSubArgs::Check(MonitorCheckSubArgs::Types(monitor_check_types))) => print_req(monitor_check_types)?,
Self::Monitor(MonitorSubArgs::Check(MonitorCheckSubArgs::List(monitor_check_list))) => print_req(monitor_check_list)?,
Self::SshKey(SshKeySubArgs::List(ssk_list)) => print_req(ssk_list)?,
Self::Record(RecordSubArgs::List(rec_list)) => print_req(rec_list)?,
Self::Network(NetworkSubArgs::List(net_list)) => print_req(net_list)?,
Self::Floating(FloatingSubArgs::List(ip_list)) => print_req(ip_list)?,
Self::Vm(VmSubArgs::List(vm_list)) => print_req(vm_list)?,
Self::Vm(VmSubArgs::Start(vm_to_start)) => print_req(vm_to_start)?,
Self::Vm(VmSubArgs::Stop(vm_to_stop)) => print_req(vm_to_stop)?,
Self::Vm(VmSubArgs::Ip(VmIpSubArgs::List(vm_ips))) => print_req(vm_ips)?,
Self::Vm(VmSubArgs::Reboot(vm_to_reboot)) => print_req(vm_to_reboot)?,
Self::Volume(VolumeSubArgs::List(vol_list)) => print_req(vol_list)?,
Self::Image(ImageSubArgs::List(image_list)) => print_req(image_list)?,
Self::Billing(BillingSubArgs::Credit(billing_credit)) => print_req(billing_credit)?,
Self::Zone(ZoneSubArgs::List(zone_list)) => print_req(zone_list)?,
Self::Zone(ZoneSubArgs::Add(zone_add_req)) => print_req(zone_add_req)?,
Self::Zone(ZoneSubArgs::Remove(zone_rem_req)) => print_req(zone_rem_req)?,
Self::Dyn(DynSubArgs::Add(dyn_add_req)) => print_req(dyn_add_req)?,
Self::Dyn(DynSubArgs::List(dyn_list)) => print_req(dyn_list)?,
Self::Dyn(DynSubArgs::Remove(dyn_del)) => print_req(dyn_del)?,
Self::Plan(PlanSubArgs::List(plan_list)) => print_req(plan_list)?,
Self::Region(RegionSubArgs::List(reg_list)) => print_req(reg_list)?,
Self::Email(EmailSubArgs::Usage(email_usage)) => print_req(email_usage)?,
Self::Email(EmailSubArgs::Domain(EmailDomainSubArgs::List(email_domain_list))) => print_req(email_domain_list)?,
Self::Email(EmailSubArgs::User(EmailUserSubArgs::List(email_user_list))) => print_req(email_user_list)?,
Self::Email(EmailSubArgs::User(EmailUserSubArgs::Add(email_add_user_req))) => print_req(email_add_user_req)?,
Self::Email(EmailSubArgs::User(EmailUserSubArgs::Remove(email_del_req))) => print_req(email_del_req)?,
Self::Email(EmailSubArgs::User(EmailUserSubArgs::SetPassword(email_user_set_password))) => print_req(email_user_set_password)?,
}
Ok(())
}
}
/// ImageListRequest is used to create a new request for the /image/list endpoint.
#[lunanode_request(response="LNImageListResponse", endpoint="image/list/")]
pub struct ImageListRequest {}
/// BillingCreditRequest handles the /billing/credits/ endpoint. It will produce a BillingCreditResponse.
#[lunanode_request(response="BillingCreditResponse", endpoint="billing/credit/")]
pub struct BillingCreditRequest {}
/// VMListRequest is used to create a new request for the /vm/list endpoint.
#[lunanode_request(response="VMListResponse", endpoint="vm/list/")]
pub struct VMListRequest {}
/// VolumeListRequest is used to create a new request for the /volume/list endpoint.
#[lunanode_request(response="VolumeListResponse", endpoint="volume/list/")]
pub struct VolumeListRequest {}
/// IpListRequest is used to create a new request for the /ip/list endpoint.
#[lunanode_request(response="FloatingIpListResponse", endpoint="floating/list/")]
pub struct FloatingIpListRequest {}
/// NetworkListRequest is used to create a new request for the /network/list endpoint.
#[lunanode_request(response="NetworkListResponse", endpoint="network/list/")]
pub struct NetworkListRequest {}
/// ZoneListRequest is used to generate a request for the dns2/zone-list/ endpoint.
#[lunanode_request(response="ZoneListResponse", endpoint="dns2/zone-list/")]
pub struct ZoneListRequest {}
/// RecordListRequest is used to get information about a specific DNS zone (usually an entire domain, but could also be a subdomain).
#[lunanode_request(response="RecordListResponse", endpoint="dns2/record-list/")]
pub struct RecordListRequest {
zone_id: i32
}
/// DynListRequest is used to get information about the dynamic DNS records set for all lunanode zones.
#[lunanode_request(response="DynListResponse", endpoint="dns/dyn-list/")]
pub struct DynListRequest {}
#[lunanode_request(response="SshKeyResponse", endpoint="sshkey/list/")]
pub struct SshKeyRequest {}
#[lunanode_request(response="PlanListResponse", endpoint="plan/list/")]
pub struct PlanListRequest {}
#[lunanode_request(response="RegionListResponse", endpoint="region/list/")]
pub struct RegionListRequest {}
#[lunanode_request(response="EmailUsageResponse", endpoint="email/usage/")]
pub struct EmailUsageRequest {}
#[lunanode_request(response="EmailDomainListResponse", endpoint="email/domain-list/")]
pub struct EmailDomainListRequest {}
#[lunanode_request(response="MonitorCheckListResponse", endpoint="monitor/check-list/")]
pub struct MonitorCheckListRequest {}
#[lunanode_request(response="MonitorCheckTypesResponse", endpoint="monitor/check-types/")]
pub struct MonitorCheckTypesRequest {}
#[lunanode_request(response="MonitorContactListResponse", endpoint="monitor/contact-list/")]
pub struct MonitorContactListRequest {}
#[lunanode_request(response="EmailUserListResponse", endpoint="email/user-list/")]
pub struct EmailUserListRequest {
domain_id: i32,
}
#[lunanode_request(response="VmStartResponse", endpoint="vm/start/")]
pub struct VmStartRequest {
vm_id: String,
}
#[lunanode_request(response="VmStopResponse", endpoint="vm/stop/")]
pub struct VmStopRequest {
vm_id: String,
}
#[lunanode_request(response="VmRebootResponse", endpoint="vm/reboot/")]
pub struct VmRebootRequest {
vm_id: String,
}
#[lunanode_request(response="EmailUserAddResponse", endpoint="email/user-add/")]
pub struct EmailUserAddRequest {
domain_id: i32,
username: String,
password: String,
}
#[lunanode_request(response="EmailUserRemoveResponse", endpoint="email/user-remove/")]
pub struct EmailUserRemoveRequest {
domain_id: i32,
user_id: i32,
}
#[lunanode_request(response="EmailUserSetPasswordResponse", endpoint="email/user-set-password/")]
pub struct EmailUserSetPasswordRequest {
domain_id: i32,
user_id: i32,
password: String,
}
#[lunanode_request(response="VmIpListResponse", endpoint="vm/iplist/")]
pub struct VmIpListRequest {
vm_id: String,
}
#[lunanode_request(response="DynRemoveResponse", endpoint="dns/dyn-remove/")]
pub struct DynRemoveRequest {
dyn_id: i32,
}
#[lunanode_request(response="DynAddResponse", endpoint="dns/dyn-add/")]
pub struct DynAddRequest {
/// The data string for the record. This is usually a FQDN, followed by a period. If you wanted to set a record for `dev.example.org`, you would put `dev.example.com.` in this field.
name: String,
/// An ip address to associate with the FQDN. This type should be stricter: TODO.
ip: String,
}
#[lunanode_request(response="ZoneAddResponse", endpoint="dns2/zone-add/")]
pub struct ZoneAddRequest {
/// A new zone, a FQDN.
name: String,
/// The default time-to-live (TTL) for the records in this zone.
ttl: i32,
}
#[lunanode_request(response="ZoneRemoveResponse", endpoint="dns2/zone-remove/")]
pub struct ZoneRemoveRequest {
zone_id: i32,
}