Skip to content

Commit 776513e

Browse files
committed
Add AWS and Cloudflare config building and slight refactor of Cloudflare SDK
1 parent f613c6a commit 776513e

10 files changed

Lines changed: 695 additions & 53 deletions

File tree

src/adapters/backend/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,22 @@ impl BackendClient {
103103
Ok(workspaces)
104104
}
105105

106+
pub(crate) async fn list_applications(
107+
&self,
108+
workspace_id: WorkspaceId,
109+
) -> Result<Vec<ApplicationDetails>> {
110+
self.is_authenicated()?;
111+
let applications: Vec<_> = self
112+
.client
113+
.applications_api()
114+
.list_applications(workspace_id)
115+
.await
116+
.into_diagnostic()?
117+
.applications;
118+
119+
Ok(applications)
120+
}
121+
106122
pub(crate) async fn lock_state(
107123
&self,
108124
meta: &RolloutMetadata,

src/adapters/cloudflare/mod.rs

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use miette::{IntoDiagnostic, Result, miette};
44
use reqwest::header::{AUTHORIZATION, HeaderMap, HeaderValue};
55
use reqwest::multipart::Part;
66
use reqwest::{Client, multipart};
7+
use serde::{Deserialize, Serialize};
78
use std::sync::OnceLock;
89
use tokio::fs::read;
910
use tracing::{debug, error};
@@ -16,6 +17,15 @@ use responses::CloudflareResponse;
1617

1718
use crate::artifacts::CloudflareManifest;
1819

20+
#[derive(Debug, Clone, Serialize, Deserialize)]
21+
pub struct WorkerScript {
22+
pub id: String,
23+
pub created_on: String,
24+
pub modified_on: String,
25+
pub usage_model: Option<String>,
26+
pub etag: String,
27+
}
28+
1929
static URL: OnceLock<Url> = OnceLock::new();
2030

2131
fn init_url() -> Url {
@@ -28,12 +38,10 @@ pub struct CloudflareClient {
2838
client: Client,
2939
/// This is the Cloudflare account id
3040
account_id: String,
31-
/// The name of the Cloudflare worker
32-
worker_name: String,
3341
}
3442

3543
impl CloudflareClient {
36-
pub fn new(account_id: String, worker_name: String, token: &str) -> Self {
44+
pub fn new(account_id: String, token: &str) -> Self {
3745
// TODO: Add a timeout.
3846
let mut default_headers = HeaderMap::new();
3947
let auth = format!("Bearer {token}");
@@ -46,11 +54,7 @@ impl CloudflareClient {
4654
.build()
4755
.expect("Must be able to construct client");
4856

49-
Self {
50-
client,
51-
account_id,
52-
worker_name,
53-
}
57+
Self { client, account_id }
5458
}
5559

5660
// Commented out until we verify if we need an upload session.
@@ -164,12 +168,12 @@ impl CloudflareClient {
164168
// https://developers.cloudflare.com/api/resources/workers/subresources/scripts/subresources/versions/methods/create/
165169
pub async fn upload_version(
166170
&self,
171+
worker_name: &String,
167172
manifest: &CloudflareManifest,
168173
main_module: &String,
169174
) -> Result<UploadVersionResponse> {
170175
debug!("Uploading Worker version");
171176
let account_id = &self.account_id;
172-
let worker_name = &self.worker_name;
173177
let path = format!("accounts/{account_id}/workers/scripts/{worker_name}/versions");
174178
let url = Self::url_with_path(&path);
175179

@@ -224,10 +228,9 @@ impl CloudflareClient {
224228

225229
// Corresponds to:
226230
// https://developers.cloudflare.com/api/resources/workers/subresources/scripts/subresources/deployments/methods/get/
227-
pub async fn get_current_version(&self) -> Result<String> {
231+
pub async fn get_current_version(&self, worker_name: &String) -> Result<String> {
228232
debug!("Getting current Worker version");
229233
let account_id = &self.account_id;
230-
let worker_name = &self.worker_name;
231234
let path = format!("accounts/{account_id}/workers/scripts/{worker_name}/deployments");
232235
let url = Self::url_with_path(&path);
233236

@@ -263,10 +266,13 @@ impl CloudflareClient {
263266

264267
// Corresponds to:
265268
// https://developers.cloudflare.com/api/resources/workers/subresources/scripts/subresources/deployments/methods/create/
266-
pub async fn create_deployment(&self, request: CreateDeploymentRequest) -> Result<()> {
269+
pub async fn create_deployment(
270+
&self,
271+
worker_name: &String,
272+
request: CreateDeploymentRequest,
273+
) -> Result<()> {
267274
debug!("Deploying updated version(s)");
268275
let account_id = &self.account_id;
269-
let worker_name = &self.worker_name;
270276
let path = format!("accounts/{account_id}/workers/scripts/{worker_name}/deployments");
271277
let url = Self::url_with_path(&path);
272278

@@ -291,14 +297,14 @@ impl CloudflareClient {
291297
// For the monitor to grab metrics within a time range.
292298
pub async fn collect_metrics(
293299
&self,
294-
worker_version_id: String,
300+
worker_name: &String,
301+
worker_version_id: &String,
295302
status_code_range_start: u16,
296303
status_code_range_end: u16,
297304
from_time: DateTime<chrono::Utc>,
298305
to_time: DateTime<chrono::Utc>,
299306
) -> Result<u32> {
300307
let account_id = &self.account_id;
301-
let worker_name = &self.worker_name;
302308
let path = format!("accounts/{account_id}/workers/observability/telemetry/query");
303309
let url = Self::url_with_path(&path);
304310

@@ -390,6 +396,32 @@ impl CloudflareClient {
390396
Ok(count)
391397
}
392398

399+
// List all workers for the account
400+
// Corresponds to: https://developers.cloudflare.com/api/resources/workers/subresources/scripts/methods/list/
401+
pub async fn list_workers(&self) -> Result<Vec<WorkerScript>> {
402+
debug!("Listing Cloudflare Workers");
403+
let account_id = &self.account_id;
404+
let path = format!("accounts/{account_id}/workers/scripts");
405+
let url = Self::url_with_path(&path);
406+
407+
let response = self.client.get(url).send().await.into_diagnostic()?;
408+
409+
if !response.status().is_success() {
410+
return Err(miette!(
411+
"Failed to list Workers. Error: {:?}",
412+
response.json::<serde_json::Value>().await
413+
));
414+
}
415+
416+
let workers_response = response
417+
.json::<CloudflareResponse<Vec<WorkerScript>>>()
418+
.await
419+
.into_diagnostic()?;
420+
421+
debug!("Workers listed successfully");
422+
Ok(workers_response.result)
423+
}
424+
393425
fn base_url() -> &'static Url {
394426
URL.get_or_init(init_url)
395427
}

src/adapters/ingresses/cloudflare.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,19 @@ use tracing::{debug, info};
1717
#[derive(Getters)]
1818
pub struct CloudflareWorkerIngress {
1919
client: Client,
20+
// The name of the worker being monitored
21+
worker_name: String,
2022
// The version id of the baseline version
2123
control_version_id: Option<String>,
2224
// The version id of the canary version
2325
canary_version_id: Option<String>,
2426
}
2527

2628
impl CloudflareWorkerIngress {
27-
pub fn new(client: Client) -> Self {
29+
pub fn new(client: Client, worker_name: String) -> Self {
2830
Self {
2931
client,
32+
worker_name,
3033
control_version_id: None,
3134
canary_version_id: None,
3235
}
@@ -38,7 +41,7 @@ impl Ingress for CloudflareWorkerIngress {
3841
fn get_config(&self) -> IngressConfig {
3942
IngressConfig::CloudflareWorker {
4043
account_id: self.client.account_id().clone(),
41-
worker_name: self.client.worker_name().clone(),
44+
worker_name: self.worker_name().clone(),
4245
}
4346
}
4447

@@ -67,7 +70,9 @@ impl Ingress for CloudflareWorkerIngress {
6770
.versions(vec![control_version, canary_version])
6871
.build();
6972

70-
self.client.create_deployment(deployment_request).await
73+
self.client
74+
.create_deployment(self.worker_name(), deployment_request)
75+
.await
7176
}
7277

7378
async fn set_canary_traffic(&mut self, percent: WholePercent) -> Result<()> {
@@ -85,7 +90,9 @@ impl Ingress for CloudflareWorkerIngress {
8590
.versions(vec![control_version, canary_version])
8691
.build();
8792

88-
self.client.create_deployment(deployment_request).await
93+
self.client
94+
.create_deployment(self.worker_name(), deployment_request)
95+
.await
8996
}
9097

9198
async fn rollback_canary(&mut self) -> Result<()> {
@@ -103,7 +110,9 @@ impl Ingress for CloudflareWorkerIngress {
103110
// no canary version and so we don't try to roll it back (again) during shutdown.
104111
self.canary_version_id = None;
105112

106-
self.client.create_deployment(deployment_request).await
113+
self.client
114+
.create_deployment(self.worker_name(), deployment_request)
115+
.await
107116
}
108117

109118
async fn promote_canary(&mut self) -> Result<()> {
@@ -121,7 +130,9 @@ impl Ingress for CloudflareWorkerIngress {
121130
// the control version and so we don't try to roll it back during shutdown.
122131
self.canary_version_id = None;
123132

124-
self.client.create_deployment(deployment_request).await
133+
self.client
134+
.create_deployment(self.worker_name(), deployment_request)
135+
.await
125136
}
126137
}
127138

src/adapters/monitors/cloudflare.rs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ use super::Monitor;
1717
#[derive(Getters)]
1818
pub struct CloudflareMonitor {
1919
client: Client,
20+
// The name of the worker being monitored
21+
worker_name: String,
2022
// The version id of the baseline version
2123
control_version_id: Option<String>,
2224
// The version id of the canary version
@@ -28,9 +30,10 @@ pub struct CloudflareMonitor {
2830
}
2931

3032
impl CloudflareMonitor {
31-
pub fn new(client: Client) -> Self {
33+
pub fn new(client: Client, worker_name: String) -> Self {
3234
Self {
3335
client,
36+
worker_name,
3437
control_version_id: None,
3538
canary_version_id: None,
3639
start_time: Utc::now(),
@@ -48,7 +51,7 @@ impl Monitor for CloudflareMonitor {
4851
fn get_config(&self) -> MonitorConfig {
4952
MonitorConfig::CloudflareWorkersObservability {
5053
account_id: self.client.account_id().clone(),
51-
worker_name: self.client.worker_name().clone(),
54+
worker_name: self.worker_name().clone(),
5255
}
5356
}
5457

@@ -68,23 +71,26 @@ impl Monitor for CloudflareMonitor {
6871
// Query all control metrics, but only if we've already received a control version id
6972
if let Some(control_version_id) = &self.control_version_id {
7073
let control_2xx_future = self.client.collect_metrics(
71-
control_version_id.clone(),
74+
self.worker_name(),
75+
control_version_id,
7276
200,
7377
299,
7478
start_query_time,
7579
end_query_time,
7680
);
7781

7882
let control_4xx_future = self.client.collect_metrics(
79-
control_version_id.clone(),
83+
self.worker_name(),
84+
control_version_id,
8085
400,
8186
499,
8287
start_query_time,
8388
end_query_time,
8489
);
8590

8691
let control_5xx_future = self.client.collect_metrics(
87-
control_version_id.clone(),
92+
self.worker_name(),
93+
control_version_id,
8894
500,
8995
599,
9096
start_query_time,
@@ -111,23 +117,26 @@ impl Monitor for CloudflareMonitor {
111117
// Query all canary metrics, but only if we've already received a control version id
112118
if let Some(canary_version_id) = &self.canary_version_id {
113119
let canary_2xx_future = self.client.collect_metrics(
114-
canary_version_id.clone(),
120+
self.worker_name(),
121+
canary_version_id,
115122
200,
116123
299,
117124
start_query_time,
118125
end_query_time,
119126
);
120127

121128
let canary_4xx_future = self.client.collect_metrics(
122-
canary_version_id.clone(),
129+
self.worker_name(),
130+
canary_version_id,
123131
400,
124132
499,
125133
start_query_time,
126134
end_query_time,
127135
);
128136

129137
let canary_5xx_future = self.client.collect_metrics(
130-
canary_version_id.clone(),
138+
self.worker_name(),
139+
canary_version_id,
131140
500,
132141
599,
133142
start_query_time,

src/adapters/platforms/cloudflare.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,21 @@ use tracing::info;
1616
#[derive(Getters)]
1717
pub struct CloudflareWorkerPlatform {
1818
client: Client,
19+
worker_name: String,
1920
artifact_path: PathBuf,
2021
main_module: String,
2122
}
2223

2324
impl CloudflareWorkerPlatform {
24-
pub fn new(client: Client, artifact_path: PathBuf, main_module: String) -> Self {
25+
pub fn new(
26+
client: Client,
27+
worker_name: String,
28+
artifact_path: PathBuf,
29+
main_module: String,
30+
) -> Self {
2531
Self {
2632
client,
33+
worker_name,
2734
artifact_path,
2835
main_module,
2936
}
@@ -35,13 +42,13 @@ impl Platform for CloudflareWorkerPlatform {
3542
fn get_config(&self) -> PlatformConfig {
3643
PlatformConfig::CloudflareWorker {
3744
account_id: self.client.account_id().clone(),
38-
worker_name: self.client.worker_name().clone(),
45+
worker_name: self.worker_name().clone(),
3946
}
4047
}
4148

4249
async fn deploy(&mut self) -> Result<(String, String)> {
4350
info!("Deploying Worker!");
44-
let baseline_version_id = self.client.get_current_version().await?;
51+
let baseline_version_id = self.client.get_current_version(self.worker_name()).await?;
4552

4653
// 1. First, we create a manifest of the files to upload
4754
let manifest = CloudflareManifest::new(&self.artifact_path).await?;
@@ -72,7 +79,7 @@ impl Platform for CloudflareWorkerPlatform {
7279
// 2. Finally, upload the files
7380
let upload_version_request = self
7481
.client
75-
.upload_version(&manifest, &self.main_module)
82+
.upload_version(self.worker_name(), &manifest, &self.main_module)
7683
.await?;
7784

7885
Ok((baseline_version_id, upload_version_request.id))

0 commit comments

Comments
 (0)