Пример #1
0
 def test_get_no_echo_parameter_keys_returns_parameter_keys_with_no_echo_set(
         self):
     template_body = {
         'Parameters': {
             'myParameter1': {
                 'Type': 'String',
                 'NoEcho': True
             },
             'myParameter2': {
                 'Type': 'String'
             },
             'myParameter3': {
                 'Type': 'Number',
                 'NoEcho': 'true'
             },
             'myParameter4': {
                 'Type': 'Number',
                 'NoEcho': 'false'
             },
             'myParameter5': {
                 'Type': 'Number',
                 'NoEcho': False
             }
         }
     }
     template = CloudFormationTemplate(template_body, 'some name')
     six.assertCountEqual(self, ['myParameter1', 'myParameter3'],
                          template.get_no_echo_parameter_keys())
Пример #2
0
 def get_file_from_url(cls, url, working_dir):
     if url.lower().startswith("s3://"):
         return CloudFormationTemplate(body_dict=cls._s3_get_file(url),
                                       name=os.path.basename(url))
     else:
         return CloudFormationTemplate(body_dict=cls._fs_get_file(
             url, working_dir),
                                       name=os.path.basename(url))
 def test_get_no_echo_parameter_keys_returns_parameter_keys_with_no_echo_set(self):
     template_body = {
         "Parameters": {
             "myParameter1": {"Type": "String", "NoEcho": True},
             "myParameter2": {"Type": "String"},
             "myParameter3": {"Type": "Number", "NoEcho": "true"},
             "myParameter4": {"Type": "Number", "NoEcho": "false"},
             "myParameter5": {"Type": "Number", "NoEcho": False},
         }
     }
     template = CloudFormationTemplate(template_body, "some name")
     six.assertCountEqual(self, ["myParameter1", "myParameter3"], template.get_no_echo_parameter_keys())
    def test_process_post_resources(self, handle_sns_subscriptions_mock):
        custom_resource_yaml = dedent("""
        PostCustomResources:
            exposeTopicSubscription:
                Type: "Custom::SNS::Subscription"
                Properties:
                    TopicArn:
                      Ref: exposeTopicArn
                    QueueResourceName: exposeQueue
        """)

        custom_resource_dict = yaml.load(custom_resource_yaml)
        template = CloudFormationTemplate(custom_resource_dict, 'foo')
        stack = CloudFormationStack(template, {}, 'foo', 'foo-region')

        CustomResourceHandler.process_post_resources(stack)
        handle_sns_subscriptions_mock.assert_called_once_with(
            {
                'Type': 'Custom::SNS::Subscription',
                'Properties': {
                    'TopicArn': {
                        'Ref': 'exposeTopicArn'
                    },
                    'QueueResourceName': 'exposeQueue'
                }
            }, stack)
Пример #5
0
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)
Пример #6
0
    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'))
Пример #7
0
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)
Пример #8
0
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"))
Пример #9
0
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"))
Пример #10
0
    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_get_template_body_dict(self):
        template_body = {
            'Description': 'some description',
            'Metadata': {
                'meta': 'value'
            },
            'Parameters': {
                'parameter': 'value'
            },
            'Mappings': {
                'mapping': 'value'
            },
            'Conditions': {
                'condition': 'value'
            },
            'Resources': {
                'resource': 'value'
            },
            'Outputs': {
                'output': 'value'
            }
        }
        template = CloudFormationTemplate(template_body, 'some name')

        self.assertEquals(template.template_format_version, '2010-09-09')
        self.assertEquals(template.description, 'some description')
        self.assertEquals(template.metadata, {'meta': 'value'})
        self.assertEquals(template.parameters, {'parameter': 'value'})
        self.assertEquals(template.mappings, {'mapping': 'value'})
        self.assertEquals(template.conditions, {'condition': 'value'})
        self.assertEquals(template.resources, {'resource': 'value'})
        self.assertEquals(template.outputs, {'output': 'value'})
Пример #12
0
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)
Пример #13
0
    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)
Пример #14
0
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)
Пример #15
0
    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)
Пример #16
0
    def test_get_template_body_dict_returns_template_format_value_as_string_if_date_given(
            self):
        template_dict = {'AWSTemplateFormatVersion': datetime.date(2010, 9, 9)}

        result = CloudFormationTemplate(template_dict,
                                        "Something").get_template_body_dict()
        template_version = result["AWSTemplateFormatVersion"]
        self.assertIsInstance(template_version, string_types)
        self.assertEqual(result["AWSTemplateFormatVersion"], "2010-09-09")
Пример #17
0
    def test_get_template_body_dict_returns_default_version_if_none_given(
            self):
        template_dict = {}

        result = CloudFormationTemplate(template_dict,
                                        "Something").get_template_body_dict()
        template_version = result["AWSTemplateFormatVersion"]
        self.assertIsInstance(template_version, string_types)
        self.assertEqual(result["AWSTemplateFormatVersion"], "2010-09-09")
