Unverified Commit a536c15b authored by John DiSanti's avatar John DiSanti Committed by GitHub
Browse files

Improve the canary Lambda implementation (#993)

* Grant the canary Lamba permission to log to CloudWatch

* Don't log the S3 bucket name in the canary

* Emit an empty workspace for the canary manifest

* Add more context to S3 metadata failure message

* Log the full result
parent bc316a0b
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@ use crate::{s3_canary, transcribe_canary};
use aws_sdk_s3 as s3;
use aws_sdk_transcribestreaming as transcribe;
use std::env;
use std::fmt;
use std::future::Future;
use std::pin::Pin;
use tracing::{info_span, Instrument};
@@ -49,12 +50,23 @@ impl Clients {
    }
}

#[derive(Debug)]
pub struct CanaryEnv {
    s3_bucket_name: String,
    expected_transcribe_result: String,
}

impl fmt::Debug for CanaryEnv {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("CanaryEnv")
            .field("s3_bucket_name", &"*** redacted ***")
            .field(
                "expected_transcribe_result",
                &self.expected_transcribe_result,
            )
            .finish()
    }
}

impl CanaryEnv {
    pub fn from_env() -> Self {
        // S3 bucket name to test against
+6 −4
Original line number Diff line number Diff line
@@ -67,11 +67,13 @@ async fn lambda_main(clients: canary::Clients) -> Result<Value, Error> {
        }
    }

    if failures.is_empty() {
        Ok(json!({ "result": "success" }))
    let result = if failures.is_empty() {
        json!({ "result": "success" })
    } else {
        Ok(json!({ "result": "failure", "failures": failures }))
    }
        json!({ "result": "failure", "failures": failures })
    };
    info!("Result: {}", result);
    Ok(result)
}

async fn canary_result(handle: JoinHandle<anyhow::Result<()>>) -> Result<(), String> {
+8 −2
Original line number Diff line number Diff line
@@ -63,8 +63,14 @@ pub async fn s3_canary(client: s3::Client, s3_bucket_name: String) -> anyhow::Re
    let mut result = Ok(());
    match output.metadata() {
        Some(map) => {
            if map.get("something") != Some(&"テスト テスト!".to_string()) {
                result = Err(CanaryError("S3 metadata was incorrect".into()).into());
            // Option::as_deref doesn't work here since the deref of &String is String
            let value = map.get("something").map(|s| s.as_str()).unwrap_or("");
            if value != "テスト テスト!" {
                result = Err(CanaryError(format!(
                    "S3 metadata was incorrect. Expected `テスト テスト!` but got `{}`.",
                    value
                ))
                .into());
            }
        }
        None => {
+14 −5
Original line number Diff line number Diff line
@@ -19,6 +19,10 @@ version = "0.1.0"
edition = "2018"
license = "Apache-2.0"

# Emit an empty workspace so that the canary can successfully build when
# built from the aws-sdk-rust repo, which has a workspace in it.
[workspace]

[[bin]]
name = "bootstrap"
path = "src/main.rs"
@@ -43,9 +47,12 @@ def main():

    with open("Cargo.toml", "w") as file:
        print(BASE_MANIFEST, file=file)
        print(format_dependency("aws-config", args.path, args.sdk_version), file=file)
        print(format_dependency("aws-sdk-s3", args.path, args.sdk_version), file=file)
        print(format_dependency("aws-sdk-transcribestreaming", args.path, args.sdk_version), file=file)
        print(format_dependency("aws-config",
              args.path, args.sdk_version), file=file)
        print(format_dependency("aws-sdk-s3",
              args.path, args.sdk_version), file=file)
        print(format_dependency("aws-sdk-transcribestreaming",
              args.path, args.sdk_version), file=file)


def format_dependency(crate, path, version):
@@ -58,8 +65,10 @@ def format_dependency(crate, path, version):
class Args:
    def __init__(self):
        parser = argparse.ArgumentParser()
        parser.add_argument("--path", dest="path", type=str, help="Path to the generated AWS Rust SDK")
        parser.add_argument("--sdk-version", dest="sdk_version", type=str, help="AWS Rust SDK version", required=True)
        parser.add_argument("--path", dest="path", type=str,
                            help="Path to the generated AWS Rust SDK")
        parser.add_argument("--sdk-version", dest="sdk_version",
                            type=str, help="AWS Rust SDK version", required=True)

        args = parser.parse_args()
        self.path = args.path
+9 −0
Original line number Diff line number Diff line
@@ -90,6 +90,15 @@ export class CanaryStack extends Stack {
            assumedBy: new ServicePrincipal("lambda.amazonaws.com"),
        });

        // Allow canaries to write logs to CloudWatch
        this.lambdaExecutionRole.addToPolicy(
            new PolicyStatement({
                actions: ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"],
                effect: Effect.ALLOW,
                resources: ["arn:aws:logs:*:*:/aws/lambda/canary-lambda-*:*"],
            }),
        );

        // Allow canaries to talk to their test bucket
        this.canaryTestBucket.grantReadWrite(this.lambdaExecutionRole);

Loading