From 405859eeff41a23722f578fc6d88c63b096c7c17 Mon Sep 17 00:00:00 2001 From: Robbie McKinstry Date: Sat, 23 Nov 2024 13:51:59 -0500 Subject: [PATCH] Plumb AWS config to ingress. --- src/adapters/ingresses/apig.rs | 13 ++++++++++++- src/adapters/ingresses/mod.rs | 2 ++ src/adapters/monitors/cloudwatch.rs | 24 ++++++++++++------------ src/cmd/deploy.rs | 13 +++++++++++-- src/config/deploy/mod.rs | 7 +++++-- src/pipeline/mod.rs | 4 ++-- 6 files changed, 44 insertions(+), 19 deletions(-) diff --git a/src/adapters/ingresses/apig.rs b/src/adapters/ingresses/apig.rs index 3cba1c5..a98d686 100644 --- a/src/adapters/ingresses/apig.rs +++ b/src/adapters/ingresses/apig.rs @@ -20,11 +20,19 @@ pub struct AwsApiGateway { lambda_artifact: Vec, apig_client: GatewayClient, lambda_client: LambdaClient, + gateway_name: String, + stage_name: String, + lambda_name: String, } impl AwsApiGateway { /// Given a path to the lambda, create a new APIG Ingress. - pub async fn new(artifact_path: PathBuf) -> Result { + pub async fn new( + artifact_path: PathBuf, + gateway_name: &str, + stage_name: &str, + lambda_name: &str, + ) -> Result { let artifact = read_file(artifact_path).await?; // Now, configure the AWS SDKs. // TODO: Extract Config into a single location so we don't have to @@ -37,6 +45,9 @@ impl AwsApiGateway { lambda_artifact: artifact, apig_client, lambda_client, + gateway_name: gateway_name.to_owned(), + stage_name: stage_name.to_owned(), + lambda_name: lambda_name.to_owned(), }) } diff --git a/src/adapters/ingresses/mod.rs b/src/adapters/ingresses/mod.rs index ba015d8..c855e0f 100644 --- a/src/adapters/ingresses/mod.rs +++ b/src/adapters/ingresses/mod.rs @@ -1,6 +1,8 @@ use async_trait::async_trait; use miette::Result; +pub use apig::AwsApiGateway; + /// Ingresses are responsible for (1) controlling how much traffic the canary /// gets (hence the name ingress, since it functions like a virtual LB) and /// (2) deploying, yanking, and promoting both the canary and the baseline. diff --git a/src/adapters/monitors/cloudwatch.rs b/src/adapters/monitors/cloudwatch.rs index a826cd0..75918d3 100644 --- a/src/adapters/monitors/cloudwatch.rs +++ b/src/adapters/monitors/cloudwatch.rs @@ -159,8 +159,8 @@ impl Monitor for CloudWatch { let control_count_future = self.query_cloudwatch( ApiMetric::Count, - "Releases", - "prod", + &self.gateway_name, + &self.stage_name, Group::Control, now, five_mins_ago, @@ -168,8 +168,8 @@ impl Monitor for CloudWatch { let control_4xx_future = self.query_cloudwatch( ApiMetric::Error4XX, - "Releases", - "prod", + &self.gateway_name, + &self.stage_name, Group::Control, now, five_mins_ago, @@ -177,8 +177,8 @@ impl Monitor for CloudWatch { let control_5xx_future = self.query_cloudwatch( ApiMetric::Error5XX, - "Releases", - "prod", + &self.gateway_name, + &self.stage_name, Group::Control, now, five_mins_ago, @@ -186,8 +186,8 @@ impl Monitor for CloudWatch { let canary_count_future = self.query_cloudwatch( ApiMetric::Count, - "Releases", - "prod", + &self.gateway_name, + &self.stage_name, Group::Experimental, now, five_mins_ago, @@ -195,8 +195,8 @@ impl Monitor for CloudWatch { let canary_4xx_future = self.query_cloudwatch( ApiMetric::Error4XX, - "Releases", - "prod", + &self.gateway_name, + &self.stage_name, Group::Experimental, now, five_mins_ago, @@ -204,8 +204,8 @@ impl Monitor for CloudWatch { let canary_5xx_future = self.query_cloudwatch( ApiMetric::Error5XX, - "Releases", - "prod", + &self.gateway_name, + &self.stage_name, Group::Experimental, now, five_mins_ago, diff --git a/src/cmd/deploy.rs b/src/cmd/deploy.rs index bc7326e..0e8623c 100644 --- a/src/cmd/deploy.rs +++ b/src/cmd/deploy.rs @@ -1,5 +1,5 @@ use crate::adapters::ChiSquareEngine; -use crate::adapters::{CloudWatch, MockIngress}; +use crate::adapters::{AwsApiGateway, CloudWatch}; use crate::config::deploy::DeploySubcommand; use crate::Pipeline; use miette::Result; @@ -10,6 +10,7 @@ pub struct Deploy { artifact_path: PathBuf, gateway_name: String, stage_name: String, + lambda_name: String, } impl Deploy { @@ -21,6 +22,7 @@ impl Deploy { artifact_path: args.artifact_path, gateway_name: args.aws_apig_name, stage_name: args.aws_apig_stage, + lambda_name: args.aws_lambda, } } @@ -29,12 +31,19 @@ impl Deploy { pub async fn dispatch(self) -> Result<()> { // • Load the monitor from the user's config. let monitor = CloudWatch::new(&self.gateway_name, &self.stage_name).await; + let ingress = AwsApiGateway::new( + self.artifact_path, + &self.gateway_name, + &self.stage_name, + &self.lambda_name, + ) + .await?; // • TODO: Create the ingress, passing in the path to the deployment artifact. // • Set up our deployment pipeline. Pipeline::builder() .monitor(Box::new(monitor)) .engine(ChiSquareEngine::new()) - .ingress(MockIngress) + .ingress(Box::new(ingress)) .build() // Run the pipeline to completion. .run() diff --git a/src/config/deploy/mod.rs b/src/config/deploy/mod.rs index fb46145..bd42abc 100644 --- a/src/config/deploy/mod.rs +++ b/src/config/deploy/mod.rs @@ -9,9 +9,12 @@ pub struct DeploySubcommand { #[arg(value_name = "FILE")] pub artifact_path: PathBuf, /// The name of the AWS API Gateway to deploy to. - #[arg(long, env)] + #[arg(long, env = "MULTI_AWS_APIG_NAME")] pub aws_apig_name: String, /// The name of the AWS API Gateway stage - #[arg(long, env)] + #[arg(long, env = "MULTI_AWS_APIG_STAGE")] pub aws_apig_stage: String, + /// The name of the AWS Lambda function to update. + #[arg(long, env = "MULTI_AWS_LAMBDA")] + pub aws_lambda: String, } diff --git a/src/pipeline/mod.rs b/src/pipeline/mod.rs index 778f70b..fd4995c 100644 --- a/src/pipeline/mod.rs +++ b/src/pipeline/mod.rs @@ -27,12 +27,12 @@ impl Pipeline { #[builder] pub fn new( monitor: ResponseMonitor, - ingress: impl Ingress + 'static, + ingress: Box, engine: impl DecisionEngine> + 'static, ) -> Self { Self { engine: Box::new(engine), - ingress: Box::new(ingress), + ingress, monitor, } }