def test_transform_template_raises_exception_on_embedded_reference(self): template_dict = { 'Resources': {'key1': {"foo": ["|foo|foo", "b"]}} } with self.assertRaises(TemplateErrorException): CloudFormationTemplateTransformer.transform_template(CloudFormationTemplate(template_dict, 'foo'))
def test_transform_template_raises_exception_on_embedded_reference(self): template_dict = { "Resources": {"key1": {"foo": ["|foo|foo", "b"]}} } with self.assertRaises(TemplateErrorException): CloudFormationTemplateTransformer.transform_template(CloudFormationTemplate(template_dict, "foo"))
def test_transform_template_raises_exception_on_unknown_at_reference_key(self): template_dict = { 'Resources': {'@foo@': "foo"} } with self.assertRaises(TemplateErrorException): CloudFormationTemplateTransformer.transform_template(CloudFormationTemplate(template_dict, 'foo'))
def test_transform_template_raises_exception_on_unknown_reference_key(self): template_dict = { "Resources": {"|key|": "foo"} } with self.assertRaises(TemplateErrorException): CloudFormationTemplateTransformer.transform_template(CloudFormationTemplate(template_dict, "foo"))
def test_transform_template_raises_exception_on_unknown_at_reference_key( self): template_dict = {'Resources': {'@foo@': "foo"}} with self.assertRaises(TemplateErrorException): CloudFormationTemplateTransformer.transform_template( CloudFormationTemplate(template_dict, 'foo'))
def test_transform_dict_to_yaml_lines(self): input = { "docker-compose": { "version": "2", "services": { "grafana": { "environment": { "GF_SECURITY_ADMIN_PASSWORD": { "Ref": "grafanaAdminPassword" } }, "ports": ["3000:3000"], "restart": "always" } } } } expected = [ "docker-compose:", " services:", " grafana:", " environment:", " GF_SECURITY_ADMIN_PASSWORD:"******"Fn::Join": ["", [" ", { "Ref": "grafanaAdminPassword" }]] }, " ports:", " - '3000:3000'", " restart: 'always'", " version: '2'" ] result = CloudFormationTemplateTransformer.transform_dict_to_yaml_lines_list( input) print(json.dumps(result, indent=4)) self.assertEqual(expected, result)
def test_transform_include_key_creates_valid_include(self): result = CloudFormationTemplateTransformer.transform_include_key( "|include|", "s3://myBucket/myTemplate.json") self.assertEqual(("Fn::Transform", { "Name": "AWS::Include", "Location": "s3://myBucket/myTemplate.json" }), result)
def render_template(filename): check_update_available() loader = FileLoader() template = loader.get_file_from_url(filename, None) template = CloudFormationTemplateTransformer.transform_template(template) click.echo(template.get_template_json())
def test_transform_template_properly_handles_reference_in_list_of_lists(self): template_dict = { "Resources": { "myResource": { "Properties": { "PolicyDocument": { "Statement": [{ "Resource": { "Fn::Join": [ "", [ "a", "|Ref|b", "c" ] ] } }] } } } } } result = CloudFormationTemplateTransformer.transform_template(CloudFormationTemplate(template_dict, "foo")) expected = {"myResource": {"Properties": { "PolicyDocument": {"Statement": [{"Resource": {"Fn::Join": ["", ["a", {"Ref": "b"}, "c"]]}}]}}}} self.assertEqual(expected, result.resources)
def test_transform_template_properly_handles_reference_in_list_of_lists(self): template_dict = { 'Resources': { 'myResource': { "Properties": { "PolicyDocument": { "Statement": [{ "Resource": { "Fn::Join": [ "", [ "a", "|Ref|b", "c" ] ] } }] } } } } } result = CloudFormationTemplateTransformer.transform_template(CloudFormationTemplate(template_dict, 'foo')) expected = {'myResource': {'Properties': { 'PolicyDocument': {'Statement': [{'Resource': {'Fn::Join': ['', ['a', {'Ref': 'b'}, 'c']]}}]}}}} self.assertEqual(expected, result.resources)
def test_transform_dict(self): input = { "a": { "baa": { "key": "value" } }, "b": [{ "c": "d" }, "e", 2, [1, 2, { "Ref": "Foo" }]] } expected = [ "a:", " baa:", " key: 'value'", "b:", " - c: 'd'", " - 'e'", " - 2", " -", " - 1", " - 2", { "Fn::Join": ["", [" - ", { "Ref": "Foo" }]] } ] result = CloudFormationTemplateTransformer._transform_dict(input) print(json.dumps(result, indent=4)) self.assertEqual(expected, result)
def test_transform_dict_to_yaml_lines_list_returns_stable_order(self): input = { 'd': 'd', 'a': 'a', 'e': 'e', 'b': { 'f': 'f', 'c': 'c', 'a': 'a' }, "#": "3" } expected = [{ 'Fn::Join': [': ', ['#', '3']] }, { 'Fn::Join': [': ', ['a', 'a']] }, 'b:', { 'Fn::Join': [': ', [' a', 'a']] }, { 'Fn::Join': [': ', [' c', 'c']] }, { 'Fn::Join': [': ', [' f', 'f']] }, { 'Fn::Join': [': ', ['d', 'd']] }, { 'Fn::Join': [': ', ['e', 'e']] }] result = CloudFormationTemplateTransformer.transform_dict_to_yaml_lines_list( input) self.assertEqual(expected, result)
def test_transform_dict_to_yaml_lines_list_accepts_joins(self): input = { "source": {"Fn::Join": [":", ["my-registry/my-app", {"Ref": "appVersion"}]]} } expected = [ { "Fn::Join": [ ": ", [ "source", { "Fn::Join": [ ":", [ "my-registry/my-app", { "Ref": "appVersion" } ] ] } ] ] } ] result = CloudFormationTemplateTransformer.transform_dict_to_yaml_lines_list(input) self.assertEqual(expected, result)
def create_or_update_stacks(self): existing_stacks = self.cfn.get_stack_names() desired_stacks = self.config.stacks stack_processing_order = DependencyResolver().get_stack_order(desired_stacks) if len(stack_processing_order) > 1: self.logger.info( "Will process stacks in the following order: {0}".format(", ".join(stack_processing_order))) for stack_name in stack_processing_order: stack_config = self.config.stacks.get(stack_name) raw_template = FileLoader.get_file_from_url(stack_config.template_url, stack_config.working_dir) template = CloudFormationTemplateTransformer.transform_template(raw_template) combined_tags = dict(self.config.tags) combined_tags.update(stack_config.tags) parameters = self.parameter_resolver.resolve_parameter_values(stack_config.parameters, stack_name) stack = CloudFormationStack(template=template, parameters=parameters, tags=combined_tags, name=stack_name, region=self.config.region, timeout=stack_config.timeout) if stack_name in existing_stacks: self.cfn.validate_stack_is_ready_for_action(stack) self.cfn.update_stack(stack) else: self.cfn.create_stack(stack) CustomResourceHandler.process_post_resources(stack)
def test_transform_taupage_user_data_key(self): input = { "application_id": "stackName", "application_version": "imageVersion", "environment": { "SSO_KEY": "mySsoKey", "QUEUE_URL": {"ref": "myQueueUrl"} } } expected = {'Fn::Base64': { 'Fn::Join': ['\n', ['#taupage-ami-config', {'Fn::Join': [': ', ['application_id', 'stackName']]}, {'Fn::Join': [': ', ['application_version', 'imageVersion']]}, 'environment:', {'Fn::Join': [': ', [' QUEUE_URL', {'ref': 'myQueueUrl'}]]}, {'Fn::Join': [': ', [' SSO_KEY', 'mySsoKey']]}] ] } } key, value = CloudFormationTemplateTransformer.transform_taupage_user_data_key('@taupageUserData@', input) self.assertEqual("UserData", key) self.assertEqual(expected, value)
def upload_cfn_to_s3(project, logger): """ This task is separate since they only work with Python2 >2.6 by the time being. Python3 support is underway. This means, when using Python<2.7, this task is not visible (see __init__.py). """ from cfn_sphere.file_loader import FileLoader from cfn_sphere.template.transformer import CloudFormationTemplateTransformer for path, filename in project.get_property('template_files'): template = FileLoader.get_file_from_url(filename, path) transformed = CloudFormationTemplateTransformer.transform_template( template) output = transformed.get_template_json() bucket_name = project.get_property('bucket_name') key_prefix = project.get_property('template_key_prefix') filename = filename.replace('.yml', '.json') filename = filename.replace('.yaml', '.json') version_path = '{0}v{1}/{2}'.format( key_prefix, project.version, filename) # latest_path = '{0}latest/{1}'.format(key_prefix, filename) acl = project.get_property('template_file_access_control') check_acl_parameter_validity('template_file_access_control', acl) upload_helper(logger, bucket_name, version_path, output, acl)
def test_transform_dict_to_yaml_lines_list_accepts_joins(self): input = { "source": { "Fn::Join": [":", ["my-registry/my-app", { "Ref": "appVersion" }]] } } expected = [{ "Fn::Join": [ ": ", [ "source", { "Fn::Join": [":", ["my-registry/my-app", { "Ref": "appVersion" }]] } ] ] }] result = CloudFormationTemplateTransformer.transform_dict_to_yaml_lines_list( input) self.assertEqual(expected, result)
def test_transform_template_transforms_dict_list_items(self): template_dict = { 'Resources': { 'key1': { 'key2': [{ 'key3': 'value3', 'foo': { '|Join|': ['a', 'b'] } }] } } } result = CloudFormationTemplateTransformer.transform_template( CloudFormationTemplate(template_dict, 'foo')) expected = { 'key1': { 'key2': [{ 'foo': { 'Fn::Join': ['', ['a', 'b']] }, 'key3': 'value3' }] } } self.assertEqual(expected, result.resources)
def test_transform_dict_to_yaml_lines_list_returns_stable_order(self): input = { "d": "d", "a": "a", "e": "e", "b": { "f": "f", "c": "c", "a": "a" }, "#": "3" } expected = [{ "Fn::Join": [": ", ["#", "3"]] }, { "Fn::Join": [": ", ["a", "a"]] }, "b:", { "Fn::Join": [": ", [" a", "a"]] }, { "Fn::Join": [": ", [" c", "c"]] }, { "Fn::Join": [": ", [" f", "f"]] }, { "Fn::Join": [": ", ["d", "d"]] }, { "Fn::Join": [": ", ["e", "e"]] }] result = CloudFormationTemplateTransformer.transform_dict_to_yaml_lines_list( input) self.assertEqual(expected, result)
def upload_cfn_to_s3(project, logger): """ This task is separate since they only work with Python2 >2.6 by the time being. Python3 support is underway. This means, when using Python<2.7, this task is not visible (see __init__.py). """ from cfn_sphere.file_loader import FileLoader from cfn_sphere.template.transformer import CloudFormationTemplateTransformer for path, filename in project.get_property('template_files'): template = FileLoader.get_cloudformation_template(filename, path) transformed = CloudFormationTemplateTransformer.transform_template( template) output = transformed.get_template_json() bucket_name = project.get_property('bucket_name') key_prefix = project.get_property('template_key_prefix') filename = filename.replace('.yml', '.json') filename = filename.replace('.yaml', '.json') version_path = '{0}v{1}/{2}'.format(key_prefix, project.version, filename) # latest_path = '{0}latest/{1}'.format(key_prefix, filename) acl = project.get_property('template_file_access_control') check_acl_parameter_validity('template_file_access_control', acl) upload_helper(logger, bucket_name, version_path, output, acl)
def test_transform_template_transforms_dict_list_items(self): template_dict = { "Resources": { "key1": { "key2": [{ "key3": "value3", "foo": { "|Join|": ["a", "b"] } }] } } } result = CloudFormationTemplateTransformer.transform_template( CloudFormationTemplate(template_dict, "foo")) expected = { "key1": { "key2": [{ "foo": { "Fn::Join": ["", ["a", "b"]] }, "key3": "value3" }] } } self.assertEqual(expected, result.resources)
def test_transform_dict_with_ref_in_nested_list(self): input = { "key": ["a", "b", ["a", {"Ref": "Foo"}]] } expected = [ "key:", " - 'a'", " - 'b'", " -", " - 'a'", { "Fn::Join": [ "", [ " - ", { "Ref": "Foo" } ] ] } ] result = CloudFormationTemplateTransformer._transform_dict(input) self.assertEqual(expected, result)
def test_transform_include_key_creates_valid_include(self): result = CloudFormationTemplateTransformer.transform_include_key( '|include|', 's3://myBucket/myTemplate.json') self.assertEqual(('Fn::Transform', { 'Name': 'AWS::Include', 'Location': 's3://myBucket/myTemplate.json' }), result)
def test_transform_template_transforms_list_values(self): template_dict = {'Resources': {'key1': ["|ref|foo", "a", "b"]}} result = CloudFormationTemplateTransformer.transform_template( CloudFormationTemplate(template_dict, 'foo')) expected = {'key1': [{'Ref': 'foo'}, 'a', 'b']} self.assertEqual(expected, result.resources)
def render_template(template_file, confirm): if not confirm: check_update_available() loader = FileLoader() template = loader.get_file_from_url(template_file, None) template = CloudFormationTemplateTransformer.transform_template(template) click.echo(template.get_pretty_template_json())
def test_transform_template_transforms_join_with_embedded_ref(self): template_dict = {'Resources': {'key1': {"|join|.": ["|ref|foo", "b"]}}} result = CloudFormationTemplateTransformer.transform_template( CloudFormationTemplate(template_dict, 'foo')) expected = {'key1': {'Fn::Join': ['.', [{'Ref': 'foo'}, 'b']]}} self.assertEqual(expected, result.resources)
def test_transform_template_transforms_join_with_embedded_ref(self): template_dict = {"Resources": {"key1": {"|join|.": ["|ref|foo", "b"]}}} result = CloudFormationTemplateTransformer.transform_template( CloudFormationTemplate(template_dict, "foo")) expected = {"key1": {"Fn::Join": [".", [{"Ref": "foo"}, "b"]]}} self.assertEqual(expected, result.resources)
def test_extend_stack_description_limits_length(self): additional_description = "my-additional-description" expected_result = DESCRIPTION_1000_CHARS[:996] + " | " + additional_description result = CloudFormationTemplateTransformer.extend_stack_description( DESCRIPTION_1000_CHARS, additional_description) self.assertEqual(expected_result, result) self.assertEqual(1024, len(result))
def test_transform_template_transforms_list_values(self): template_dict = {"Resources": {"key1": ["|ref|foo", "a", "b"]}} result = CloudFormationTemplateTransformer.transform_template( CloudFormationTemplate(template_dict, "foo")) expected = {"key1": [{"Ref": "foo"}, "a", "b"]} self.assertEqual(expected, result.resources)
def test_transform_dict_to_yaml_lines_preserves_boolean_values(self): input = {"a": True} expected = ["a: True"] result = CloudFormationTemplateTransformer.transform_dict_to_yaml_lines_list( input) print(json.dumps(result, indent=4)) self.assertEqual(expected, result)
def test_transform_dict_to_yaml_lines_list_accepts_int_key_value(self): input = {'ports': {8080: 9000}} result = CloudFormationTemplateTransformer.transform_dict_to_yaml_lines_list( input) expected = ["ports:", {"Fn::Join": [": ", [" 8080", 9000]]}] self.assertEqual(expected, result)
def test_extend_stack_description_limits_length(self): additional_description = "my-additional-description" expected_result = DESCRIPTION_1000_CHARS[:996] + " | " + additional_description result = CloudFormationTemplateTransformer.extend_stack_description(DESCRIPTION_1000_CHARS, additional_description) self.assertEqual(expected_result, result) self.assertEqual(1024, len(result))
def render_template(template_file, confirm, yes): confirm = confirm or yes if not confirm: check_update_available() loader = FileLoader() template = loader.get_cloudformation_template(template_file, None) template = CloudFormationTemplateTransformer.transform_template(template) click.echo(template.get_pretty_template_json())
def test_transform_template_transforms_references_in_conditions_section(self): template_dict = { "Conditions": {"key1": ["|ref|foo", "a", "b"], "key2": "|Ref|baa"} } result = CloudFormationTemplateTransformer.transform_template(CloudFormationTemplate(template_dict, "foo")) expected = {"key1": [{"Ref": "foo"}, "a", "b"], "key2": {"Ref": "baa"}} self.assertEqual(expected, result.conditions)
def test_extend_stack_description_does_not_cut_description(self): description = DESCRIPTION_1000_CHARS[:996] additional_description = "my-additional-description" expected_result = description + " | " + additional_description result = CloudFormationTemplateTransformer.extend_stack_description(description, additional_description) self.assertEqual(expected_result, result) self.assertEqual(1024, len(result))
def test_transform_dict_to_yaml_lines_list_accepts_multiple_sub_dicts( self): input = {"foo": {"baa": {"key": "value"}}} expected = ["foo:", " baa:", " key: 'value'"] result = CloudFormationTemplateTransformer.transform_dict_to_yaml_lines_list( input) print(json.dumps(result, indent=4)) self.assertEqual(expected, result)
def render_template(template_file, confirm, yes): confirm = confirm or yes if not confirm: check_update_available() loader = FileLoader() template = loader.get_cloudformation_template(template_file, None) template = CloudFormationTemplateTransformer.transform_template(template) click.echo(template.get_pretty_template_json())
def test_transform_template_transforms_join_with_embedded_ref(self): template_dict = { 'Resources': {'key1': {"|join|.": ["|ref|foo", "b"]}} } result = CloudFormationTemplateTransformer.transform_template(CloudFormationTemplate(template_dict, 'foo')) expected = {'key1': {'Fn::Join': ['.', [{'Ref': 'foo'}, 'b']]}} self.assertEqual(expected, result.resources)
def test_transform_template_transforms_dict_list_items(self): template_dict = { 'Resources': {'key1': {'key2': [{'key3': 'value3', 'foo': {'|Join|': ['a', 'b']}}]}} } result = CloudFormationTemplateTransformer.transform_template(CloudFormationTemplate(template_dict, 'foo')) expected = {'key1': {'key2': [{'foo': {'Fn::Join': ['', ['a', 'b']]}, 'key3': 'value3'}]}} self.assertEqual(expected, result.resources)
def test_transform_template_transforms_list_values(self): template_dict = { 'Resources': {'key1': ["|ref|foo", "a", "b"]} } result = CloudFormationTemplateTransformer.transform_template(CloudFormationTemplate(template_dict, 'foo')) expected = {'key1': [{'Ref': 'foo'}, 'a', 'b']} self.assertEqual(expected, result.resources)
def test_transform_template_transforms_references_in_conditions_section(self): template_dict = { 'Conditions': {'key1': ["|ref|foo", "a", "b"], "key2": "|Ref|baa"} } result = CloudFormationTemplateTransformer.transform_template(CloudFormationTemplate(template_dict, 'foo')) expected = {'key1': [{'Ref': 'foo'}, 'a', 'b'], 'key2': {'Ref': 'baa'}} self.assertEqual(expected, result.conditions)
def test_scan_dict_values_executes_value_handler_for_all_matching_prefixes(self): dictionary = {'a': 'foo123', 'b': {'c': 'foo234'}} handler = Mock() handler.return_value = "foo" result = CloudFormationTemplateTransformer.scan_dict_values(dictionary, handler) expected_calls = [mock.call('foo123'), mock.call('foo234')] six.assertCountEqual(self, expected_calls, handler.mock_calls) six.assertCountEqual(self, result, {'a': 'foo', 'b': {'c': 'foo'}})
def test_transform_dict_to_yaml_lines_list_indents_sub_dicts(self): result = CloudFormationTemplateTransformer.transform_dict_to_yaml_lines_list( {'my-key': { 'my-sub-key': 'value' }}) self.assertEqual( ['my-key:', { 'Fn::Join': [': ', [' my-sub-key', 'value']] }], result)
def test_extend_stack_description_does_not_cut_description(self): description = DESCRIPTION_1000_CHARS[:996] additional_description = "my-additional-description" expected_result = description + " | " + additional_description result = CloudFormationTemplateTransformer.extend_stack_description( description, additional_description) self.assertEqual(expected_result, result) self.assertEqual(1024, len(result))
def test_transform_dict_to_yaml_lines_list_accepts_int_key_value(self): input = {'ports': {8080: 9000}} result = CloudFormationTemplateTransformer.transform_dict_to_yaml_lines_list(input) expected = [ "ports:", {"Fn::Join": [": ", [" 8080", 9000]]} ] self.assertEqual(expected, result)
def test_scan_executes_key_handler_for_all_matching_keys(self): dictionary = {"|key|": "value"} handler = Mock() handler.return_value = "new-key", "new-value" result = CloudFormationTemplateTransformer.scan(dictionary, [handler], []) expected_calls = [mock.call("|key|", "value")] self.assertEqual(expected_calls, handler.mock_calls) self.assertEqual(result, {"new-key": "new-value"})
def test_scan_executes_value_handler_for_all_matching_prefixes(self): dictionary = {"a": "foo123", "b": {"c": "foo234"}} handler = Mock() handler.return_value = "foo" result = CloudFormationTemplateTransformer.scan(dictionary, [], [handler]) expected_calls = [mock.call("foo123"), mock.call("foo234")] self.assertEqual(sorted(expected_calls), sorted(handler.mock_calls)) self.assertEqual(result, {"a": "foo", "b": {"c": "foo"}})
def test_scan_executes_key_handler_for_all_matching_keys(self): dictionary = {'|key|': 'value'} handler = Mock() handler.return_value = 'new-key', 'new-value' result = CloudFormationTemplateTransformer.scan(dictionary, [handler], []) expected_calls = [mock.call('|key|', 'value')] self.assertEqual(expected_calls, handler.mock_calls) self.assertEqual(result, {'new-key': 'new-value'})
def test_scan_dict_keys_executes_key_handler_for_all_matching_keys(self): dictionary = {'key': 'value'} handler = Mock() handler.return_value = 'new-key', 'new-value' result = CloudFormationTemplateTransformer.scan_dict_keys(dictionary, handler) expected_calls = [mock.call('key', 'value')] six.assertCountEqual(self, expected_calls, handler.mock_calls) self.assertDictEqual(result, {'new-key': 'new-value'})
def test_scan_executes_value_handler_for_all_matching_prefixes(self): dictionary = {'a': 'foo123', 'b': {'c': 'foo234'}} handler = Mock() handler.return_value = "foo" result = CloudFormationTemplateTransformer.scan(dictionary, [], [handler]) expected_calls = [mock.call('foo123'), mock.call('foo234')] self.assertEqual(sorted(expected_calls), sorted(handler.mock_calls)) self.assertEqual(result, {'a': 'foo', 'b': {'c': 'foo'}})
def test_scan_executes_value_handler_for_all_matching_prefixes(self): dictionary = {'a': 'foo123', 'b': {'c': 'foo234'}} handler = Mock() handler.return_value = "foo" result = CloudFormationTemplateTransformer.scan( dictionary, [], [handler]) expected_calls = [mock.call('foo123'), mock.call('foo234')] self.assertEqual(sorted(expected_calls), sorted(handler.mock_calls)) self.assertEqual(result, {'a': 'foo', 'b': {'c': 'foo'}})
def test_transform_dict_to_yaml_lines_list_returns_stable_order(self): input = {'d': 'd', 'a': 'a', 'e': 'e', 'b': {'f': 'f', 'c': 'c', 'a': 'a'}, "#": "3"} expected = [{'Fn::Join': [': ', ['#', '3']]}, {'Fn::Join': [': ', ['a', 'a']]}, 'b:', {'Fn::Join': [': ', [' a', 'a']]}, {'Fn::Join': [': ', [' c', 'c']]}, {'Fn::Join': [': ', [' f', 'f']]}, {'Fn::Join': [': ', ['d', 'd']]}, {'Fn::Join': [': ', ['e', 'e']]}] result = CloudFormationTemplateTransformer.transform_dict_to_yaml_lines_list(input) self.assertEqual(expected, result)
def test_transform_dict_to_yaml_lines_list_accepts_multiple_sub_dicts(self): input = { "foo": { 'baa': {'key': 'value'} } } expected = [ 'foo:', ' baa:', {'Fn::Join': [': ', [' key', 'value']]} ] result = CloudFormationTemplateTransformer.transform_dict_to_yaml_lines_list(input) self.assertEqual(expected, result)
def create_or_update_stacks(self): existing_stacks = self.cfn.get_stack_names() desired_stacks = self.config.stacks stack_processing_order = DependencyResolver().get_stack_order(desired_stacks) if len(stack_processing_order) > 1: self.logger.info( "Will process stacks in the following order: {0}".format(", ".join(stack_processing_order))) for stack_name in stack_processing_order: stack_config = self.config.stacks.get(stack_name) template = FileLoader.get_cloudformation_template(stack_config.template_url,stack_config.working_dir) transformed_template = CloudFormationTemplateTransformer.transform_template(template) if stack_config.stack_policy_url: self.logger.info("Using stack policy from {0}".format(stack_config.stack_policy_url)) stack_policy = FileLoader.get_yaml_or_json_file(stack_config.stack_policy_url, stack_config.working_dir) else: stack_policy = None parameters = self.parameter_resolver.resolve_parameter_values(stack_name, stack_config) merged_parameters = self.parameter_resolver.update_parameters_with_cli_parameters( parameters=parameters, cli_parameters=self.cli_parameters, stack_name=stack_name) self.logger.debug("Parameters after merging with cli options: {0}".format(merged_parameters)) stack = CloudFormationStack(template=transformed_template, parameters=merged_parameters, tags=stack_config.tags, name=stack_name, region=self.config.region, timeout=stack_config.timeout, service_role=stack_config.service_role, stack_policy=stack_policy) if stack_name in existing_stacks: self.cfn.validate_stack_is_ready_for_action(stack) self.cfn.update_stack(stack) else: self.cfn.create_stack(stack) CustomResourceHandler.process_post_resources(stack)
def validate_template(template_file, confirm): if not confirm: check_update_available() try: loader = FileLoader() template = loader.get_file_from_url(template_file, None) template = CloudFormationTemplateTransformer.transform_template(template) CloudFormation().validate_template(template) click.echo("Template is valid") except CfnSphereException as e: LOGGER.error(e) sys.exit(1) except Exception as e: LOGGER.error("Failed with unexpected error") LOGGER.exception(e) LOGGER.info("Please report at https://github.com/cfn-sphere/cfn-sphere/issues!") sys.exit(1)
def test_transform_dict_to_yaml_lines_list_indents_sub_dicts(self): result = CloudFormationTemplateTransformer.transform_dict_to_yaml_lines_list( {'my-key': {'my-sub-key': 'value'}}) self.assertEqual(['my-key:', {'Fn::Join': [': ', [' my-sub-key', 'value']]}], result)
def test_transform_dict_to_yaml_lines_list_accepts_list_values(self): result = CloudFormationTemplateTransformer.transform_dict_to_yaml_lines_list({'my-key': ['a', 'b']}) self.assertEqual(['my-key:', '- a', '- b'], result)
def test_transform_dict_to_yaml_lines_list_accepts_integer_values(self): result = CloudFormationTemplateTransformer.transform_dict_to_yaml_lines_list({'my-key': 3}) self.assertEqual([{'Fn::Join': [': ', ['my-key', 3]]}], result)
def test_transform_join_key_accepts_empty_join_string(self): result = CloudFormationTemplateTransformer.transform_join_key('|join|', ['a', 'b']) self.assertEqual(('Fn::Join', ['', ['a', 'b']]), result)
def test_transform_join_key_creates_valid_cfn_join(self): result = CloudFormationTemplateTransformer.transform_join_key('|join|-', ['a', 'b']) self.assertEqual(('Fn::Join', ['-', ['a', 'b']]), result)