Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/semgrep.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
on:
pull_request: {}
workflow_dispatch: {}
push:
branches:
- main
- master
schedule:
- cron: '0 0 * * *'
name: Semgrep config
jobs:
semgrep:
name: semgrep/ci
runs-on: ubuntu-latest
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
SEMGREP_URL: https://cloudflare.semgrep.dev
SEMGREP_APP_URL: https://cloudflare.semgrep.dev
SEMGREP_VERSION_CHECK_URL: https://cloudflare.semgrep.dev/api/check-version
container:
image: semgrep/semgrep
steps:
- uses: actions/checkout@v4
- run: semgrep ci
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
[workspace]
resolver = "2"

members = [
"cloudflare",
"cloudflare-examples",
"cloudflare-e2e-test",
]
]
4 changes: 3 additions & 1 deletion cloudflare-e2e-test/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "cloudflare-e2e-test"
version = "0.5.0"
edition = "2018"
edition = "2021"
description = "End-to-end tests of the Cloudflare Rust API client"
license = "BSD-3-Clause"

Expand All @@ -14,3 +14,5 @@ anyhow = "1.0.33"
clap = { version = "4.1", features = ["env"] }
cloudflare = { path = "../cloudflare" }
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
serde_json = "1.0.138"
rand = "0.8.5"
90 changes: 18 additions & 72 deletions cloudflare-e2e-test/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,79 +1,20 @@
#![forbid(unsafe_code)]
mod routing_performance;
mod storage_databases;

use clap::{Arg, Command};
use cloudflare::framework::async_api::Client as AsyncClient;
use cloudflare::framework::{async_api, auth::Credentials, Environment, HttpApiClientConfig};
use cloudflare::framework::client::async_api::Client as AsyncClient;
use cloudflare::framework::client::ClientConfig;
use cloudflare::framework::{auth::Credentials, client::async_api, Environment};
use std::fmt::Display;
use std::net::{IpAddr, Ipv4Addr};

async fn tests(api_client: &AsyncClient, account_id: &str) -> anyhow::Result<()> {
test_lb_pool(api_client, account_id).await?;
routing_performance::load_balancers::test_lb_pool(api_client, account_id).await?;
storage_databases::kv::test_kv(api_client, account_id).await?;
println!("Tests passed");
Ok(())
}

