cloudflare/endpoints/load_balancing/mod.rs
1pub mod create_lb;
2pub mod create_pool;
3pub mod delete_lb;
4pub mod delete_pool;
5pub mod list_lb;
6pub mod pool_details;
7
8use crate::framework::ApiResultTraits;
9use chrono::offset::Utc;
10use chrono::DateTime;
11use std::collections::{HashMap, HashSet};
12use std::hash::{Hash, Hasher};
13use std::net::IpAddr;
14
15#[derive(Eq, PartialEq, Deserialize, Serialize, Clone, Debug)]
16pub struct LoadBalancer {
17 pub id: String,
18 pub created_on: DateTime<Utc>,
19 pub modified_on: DateTime<Utc>,
20 pub description: String,
21 /// The DNS hostname to associate with your Load Balancer. If this hostname already exists as a
22 /// DNS record in Cloudflare's DNS, the Load Balancer will take precedence and the DNS record
23 /// will not be used.
24 pub name: String,
25 pub enabled: bool,
26 /// Time to live (TTL) of the DNS entry for the IP address returned by this load balancer. This
27 /// only applies to gray-clouded (unproxied) load balancers.
28 #[serde(default = "LoadBalancer::default_ttl")]
29 pub ttl: u32,
30 /// The pool ID to use when all other pools are detected as unhealthy.
31 pub fallback_pool: LbPoolId,
32 /// A list of pool IDs ordered by their failover priority. Pools defined here are used by
33 /// default, or when region_pools are not configured for a given region.
34 pub default_pools: Vec<LbPoolId>,
35 /// A mapping of region/country codes to a list of pool IDs (ordered by their failover priority)
36 /// for the given region. Any regions not explicitly defined will fall back to using
37 /// default_pools.
38 pub region_pools: LbPoolMapping,
39 /// A mapping of Cloudflare PoP identifiers to a list of pool IDs (ordered by their failover
40 /// priority) for the PoP (datacenter). Any PoPs not explicitly defined will fall back to using
41 /// default_pools.
42 pub pop_pools: LbPoolMapping,
43 pub proxied: bool,
44 pub steering_policy: SteeringPolicy,
45 pub session_affinity: SessionAffinity,
46 pub session_affinity_attributes: SessionAffinityAttributes,
47 #[serde(default = "LoadBalancer::default_session_affinity_ttl")]
48 pub session_affinity_ttl: u32,
49}
50
51impl LoadBalancer {
52 fn default_ttl() -> u32 {
53 30
54 }
55 fn default_session_affinity_ttl() -> u32 {
56 5000
57 }
58}
59
60type LbPoolId = String;
61type LbPoolMapping = HashMap<String, Vec<LbPoolId>>;
62
63#[derive(Eq, PartialEq, Deserialize, Serialize, Clone, Debug)]
64#[serde(rename_all = "lowercase")]
65pub enum SteeringPolicy {
66 /// Empty policy maps to `Geo` if `region_pools` or `pop_pools` are used, or otherwise `Off`.
67 #[serde(rename = "")]
68 Nil,
69 Off,
70 Geo,
71 Random,
72 DynamicLatency,
73}
74
75#[derive(Eq, PartialEq, Deserialize, Serialize, Clone, Debug)]
76#[serde(rename_all = "lowercase")]
77pub enum SessionAffinity {
78 /// Empty has the same behaviour as `None`.
79 #[serde(rename = "")]
80 Nil,
81 None,
82 Cookie,
83 IpCookie,
84}
85
86#[derive(Eq, PartialEq, Deserialize, Serialize, Clone, Debug)]
87pub struct SessionAffinityAttributes {
88 pub samesite: SameSite,
89 pub secure: Secure,
90 pub drain_duration: u32,
91}
92
93#[derive(Eq, PartialEq, Deserialize, Serialize, Clone, Debug)]
94pub enum SameSite {
95 /// `Auto` maps to `Lax` if Always Use HTTPS is set, or `None` otherwise.
96 Auto,
97 Lax,
98 None,
99 Strict,
100}
101
102#[derive(Eq, PartialEq, Deserialize, Serialize, Clone, Debug)]
103pub enum Secure {
104 /// `Auto` maps to `Always` if Always Use HTTPS is set, or `Never` otherwise.
105 Auto,
106 Always,
107 Never,
108}
109
110impl ApiResultTraits for LoadBalancer {}
111
112/// A pool is a set of origins that requests could be routed to (e.g. each of your data centers or
113/// regions have its own pool).
114/// Requests will be routed to particular pools according to your steering policy, and then balanced
115/// across origins in that pool, proportional to each origin's weight.
116///
117/// For example, you might have two pools: one for the US, and one for Oceania. Inside each pool,
118/// there would be many origins, with weight roughly proportional to the number of requests they can
119/// handle. Then you might use a "dynamic latency" steering policy to ensure requests get routed
120/// to whatever pool can serve them fastest. So US users will probably get routed to the US pool. If
121/// the US pool becomes unavailable, they'll fail over to the Oceania pool.
122#[derive(Eq, PartialEq, Deserialize, Serialize, Clone, Debug)]
123pub struct Pool {
124 pub id: String,
125 pub created_on: DateTime<Utc>,
126 pub modified_on: DateTime<Utc>,
127 /// A human-readable description of the pool.
128 /// e.g. "Primary data center - Provider XYZ"
129 pub description: String,
130 pub name: String,
131 /// Whether to enable (the default) this pool. Disabled pools will not receive traffic and are
132 /// excluded from health checks. Disabling a pool will cause any load balancers using it to
133 /// failover to the next pool (if any).
134 pub enabled: bool,
135 /// The minimum number of origins that must be healthy for this pool to serve traffic. If the
136 /// number of healthy origins falls below this number, the pool will be marked unhealthy and we
137 /// will failover to the next available pool.
138 pub minimum_origins: u8,
139 /// The ID of the Monitor to use for health checking origins within this pool.
140 pub monitor: String,
141 pub check_regions: Option<Vec<String>>,
142 /// The list of origins within this pool. Traffic directed at this pool is balanced across all
143 /// currently healthy origins, provided the pool itself is healthy.
144 pub origins: HashSet<Origin>,
145 /// The email address to send health status notifications to. This can be an individual mailbox
146 /// or a mailing list.
147 pub notification_email: String,
148}
149
150/// An origin represents something that can serve user requests. Usually a machine, maybe an ELB.
151/// Origins with similar latency functions (e.g. origins in the same data center or region) might be
152/// in the same pool.
153#[derive(Deserialize, Serialize, Clone, Debug)]
154pub struct Origin {
155 /// A human-identifiable name for the origin.
156 /// e.g. app-server-1
157 pub name: String,
158 /// The IP address (IPv4 or IPv6) of the origin, or the publicly addressable hostname.
159 /// Hostnames entered here should resolve directly to the origin, and not be a hostname proxied
160 /// by Cloudflare.
161 /// e.g. 0.0.0.0
162 pub address: IpAddr,
163 /// Whether to enable (the default) this origin within the Pool. Disabled origins will not
164 /// receive traffic and are excluded from health checks. The origin will only be disabled for
165 /// the current pool.
166 pub enabled: bool,
167 /// The weight of this origin relative to other origins in the Pool. Based on the configured
168 /// weight the total traffic is distributed among origins within the Pool.
169 pub weight: f64,
170}
171
172// f64 doesn't impl Eq or Hash, so we need some custom implementations.
173impl PartialEq for Origin {
174 fn eq(&self, other: &Self) -> bool {
175 let diff_is_small = (self.weight - other.weight).abs() < 0.01;
176 self.name == other.name
177 && self.address == other.address
178 && self.enabled == other.enabled
179 && diff_is_small
180 }
181}
182impl Eq for Origin {}
183
184impl Hash for Origin {
185 fn hash<H: Hasher>(&self, state: &mut H) {
186 self.name.hash(state);
187 self.address.hash(state);
188 self.enabled.hash(state);
189 self.weight.to_bits().hash(state);
190 }
191}
192
193impl ApiResultTraits for Origin {}
194impl ApiResultTraits for Pool {}