Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move jsonification to given #308

Merged
merged 1 commit into from
Jul 3, 2020
Merged
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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# CHANGELOG

## Unreleased
* Jsonfiy the stash on creation to prevent bugs related to jsonification.

## 1.2.7 (2020-06-19)
* Fixed faulty over restriction in [Then its singular value condition match the "search_regex" regex](https://terraform-compliance.com/pages/bdd-references/then.html#then-its-singular-value-condition-match-the-search-regex-regex).
* New scenario tag: [noskip](https://terraform-compliance.com/pages/bdd-references/using_tags.html#supported-tags) tags
Expand Down
16 changes: 16 additions & 0 deletions terraform_compliance/common/helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,22 @@ def jsonify(string):
return string


def recursive_jsonify(haystack):
if isinstance(haystack, str):
haystack = jsonify(haystack)
if isinstance(haystack, (list, dict)):
return recursive_jsonify(haystack)
return haystack

if isinstance(haystack, dict):
haystack = {key: recursive_jsonify(value) for key, value in haystack.items()}

if isinstance(haystack, list):
haystack = [recursive_jsonify(value) for value in haystack]

return haystack


def get_resource_name_from_stash(stash, alternative_stash=None, address=None):
if address is not None:
return {'address': address}
Expand Down
21 changes: 11 additions & 10 deletions terraform_compliance/steps/given/i_have_name_section_configured.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
find_root_by_key,
remove_mounted_resources,
transform_asg_style_tags,
convert_resource_type
convert_resource_type,
recursive_jsonify
)
from terraform_compliance.extensions.ext_radish_bdd import skip_step
import re
Expand Down Expand Up @@ -40,23 +41,23 @@ def i_have_name_section_configured(_step_obj, name, type_name='resource', _terra
if name in ('a resource', 'any resource', 'resources'):
_step_obj.context.type = type_name
_step_obj.context.name = name
_step_obj.context.stash = [obj for key, obj in _terraform_config.config.terraform.resources_raw.items()]
_step_obj.context.stash = recursive_jsonify([obj for key, obj in _terraform_config.config.terraform.resources_raw.items()])
_step_obj.context.addresses = get_resource_address_list_from_stash(_step_obj.context.stash)
_step_obj.context.property_name = type_name
return True

elif name in ('an output', 'any output', 'outputs'):
_step_obj.context.type = 'output'
_step_obj.context.name = name
_step_obj.context.stash = [obj for key, obj in _terraform_config.config.terraform.configuration['outputs'].items()]
_step_obj.context.stash = recursive_jsonify([obj for key, obj in _terraform_config.config.terraform.configuration['outputs'].items()])
_step_obj.context.addresses = get_resource_address_list_from_stash(_terraform_config.config.terraform.configuration['outputs'])
_step_obj.context.property_name = 'output'
return True

elif name in ('a variable', 'any variable', 'variables'):
_step_obj.context.type = 'variable'
_step_obj.context.name = name
_step_obj.context.stash = [obj for key, obj in _terraform_config.config.terraform.configuration['variables'].items()]
_step_obj.context.stash = recursive_jsonify([obj for key, obj in _terraform_config.config.terraform.configuration['variables'].items()])
_step_obj.context.addresses = 'variable'
_step_obj.context.property_name = 'variable'
return True
Expand All @@ -79,7 +80,7 @@ def i_have_name_section_configured(_step_obj, name, type_name='resource', _terra
if resource_list:
_step_obj.context.type = type_name
_step_obj.context.name = name
_step_obj.context.stash = resource_list
_step_obj.context.stash = recursive_jsonify(resource_list)
_step_obj.context.addresses = get_resource_address_list_from_stash(resource_list)
_step_obj.context.property_name = type_name
return True
Expand All @@ -91,7 +92,7 @@ def i_have_name_section_configured(_step_obj, name, type_name='resource', _terra
if resource_list:
_step_obj.context.type = type_name
_step_obj.context.name = name
_step_obj.context.stash = resource_list
_step_obj.context.stash = recursive_jsonify(resource_list)
_step_obj.context.addresses = get_resource_address_list_from_stash(resource_list)
_step_obj.context.property_name = type_name
return True
Expand All @@ -102,7 +103,7 @@ def i_have_name_section_configured(_step_obj, name, type_name='resource', _terra
if found_variable:
_step_obj.context.type = type_name
_step_obj.context.name = name
_step_obj.context.stash = found_variable
_step_obj.context.stash = recursive_jsonify(found_variable)
_step_obj.context.addresses = name
_step_obj.context.property_name = type_name
return True
Expand All @@ -113,7 +114,7 @@ def i_have_name_section_configured(_step_obj, name, type_name='resource', _terra
if found_output:
_step_obj.context.type = type_name
_step_obj.context.name = name
_step_obj.context.stash = found_output
_step_obj.context.stash = recursive_jsonify(found_output)
_step_obj.context.addresses = name
_step_obj.context.property_name = type_name
return True
Expand All @@ -124,7 +125,7 @@ def i_have_name_section_configured(_step_obj, name, type_name='resource', _terra
if found_provider:
_step_obj.context.type = type_name
_step_obj.context.name = name
_step_obj.context.stash = found_provider
_step_obj.context.stash = recursive_jsonify(found_provider)
_step_obj.context.addresses = name
_step_obj.context.address = name
_step_obj.context.property_name = type_name
Expand All @@ -137,7 +138,7 @@ def i_have_name_section_configured(_step_obj, name, type_name='resource', _terra
if data_list:
_step_obj.context.type = type_name
_step_obj.context.name = name
_step_obj.context.stash = data_list
_step_obj.context.stash = recursive_jsonify(data_list)
_step_obj.context.addresses = name
_step_obj.context.address = name
_step_obj.context.property_name = type_name
Expand Down
27 changes: 27 additions & 0 deletions tests/functional/test_issue-307/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
resource "aws_sns_topic" "test" {
name = "my-topic-with-policy"
}

resource "" "default" {
arn = aws_sns_topic.test.arn

policy =<<POLICY

{
"Statement": [{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": {
"AWS": "111122223333"
},
"Action": ["sns:Subscribe"],
"Resource": "arn:aws:sns:us-east-2:444455556666:MyTopic",
"Condition": {
"StringEquals": {
"sns:Protocol": "https"
}
}
}]
}
POLICY
}
1 change: 1 addition & 0 deletions tests/functional/test_issue-307/plan.out.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"format_version":"0.1","terraform_version":"0.12.26","planned_values":{"root_module":{"resources":[{"address":"aws_sns_topic.test","mode":"managed","type":"aws_sns_topic","name":"test","provider_name":"aws","schema_version":0,"values":{"application_failure_feedback_role_arn":null,"application_success_feedback_role_arn":null,"application_success_feedback_sample_rate":null,"delivery_policy":null,"display_name":null,"http_failure_feedback_role_arn":null,"http_success_feedback_role_arn":null,"http_success_feedback_sample_rate":null,"kms_master_key_id":null,"lambda_failure_feedback_role_arn":null,"lambda_success_feedback_role_arn":null,"lambda_success_feedback_sample_rate":null,"name":"my-topic-with-policy","name_prefix":null,"sqs_failure_feedback_role_arn":null,"sqs_success_feedback_role_arn":null,"sqs_success_feedback_sample_rate":null,"tags":null}},{"address":"aws_sns_topic_policy.default","mode":"managed","type":"aws_sns_topic_policy","name":"default","provider_name":"aws","schema_version":0,"values":{"policy":" \r\n {\r\n \"Statement\": [{\r\n \"Sid\": \"Statement1\",\r\n \"Effect\": \"Allow\",\r\n \"Principal\": {\r\n \"AWS\": \"111122223333\"\r\n },\r\n \"Action\": [\"sns:Subscribe\"],\r\n \"Resource\": \"arn:aws:sns:us-east-2:444455556666:MyTopic\",\r\n \"Condition\": {\r\n \"StringEquals\": {\r\n \"sns:Protocol\": \"https\"\r\n }\r\n }\r\n }]\r\n}\r\n"}}]}},"resource_changes":[{"address":"aws_sns_topic.test","mode":"managed","type":"aws_sns_topic","name":"test","provider_name":"aws","change":{"actions":["create"],"before":null,"after":{"application_failure_feedback_role_arn":null,"application_success_feedback_role_arn":null,"application_success_feedback_sample_rate":null,"delivery_policy":null,"display_name":null,"http_failure_feedback_role_arn":null,"http_success_feedback_role_arn":null,"http_success_feedback_sample_rate":null,"kms_master_key_id":null,"lambda_failure_feedback_role_arn":null,"lambda_success_feedback_role_arn":null,"lambda_success_feedback_sample_rate":null,"name":"my-topic-with-policy","name_prefix":null,"sqs_failure_feedback_role_arn":null,"sqs_success_feedback_role_arn":null,"sqs_success_feedback_sample_rate":null,"tags":null},"after_unknown":{"arn":true,"id":true,"policy":true}}},{"address":"aws_sns_topic_policy.default","mode":"managed","type":"aws_sns_topic_policy","name":"default","provider_name":"aws","change":{"actions":["create"],"before":null,"after":{"policy":" \r\n {\r\n \"Statement\": [{\r\n \"Sid\": \"Statement1\",\r\n \"Effect\": \"Allow\",\r\n \"Principal\": {\r\n \"AWS\": \"111122223333\"\r\n },\r\n \"Action\": [\"sns:Subscribe\"],\r\n \"Resource\": \"arn:aws:sns:us-east-2:444455556666:MyTopic\",\r\n \"Condition\": {\r\n \"StringEquals\": {\r\n \"sns:Protocol\": \"https\"\r\n }\r\n }\r\n }]\r\n}\r\n"},"after_unknown":{"arn":true,"id":true}}}],"configuration":{"provider_config":{"aws":{"name":"aws","expressions":{"region":{"constant_value":"us-east-1"},"skip_credentials_validation":{"constant_value":true},"skip_requesting_account_id":{"constant_value":true}}}},"root_module":{"resources":[{"address":"aws_sns_topic.test","mode":"managed","type":"aws_sns_topic","name":"test","provider_config_key":"aws","expressions":{"name":{"constant_value":"my-topic-with-policy"}},"schema_version":0},{"address":"aws_sns_topic_policy.default","mode":"managed","type":"aws_sns_topic_policy","name":"default","provider_config_key":"aws","expressions":{"arn":{"references":["aws_sns_topic.test"]},"policy":{"constant_value":" \r\n {\r\n \"Statement\": [{\r\n \"Sid\": \"Statement1\",\r\n \"Effect\": \"Allow\",\r\n \"Principal\": {\r\n \"AWS\": \"111122223333\"\r\n },\r\n \"Action\": [\"sns:Subscribe\"],\r\n \"Resource\": \"arn:aws:sns:us-east-2:444455556666:MyTopic\",\r\n \"Condition\": {\r\n \"StringEquals\": {\r\n \"sns:Protocol\": \"https\"\r\n }\r\n }\r\n }]\r\n}\r\n"}},"schema_version":0}]}}}
7 changes: 7 additions & 0 deletions tests/functional/test_issue-307/test.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Feature: Feature for issue #307

@noskip
Scenario: sns topic policy should not allow * principal - test2
Given I have aws_sns_topic_policy defined
When it has policy
And it has Statement