cfn_guard_lambda/
main.rs

1// Copyright Amazon Web Services, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4use cfn_guard::{run_checks, ValidateInput};
5use lambda_runtime::{handler_fn, Context, Error};
6use log::{self, info, LevelFilter};
7use serde_derive::{Deserialize, Serialize};
8use simple_logger::SimpleLogger;
9
10fn default_as_true() -> bool {
11    true
12}
13
14#[derive(Serialize, Deserialize, Debug)]
15pub struct CustomEvent {
16    #[serde(rename = "data")]
17    pub data: String,
18    #[serde(rename = "rules")]
19    pub rules: Vec<String>,
20    #[serde(rename = "verbose", default = "default_as_true")] // for backward compatibility
21    pub verbose: bool,
22}
23
24#[derive(Serialize)]
25pub struct CustomOutput {
26    pub message: Vec<serde_json::Value>,
27}
28
29#[tokio::main]
30#[allow(dead_code)]
31async fn main() -> Result<(), Error> {
32    SimpleLogger::new()
33        .with_level(LevelFilter::Info)
34        .init()
35        .unwrap();
36    let func = handler_fn(call_cfn_guard);
37    lambda_runtime::run(func).await?;
38    Ok(())
39}
40
41pub async fn call_cfn_guard(e: CustomEvent, _c: Context) -> Result<CustomOutput, Error> {
42    info!("Template is: [{}]", &e.data);
43    info!("Rules are: [{:?}]", &e.rules);
44    let mut results_vec = Vec::new();
45    for rule in e.rules.iter() {
46        let result = match run_checks(
47            ValidateInput {
48                content: &e.data,
49                file_name: "lambda-payload",
50            },
51            ValidateInput {
52                content: rule,
53                file_name: "lambda-rule",
54            },
55            e.verbose,
56        ) {
57            Ok(t) => t,
58            Err(e) => e.to_string(),
59        };
60        let json_value: serde_json::Value = serde_json::from_str(&result)?;
61        results_vec.push(json_value)
62    }
63    Ok(CustomOutput {
64        message: results_vec,
65    })
66}
67
68impl std::fmt::Display for CustomEvent {
69    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
70        write!(f, "{}", serde_json::to_string_pretty(&self).unwrap())?;
71        Ok(())
72    }
73}
74
75impl std::fmt::Display for CustomOutput {
76    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
77        for message in &self.message {
78            write!(
79                f,
80                "{}",
81                match serde_json::to_string_pretty(message) {
82                    Ok(message) => message,
83                    Err(_) => unreachable!(),
84                }
85            )?;
86        }
87        Ok(())
88    }
89}