diff --git a/guard-lambda/README.md b/guard-lambda/README.md index a90dd87f5..085d8e02e 100644 --- a/guard-lambda/README.md +++ b/guard-lambda/README.md @@ -51,6 +51,7 @@ aws lambda create-function --function-name cfnGuardLambda \ The payload JSON to `cfn-guard-lambda` requires the following two fields: * `data` - String version of the YAML or JSON structured data * `rules` - List of string version of rules files that you want to run your YAML or JSON structured data against. +* `parse_output` - Boolean. If true, returns parsed output. If false, return raw json output. ## Invoking `cfn-guard-lambda` @@ -58,7 +59,7 @@ To invoke the submitted cfn-guard as a AWS Lambda function run: ```bash aws lambda invoke --function-name cfnGuardLambda \ - --payload "{"data": "", "rules" : ["", "", ...]}" \ + --payload "{"data": "", "rules" : ["", "", ...], "parse_output": true}" \ output.json ``` The above works for AWS CLI version 1. If you are planning to use the AWS CLI version 2 please refer to the [Migrating from AWS CLI version 1 to version 2 document](https://docs.aws.amazon.com/cli/latest/userguide/cliv2-migration.html#cliv2-migration-binaryparam) for changes required to the above command. @@ -66,7 +67,7 @@ The above works for AWS CLI version 1. If you are planning to use the AWS CLI ve ### Example ```bash -aws lambda invoke --function-name cfnGuard --payload '{"data": "{\"Resources\":{\"NewVolume\":{\"Type\":\"AWS::EC2::Volume\",\"Properties\":{\"Size\":500,\"Encrypted\":false,\"AvailabilityZone\":\"us-west-2b\"}},\"NewVolume2\":{\"Type\":\"AWS::EC2::Volume\",\"Properties\":{\"Size\":50,\"Encrypted\":false,\"AvailabilityZone\":\"us-west-2c\"}}}}", "rules" : [ "Resources.*[ Type == /EC2::Volume/ ].Properties.Encrypted == false" ]}' output.json +aws lambda invoke --function-name cfnGuard --payload '{"data": "{\"Resources\":{\"NewVolume\":{\"Type\":\"AWS::EC2::Volume\",\"Properties\":{\"Size\":500,\"Encrypted\":false,\"AvailabilityZone\":\"us-west-2b\"}},\"NewVolume2\":{\"Type\":\"AWS::EC2::Volume\",\"Properties\":{\"Size\":50,\"Encrypted\":false,\"AvailabilityZone\":\"us-west-2c\"}}}}", "rules" : [ "Resources.*[ Type == /EC2::Volume/ ].Properties.Encrypted == false" ], "parse_output": true}' output.json ``` ## FAQs diff --git a/guard-lambda/src/main.rs b/guard-lambda/src/main.rs index 1ed43f26d..d17ea1275 100644 --- a/guard-lambda/src/main.rs +++ b/guard-lambda/src/main.rs @@ -13,6 +13,8 @@ struct CustomEvent { data: String, #[serde(rename = "rules")] rules: Vec, + #[serde(rename = "parse_output")] + parse_output: bool, } #[derive(Serialize)] @@ -34,7 +36,7 @@ pub(crate) async fn call_cfn_guard(e: CustomEvent, _c: Context) -> Result t, Err(e) => (e.to_string()), }; diff --git a/guard/src/commands/helper.rs b/guard/src/commands/helper.rs index 34f116426..20fb02827 100644 --- a/guard/src/commands/helper.rs +++ b/guard/src/commands/helper.rs @@ -2,16 +2,15 @@ // SPDX-License-Identifier: Apache-2.0 use crate::rules::errors::{Error, ErrorKind}; -use crate::rules::evaluate::RootScope; +use crate::rules::eval_context::simplifed_json_from_root; use crate::rules::path_value::PathAwareValue; -use crate::commands::tracker::StackTracker; -use crate::commands::validate::ConsoleReporter; -use crate::rules::{Evaluate, Result}; +use crate::rules::Result; use std::convert::TryFrom; pub fn validate_and_return_json( data: &str, rules: &str, + parse_output: &bool ) -> Result { let input_data = match serde_json::from_str::(&data) { Ok(value) => PathAwareValue::try_from(value), @@ -28,16 +27,15 @@ pub fn validate_and_return_json( let mut root_scope = crate::rules::eval_context::root_scope(&rules, &root)?; let mut tracker = crate::rules::eval_context::RecordTracker::new(&mut root_scope); let _status = crate::rules::eval::eval_rules_file(&rules, &mut tracker)?; - let event = tracker.final_event.unwrap(); - Ok(serde_json::to_string_pretty(&event)?) + let event = tracker.extract(); -// let root_context = RootScope::new(&rules, &root); -// let stacker = StackTracker::new(&root_context); -// let reporters = vec![]; -// let reporter = ConsoleReporter::new(stacker, &reporters, "lambda-run","lambda-payload", true, true, false); -// rules.evaluate(&root, &reporter)?; -// let json_result = reporter.get_result_json(); -// return Ok(json_result); + if *parse_output { + Ok(serde_json::to_string_pretty(&simplifed_json_from_root( + &event, + )?)?) + } else { + Ok(serde_json::to_string_pretty(&event)?) + } } Err(e) => return Err(e), } diff --git a/guard/src/commands/validate.rs b/guard/src/commands/validate.rs index 75cb31441..f13c2b976 100644 --- a/guard/src/commands/validate.rs +++ b/guard/src/commands/validate.rs @@ -324,44 +324,6 @@ or rules files. } } -pub fn validate_and_return_json( - data: &str, - rules: &str, -) -> Result { - let input_data = match serde_json::from_str::(&data) { - Ok(value) => PathAwareValue::try_from(value), - Err(e) => return Err(Error::new(ErrorKind::ParseError(e.to_string()))), - }; - - let span = crate::rules::parser::Span::new_extra(&rules, "lambda"); - - match crate::rules::parser::rules_file(span) { - Ok(rules) => { - match input_data { - Ok(root) => { - let mut root_scope = crate::rules::eval_context::root_scope(&rules, &root)?; - let mut tracker = crate::rules::eval_context::RecordTracker::new(&mut root_scope); - let _status = crate::rules::eval::eval_rules_file(&rules, &mut tracker)?; - let event = tracker.final_event.unwrap(); - let file_report = simplifed_json_from_root(&event)?; - Ok(serde_json::to_string_pretty(&file_report)?) - - -// let root_context = RootScope::new(&rules, &root); -// let stacker = StackTracker::new(&root_context); -// let reporters = vec![]; -// let reporter = ConsoleReporter::new(stacker, &reporters, "lambda-function", "input-payload", true, true, false); -// rules.evaluate(&root, &reporter)?; -// let json_result = reporter.get_result_json(); -// return Ok(json_result); - } - Err(e) => return Err(e), - } - } - Err(e) => return Err(Error::new(ErrorKind::ParseError(e.to_string()))), - } -} - #[derive(Debug)] pub(crate) struct ConsoleReporter<'r> { root_context: StackTracker<'r>, diff --git a/guard/src/lib.rs b/guard/src/lib.rs index b4d8ef47f..b11b61015 100644 --- a/guard/src/lib.rs +++ b/guard/src/lib.rs @@ -9,6 +9,7 @@ mod migrate; pub extern "C" fn run_checks( data: &str, rules: &str, + parse_output: &bool, ) -> crate::rules::Result { - return crate::commands::helper::validate_and_return_json(&data, &rules); + return crate::commands::helper::validate_and_return_json(&data, &rules, &parse_output); }