Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions guard-lambda/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,23 @@ 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`

To invoke the submitted cfn-guard as a AWS Lambda function run:

```bash
aws lambda invoke --function-name cfnGuardLambda \
--payload "{"data": "<input data>", "rules" : ["<input rules 1>", "<input rules 2>", ...]}" \
--payload "{"data": "<input data>", "rules" : ["<input rules 1>", "<input rules 2>", ...], "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.

### 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
Expand Down
4 changes: 3 additions & 1 deletion guard-lambda/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ struct CustomEvent {
data: String,
#[serde(rename = "rules")]
rules: Vec<String>,
#[serde(rename = "parse_output")]
parse_output: bool,
}

#[derive(Serialize)]
Expand All @@ -34,7 +36,7 @@ pub(crate) async fn call_cfn_guard(e: CustomEvent, _c: Context) -> Result<Custom
info!("Rule Set is: [{:?}]", &e.rules);
let mut results_vec = Vec::new();
for rule in e.rules.iter() {
let result = match cfn_guard::run_checks(&e.data, &rule) {
let result = match cfn_guard::run_checks(&e.data, &rule, &e.parse_output) {
Ok(t) => t,
Err(e) => (e.to_string()),
};
Expand Down
24 changes: 11 additions & 13 deletions guard/src/commands/helper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> {
let input_data = match serde_json::from_str::<serde_json::Value>(&data) {
Ok(value) => PathAwareValue::try_from(value),
Expand All @@ -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),
}
Expand Down
38 changes: 0 additions & 38 deletions guard/src/commands/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,44 +324,6 @@ or rules files.
}
}

pub fn validate_and_return_json(
data: &str,
rules: &str,
) -> Result<String> {
let input_data = match serde_json::from_str::<serde_json::Value>(&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>,
Expand Down
3 changes: 2 additions & 1 deletion guard/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod migrate;
pub extern "C" fn run_checks(
data: &str,
rules: &str,
parse_output: &bool,
) -> crate::rules::Result<String> {
return crate::commands::helper::validate_and_return_json(&data, &rules);
return crate::commands::helper::validate_and_return_json(&data, &rules, &parse_output);
}