diff --git a/src/adapters/ingresses/apig.rs b/src/adapters/ingresses/apig.rs index 3cba1c5..2377b28 100644 --- a/src/adapters/ingresses/apig.rs +++ b/src/adapters/ingresses/apig.rs @@ -4,6 +4,7 @@ use crate::utils::load_default_aws_config; use super::Ingress; use async_trait::async_trait; +use aws_sdk_apigateway::types::{Op, PatchOperation}; use miette::miette; use miette::{IntoDiagnostic, Result}; use tokio::{fs::File, io::AsyncReadExt}; @@ -104,6 +105,36 @@ impl AwsApiGateway { Ok(()) } + + pub async fn promote_apig_canary(&self, api_id: &str, stage_name: &str) -> Result<()> { + // Overwrite the main deployment's ID with the canary's + let replace_deployment_op = PatchOperation::builder() + .op(Op::Copy) + .from("/canarySettings/deploymentId") + .path("/deploymentId") + .build(); + + // Reset canary traffic to 0% so we're ready for another release + let reset_traffic_op = PatchOperation::builder() + .op(Op::Replace) + .path("/canarySettings/percentTraffic") + // Note: this must be a string to pass into Value, but it's actually an f64 in AWS + .value("0.0") + .build(); + + // Send request to update stage + self.apig_client + .update_stage() + .rest_api_id(api_id) + .stage_name(stage_name) + .patch_operations(replace_deployment_op) + .patch_operations(reset_traffic_op) + .send() + .await + .into_diagnostic()?; + + Ok(()) + } } /// given a path to a file, load it as an array of bytes. @@ -128,4 +159,10 @@ impl Ingress for AwsApiGateway { Ok(()) } + + async fn promote_canary(&mut self) -> Result<()> { + self.promote_apig_canary("Releases", "prod").await?; + + Ok(()) + } } diff --git a/src/adapters/ingresses/mod.rs b/src/adapters/ingresses/mod.rs index ba015d8..37a7bba 100644 --- a/src/adapters/ingresses/mod.rs +++ b/src/adapters/ingresses/mod.rs @@ -11,7 +11,7 @@ pub trait Ingress { // TODO: define the other methods on this type. // async fn yank_canary(&mut self) -> Result<()>; - // async fn promote_canary(&mut self) -> Result<()>; + async fn promote_canary(&mut self) -> Result<()>; // async fn set_canary_traffic(&mut self, percent: u8); } @@ -22,6 +22,10 @@ impl Ingress for MockIngress { async fn deploy(&mut self) -> Result<()> { todo!() } + + async fn promote_canary(&mut self) -> Result<()> { + todo!() + } } impl From for BoxIngress {