-
Notifications
You must be signed in to change notification settings - Fork 85
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Now that Argo Tunnel is a deprecated API, this commit adds support for Cfd Tunnels --------- Co-authored-by: GoncaloGarcia <[email protected]>
- Loading branch information
1 parent
b4fa5ef
commit 2b1e12a
Showing
12 changed files
with
349 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
use crate::endpoints::cfd_tunnel::{ConfigurationSrc, Tunnel}; | ||
use serde::Serialize; | ||
use serde_with::{ | ||
base64::{Base64, Standard}, | ||
formats::Padded, | ||
serde_as, | ||
}; | ||
|
||
use crate::framework::endpoint::{EndpointSpec, Method}; | ||
|
||
/// Create a Cfd Tunnel | ||
/// This creates the Tunnel, which can then be routed and ran. Creating the Tunnel per se is only | ||
/// a metadata operation (i.e. no Tunnel is running at this point). | ||
/// <https://developers.cloudflare.com/api/operations/cloudflare-tunnel-create-a-cloudflare-tunnel> | ||
#[derive(Debug)] | ||
pub struct CreateTunnel<'a> { | ||
pub account_identifier: &'a str, | ||
pub params: Params<'a>, | ||
} | ||
|
||
impl<'a> EndpointSpec<Tunnel> for CreateTunnel<'a> { | ||
fn method(&self) -> Method { | ||
Method::POST | ||
} | ||
fn path(&self) -> String { | ||
format!("accounts/{}/cfd_tunnel", self.account_identifier) | ||
} | ||
#[inline] | ||
fn body(&self) -> Option<String> { | ||
let body = serde_json::to_string(&self.params).unwrap(); | ||
Some(body) | ||
} | ||
} | ||
|
||
/// Params for creating a Named Argo Tunnel | ||
#[serde_as] | ||
#[serde_with::skip_serializing_none] | ||
#[derive(Serialize, Clone, Debug)] | ||
pub struct Params<'a> { | ||
/// The name for the Tunnel to be created. It must be unique within the account. | ||
pub name: &'a str, | ||
/// The byte array (with 32 or more bytes) representing a secret for the tunnel. This is | ||
/// encoded into JSON as a base64 String. This secret is necessary to run the tunnel. | ||
#[serde_as(as = "Base64<Standard, Padded>")] | ||
pub tunnel_secret: &'a Vec<u8>, | ||
|
||
pub config_src: &'a ConfigurationSrc, | ||
|
||
/// Arbitrary metadata for the tunnel. | ||
pub metadata: Option<serde_json::Value>, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
use chrono::{offset::Utc, DateTime}; | ||
use serde::{Deserialize, Serialize}; | ||
use std::net::IpAddr; | ||
use uuid::Uuid; | ||
|
||
use crate::framework::response::ApiResult; | ||
|
||
/// A Cfd Tunnel | ||
/// This is an Cfd Tunnel that has been created. It can be used for routing and subsequent running. | ||
#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)] | ||
pub struct Tunnel { | ||
pub id: Uuid, | ||
pub created_at: DateTime<Utc>, | ||
pub deleted_at: Option<DateTime<Utc>>, | ||
pub name: String, | ||
pub connections: Vec<ActiveConnection>, | ||
pub metadata: serde_json::Value, | ||
} | ||
|
||
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug, Clone)] | ||
pub struct TunnelWithConnections { | ||
pub id: Uuid, | ||
pub account_tag: String, | ||
pub created_at: DateTime<Utc>, | ||
pub deleted_at: Option<DateTime<Utc>>, | ||
pub name: String, | ||
pub connections: Vec<ActiveConnection>, | ||
pub conns_active_at: Option<DateTime<Utc>>, | ||
pub conns_inactive_at: Option<DateTime<Utc>>, | ||
// tun_type can be inferred from metadata | ||
#[serde(flatten)] | ||
pub metadata: serde_json::Value, | ||
pub status: TunnelStatusType, | ||
// This field is only present for tunnels that make sense to report (e.g: Cfd_Tunnel), which | ||
// are the ones that can be managed via UI or dash in terms of their YAML file. | ||
#[serde(skip_serializing_if = "Option::is_none")] | ||
pub remote_config: Option<bool>, | ||
} | ||
|
||
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone, Copy, Eq, Hash)] | ||
#[serde(rename_all = "snake_case")] | ||
pub enum TunnelStatusType { | ||
Inactive, // Tunnel has been created but a connection has yet to be registered | ||
Down, // Tunnel is down and all connections are unregistered | ||
Degraded, // Tunnel health is degraded but still serving connections | ||
Healthy, // Tunnel is healthy | ||
} | ||
|
||
#[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] | ||
pub enum ConfigurationSrc { | ||
#[serde(rename = "local")] | ||
#[default] | ||
Local, | ||
#[serde(rename = "cloudflare")] | ||
Cloudflare, | ||
} | ||
/// An active connection for a Cfd Tunnel | ||
#[derive(Serialize, Deserialize, Eq, PartialEq, Debug, Clone, Hash)] | ||
pub struct ActiveConnection { | ||
pub colo_name: String, | ||
/// Deprecated, use `id` instead. | ||
pub uuid: Uuid, | ||
pub id: Uuid, | ||
pub is_pending_reconnect: bool, | ||
pub origin_ip: IpAddr, | ||
pub opened_at: DateTime<Utc>, | ||
pub client_id: Uuid, | ||
pub client_version: String, | ||
} | ||
|
||
impl ApiResult for Tunnel {} | ||
impl ApiResult for Vec<Tunnel> {} | ||
|
||
/// The result of a route request for a Cfd Tunnel | ||
#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)] | ||
#[serde(untagged)] | ||
pub enum RouteResult { | ||
Dns(DnsRouteResult), | ||
Lb(LoadBalancerRouteResult), | ||
} | ||
|
||
#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)] | ||
pub struct DnsRouteResult { | ||
pub cname: Change, | ||
pub name: String, | ||
pub dns_tag: String, | ||
} | ||
|
||
#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)] | ||
pub struct LoadBalancerRouteResult { | ||
pub load_balancer: Change, | ||
pub pool: Change, | ||
} | ||
|
||
#[derive(Deserialize, Serialize, Debug, Clone, PartialEq, Eq)] | ||
#[serde(rename_all = "lowercase")] | ||
pub enum Change { | ||
Unchanged, | ||
New, | ||
Updated, | ||
} | ||
|
||
impl ApiResult for RouteResult {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
use crate::framework::endpoint::{serialize_query, EndpointSpec, Method}; | ||
use serde::Serialize; | ||
|
||
use super::Tunnel; | ||
|
||
/// Delete a tunnel | ||
/// <https://developers.cloudflare.com/api/operations/cloudflare-tunnel-delete-a-cloudflare-tunnel> | ||
#[derive(Debug)] | ||
pub struct DeleteTunnel<'a> { | ||
pub account_identifier: &'a str, | ||
pub tunnel_id: &'a str, | ||
pub params: Params, | ||
} | ||
|
||
impl<'a> EndpointSpec<Tunnel> for DeleteTunnel<'a> { | ||
fn method(&self) -> Method { | ||
Method::DELETE | ||
} | ||
fn path(&self) -> String { | ||
format!( | ||
"accounts/{}/cfd_tunnel/{}", | ||
self.account_identifier, self.tunnel_id | ||
) | ||
} | ||
#[inline] | ||
fn query(&self) -> Option<String> { | ||
serialize_query(&self.params) | ||
} | ||
} | ||
|
||
#[serde_with::skip_serializing_none] | ||
#[derive(Serialize, Clone, Debug, Default)] | ||
pub struct Params { | ||
// should delete tunnel connections if any exists | ||
pub cascade: bool, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
use crate::endpoints::cfd_tunnel::Tunnel; | ||
use chrono::{DateTime, Utc}; | ||
use serde::Serialize; | ||
|
||
use crate::framework::endpoint::{serialize_query, EndpointSpec, Method}; | ||
|
||
/// List/search tunnels in an account. | ||
/// <https://developers.cloudflare.com/api/operations/cloudflare-tunnel-list-cloudflare-tunnels> | ||
#[derive(Debug)] | ||
pub struct ListTunnels<'a> { | ||
pub account_identifier: &'a str, | ||
pub params: Params, | ||
} | ||
|
||
impl<'a> EndpointSpec<Vec<Tunnel>> for ListTunnels<'a> { | ||
fn method(&self) -> Method { | ||
Method::GET | ||
} | ||
fn path(&self) -> String { | ||
format!("accounts/{}/cfd_tunnel", self.account_identifier) | ||
} | ||
#[inline] | ||
fn query(&self) -> Option<String> { | ||
serialize_query(&self.params) | ||
} | ||
} | ||
|
||
/// Params for filtering listed tunnels | ||
#[serde_with::skip_serializing_none] | ||
#[derive(Serialize, Clone, Debug, Default)] | ||
pub struct Params { | ||
pub name: Option<String>, | ||
pub uuid: Option<String>, | ||
pub is_deleted: Option<bool>, | ||
pub existed_at: Option<DateTime<Utc>>, | ||
pub was_active_at: Option<DateTime<Utc>>, | ||
pub include_prefix: Option<String>, | ||
pub was_inactive_at: Option<DateTime<Utc>>, | ||
pub exclude_prefix: Option<String>, | ||
#[serde(flatten)] | ||
pub pagination_params: Option<PaginationParams>, | ||
} | ||
|
||
#[derive(Serialize, Clone, Debug)] | ||
pub struct PaginationParams { | ||
pub page: u64, | ||
pub per_page: u64, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
pub mod create_tunnel; | ||
mod data_structures; | ||
pub mod delete_tunnel; | ||
pub mod list_tunnels; | ||
pub mod route_dns; | ||
pub mod update_tunnel; | ||
|
||
pub use data_structures::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
use crate::framework::endpoint::{EndpointSpec, Method}; | ||
|
||
use super::RouteResult; | ||
use serde::Serialize; | ||
use uuid::Uuid; | ||
|
||
/// Route for a Named Argo Tunnel | ||
/// This creates a new route for the identified Tunnel. More than 1 route may co-exist for the same | ||
/// Tunnel. | ||
/// Note that this modifies only metadata on Cloudflare side to route traffic to the Tunnel, but | ||
/// it is still up to the user to run the Tunnel to receive that traffic. | ||
#[derive(Debug)] | ||
pub struct RouteTunnel<'a> { | ||
pub zone_tag: &'a str, | ||
pub tunnel_id: Uuid, | ||
pub params: Params<'a>, | ||
} | ||
|
||
impl<'a> EndpointSpec<RouteResult> for RouteTunnel<'a> { | ||
fn method(&self) -> Method { | ||
Method::PUT | ||
} | ||
fn path(&self) -> String { | ||
format!("zones/{}/tunnels/{}/routes", self.zone_tag, self.tunnel_id) | ||
} | ||
#[inline] | ||
fn body(&self) -> Option<String> { | ||
let body = serde_json::to_string(&self.params).unwrap(); | ||
Some(body) | ||
} | ||
} | ||
|
||
/// Params for routing a Named Argo Tunnel | ||
#[derive(Serialize, Clone, Debug)] | ||
#[serde(tag = "type", rename_all = "lowercase")] | ||
pub enum Params<'a> { | ||
Dns { user_hostname: &'a str }, | ||
Lb { lb_name: &'a str, lb_pool: &'a str }, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
use crate::endpoints::cfd_tunnel::Tunnel; | ||
use serde::Serialize; | ||
use serde_with::{ | ||
base64::{Base64, Standard}, | ||
formats::Padded, | ||
serde_as, | ||
}; | ||
|
||
use crate::framework::endpoint::{EndpointSpec, Method}; | ||
|
||
/// Create a Cfd Tunnel | ||
/// This creates the Tunnel, which can then be routed and ran. Creating the Tunnel per se is only | ||
/// a metadata operation (i.e. no Tunnel is running at this point). | ||
/// <https://developers.cloudflare.com/api/operations/cloudflare-tunnel-create-a-cloudflare-tunnel> | ||
#[derive(Debug)] | ||
pub struct UpdateTunnel<'a> { | ||
pub account_identifier: &'a str, | ||
pub tunnel_id: &'a str, | ||
pub params: Params<'a>, | ||
} | ||
|
||
impl<'a> EndpointSpec<Tunnel> for UpdateTunnel<'a> { | ||
fn method(&self) -> Method { | ||
Method::PATCH | ||
} | ||
fn path(&self) -> String { | ||
format!( | ||
"accounts/{}/cfd_tunnel/{}", | ||
self.account_identifier, self.tunnel_id | ||
) | ||
} | ||
#[inline] | ||
fn body(&self) -> Option<String> { | ||
let body = serde_json::to_string(&self.params).unwrap(); | ||
Some(body) | ||
} | ||
} | ||
|
||
/// Params for updating a Cfd Tunnel | ||
#[serde_as] | ||
#[serde_with::skip_serializing_none] | ||
#[derive(Serialize, Clone, Debug)] | ||
pub struct Params<'a> { | ||
/// The new name for the Tunnel | ||
pub name: &'a str, | ||
/// The byte array (with 32 or more bytes) representing a secret for the tunnel. This is | ||
/// encoded into JSON as a base64 String. This secret is necessary to run the tunnel. | ||
#[serde_as(as = "Base64<Standard, Padded>")] | ||
pub tunnel_secret: &'a Vec<u8>, | ||
|
||
/// Arbitrary metadata for the tunnel. | ||
pub metadata: Option<serde_json::Value>, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.