mod api_error;
mod builder;
mod data;
mod instance_type;
mod vultr_error;
use api_error::VultrApiError;
use serde::Serialize;
use serde_json::json;
use std::collections::HashMap;
use uuid::Uuid;
pub use builder::create_instance_builder::CreateInstanceBuilder;
pub use builder::create_instance_builder::LinuxUserScheme;
pub use builder::update_dns_record::VultrUpdateDnsRecordBuilder;
pub use data::dns::{
VultrDomain, VultrDomainRecord, VultrDomainRecordRoot, VultrDomainRecordsRoot, VultrDomainRoot,
VultrDomainsRoot,
};
pub use data::firewall::{
VultrFirewallGroup, VultrFirewallGroupRule, VultrFirewallGroupRuleIpType,
VultrFirewallGroupRuleProtocol,
};
use data::firewall::{
VultrFirewallGroupRoot, VultrFirewallGroupRuleRoot, VultrFirewallGroupRulesRoot,
VultrFirewallGroupsRoot,
};
pub use data::instance::{
VultrAccount, VultrAccountRoot, VultrInstance, VultrInstanceRoot, VultrInstancesRoot, VultrOS,
VultrOSRoot, VultrPlan, VultrPlansRoot, VultrRegion, VultrRegionsRoot, VultrSSHKey,
VultrSSHKeyRoot, VultrSSHKeysRoot,
};
pub use instance_type::VultrInstanceType;
pub use vultr_error::VultrError;
#[derive(Clone)]
pub struct VultrApi {
token: String,
}
impl<'a> VultrApi {
pub fn new<S>(token: S) -> VultrApi
where
S: Into<String>,
{
VultrApi {
token: token.into(),
}
}
async fn get_async(&self, url: &str) -> Result<reqwest::Response, VultrError> {
let client = reqwest::Client::new();
let resp = client
.get(url)
.bearer_auth(&self.token)
.send()
.await
.map_err(|e| VultrError::Reqwest(e))?;
let status = resp.status();
if status.is_client_error() {
let result: VultrApiError = resp.json().await?;
Err(VultrError::VultrApi(result.error))
} else {
Ok(resp.error_for_status()?)
}
}
#[cfg(feature = "blocking")]
fn get(&self, url: &str) -> Result<reqwest::blocking::Response, VultrError> {
let client = reqwest::blocking::Client::new();
let resp = client.get(url).bearer_auth(&self.token).send()?;
let status = resp.status();
if status.is_client_error() {
let result: VultrApiError = resp.json()?;
Err(VultrError::VultrApi(result.error))
} else {
Ok(resp.error_for_status()?)
}
}
async fn post_async<T>(&self, url: &str, json: T) -> Result<reqwest::Response, VultrError>
where
T: Serialize + Sized,
{
let client = reqwest::Client::new();
let resp = client
.post(url)
.bearer_auth(&self.token)
.json(&json)
.send()
.await?;
let status = resp.status();
if status.is_client_error() {
let result: VultrApiError = resp.json().await?;
Err(VultrError::VultrApi(result.error))
} else {
Ok(resp.error_for_status()?)
}
}
#[cfg(feature = "blocking")]
fn post<T>(&self, url: &str, json: T) -> Result<reqwest::blocking::Response, VultrError>
where
T: Serialize + Sized,
{
let client = reqwest::blocking::Client::new();
let resp = client
.post(url)
.bearer_auth(&self.token)
.json(&json)
.send()?;
let status = resp.status();
if status.is_client_error() {
let result: VultrApiError = resp.json()?;
Err(VultrError::VultrApi(result.error))
} else {
Ok(resp.error_for_status()?)
}
}
async fn put_async<T>(&self, url: &str, json: T) -> Result<reqwest::Response, VultrError>
where
T: Serialize + Sized,
{
let client = reqwest::Client::new();
let resp = client
.put(url)
.bearer_auth(&self.token)
.json(&json)
.send()
.await?;
let status = resp.status();
if status.is_client_error() {
let result: VultrApiError = resp.json().await?;
Err(VultrError::VultrApi(result.error))
} else {
Ok(resp.error_for_status()?)
}
}
#[cfg(feature = "blocking")]
fn put<T>(&self, url: &str, json: T) -> Result<reqwest::blocking::Response, VultrError>
where
T: Serialize + Sized,
{
let client = reqwest::blocking::Client::new();
let resp = client
.put(url)
.bearer_auth(&self.token)
.json(&json)
.send()?;
let status = resp.status();
if status.is_client_error() {
let result: VultrApiError = resp.json()?;
Err(VultrError::VultrApi(result.error))
} else {
Ok(resp.error_for_status()?)
}
}
async fn patch_async<T>(&self, url: &str, json: T) -> Result<reqwest::Response, VultrError>
where
T: Serialize + Sized,
{
let client = reqwest::Client::new();
let resp = client
.patch(url)
.bearer_auth(&self.token)
.json(&json)
.send()
.await?;
let status = resp.status();
if status.is_client_error() {
let result: VultrApiError = resp.json().await?;
Err(VultrError::VultrApi(result.error))
} else {
Ok(resp.error_for_status()?)
}
}
#[cfg(feature = "blocking")]
fn patch<T>(&self, url: &str, json: T) -> Result<reqwest::blocking::Response, VultrError>
where
T: Serialize + Sized,
{
let client = reqwest::blocking::Client::new();
let resp = client
.patch(url)
.bearer_auth(&self.token)
.json(&json)
.send()?;
let status = resp.status();
if status.is_client_error() {
let result: VultrApiError = resp.json()?;
Err(VultrError::VultrApi(result.error))
} else {
Ok(resp.error_for_status()?)
}
}
async fn delete_async(&self, url: &str) -> Result<reqwest::Response, VultrError> {
let client = reqwest::Client::new();
let resp = client.delete(url).bearer_auth(&self.token).send().await?;
let status = resp.status();
if status.is_client_error() {
let result: VultrApiError = resp.json().await?;
Err(VultrError::VultrApi(result.error))
} else {
Ok(resp.error_for_status()?)
}
}
#[cfg(feature = "blocking")]
fn delete(&self, url: &str) -> Result<reqwest::blocking::Response, VultrError> {
let client = reqwest::blocking::Client::new();
let resp = client.delete(url).bearer_auth(&self.token).send()?;
let status = resp.status();
if status.is_client_error() {
let result: VultrApiError = resp.json()?;
Err(VultrError::VultrApi(result.error))
} else {
Ok(resp.error_for_status()?)
}
}
pub async fn get_account_info_async(&self) -> Result<VultrAccount, VultrError> {
Ok(self
.get_async("https://api.vultr.com/v2/account")
.await?
.json::<VultrAccountRoot>()
.await
.map_err(|e| VultrError::Reqwest(e))?
.account)
}
#[cfg(feature = "blocking")]
pub fn get_account_info(&self) -> Result<VultrAccount, VultrError> {
Ok(self
.get("https://api.vultr.com/v2/account")?
.json::<VultrAccountRoot>()?
.account)
}
pub async fn get_dns_domain_list_async(&self) -> Result<Vec<VultrDomain>, VultrError> {
Ok(self
.get_async("https://api.vultr.com/v2/domains")
.await?
.json::<VultrDomainsRoot>()
.await?
.domains)
}
#[cfg(feature = "blocking")]
pub fn get_dns_domain_list(&self) -> Result<Vec<VultrDomain>, VultrError> {
Ok(self
.get("https://api.vultr.com/v2/domains")?
.json::<VultrDomainsRoot>()?
.domains)
}
pub async fn get_dns_domain_async<S>(&self, domain: S) -> Result<VultrDomain, VultrError>
where
S: Into<String>,
{
let url = format!("https://api.vultr.com/v2/domains/{}", domain.into());
Ok(self
.get_async(&url)
.await?
.json::<VultrDomainRoot>()
.await?
.domain)
}
#[cfg(feature = "blocking")]
pub fn get_dns_domain<S>(&self, domain: S) -> Result<VultrDomain, VultrError>
where
S: Into<String>,
{
let url = format!("https://api.vultr.com/v2/domains/{}", domain.into());
Ok(self.get(&url)?.json::<VultrDomainRoot>()?.domain)
}
pub async fn delete_dns_domain_async<S>(&self, domain: S) -> Result<(), VultrError>
where
S: Into<String>,
{
let url = format!("https://api.vultr.com/v2/domains/{}", domain.into());
self.delete_async(&url).await?;
Ok(())
}
#[cfg(feature = "blocking")]
pub fn delete_dns_domain<S>(&self, domain: S) -> Result<(), VultrError>
where
S: Into<String>,
{
let url = format!("https://api.vultr.com/v2/domains/{}", domain.into());
self.delete(&url)?;
Ok(())
}
#[cfg(feature = "blocking")]
pub fn create_dns_domain<S>(
&self,
domain: S,
ip: Option<String>,
dns_sec: bool,
) -> Result<VultrDomain, VultrError>
where
S: Into<String>,
{
let mut map = HashMap::new();
map.insert("domain", domain.into());
if let Some(ip) = ip {
map.insert("ip", ip);
}
map.insert(
"dns_sec",
if dns_sec {
String::from("enabled")
} else {
String::from("disabled")
},
);
let url = "https://api.vultr.com/v2/domains";
Ok(self.post(&url, map)?.json::<VultrDomainRoot>()?.domain)
}
pub async fn create_dns_domain_async<S>(
&self,
domain: S,
ip: Option<String>,
dns_sec: bool,
) -> Result<VultrDomain, VultrError>
where
S: Into<String>,
{
let mut map = HashMap::new();
map.insert("domain", domain.into());
if let Some(ip) = ip {
map.insert("ip", ip);
}
map.insert(
"dns_sec",
if dns_sec {
String::from("enabled")
} else {
String::from("disabled")
},
);
let url = "https://api.vultr.com/v2/domains";
Ok(self
.post_async(&url, map)
.await?
.json::<VultrDomainRoot>()
.await?
.domain)
}
#[cfg(feature = "blocking")]
pub fn create_dns_domain_record<S1, S2, S3, S4>(
&self,
domain: S1,
record_type: S2,
name: S3,
ip: S4,
ttl: Option<u32>,
priority: Option<u32>,
) -> Result<VultrDomainRecord, VultrError>
where
S1: Into<String>,
S2: Into<String>,
S3: Into<String>,
S4: Into<String>,
{
let mut map: HashMap<&str, String> = HashMap::new();
map.insert("type", record_type.into());
map.insert("name", name.into());
map.insert("data", ip.into());
if let Some(ttl) = ttl {
map.insert("ttl", ttl.to_string());
}
if let Some(priority) = priority {
let priority = priority.to_string();
map.insert("priority", priority);
}
let url = format!("https://api.vultr.com/v2/domains/{}/records", domain.into());
Ok(self
.post(&url, map)?
.json::<VultrDomainRecordRoot>()?
.record)
}
pub async fn create_dns_domain_record_async<S1, S2, S3, S4>(
&self,
domain: S1,
record_type: S2,
name: S3,
ip: S4,
ttl: Option<u32>,
priority: Option<u32>,
) -> Result<VultrDomainRecord, VultrError>
where
S1: Into<String>,
S2: Into<String>,
S3: Into<String>,
S4: Into<String>,
{
let mut map: HashMap<&str, String> = HashMap::new();
map.insert("type", record_type.into());
map.insert("name", name.into());
map.insert("data", ip.into());
if let Some(ttl) = ttl {
map.insert("ttl", ttl.to_string());
}
if let Some(priority) = priority {
let priority = priority.to_string();
map.insert("priority", priority);
}
let url = format!("https://api.vultr.com/v2/domains/{}/records", domain.into());
Ok(self
.post_async(&url, map)
.await?
.json::<VultrDomainRecordRoot>()
.await?
.record)
}
pub fn update_dns_record<S1: Into<String>, S2: Into<String>>(
&self,
domainname: S1,
record_id: S2,
) -> VultrUpdateDnsRecordBuilder {
VultrUpdateDnsRecordBuilder::new(self, domainname, record_id)
}
#[cfg(feature = "blocking")]
pub fn get_dns_domain_records<S>(&self, domain: S) -> Result<Vec<VultrDomainRecord>, VultrError>
where
S: Into<String>,
{
let url = format!("https://api.vultr.com/v2/domains/{}/records", domain.into());
let resp: VultrDomainRecordsRoot = self.get(&url)?.json()?;
Ok(resp.records)
}
pub async fn get_dns_domain_records_async<S>(
&self,
domain: S,
) -> Result<Vec<VultrDomainRecord>, VultrError>
where
S: Into<String>,
{
let url = format!("https://api.vultr.com/v2/domains/{}/records", domain.into());
let resp: VultrDomainRecordsRoot = self.get_async(&url).await?.json().await?;
Ok(resp.records)
}
#[cfg(feature = "blocking")]
pub fn delete_dns_domain_record<S1, S2>(
&self,
domain: S1,
record_id: S2,
) -> Result<(), VultrError>
where
S1: Into<String>,
S2: Into<String>,
{
let url = format!(
"https://api.vultr.com/v2/domains/{}/records/{}",
domain.into(),
record_id.into(),
);
self.delete(&url)?;
Ok(())
}
pub async fn delete_dns_domain_record_async<S1, S2>(
&self,
domain: S1,
record_id: S2,
) -> Result<(), VultrError>
where
S1: Into<String>,
S2: Into<String>,
{
let url = format!(
"https://api.vultr.com/v2/domains/{}/records/{}",
domain.into(),
record_id.into(),
);
self.delete_async(&url).await?;
Ok(())
}
#[cfg(feature = "blocking")]
pub fn get_plans(&self) -> Result<Vec<VultrPlan>, VultrError> {
let url = format!("https://api.vultr.com/v2/plans");
Ok(self.get(&url)?.json::<VultrPlansRoot>()?.plans)
}
pub async fn get_plans_async(&self) -> Result<Vec<VultrPlan>, VultrError> {
let url = format!("https://api.vultr.com/v2/plans");
Ok(self
.get_async(&url)
.await?
.json::<VultrPlansRoot>()
.await?
.plans)
}
#[cfg(feature = "blocking")]
pub fn get_regions(&self) -> Result<Vec<VultrRegion>, VultrError> {
let url = format!("https://api.vultr.com/v2/regions");
Ok(self.get(&url)?.json::<VultrRegionsRoot>()?.regions)
}
pub async fn get_regions_async(&self) -> Result<Vec<VultrRegion>, VultrError> {
let url = format!("https://api.vultr.com/v2/regions");
Ok(self
.get_async(&url)
.await?
.json::<VultrRegionsRoot>()
.await?
.regions)
}
#[cfg(feature = "blocking")]
pub fn get_os_list(&self) -> Result<Vec<VultrOS>, VultrError> {
let url = format!("https://api.vultr.com/v2/os");
Ok(self.get(&url)?.json::<VultrOSRoot>()?.os)
}
pub async fn get_os_list_async(&self) -> Result<Vec<VultrOS>, VultrError> {
let url = format!("https://api.vultr.com/v2/os");
Ok(self.get_async(&url).await?.json::<VultrOSRoot>().await?.os)
}
#[cfg(feature = "blocking")]
pub fn get_sshkey_list(&self) -> Result<Vec<VultrSSHKey>, VultrError> {
let url = format!("https://api.vultr.com/v2/ssh-keys");
Ok(self.get(&url)?.json::<VultrSSHKeysRoot>()?.ssh_keys)
}
pub async fn get_sshkey_list_async(&self) -> Result<Vec<VultrSSHKey>, VultrError> {
let url = format!("https://api.vultr.com/v2/ssh-keys");
Ok(self
.get_async(&url)
.await?
.json::<VultrSSHKeysRoot>()
.await?
.ssh_keys)
}
#[cfg(feature = "blocking")]
pub fn get_sshkey<S>(&self, key_id: S) -> Result<VultrSSHKey, VultrError>
where
S: Into<String>,
{
let url = format!("https://api.vultr.com/v2/ssh-keys/{}", key_id.into());
Ok(self.get(&url)?.json::<VultrSSHKeyRoot>()?.ssh_key)
}
pub async fn get_sshkey_async<S>(&self, key_id: S) -> Result<VultrSSHKey, VultrError>
where
S: Into<String>,
{
let url = format!("https://api.vultr.com/v2/ssh-keys/{}", key_id.into());
Ok(self
.get_async(&url)
.await?
.json::<VultrSSHKeyRoot>()
.await?
.ssh_key)
}
#[cfg(feature = "blocking")]
pub fn create_sshkey<S>(&self, name: S, ssh_key: S) -> Result<VultrSSHKey, VultrError>
where
S: Into<String>,
{
let mut map: HashMap<&str, String> = HashMap::new();
map.insert("name", name.into());
map.insert("ssh_key", ssh_key.into());
let url = format!("https://api.vultr.com/v2/ssh-keys");
Ok(self.post(&url, map)?.json::<VultrSSHKeyRoot>()?.ssh_key)
}
pub async fn create_sshkey_async<S>(
&self,
name: S,
ssh_key: S,
) -> Result<VultrSSHKey, VultrError>
where
S: Into<String>,
{
let mut map: HashMap<&str, String> = HashMap::new();
map.insert("name", name.into());
map.insert("ssh_key", ssh_key.into());
let url = format!("https://api.vultr.com/v2/ssh-keys");
Ok(self
.post_async(&url, map)
.await?
.json::<VultrSSHKeyRoot>()
.await?
.ssh_key)
}
#[cfg(feature = "blocking")]
pub fn delete_sshkey<S>(&self, key_id: S) -> Result<(), VultrError>
where
S: Into<String>,
{
let url = format!("https://api.vultr.com/v2/ssh-keys/{}", key_id.into());
self.delete(&url)?;
Ok(())
}
pub async fn delete_sshkey_async<S>(&self, key_id: S) -> Result<(), VultrError>
where
S: Into<String>,
{
let url = format!("https://api.vultr.com/v2/ssh-keys/{}", key_id.into());
self.delete_async(&url).await?;
Ok(())
}
#[cfg(feature = "blocking")]
pub fn get_instance_list(&self) -> Result<Vec<VultrInstance>, VultrError> {
let url = format!("https://api.vultr.com/v2/instances");
let resp: VultrInstancesRoot = self.get(&url)?.json()?;
Ok(resp.instances)
}
pub async fn get_instance_list_async(&self) -> Result<Vec<VultrInstance>, VultrError> {
let url = format!("https://api.vultr.com/v2/instances");
let resp: VultrInstancesRoot = self.get_async(&url).await?.json().await?;
Ok(resp.instances)
}
#[cfg(feature = "blocking")]
pub fn get_instance<S>(&self, instance_id: S) -> Result<VultrInstance, VultrError>
where
S: Into<String>,
{
let url = format!("https://api.vultr.com/v2/instances/{}", instance_id.into());
Ok(self.get(&url)?.json::<VultrInstanceRoot>()?.instance)
}
pub async fn get_instance_async<S>(&self, instance_id: S) -> Result<VultrInstance, VultrError>
where
S: Into<String>,
{
let url = format!("https://api.vultr.com/v2/instances/{}", instance_id.into());
Ok(self
.get_async(&url)
.await?
.json::<VultrInstanceRoot>()
.await?
.instance)
}
pub fn create_instance<S1, S2>(
&self,
region_id: S1,
plan_id: S2,
instance_type: VultrInstanceType,
) -> CreateInstanceBuilder
where
S1: Into<String>,
S2: Into<String>,
{
CreateInstanceBuilder::new(self.clone(), region_id, plan_id, instance_type)
}
#[cfg(feature = "blocking")]
pub fn stop_instance<S, T>(&self, instance_ids: S) -> Result<(), VultrError>
where
S: IntoIterator<Item = T>,
T: AsRef<str>,
{
let vec: Vec<String> = instance_ids
.into_iter()
.map(|item| item.as_ref().to_string())
.collect();
self.post(
"https://api.vultr.com/v2/instances/halt",
json!({"instance_ids":vec}),
)?;
Ok(())
}
pub async fn stop_instance_async<S, T>(&self, instance_ids: S) -> Result<(), VultrError>
where
S: IntoIterator<Item = T>,
T: AsRef<str>,
{
let vec: Vec<String> = instance_ids
.into_iter()
.map(|item| item.as_ref().to_string())
.collect();
self.post_async(
"https://api.vultr.com/v2/instances/halt",
json!({"instance_ids":vec}),
)
.await?;
Ok(())
}
#[cfg(feature = "blocking")]
pub fn delete_instance<S>(&self, instance_id: S) -> Result<(), VultrError>
where
S: Into<String>,
{
let url = format!("https://api.vultr.com/v2/instances/{}", instance_id.into());
self.delete(&url)?;
Ok(())
}
pub async fn delete_instance_async<S>(&self, instance_id: S) -> Result<(), VultrError>
where
S: Into<String>,
{
let url = format!("https://api.vultr.com/v2/instances/{}", instance_id.into());
self.delete_async(&url).await?;
Ok(())
}
#[cfg(feature = "blocking")]
pub fn get_firewall_groups(&self) -> Result<Vec<VultrFirewallGroup>, VultrError> {
let mut result_list = vec![];
let mut cursor_str = format!("");
loop {
let url = format!(
"https://api.vultr.com/v2/firewalls?per_page=10{}",
cursor_str
);
let result = self.get(&url)?.json::<VultrFirewallGroupsRoot>()?;
result_list.extend(result.firewall_groups);
if result.meta.links.next.is_empty() {
break;
} else {
cursor_str = format!("&cursor={}", result.meta.links.next);
}
}
Ok(result_list)
}
pub async fn get_firewall_groups_async(&self) -> Result<Vec<VultrFirewallGroup>, VultrError> {
let mut result_list = vec![];
let mut cursor_str = format!("");
loop {
let url = format!(
"https://api.vultr.com/v2/firewalls?per_page=10{}",
cursor_str
);
let result = self
.get_async(&url)
.await?
.json::<VultrFirewallGroupsRoot>()
.await?;
result_list.extend(result.firewall_groups);
if result.meta.links.next.is_empty() {
break;
} else {
cursor_str = format!("&cursor={}", result.meta.links.next);
}
}
Ok(result_list)
}
#[cfg(feature = "blocking")]
pub fn get_firewall_group<TGroupId: Into<Uuid>>(
&self,
group_id: TGroupId,
) -> Result<VultrFirewallGroup, VultrError> {
let url = format!("https://api.vultr.com/v2/firewalls/{}", group_id.into());
let result = self.get(&url)?.json::<VultrFirewallGroupRoot>()?;
Ok(result.firewall_group)
}
pub async fn get_firewall_group_async<TGroupId: Into<Uuid>>(
&self,
group_id: TGroupId,
) -> Result<VultrFirewallGroup, VultrError> {
let url = format!("https://api.vultr.com/v2/firewalls/{}", group_id.into());
let result = self
.get_async(&url)
.await?
.json::<VultrFirewallGroupRoot>()
.await?;
Ok(result.firewall_group)
}
#[cfg(feature = "blocking")]
pub fn create_firewall_group<TDescription: Into<String>>(
&self,
description: TDescription,
) -> Result<VultrFirewallGroup, VultrError> {
let url = format!("https://api.vultr.com/v2/firewalls");
let mut map: HashMap<&str, String> = HashMap::new();
map.insert("description", description.into());
let result = self.post(&url, map)?.json::<VultrFirewallGroupRoot>()?;
Ok(result.firewall_group)
}
pub async fn create_firewall_group_async<TDescription: Into<String>>(
&self,
description: TDescription,
) -> Result<VultrFirewallGroup, VultrError> {
let url = format!("https://api.vultr.com/v2/firewalls");
let mut map: HashMap<&str, String> = HashMap::new();
map.insert("description", description.into());
let result = self
.post_async(&url, map)
.await?
.json::<VultrFirewallGroupRoot>()
.await?;
Ok(result.firewall_group)
}
#[cfg(feature = "blocking")]
pub fn update_firewall_group<TGroupId: Into<Uuid>, TDescription: Into<String>>(
&self,
group_id: TGroupId,
description: TDescription,
) -> Result<(), VultrError> {
let url = format!("https://api.vultr.com/v2/firewalls/{}", group_id.into());
let mut map: HashMap<&str, String> = HashMap::new();
map.insert("description", description.into());
let _result = self.put(&url, map)?;
Ok(())
}
pub async fn update_firewall_group_async<TGroupId: Into<Uuid>, TDescription: Into<String>>(
&self,
group_id: TGroupId,
description: TDescription,
) -> Result<(), VultrError> {
let url = format!("https://api.vultr.com/v2/firewalls/{}", group_id.into());
let mut map: HashMap<&str, String> = HashMap::new();
map.insert("description", description.into());
let _result = self.put_async(&url, map).await?;
Ok(())
}
#[cfg(feature = "blocking")]
pub fn delete_firewall_group<TGroupId: Into<Uuid>>(
&self,
group_id: TGroupId,
) -> Result<(), VultrError> {
let url = format!("https://api.vultr.com/v2/firewalls/{}", group_id.into());
let _result = self.delete(&url)?;
Ok(())
}
pub async fn delete_firewall_group_async<TGroupId: Into<Uuid>>(
&self,
group_id: TGroupId,
) -> Result<(), VultrError> {
let url = format!("https://api.vultr.com/v2/firewalls/{}", group_id.into());
let _result = self.delete_async(&url).await?;
Ok(())
}
#[cfg(feature = "blocking")]
pub fn get_firewall_group_rules<TGroupId: Into<String>>(
&self,
group_id: TGroupId,
) -> Result<Vec<VultrFirewallGroupRule>, VultrError> {
let mut result_list = vec![];
let mut cursor_str = format!("");
let group_id = group_id.into();
loop {
let url = format!(
"https://api.vultr.com/v2/firewalls/{}/rules?per_page=10{}",
group_id.clone(),
cursor_str,
);
let result = self.get(&url)?.json::<VultrFirewallGroupRulesRoot>()?;
result_list.extend(result.firewall_rules);
if result.meta.links.next.is_empty() {
break;
} else {
cursor_str = format!("&cursor={}", result.meta.links.next);
}
}
Ok(result_list)
}
pub async fn get_firewall_group_rules_async<TGroupId: Into<String>>(
&self,
group_id: TGroupId,
) -> Result<Vec<VultrFirewallGroupRule>, VultrError> {
let mut result_list = vec![];
let mut cursor_str = format!("");
let group_id = group_id.into();
loop {
let url = format!(
"https://api.vultr.com/v2/firewalls/{}/rules?per_page=10{}",
group_id.clone(),
cursor_str,
);
let result = self
.get_async(&url)
.await?
.json::<VultrFirewallGroupRulesRoot>()
.await?;
result_list.extend(result.firewall_rules);
if result.meta.links.next.is_empty() {
break;
} else {
cursor_str = format!("&cursor={}", result.meta.links.next);
}
}
Ok(result_list)
}
#[cfg(feature = "blocking")]
pub fn create_firewall_group_rule<
TGroupId: Into<String>,
TSubnet: Into<String>,
TSource: Into<String>,
TNotes: Into<String>,
>(
&self,
group_id: TGroupId,
ip_type: VultrFirewallGroupRuleIpType,
protocol: VultrFirewallGroupRuleProtocol,
subnet: TSubnet,
subnet_size: u8,
port: Option<u16>,
source: Option<TSource>,
notes: Option<TNotes>,
) -> Result<VultrFirewallGroupRule, VultrError> {
let group_id = group_id.into();
let url = format!(
"https://api.vultr.com/v2/firewalls/{}/rules",
group_id.clone(),
);
let mut map: HashMap<&str, String> = HashMap::new();
map.insert("ip_type", ip_type.to_string());
map.insert("protocol", protocol.into());
map.insert("subnet", subnet.into());
map.insert("subnet_size", subnet_size.to_string());
if let Some(port) = port {
map.insert("port", port.to_string());
}
if let Some(source) = source {
map.insert("source", source.into());
}
if let Some(notes) = notes {
map.insert("notes", notes.into());
}
let result = self.post(&url, map)?.json::<VultrFirewallGroupRuleRoot>()?;
Ok(result.firewall_rule)
}
pub async fn create_firewall_group_rule_async<
TGroupId: Into<String>,
TSubnet: Into<String>,
TSource: Into<String>,
TNotes: Into<String>,
>(
&self,
group_id: TGroupId,
ip_type: VultrFirewallGroupRuleIpType,
protocol: VultrFirewallGroupRuleProtocol,
subnet: TSubnet,
subnet_size: u8,
port: Option<u16>,
source: Option<TSource>,
notes: Option<TNotes>,
) -> Result<VultrFirewallGroupRule, VultrError> {
let group_id = group_id.into();
let url = format!(
"https://api.vultr.com/v2/firewalls/{}/rules",
group_id.clone(),
);
let mut map: HashMap<&str, String> = HashMap::new();
map.insert("ip_type", ip_type.to_string());
map.insert("protocol", protocol.to_string());
map.insert("subnet", subnet.into());
map.insert("subnet_size", subnet_size.to_string());
if let Some(port) = port {
map.insert("port", port.to_string());
}
if let Some(source) = source {
map.insert("source", source.into());
}
if let Some(notes) = notes {
map.insert("notes", notes.into());
}
let result = self
.post_async(&url, map)
.await?
.json::<VultrFirewallGroupRuleRoot>()
.await?;
Ok(result.firewall_rule)
}
}