From da4a6fe6162fb981b82199f35dacff7fc8973959 Mon Sep 17 00:00:00 2001 From: Waldemar Hummer Date: Wed, 10 Jan 2018 19:57:49 -0500 Subject: [PATCH] implement Fn::GetAZs function in CloudFormation --- moto/cloudformation/parsing.py | 10 +++++++ .../test_cloudformation/test_stack_parsing.py | 27 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/moto/cloudformation/parsing.py b/moto/cloudformation/parsing.py index e617fa9f8..81f47f4a3 100644 --- a/moto/cloudformation/parsing.py +++ b/moto/cloudformation/parsing.py @@ -106,6 +106,8 @@ NULL_MODELS = [ "AWS::CloudFormation::WaitConditionHandle", ] +DEFAULT_REGION = 'us-east-1' + logger = logging.getLogger("moto") @@ -203,6 +205,14 @@ def clean_json(resource_json, resources_map): if any(values): return values[0] + if 'Fn::GetAZs' in resource_json: + region = resource_json.get('Fn::GetAZs') or DEFAULT_REGION + result = [] + # TODO: make this configurable, to reflect the real AWS AZs + for az in ('a', 'b', 'c', 'd'): + result.append('%s%s' % (region, az)) + return result + cleaned_json = {} for key, value in resource_json.items(): cleaned_val = clean_json(value, resources_map) diff --git a/tests/test_cloudformation/test_stack_parsing.py b/tests/test_cloudformation/test_stack_parsing.py index d9fe4d80d..af7e608db 100644 --- a/tests/test_cloudformation/test_stack_parsing.py +++ b/tests/test_cloudformation/test_stack_parsing.py @@ -75,6 +75,14 @@ get_attribute_output = { } } +get_availability_zones_output = { + "Outputs": { + "Output1": { + "Value": {"Fn::GetAZs": ""} + } + } +} + split_select_template = { "AWSTemplateFormatVersion": "2010-09-09", "Resources": { @@ -146,6 +154,8 @@ bad_outputs_template = dict( list(dummy_template.items()) + list(bad_output.items())) get_attribute_outputs_template = dict( list(dummy_template.items()) + list(get_attribute_output.items())) +get_availability_zones_template = dict( + list(dummy_template.items()) + list(get_availability_zones_output.items())) dummy_template_json = json.dumps(dummy_template) name_type_template_json = json.dumps(name_type_template) @@ -153,6 +163,8 @@ output_type_template_json = json.dumps(outputs_template) bad_output_template_json = json.dumps(bad_outputs_template) get_attribute_outputs_template_json = json.dumps( get_attribute_outputs_template) +get_availability_zones_template_json = json.dumps( + get_availability_zones_template) split_select_template_json = json.dumps(split_select_template) sub_template_json = json.dumps(sub_template) export_value_template_json = json.dumps(export_value_template) @@ -243,6 +255,21 @@ def test_parse_stack_with_get_attribute_outputs(): output.value.should.equal("my-queue") +def test_parse_stack_with_get_availability_zones(): + stack = FakeStack( + stack_id="test_id", + name="test_stack", + template=get_availability_zones_template_json, + parameters={}, + region_name='us-east-1') + + stack.output_map.should.have.length_of(1) + list(stack.output_map.keys())[0].should.equal('Output1') + output = list(stack.output_map.values())[0] + output.should.be.a(Output) + output.value.should.equal([ "us-east-1a", "us-east-1b", "us-east-1c", "us-east-1d" ]) + + def test_parse_stack_with_bad_get_attribute_outputs(): FakeStack.when.called_with( "test_id", "test_stack", bad_output_template_json, {}, "us-west-1").should.throw(ValidationError)