async fn test_lb_pool(api_client: &AsyncClient, account_identifier: &str) -> anyhow::Result<()> {
use cloudflare::endpoints::load_balancing::*;

// Create a pool
let origins = vec![
Origin {
name: "test-origin".to_owned(),
address: IpAddr::V4(Ipv4Addr::new(152, 122, 3, 1)),
enabled: true,
weight: 1.0,
},
Origin {
name: "test-origin-2".to_owned(),
address: IpAddr::V4(Ipv4Addr::new(152, 122, 3, 2)),
enabled: true,
weight: 1.0,
},
];
let pool = api_client
.request(&create_pool::CreatePool {
account_identifier,
params: create_pool::Params {
name: "test-pool",
optional_params: Some(create_pool::OptionalParams {
description: Some("test description"),
enabled: Some(true),
minimum_origins: Some(2),
monitor: Some("9004c07f1c0f33255410e45590251cf4"),
notification_email: Some("test@example.com"),
}),
origins: &origins,
},
})
.await
.log_err(|e| println!("Error in CreatePool: {e}"))?
.result;

// Get the details, but wait until after we delete the pool to validate it.
let pool_details = api_client
.request(&pool_details::PoolDetails {
account_identifier,
identifier: &pool.id,
})
.await
.log_err(|e| println!("Error in PoolDetails: {e}"));

// Delete the pool
let _ = api_client
.request(&delete_pool::DeletePool {
account_identifier,
identifier: &pool.id,
})
.await
.log_err(|e| println!("Error in DeletePool: {e}"))?;

// Validate the pool we got was the same as the pool we sent
let pool_details = pool_details?.result;
assert_eq!(pool, pool_details);

Ok(())
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
let cli =
Expand All @@ -83,33 +24,38 @@ async fn main() -> anyhow::Result<()> {
.about("Issues example requests to the Cloudflare API using the cloudflare-rust client library")
.arg(Arg::new("email")
.long("email")
.env("CF_RS_EMAIL")
.help("Email address associated with your account")
.requires("auth-key"))
.arg(Arg::new("auth-key")
.long("auth-key")
.alias("api-key")
.env("CF_RS_AUTH_KEY")
.env("CF_RS_API_KEY")
.help("API key generated on the \"My Account\" page")
.requires("email"))
.arg(Arg::new("auth-token")
.long("auth-token")
.alias("api-token")
.env("CF_RS_AUTH_TOKEN")
.env("CF_RS_API_TOKEN")
.help("API token generated on the \"My Account\" page")
.conflicts_with_all(["email", "auth-key"]))
.arg(Arg::new("account-id")
.long("account-id")
.env("CF_RS_ZONE_ID")
.env("CF_RS_ACCOUNT_ID")
.help("The ID of the account tests should be run on"))
.arg_required_else_help(true);

let mut matches = cli.get_matches();
let email = matches.remove_one("email").unwrap();
let email = matches.remove_one("email");
let key = matches.remove_one("auth-key");
let token = matches.remove_one("auth-token");
let account_id = matches
let account_id: String = matches
.remove_one("account-id")
.expect("account_id is mandatory");

let credentials: Credentials = if let Some(key) = key {
let credentials: Credentials = if let (Some(email), Some(key)) = (email, key) {
Credentials::UserAuthKey { email, key }
} else if let Some(token) = token {
Credentials::UserAuthToken { token }
Expand All @@ -119,11 +65,11 @@ async fn main() -> anyhow::Result<()> {

let api_client = async_api::Client::new(
credentials,
HttpApiClientConfig::default(),
ClientConfig::default(),
Environment::Production,
)?;

tests(&api_client, account_id).await
tests(&api_client, account_id.as_str()).await
}

pub trait ResultExt<T, E: Display> {
Expand Down
68 changes: 68 additions & 0 deletions cloudflare-e2e-test/src/routing_performance/load_balancers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
use crate::AsyncClient;

pub async fn test_lb_pool(
api_client: &AsyncClient,
account_identifier: &str,
) -> anyhow::Result<()> {
use crate::ResultExt;
use cloudflare::endpoints::load_balancing::*;
use std::net::{IpAddr, Ipv4Addr};

// Create a pool
let origins = vec![
Origin {
name: "test-origin".to_owned(),
address: IpAddr::V4(Ipv4Addr::new(152, 122, 3, 1)),
enabled: true,
weight: 1.0,
},
Origin {
name: "test-origin-2".to_owned(),
address: IpAddr::V4(Ipv4Addr::new(152, 122, 3, 2)),
enabled: true,
weight: 1.0,
},
];
let pool = api_client
.request(&create_pool::CreatePool {
account_identifier,
params: create_pool::Params {
name: "test-pool",
optional_params: Some(create_pool::OptionalParams {
description: Some("test description"),
enabled: Some(true),
minimum_origins: Some(2),
monitor: Some("9004c07f1c0f33255410e45590251cf4"),
notification_email: Some("test@example.com"),
}),
origins: &origins,
},
})
.await
.log_err(|e| println!("Error in CreatePool: {e}"))?
.result;

// Get the details, but wait until after we delete the pool to validate it.
let pool_details = api_client
.request(&pool_details::PoolDetails {
account_identifier,
identifier: &pool.id,
})
.await
.log_err(|e| println!("Error in PoolDetails: {e}"));

// Delete the pool
let _ = api_client
.request(&delete_pool::DeletePool {
account_identifier,
identifier: &pool.id,
})
.await
.log_err(|e| println!("Error in DeletePool: {e}"))?;

// Validate the pool we got was the same as the pool we sent
let pool_details = pool_details?.result;
assert_eq!(pool, pool_details);

Ok(())
}
1 change: 1 addition & 0 deletions cloudflare-e2e-test/src/routing_performance/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod load_balancers;
Loading
Loading