Пример #18
0
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_transform_template_properly_renders_dict(self):
        template_dict = {
            'Resources': {
                'key1': '|ref|value',
                'key2': '|getatt|resource|attribute',
                '@TaupageUserData@': {
                    'key1': 'value',
                    'key2': {
                        'ref': 'value'
                    },
                    'key3': {
                        '|join|.': ['a', 'b', 'c']
                    }
                }
            }
        }

        result = CloudFormationTemplateTransformer.transform_template(
            CloudFormationTemplate(template_dict, 'foo'))

        expected = {
            "key1": {
                "Ref": "value"
            },
            "key2": {
                "Fn::GetAtt": ["resource", "attribute"]
            },
            "UserData": {
                "Fn::Base64": {
                    "Fn::Join": [
                        "\n",
                        [
                            "#taupage-ami-config", {
                                "Fn::Join": [": ", ["key1", "value"]]
                            }, {
                                "Fn::Join": [": ", ["key2", {
                                    "ref": "value"
                                }]]
                            }, {
                                "Fn::Join": [
                                    ": ",
                                    [
                                        "key3", {
                                            "Fn::Join": [".", ["a", "b", "c"]]
                                        }
                                    ]
                                ]
                            }
                        ]
                    ]
                }
            }
        }
        six.assertCountEqual(self, expected, result.resources)
Пример #20
0
    def package(cls, template_url, working_dir, template, region,
                package_bucket):
        logger = get_logger()

        if not package_bucket:
            return template

        if template_url.lower().startswith(
                "s3://") or template_url.lower().startswith("https://"):
            raise Exception(
                "SAM packaging is only supported for local templates (not S3/HTTPS)"
            )

        template_body_dict = template.get_template_body_dict()

        # Save template to a temporary file in the original template's
        # directory. Call `aws cloudformation package` to upload artifacts
        # to S3.
        aws_credentials = boto3.DEFAULT_SESSION.get_credentials()
        with tempfile.NamedTemporaryFile(
                mode="w",
                dir=os.path.dirname(os.path.join(working_dir, template_url)),
                suffix=".json") as src_fp:
            # Save the template. Ensure the buffer's flushed to disk before
            # calling `aws cloudformation package`.
            json.dump(template_body_dict, src_fp)
            src_fp.flush()

            # Open temporary file for the packaged template.
            # We'd previously used stdout, but the packaging process also
            # wrote status to stdout when the source artifact changed, causing
            # malformed JSON.
            with tempfile.NamedTemporaryFile(mode="r") as dst_fp:
                logger.info("Packaging {}".format(template_url))
                result = subprocess.check_call(
                    args=[
                        "aws", "cloudformation", "package", "--template-file",
                        src_fp.name, "--s3-bucket", package_bucket,
                        "--output-template-file", dst_fp.name, "--use-json"
                    ],
                    env=dict(os.environ,
                             AWS_REGION=region,
                             AWS_ACCESS_KEY_ID=aws_credentials.access_key,
                             AWS_SECRET_ACCESS_KEY=aws_credentials.secret_key,
                             AWS_SESSION_TOKEN=aws_credentials.token or ''),
                    stdout=subprocess.DEVNULL,
                    stderr=sys.stderr)

                result = dst_fp.read()

        template_body_dict = json.loads(result)
        template = CloudFormationTemplate(template_body_dict, template.name)
        return template
Пример #21
0
 def get_cloudformation_template(cls, url, working_dir):
     """
     Load file content from url and return cfn-sphere CloudFormationTemplate
     :param url: str
     :param working_dir: str
     :return: CloudFormationTemplate
     """
     try:
         template_body_dict = cls.get_yaml_or_json_file(url, working_dir)
         return CloudFormationTemplate(body_dict=template_body_dict, name=os.path.basename(url))
     except Exception as e:
         raise TemplateErrorException("Could not load file from {0}: {1}".format(url, e))
Пример #22
0
    def test_get_pretty_parameters_string(self):
        template_body = {
            'Parameters': {
                'myParameter1': {
                    'Type': 'String',
                    'NoEcho': True
                },
                'myParameter2': {
                    'Type': 'String'
                },
                'myParameter3': {
                    'Type': 'Number',
                    'NoEcho': 'true'
                },
                'myParameter4': {
                    'Type': 'Number',
                    'NoEcho': 'false'
                },
                'myParameter5': {
                    'Type': 'Number',
                    'NoEcho': False
                }
            }
        }

        parameters = {
            'myParameter1': 'super-secret',
            'myParameter2': 'not-that-secret',
            'myParameter3': 'also-super-secret',
            'myParameter4': 'could-be-public',
            'myParameter5': 'also-ok'
        }

        template = CloudFormationTemplate(template_body,
                                          'just-another-template')
        stack = CloudFormationStack(template, parameters, 'just-another-stack',
                                    'eu-west-1')

        expected_string = """+--------------+-----------------+
|  Parameter   |      Value      |
+--------------+-----------------+
| myParameter1 |       ***       |
| myParameter2 | not-that-secret |
| myParameter3 |       ***       |
| myParameter4 | could-be-public |
| myParameter5 |     also-ok     |
+--------------+-----------------+"""

        self.assertEqual(expected_string,
                         util.get_pretty_parameters_string(stack))
