Skip to content

Commit

Permalink
Add create/delete/list for Load Balancers (#139)
Browse files Browse the repository at this point in the history
Co-authored-by: Nuno Diegues <[email protected]>
  • Loading branch information
nmldiegues and nmldiegues authored Apr 19, 2021
1 parent e7a886e commit dbd4f26
Show file tree
Hide file tree
Showing 5 changed files with 218 additions and 1 deletion.
1 change: 1 addition & 0 deletions cloudflare/src/endpoints/dns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ pub enum DnsContent {
NS { content: String },
MX { content: String, priority: u16 },
TXT { content: String },
SRV { content: String },
}

#[derive(Deserialize, Debug)]
Expand Down
63 changes: 63 additions & 0 deletions cloudflare/src/endpoints/load_balancing/create_lb.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use crate::endpoints::load_balancing::{LbPoolId, SteeringPolicy, SessionAffinityAttributes, LbPoolMapping, SessionAffinity, LoadBalancer};
use crate::framework::endpoint::{Endpoint, Method};

/// Create Load Balancer
/// https://api.cloudflare.com/#load-balancers-create-load-balancer
#[derive(Debug)]
pub struct CreateLoadBalancer<'a> {
/// The Zone to which this Load Balancer shall belong.
pub zone_identifier: &'a str,
/// Optional parameters for the API call
pub params: Params<'a>,
}

/// Mandatory parameters for creating a Load Balancer.
#[serde_with::skip_serializing_none]
#[derive(Serialize, Clone, Debug)]
pub struct Params<'a> {
/// A short name (tag) for the load balancer.
/// Only alphanumeric characters, hyphens and underscores are allowed.
/// E.g. "lb-user-facing"
pub name: &'a str,
/// The list of LB Pools (by their IDs) ordered by their failover priority.
pub default_pools: &'a [LbPoolId],
/// The LB Pool ID to use when all other pools are detected as unhealthy.
pub fallback_pool: &'a LbPoolId,
#[serde(flatten)]
pub optional_params: Option<OptionalParams<'a>>,
}

/// Optional parameters for creating a Load Balancer.
#[serde_with::skip_serializing_none]
#[derive(Serialize, Clone, Debug, Default)]
pub struct OptionalParams<'a> {
pub description: Option<&'a str>,
/// Time to live (TTL) of the DNS entry for the IP address returned by this load balancer. This
/// only applies to gray-clouded (unproxied) load balancers.
pub ttl: Option<u32>,
/// A mapping of Cloudflare PoP identifiers to a list of pool IDs (ordered by their failover
/// priority) for the PoP (datacenter). Any PoPs not explicitly defined will fall back to using
/// default_pools.
pub pop_pools: Option<LbPoolMapping>,
/// A mapping of region/country codes to a list of pool IDs (ordered by their failover priority)
/// for the given region. Any regions not explicitly defined will fall back to using
/// default_pools.
pub region_pools: Option<LbPoolMapping>,
pub proxied: Option<bool>,
pub steering_policy: Option<SteeringPolicy>,
pub session_affinity: Option<SessionAffinity>,
pub session_affinity_attributes: Option<SessionAffinityAttributes>,
pub session_affinity_ttl: Option<u32>,
}

impl<'a> Endpoint<LoadBalancer, (), Params<'a>> for CreateLoadBalancer<'a> {
fn method(&self) -> Method {
Method::Post
}
fn path(&self) -> String {
format!("zones/{}/load_balancers", self.zone_identifier)
}
fn body(&self) -> Option<Params<'a>> {
Some(self.params.clone())
}
}
30 changes: 30 additions & 0 deletions cloudflare/src/endpoints/load_balancing/delete_lb.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use crate::framework::endpoint::{Endpoint, Method};
use crate::framework::response::ApiResult;

/// Delete Load Balancer
/// https://api.cloudflare.com/#load-balancers-delete-load-balancer
#[derive(Debug)]
pub struct DeleteLoadBalancer<'a> {
/// The Zone to which this Load Balancer belongs.
pub zone_identifier: &'a str,
/// Which load balancer to delete.
pub identifier: &'a str,
}

impl<'a> Endpoint<Response, (), ()> for DeleteLoadBalancer<'a> {
fn method(&self) -> Method {
Method::Delete
}
fn path(&self) -> String {
format!(
"zones/{}/load_balancers/{}",
self.zone_identifier, self.identifier
)
}
}

#[derive(Deserialize, Clone, Debug)]
pub struct Response {
id: String,
}
impl ApiResult for Response {}
22 changes: 22 additions & 0 deletions cloudflare/src/endpoints/load_balancing/list_lb.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use crate::endpoints::load_balancing::LoadBalancer;
use crate::framework::endpoint::{Endpoint, Method};
use crate::framework::response::ApiResult;

