def test_transform_unhandled_failure_empty_managed_policy_map(): document = { 'Transform': 'AWS::Serverless-2016-10-31', 'Resources': { 'Resource': { 'Type': 'AWS::Serverless::Function', 'Properties': { 'CodeUri': 's3://bucket/key', 'Handler': 'index.handler', 'Runtime': 'nodejs4.3', 'Policies': 'AmazonS3FullAccess' } } } } parameter_values = get_template_parameter_values() mock_policy_loader = MagicMock() mock_policy_loader.load.return_value = {} with pytest.raises(Exception) as e: transform(document, parameter_values, mock_policy_loader) error_message = str(e.value) assert error_message == 'Managed policy map is empty, but should not be.'
def test_swagger_definitionuri_sha_gets_recomputed(): document = { "Transform": "AWS::Serverless-2016-10-31", "Resources": { "Resource": { "Type": "AWS::Serverless::Api", "Properties": {"StageName": "Prod", "DefinitionUri": "s3://bucket/key"}, } }, } mock_policy_loader = get_policy_mock() parameter_values = get_template_parameter_values() output_fragment = transform(document, parameter_values, mock_policy_loader) print(json.dumps(output_fragment, indent=2)) deployment_key = get_deployment_key(output_fragment) assert deployment_key # Now let's change the Body property and transform again document["Resources"]["Resource"]["Properties"]["DefinitionUri"] = "s3://bucket/key1/key2" output_fragment = transform(document, parameter_values, mock_policy_loader) deployment_key_changed = get_deployment_key(output_fragment) assert deployment_key_changed assert deployment_key != deployment_key_changed # Now let's re-deploy the document without any changes. Deployment Key must NOT change output_fragment = transform(document, parameter_values, mock_policy_loader) assert get_deployment_key(output_fragment) == deployment_key_changed
def test_transform_unhandled_failure_empty_managed_policy_map(): document = { "Transform": "AWS::Serverless-2016-10-31", "Resources": { "Resource": { "Type": "AWS::Serverless::Function", "Properties": { "CodeUri": "s3://bucket/key", "Handler": "index.handler", "Runtime": "nodejs12.x", "Policies": "AmazonS3FullAccess", }, } }, } parameter_values = get_template_parameter_values() mock_policy_loader = MagicMock() mock_policy_loader.load.return_value = {} with pytest.raises(Exception) as e: transform(document, parameter_values, mock_policy_loader) error_message = str(e.value) assert error_message == "Managed policy map is empty, but should not be."
def test_transform_unhandled_failure_empty_managed_policy_map(): document = { 'Transform': 'AWS::Serverless-2016-10-31', 'Resources': { 'Resource': { 'Type': 'AWS::Serverless::Function', 'Properties': { 'CodeUri': 's3://bucket/key', 'Handler': 'index.handler', 'Runtime': 'nodejs4.3', 'Policies': 'AmazonS3FullAccess' } } } } parameter_values = get_template_parameter_values() mock_policy_loader = MagicMock() mock_policy_loader.load.return_value = {} with pytest.raises(Exception) as e: transform(document, parameter_values, mock_policy_loader) error_message = e.value.message assert error_message == 'Managed policy map is empty, but should not be.'
def test_transform_invalid_document(testcase): manifest = yaml_parse(open(os.path.join(INPUT_FOLDER, testcase + '.yaml'), 'r')) expected = json.load(open(os.path.join(OUTPUT_FOLDER, testcase + '.json'), 'r')) mock_policy_loader = MagicMock() parameter_values = get_template_parameter_values() with pytest.raises(InvalidDocumentException) as e: transform(manifest, parameter_values, mock_policy_loader) error_message = get_exception_error_message(e) assert error_message == expected.get('errorMessage')
def test_transform_invalid_document(testcase): manifest = yaml.load(open(os.path.join(input_folder, testcase + '.yaml'), 'r')) expected = json.load(open(os.path.join(output_folder, testcase + '.json'), 'r')) mock_policy_loader = MagicMock() parameter_values = get_template_parameter_values() with pytest.raises(InvalidDocumentException) as e: transform(manifest, parameter_values, mock_policy_loader) error_message = get_exception_error_message(e) assert error_message == expected.get('errorMessage')
def test_transform_invalid_document(testcase): manifest = yaml_parse(open(os.path.join(INPUT_FOLDER, testcase + ".yaml"), "r")) expected = json.load(open(os.path.join(OUTPUT_FOLDER, testcase + ".json"), "r")) mock_policy_loader = MagicMock() parameter_values = get_template_parameter_values() with pytest.raises(InvalidDocumentException) as e: transform(manifest, parameter_values, mock_policy_loader) error_message = get_exception_error_message(e) assert error_message == expected.get("errorMessage")
def main(): print(cwd) input_file_path = cwd + '/ruleapi.yaml' output_file_path = cwd + '/ruleapi_cfn.yaml' print(input_file_path) with open(input_file_path, 'r') as f: sam_template = yaml_parse(f) try: cloud_formation_template = transform(sam_template, {}, ManagedPolicyLoader(iam_client)) cloud_formation_template_prettified = json.dumps( cloud_formation_template, indent=2) with open(output_file_path, 'w') as f: f.write(cloud_formation_template_prettified) print('Wrote transformed CloudFormation template to: ' + output_file_path) except InvalidDocumentException as e: errorMessage = reduce( lambda message, error: message + ' ' + error.message, e.causes, e.message) print(errorMessage) errors = map(lambda cause: cause.message, e.causes) print(errors)
def test_transform_success(self, testcase, partition_with_region): partition = partition_with_region[0] region = partition_with_region[1] manifest = yaml_parse(open(os.path.join(INPUT_FOLDER, testcase + '.yaml'), 'r')) # To uncover unicode-related bugs, convert dict to JSON string and parse JSON back to dict manifest = json.loads(json.dumps(manifest)) partition_folder = partition if partition != "aws" else "" expected = json.load(open(os.path.join(OUTPUT_FOLDER, partition_folder, testcase + '.json'), 'r')) with patch('boto3.session.Session.region_name', region): parameter_values = get_template_parameter_values() mock_policy_loader = MagicMock() mock_policy_loader.load.return_value = { 'AWSLambdaBasicExecutionRole': 'arn:{}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'.format(partition), 'AmazonDynamoDBFullAccess': 'arn:{}:iam::aws:policy/AmazonDynamoDBFullAccess'.format(partition), 'AmazonDynamoDBReadOnlyAccess': 'arn:{}:iam::aws:policy/AmazonDynamoDBReadOnlyAccess'.format(partition), 'AWSLambdaRole': 'arn:{}:iam::aws:policy/service-role/AWSLambdaRole'.format(partition), } output_fragment = transform( manifest, parameter_values, mock_policy_loader) print(json.dumps(output_fragment, indent=2)) # Only update the deployment Logical Id hash in Py3. if sys.version_info.major >= 3: self._update_logical_id_hash(expected) self._update_logical_id_hash(output_fragment) assert deep_sort_lists(output_fragment) == deep_sort_lists(expected)
def transform_template(sam_template_path, cfn_output_path): """ Locally transforms a SAM template to a Cloud Formation template Parameters ---------- sam_template_path : Path SAM template input path cfn_output_path : Path Cloud formation template output path """ LOG = logging.getLogger(__name__) iam_client = boto3.client("iam") with open(sam_template_path) as f: sam_template = yaml_parse(f) try: cloud_formation_template = transform(sam_template, {}, ManagedPolicyLoader(iam_client)) cloud_formation_template_prettified = json.dumps( cloud_formation_template, indent=2) with open(cfn_output_path, "w") as f: f.write(cloud_formation_template_prettified) print("Wrote transformed CloudFormation template to: " + cfn_output_path) except InvalidDocumentException as e: error_message = reduce( lambda message, error: message + " " + error.message, e.causes, e.message) LOG.error(error_message) errors = map(lambda cause: cause.message, e.causes) LOG.error(errors)
def test_transform_success(self, testcase, partition_with_region): partition = partition_with_region[0] region = partition_with_region[1] manifest = yaml_parse(open(os.path.join(input_folder, testcase + '.yaml'), 'r')) # To uncover unicode-related bugs, convert dict to JSON string and parse JSON back to dict manifest = json.loads(json.dumps(manifest)) partition_folder = partition if partition != "aws" else "" expected = json.load(open(os.path.join(output_folder,partition_folder, testcase + '.json'), 'r')) old_region = os.environ.get("AWS_DEFAULT_REGION", "") os.environ["AWS_DEFAULT_REGION"] = region try: parameter_values = get_template_parameter_values() mock_policy_loader = MagicMock() mock_policy_loader.load.return_value = { 'AWSLambdaBasicExecutionRole': 'arn:{}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'.format(partition), 'AmazonDynamoDBFullAccess': 'arn:{}:iam::aws:policy/AmazonDynamoDBFullAccess'.format(partition), 'AmazonDynamoDBReadOnlyAccess': 'arn:{}:iam::aws:policy/AmazonDynamoDBReadOnlyAccess'.format(partition), 'AWSLambdaRole': 'arn:{}:iam::aws:policy/service-role/AWSLambdaRole'.format(partition), } output_fragment = transform( manifest, parameter_values, mock_policy_loader) finally: os.environ["AWS_DEFAULT_REGION"] = old_region print json.dumps(output_fragment, indent=2) assert deep_sorted(output_fragment) == deep_sorted(expected)
def transform_template(input_file_path, output_file_path): with open(input_file_path, "r") as f: sam_template = yaml_parse(f) try: feature_toggle = FeatureToggle( FeatureToggleLocalConfigProvider( os.path.join(my_path, "..", "tests", "feature_toggle", "input", "feature_toggle_config.json"))) cloud_formation_template = transform(sam_template, {}, ManagedPolicyLoader(iam_client), feature_toggle) cloud_formation_template_prettified = json.dumps( cloud_formation_template, indent=2) with open(output_file_path, "w") as f: f.write(cloud_formation_template_prettified) print("Wrote transformed CloudFormation template to: " + output_file_path) except InvalidDocumentException as e: errorMessage = reduce( lambda message, error: message + " " + error.message, e.causes, e.message) LOG.error(errorMessage) errors = map(lambda cause: cause.message, e.causes) LOG.error(errors)
def _do_transform(self, document, parameter_values=get_template_parameter_values()): mock_policy_loader = get_policy_mock() output_fragment = transform(document, parameter_values, mock_policy_loader) print json.dumps(output_fragment, indent=2) return output_fragment
def _do_transform(self, document, parameter_values=get_template_parameter_values()): mock_policy_loader = get_policy_mock() output_fragment = transform(document, parameter_values, mock_policy_loader) print(json.dumps(output_fragment, indent=2)) return output_fragment
def test_transform_success_resource_policy(self, testcase, partition_with_region): partition = partition_with_region[0] region = partition_with_region[1] manifest = yaml_parse(open(os.path.join(INPUT_FOLDER, testcase + ".yaml"), "r")) # To uncover unicode-related bugs, convert dict to JSON string and parse JSON back to dict manifest = json.loads(json.dumps(manifest)) partition_folder = partition if partition != "aws" else "" expected_filepath = os.path.join(OUTPUT_FOLDER, partition_folder, testcase + ".json") expected = json.load(open(expected_filepath, "r")) with patch("boto3.session.Session.region_name", region): parameter_values = get_template_parameter_values() mock_policy_loader = MagicMock() mock_policy_loader.load.return_value = { "AWSLambdaBasicExecutionRole": "arn:{}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole".format( partition ), "AmazonDynamoDBFullAccess": "arn:{}:iam::aws:policy/AmazonDynamoDBFullAccess".format(partition), "AmazonDynamoDBReadOnlyAccess": "arn:{}:iam::aws:policy/AmazonDynamoDBReadOnlyAccess".format(partition), "AWSLambdaRole": "arn:{}:iam::aws:policy/service-role/AWSLambdaRole".format(partition), } output_fragment = transform(manifest, parameter_values, mock_policy_loader) print(json.dumps(output_fragment, indent=2)) # Only update the deployment Logical Id hash in Py3. if sys.version_info.major >= 3: self._update_logical_id_hash(expected) self._update_logical_id_hash(output_fragment) assert deep_sort_lists(output_fragment) == deep_sort_lists(expected)
def translate_and_find_deployment_ids(manifest): parameter_values = get_template_parameter_values() output_fragment = transform(manifest, parameter_values, mock_policy_loader) print(json.dumps(output_fragment, indent=2)) deployment_ids = set() for key, value in output_fragment["Resources"].items(): if value["Type"] == "AWS::ApiGateway::Deployment": deployment_ids.add(key) return deployment_ids
def test_swagger_body_sha_gets_recomputed(): document = { 'Transform': 'AWS::Serverless-2016-10-31', 'Resources': { 'Resource': { 'Type': 'AWS::Serverless::Api', 'Properties': { "StageName": "Prod", "DefinitionBody": { # Some body property will do "a": "b" } } } } } mock_policy_loader = get_policy_mock() parameter_values = get_template_parameter_values() output_fragment = transform(document, parameter_values, mock_policy_loader) print json.dumps(output_fragment, indent=2) deployment_key = get_deployment_key(output_fragment) assert deployment_key # Now let's change the Body property and transform again document["Resources"]["Resource"]["Properties"]["DefinitionBody"]["a"] = "foo" output_fragment = transform(document, parameter_values, mock_policy_loader) deployment_key_changed = get_deployment_key(output_fragment) assert deployment_key_changed assert deployment_key != deployment_key_changed # Now let's re-deploy the document without any changes. Deployment Key must NOT change output_fragment = transform(document, parameter_values, mock_policy_loader) assert get_deployment_key(output_fragment) == deployment_key_changed
def test_swagger_body_sha_gets_recomputed(): document = { 'Transform': 'AWS::Serverless-2016-10-31', 'Resources': { 'Resource': { 'Type': 'AWS::Serverless::Api', 'Properties': { "StageName": "Prod", "DefinitionBody": { # Some body property will do "a": "b" } } } } } mock_policy_loader = get_policy_mock() parameter_values = get_template_parameter_values() output_fragment = transform(document, parameter_values, mock_policy_loader) print(json.dumps(output_fragment, indent=2)) deployment_key = get_deployment_key(output_fragment) assert deployment_key # Now let's change the Body property and transform again document["Resources"]["Resource"]["Properties"]["DefinitionBody"]["a"] = "foo" output_fragment = transform(document, parameter_values, mock_policy_loader) deployment_key_changed = get_deployment_key(output_fragment) assert deployment_key_changed assert deployment_key != deployment_key_changed # Now let's re-deploy the document without any changes. Deployment Key must NOT change output_fragment = transform(document, parameter_values, mock_policy_loader) assert get_deployment_key(output_fragment) == deployment_key_changed
def test_transform_success_openapi3(self, testcase, partition_with_region): partition = partition_with_region[0] region = partition_with_region[1] manifest = yaml_parse(open(os.path.join(INPUT_FOLDER, testcase + '.yaml'), 'r')) # To uncover unicode-related bugs, convert dict to JSON string and parse JSON back to dict manifest = json.loads(json.dumps(manifest)) partition_folder = partition if partition != "aws" else "" expected_filepath = os.path.join(OUTPUT_FOLDER, partition_folder, testcase + '.json') expected = json.load(open(expected_filepath, 'r')) with patch('boto3.session.Session.region_name', region): parameter_values = get_template_parameter_values() mock_policy_loader = MagicMock() mock_policy_loader.load.return_value = { 'AWSLambdaBasicExecutionRole': 'arn:{}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole'.format(partition), 'AmazonDynamoDBFullAccess': 'arn:{}:iam::aws:policy/AmazonDynamoDBFullAccess'.format(partition), 'AmazonDynamoDBReadOnlyAccess': 'arn:{}:iam::aws:policy/AmazonDynamoDBReadOnlyAccess'.format(partition), 'AWSLambdaRole': 'arn:{}:iam::aws:policy/service-role/AWSLambdaRole'.format(partition), } output_fragment = transform( manifest, parameter_values, mock_policy_loader) print(json.dumps(output_fragment, indent=2)) # Run cfn-lint on translator test output files. rules = cfnlint.core.get_rules([], LINT_IGNORE_WARNINGS, []) # Only update the deployment Logical Id hash in Py3. if sys.version_info.major >= 3: self._update_logical_id_hash(expected) self._update_logical_id_hash(output_fragment) output_template = cfnlint.decode.cfn_json.load(expected_filepath) else: # deprecation warning catching in py2 import warnings with warnings.catch_warnings(): warnings.filterwarnings("ignore",category=DeprecationWarning) output_template = cfnlint.decode.cfn_json.load(expected_filepath) runner = cfnlint.Runner(rules, expected_filepath, output_template, [region]) matches = [] # Only run linter on normal/gov partitions. It errors on china regions if testcase not in LINT_IGNORE_TESTS and partition != 'aws-cn': matches = runner.run() print('cfn-lint ({}): {}'.format(expected_filepath, matches)) assert deep_sort_lists(output_fragment) == deep_sort_lists(expected) assert len(matches) == 0
def main(): input_file_path, output_file_path = parse_arguments() with open(input_file_path) as f: sam_template = yaml_parse(f) iam = boto3.client('iam') cloudformation_template = transform(sam_template, {}, ManagedPolicyLoader(iam)) with open(output_file_path, 'w') as f: f.write(json.dumps(cloudformation_template, indent=2)) print(f'Wrote transformed Cloudformation template to {output_file_path}')
def main(): input_file_path, output_file_path = get_input_output_file_paths() with open(input_file_path, 'r') as f: sam_template = yaml_parse(f) cloud_formation_template = transform(sam_template, {}, ManagedPolicyLoader(iam_client)) cloud_formation_template_prettified = json.dumps(cloud_formation_template, indent=2) with open(output_file_path, 'w') as f: f.write(cloud_formation_template_prettified) print('Wrote transformed CloudFormation template to: ' + output_file_path)
def _normalize_template_format(self, template_data): """ Normalize the template data as SAM or CloudFormation depending on config. :param template_data: the template data to convert from SAM if convert_sam_to_cfn is enabled :return: the normalized template data """ if self.convert_sam_to_cfn and template_data.get('Transform') \ == 'AWS::Serverless-2016-10-31': # Make a deep copy of the dict that's mutable (ODict, the type that cfn_flip # uses internally, overrides items() to return a new list each time, which foils # the transformer). template_data = copy_dict(template_data, impl=OrderedDict) return transform(template_data, {}, self.managed_policy_loader) else: return template_data
def transform_template(input_file_path, output_file_path): with open(input_file_path, "r") as f: sam_template = yaml_parse(f) try: cloud_formation_template = transform(sam_template, {}, ManagedPolicyLoader(iam_client)) cloud_formation_template_prettified = json.dumps(cloud_formation_template, indent=2) with open(output_file_path, "w") as f: f.write(cloud_formation_template_prettified) print ("Wrote transformed CloudFormation template to: " + output_file_path) except InvalidDocumentException as e: errorMessage = reduce(lambda message, error: message + " " + error.message, e.causes, e.message) LOG.error(errorMessage) errors = map(lambda cause: cause.message, e.causes) LOG.error(errors)
def transform_template(input_file_path, output_file_path): with open(input_file_path, 'r') as f: sam_template = yaml_parse(f) try: cloud_formation_template = transform( sam_template, {}, ManagedPolicyLoader(iam_client)) cloud_formation_template_prettified = json.dumps( cloud_formation_template, indent=2) with open(output_file_path, 'w') as f: f.write(cloud_formation_template_prettified) print('Wrote transformed CloudFormation template to: ' + output_file_path) except InvalidDocumentException as e: errorMessage = reduce(lambda message, error: message + ' ' + error.message, e.causes, e.message) LOG.error(errorMessage) errors = map(lambda cause: cause.message, e.causes) LOG.error(errors)
def apply_sam_translate(template_string, logger): iam = boto3.client("iam") template = yaml.load(template_string, Loader=yaml.FullLoader) template = transform(template, {}, ManagedPolicyLoader(iam)) return yaml.dump(template)
#!/usr/bin/env python """Script to convert AWS SAM templates to AWS CloudFormation templates. Expects SAM template on stdin and prints out CloudFormation template on stdout. """ import sys import boto3 import yaml from cfn_tools import dump_yaml from samtranslator.public.translator import ManagedPolicyLoader from samtranslator.translator.transform import transform input_fragment = yaml.load(sys.stdin.read()) iam_client = boto3.client('iam') transformed = transform(input_fragment, {}, ManagedPolicyLoader(iam_client)) print(dump_yaml(transformed))