Пример #23
0
    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)
Пример #24
0
    def test_get_template_calls_file_handler(
            self, get_git_repository_remote_url_mock,
            template_transformer_mock, file_loader_mock):
        template = CloudFormationTemplate({}, "my-template")
        file_loader_mock.get_cloudformation_template.return_value = template
        get_git_repository_remote_url_mock.return_value = "my-repository-url"

        TemplateHandler.get_template("my-template-url", "my-working-directory")

        file_loader_mock.get_cloudformation_template.assert_called_once_with(
            "my-template-url", "my-working-directory")
        get_git_repository_remote_url_mock.assert_called_once_with(
            "my-working-directory")
        template_transformer_mock.transform_template.assert_called_once_with(
            template, "Config repo url: my-repository-url")
Пример #25
0
    def test_get_no_echo_parameter_keys(self):
        template_dict = {
            'Parameters': {
                "a": {
                    "Description": "param a",
                    "Type": "String",
                    "NoEcho": True
                },
                "b": {
                    "Description": "param a",
                    "Type": "String"
                },
                "c": {
                    "Description": "param a",
                    "Type": "String"
                },
                "d": {
                    "Description": "param a",
                    "Type": "String",
                    "NoEcho": "true"
                },
                "e": {
                    "Description": "param a",
                    "Type": "String",
                    "NoEcho": "True"
                },
                "f": {
                    "Description": "param a",
                    "Type": "String",
                    "NoEcho": None
                },
                "g": {
                    "Description": "param a",
                    "Type": "String",
                    "noecho": True
                },
            }
        }

        result = CloudFormationTemplate(
            template_dict, "Something").get_no_echo_parameter_keys()
        self.assertEqual(sorted(result), ['a', 'd', 'e'])
Пример #26
0
    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_get_no_echo_parameter_keys_returns_empty_list_with_none_parameters(self):
     template_body = {"Parameters": None}
     template = CloudFormationTemplate(template_body, "some name")
     six.assertCountEqual(self, [], template.get_no_echo_parameter_keys())
Пример #28
0
def test_transform_template_properly_renders_dict(self):
    template_dict = {
        "Resources": {
            "myResource": {
                "key1": "|ref|value",
                "key2": "|getatt|resource|attribute",
                "@TaupageUserData@": {
                    "key1": "value",
                    "key2": {
                        "ref": "value"
                    },
                    "key3": {
                        "|join|.": ["|Ref|a", "b", "c"]
                    },
                    "key4": "|ref|value"
                }
            }
        }
    }

    result = CloudFormationTemplateTransformer.transform_template(
        CloudFormationTemplate(template_dict, "foo"))

    expected = {
        "myResource": {
            "key1": {
                "Ref": "value"
            },
            "key2": {
                "Fn::GetAtt": ["resource", "attribute"]
            },
            "UserData": {
                "Fn::Base64": {
                    "Fn::Join": [
                        "\n",
                        [
                            "#taupage-ami-config",
                            {
                                "Fn::Join": [": ", ["key1", "value"]]
                            },
                            {
                                "Fn::Join": [": ", ["key2", {
                                    "ref": "value"
                                }]]
                            },
                            {
                                "Fn::Join": [
                                    ": ",
                                    [
                                        "key3", {
                                            "Fn::Join":
                                            [".", [{
                                                "Ref": "a"
                                            }, "b", "c"]]
                                        }
                                    ]
                                ]
                            },
                            {
                                "Fn::Join": [": ", ["key4", {
                                    "Ref": "value"
                                }]]
                            },
                        ]
                    ]
                }
            }
        }
    }

    self.assertEqual(expected, result.resources)
Пример #29
0
 def test_get_no_echo_parameter_keys_returns_empty_list_with_none_parameters(
         self):
     template_body = {'Parameters': None}
     template = CloudFormationTemplate(template_body, 'some name')
     six.assertCountEqual(self, [], template.get_no_echo_parameter_keys())
Пример #30
0
    def test_get_no_echo_parameter_keys_for_empty_parameters(self):
        template_dict = {}

        result = CloudFormationTemplate(
            template_dict, "Something").get_no_echo_parameter_keys()
        self.assertEqual(result, [])