/// List Load Balancers
/// https://api.cloudflare.com/#load-balancers-list-load-balancers
#[derive(Debug)]
pub struct ListLoadBalancers<'a> {
/// The Zone to list Load Balancers from.
pub zone_identifier: &'a str,
}

impl<'a> Endpoint<Vec<LoadBalancer>, ()> for ListLoadBalancers<'a> {
fn method(&self) -> Method {
Method::Get
}
fn path(&self) -> String {
format!("zones/{}/load_balancers", self.zone_identifier)
}
}

impl ApiResult for Vec<LoadBalancer> {}
103 changes: 102 additions & 1 deletion cloudflare/src/endpoints/load_balancing/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,115 @@
pub mod create_lb;
pub mod create_pool;
pub mod delete_lb;
pub mod delete_pool;
pub mod list_lb;
pub mod pool_details;

use crate::framework::response::ApiResult;
use chrono::offset::Utc;
use chrono::DateTime;
use std::collections::HashSet;
use std::collections::{HashSet, HashMap};
use std::hash::{Hash, Hasher};
use std::net::IpAddr;

#[derive(Eq, PartialEq, Deserialize, Serialize, Clone, Debug)]
pub struct LoadBalancer {
pub id: String,
pub created_on: DateTime<Utc>,
pub modified_on: DateTime<Utc>,
pub description: String,
/// The DNS hostname to associate with your Load Balancer. If this hostname already exists as a
/// DNS record in Cloudflare's DNS, the Load Balancer will take precedence and the DNS record
/// will not be used.
pub name: String,
pub enabled: bool,
/// Time to live (TTL) of the DNS entry for the IP address returned by this load balancer. This
/// only applies to gray-clouded (unproxied) load balancers.
#[serde(default = "LoadBalancer::default_ttl")]
pub ttl: u32,
/// The pool ID to use when all other pools are detected as unhealthy.
pub fallback_pool: LbPoolId,
/// A list of pool IDs ordered by their failover priority. Pools defined here are used by
/// default, or when region_pools are not configured for a given region.
pub default_pools: Vec<LbPoolId>,
/// A mapping of region/country codes to a list of pool IDs (ordered by their failover priority)
/// for the given region. Any regions not explicitly defined will fall back to using
/// default_pools.
pub region_pools: LbPoolMapping,
/// A mapping of Cloudflare PoP identifiers to a list of pool IDs (ordered by their failover
/// priority) for the PoP (datacenter). Any PoPs not explicitly defined will fall back to using
/// default_pools.
pub pop_pools: LbPoolMapping,
pub proxied: bool,
pub steering_policy: SteeringPolicy,
pub session_affinity: SessionAffinity,
pub session_affinity_attributes: SessionAffinityAttributes,
#[serde(default = "LoadBalancer::default_session_affinity_ttl")]
pub session_affinity_ttl: u32,
}

impl LoadBalancer {
fn default_ttl() -> u32 {
30
}
fn default_session_affinity_ttl() -> u32 {
5000
}
}

type LbPoolId = String;
type LbPoolMapping = HashMap<String, Vec<LbPoolId>>;

#[derive(Eq, PartialEq, Deserialize, Serialize, Clone, Debug)]
#[serde(rename_all = "lowercase")]
pub enum SteeringPolicy {
/// Empty policy maps to `Geo` if `region_pools` or `pop_pools` are used, or otherwise `Off`.
#[serde(rename = "")]
Nil,
Off,
Geo,
Random,
DynamicLatency,
}

#[derive(Eq, PartialEq, Deserialize, Serialize, Clone, Debug)]
#[serde(rename_all = "lowercase")]
pub enum SessionAffinity {
/// Empty has the same behaviour as `None`.
#[serde(rename = "")]
Nil,
None,
Cookie,
IpCookie
}

#[derive(Eq, PartialEq, Deserialize, Serialize, Clone, Debug)]
pub struct SessionAffinityAttributes {
pub samesite: SameSite,
pub secure: Secure,
pub drain_duration: u32,
}

#[derive(Eq, PartialEq, Deserialize, Serialize, Clone, Debug)]
pub enum SameSite {
/// `Auto` maps to `Lax` if Always Use HTTPS is set, or `None` otherwise.
Auto,
Lax,
None,
Strict,
}

#[derive(Eq, PartialEq, Deserialize, Serialize, Clone, Debug)]
pub enum Secure {
/// `Auto` maps to `Always` if Always Use HTTPS is set, or `Never` otherwise.
Auto,
Always,
Never
}

impl ApiResult for LoadBalancer {}


/// A pool is a set of origins that requests could be routed to (e.g. each of your data centers or
/// regions have its own pool).
/// Requests will be routed to particular pools according to your steering policy, and then balanced
Expand Down

0 comments on commit dbd4f26

Please sign in to comment.