def test_gh_63_value(): """ Test that Joins with conditionals that cannot evaluate to AWS::NoValue are converted to Fn::Sub """ source = { "Fn::Join": [ ",", [{ "Fn::If": ["Condition1", "True1", "False1"] }, { "Fn::If": ["Condition2", "True2", "False2"] }] ] } expected = ODict((("Fn::Sub", [ "${Param1},${Param2}", ODict(( ("Param1", ODict((("Fn::If", ["Condition1", "True1", "False1"]), ))), ("Param2", ODict((("Fn::If", ["Condition2", "True2", "False2"]), ))), )), ]), )) actual = clean(source) assert actual == expected
def test_others(): """ GetAtt should be replaced by ${Thing.Property} """ source = { "Fn::Join": [ " ", ["The", { "Fn::Base64": "Notreallybase64" }, "is", "a", "lie"], ], } expected = { "Fn::Sub": [ "The ${Param1} is a lie", { "Param1": { "Fn::Base64": "Notreallybase64", }, }, ], } actual = clean(source) assert expected == actual
def to_json(template, clean_up=False): """ Assume the input is YAML and convert to JSON """ data = load_yaml(template) if clean_up: data = clean(data) return dump_json(data)
def to_yaml(template, clean_up=False, long_form=False): """ Assume the input is JSON and convert to YAML """ data = load_json(template) if clean_up: data = clean(data) return dump_yaml(data, clean_up, long_form)
def to_yaml(template, clean_up=False, long_form=False, literal=True): """ Assume the input is JSON and convert to YAML """ data, _ = load(template) if clean_up: data = clean(data) if literal: data = cfn_literal_parser(data) return dump_yaml(data, clean_up, long_form)
def yaml_to_json(p_input_file): json_out = ROOT_DIR+'/../../../tacocat_cf.json' with open( p_input_file,'r') as yaml_in: yaml_data = load_yaml(yaml_in) yaml_data = clean(yaml_data) with open(json_out,'w') as out_file: json_data = dump_json(yaml_data) json_data = load_json(json_data) json.dump(json_data ,out_file, sort_keys=True, indent=4, separators=(',', ': ')) print('*--*--*--*--*--*--*--*--*--*--*--*--**--*--*--*--*--*--*--*--*--*--*--*') print('The new JSON file has been created in the root folder of the project with the name tacocat_cf.json') print('*--*--*--*--*--*--*--*--*--*--*--*--**--*--*--*--*--*--*--*--*--*--*--*')
def flip(template, in_format=None, out_format=None, clean_up=False, no_flip=False, long_form=False): """ Figure out the input format and convert the data to the opposing output format """ # Do we need to figure out the input format? if not in_format: # Load the template as JSON? if (out_format == "json" and no_flip) or (out_format == "yaml" and not no_flip): in_format = "json" elif (out_format == "yaml" and no_flip) or (out_format == "json" and not no_flip): in_format = "yaml" # Load the data if in_format == "json": data = load_json(template) elif in_format == "yaml": data = load_yaml(template) else: data, in_format = load(template) # Clean up? if clean_up: data = clean(data) # Figure out the output format if not out_format: if (in_format == "json" and no_flip) or (in_format == "yaml" and not no_flip): out_format = "json" else: out_format = "yaml" # Finished! if out_format == "json": if sys.version[0] == "3": return dump_json(data) else: return dump_json(data).encode('utf-8') return dump_yaml(data, clean_up, long_form)
def test_basic_case(): """ As simple as it gets """ source = { "Fn::Join": [ " ", ["The", "cake", "is", "a", "lie"], ], } expected = "The cake is a lie" actual = clean(source) assert expected == actual
def test_literals(): """ Test that existing ${var} in source is respected """ source = { "Fn::Join": [ " ", ["The", "${cake}", "is", "a", "lie"], ], } expected = "The ${!cake} is a lie" actual = clean(source) assert expected == actual
def test_in_array(): """ Converting Join to Sub should still work when the join is part of a larger array """ source = { "things": [ "Just a string", { "Fn::Join": [ " ", [ "The", { "Fn::Base64": "Notreallybase64" }, "is", "a", "lie" ], ], }, { "Another": "thing", }, ], } expected = { "things": [ "Just a string", { "Fn::Sub": [ "The ${Param1} is a lie", { "Param1": { "Fn::Base64": "Notreallybase64", }, }, ], }, { "Another": "thing", }, ], } actual = clean(source) assert expected == actual
def convert_yaml_to_json(yaml_file): converted_file = ROOT_DIR + '/../../../tacocat_cf.json' with open(yaml_file, 'r') as file_in: yaml_data = load_yaml(file_in) yaml_data = clean(yaml_data) with open(converted_file, 'w') as file_out: json_data = dump_json(yaml_data) json_data = load_json(json_data) json.dump(json_data, file_out, sort_keys=True, indent=4, separators=(',', ': ')) print( '#####--Converted successfully, please check the root folder with the name tacocat_cf.json--#####' )
def test_gh_63_no_value(): """ Test that Joins with conditionals that can evaluate to AWS::NoValue are not converted to Fn::Sub """ source = { "Fn::Join": [ ",", [{ "Fn::If": ["Condition1", "True1", "Ref: AWS::NoValue"] }, { "Fn::If": ["Condition2", "True2", "False2"] }] ] } assert source == clean(source)
def test_get_att(): """ Intrinsics should be replaced by parameters to Sub """ source = { "Fn::Join": [ " ", ["The", { "Fn::GetAtt": ["Cake", "Hole"] }, "is", "a", "lie"], ], } expected = { "Fn::Sub": "The ${Cake.Hole} is a lie", } actual = clean(source) assert expected == actual
def test_ref(): """ Refs should be replaced by ${value} """ source = { "Fn::Join": [ " ", ["The", { "Ref": "Cake" }, "is", "a", "lie"], ], } expected = { "Fn::Sub": "The ${Cake} is a lie", } actual = clean(source) assert expected == actual
def test_reused_sub_params(): """ Test that params in Joins converted to Subs get reused when possible """ source = { "Fn::Join": [ " ", [ "The", { "Fn::Join": ["-", [{ "Ref": "Cake" }, "Lie"]], }, "is", { "Fn::Join": ["-", [{ "Ref": "Cake" }, "Lie"]], }, "and isn't", { "Fn::Join": ["-", [{ "Ref": "Pizza" }, "Truth"]], }, ], ], } expected = ODict((("Fn::Sub", [ "The ${Param1} is ${Param1} and isn't ${Param2}", ODict(( ("Param1", ODict((("Fn::Sub", "${Cake}-Lie"), ))), ("Param2", ODict((("Fn::Sub", "${Pizza}-Truth"), ))), )), ]), )) assert clean(source) == expected
def test_deep_nested_join(): """ Test that a join works correctly when inside an intrinsic, inside a join """ source = { "Fn::Join": [ " ", [ "The", "cake", "is", "a", { "Fn::ImportValue": { "Fn::Join": [ "-", [{ "Ref": "lieStack" }, "lieValue"], ] }, } ], ], } expected = { "Fn::Sub": [ "The cake is a ${Param1}", { "Param1": { "Fn::ImportValue": { "Fn::Sub": "${lieStack}-lieValue", }, }, }, ] } actual = clean(source) assert expected == actual
def test_nested_join(): """ Test that a join of joins works correctly """ source = { "Fn::Join": [ " ", ["The", "cake", { "Fn::Join": [ " ", ["is", "a"], ], }, "lie"], ], } expected = "The cake is a lie" actual = clean(source) assert expected == actual
def flip(template, out_format=None, clean_up=False, no_flip=False, long_form=False): """ Figure out the input format and convert the data to the opposing output format """ data = None in_format = None if no_flip: in_format = out_format elif out_format == "json": in_format = "yaml" elif out_format == "yaml": in_format = "json" if in_format == "json": data = load_json(template) elif in_format == "yaml": data = load_yaml(template) else: try: data, in_format = load(template) except Exception: raise Exception("Could not determine the input format") if no_flip: out_format = in_format elif in_format == "json": out_format = "yaml" else: out_format = "json" if clean_up: data = clean(data) if out_format == "json": return dump_json(data) return dump_yaml(data, clean_up, long_form)
def test_multi_level_get_att(): """ Intrinsics should be replaced by parameters to Sub """ source = { "Fn::Join": [ " ", [ "The", { "Fn::GetAtt": ["First", "Second", "Third"] }, "is", "a", "lie" ], ], } expected = { "Fn::Sub": "The ${First.Second.Third} is a lie", } actual = clean(source) assert expected == actual