Exemplo n.º 1
0
    def test_get_yaml_or_json_file_parses_yaml_on_yml_suffix(
            self, get_file_mock, yaml_mock):
        get_file_return_value = Mock()
        get_file_mock.return_value = get_file_return_value

        FileLoader.get_yaml_or_json_file('foo.yml', 'baa')
        yaml_mock.load.assert_called_once_with(get_file_return_value)
Exemplo n.º 2
0
    def test_get_yaml_or_json_file_parses_json_on_json_suffix(
            self, get_file_mock, json_mock):
        get_file_return_value = Mock()
        get_file_mock.return_value = get_file_return_value

        FileLoader.get_yaml_or_json_file('foo.json', 'baa')
        json_mock.loads.assert_called_once_with(get_file_return_value,
                                                encoding="utf-8")
Exemplo n.º 3
0
    def test_get_yaml_or_json_file_parses_yaml_on_yaml_suffix(
            self, get_file_mock, yaml_mock):
        get_file_return_value = Mock()
        get_file_mock.return_value = get_file_return_value

        FileLoader.get_yaml_or_json_file('foo.yaml', 'baa')
        if hasattr(yaml_mock, 'FullLoader'):
            loader = yaml_mock.FullLoader
        else:
            loader = yaml_mock.Loader

        yaml_mock.load.assert_called_once_with(get_file_return_value,
                                               Loader=loader)
Exemplo n.º 4
0
    def __init__(self,
                 config_file=None,
                 config_dict=None,
                 cli_params=None,
                 stack_name_suffix=None):
        self.logger = get_logger()

        if isinstance(config_dict, dict):
            self.stack_config_base_dir = None
        elif config_file:
            self.stack_config_base_dir = os.path.dirname(
                os.path.realpath(config_file))
            config_dict = FileLoader.get_yaml_or_json_file(
                config_file, working_dir=os.getcwd())
        else:
            raise InvalidConfigException(
                "You need to pass either config_file (path to a file) or config_dict (python dict) property"
            )

        self.cli_params = self._parse_cli_parameters(cli_params)
        self.region = config_dict.get("region")
        self.stack_name_suffix = stack_name_suffix

        self.default_service_role = config_dict.get("service-role")
        self.default_stack_policy_url = config_dict.get("stack-policy-url")
        self.default_timeout = config_dict.get("timeout", 600)
        self.default_tags = config_dict.get("tags", {})
        self.default_failure_action = config_dict.get("on_failure", "ROLLBACK")
        self.default_disable_rollback = config_dict.get(
            "disable_rollback", False)

        self._validate(config_dict)

        stacks = self._parse_stack_configs(config_dict)
        self.stacks = self._apply_stack_name_suffix(stacks, stack_name_suffix)
Exemplo n.º 5
0
 def test_get_yaml_or_json_file_accepts_yaml_template_with_getatt_constructor_tag(
         self, get_file_mock):
     get_file_mock.return_value = "myKey: !GetAtt myResource.attributeName"
     result = FileLoader.get_yaml_or_json_file("my-template.yaml", None)
     self.assertEqual(
         {"myKey": {
             "Fn::GetAtt": ["myResource", "attributeName"]
         }}, result)
Exemplo n.º 6
0
 def test_get_yaml_or_json_file_accepts_yaml_with_nested_constructor_tags(
         self, get_file_mock):
     get_file_mock.return_value = "myKey: !Join [ b, [ !ref a, !ref b] ]"
     result = FileLoader.get_yaml_or_json_file("my-template.yaml", None)
     self.assertEqual(
         {"myKey": {
             "Fn::Join": ["b", [{
                 "Ref": "a"
             }, {
                 "Ref": "b"
             }]]
         }}, result)
Exemplo n.º 7
0
    def handle_file_value(value, working_dir):
        components = value.split('|', 3)

        if len(components) == 3:
            url = components[2]
            return FileLoader.get_file(url, working_dir)
        elif len(components) == 4:
            url = components[2]
            pattern = components[3]
            file_content = FileLoader.get_yaml_or_json_file(url, working_dir)
            try:
                return jmespath.search(pattern, file_content)
            except JMESPathError as e:
                raise CfnSphereException(e)
        else:
            raise CfnSphereException("Invalid format for |File| macro, it must be |File|<path>[|<pattern>]")
Exemplo n.º 8
0
    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)
Exemplo n.º 9
0
    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)

            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

            template = TemplateHandler.get_template(stack_config.template_url,
                                                    stack_config.working_dir)
            parameters = self.parameter_resolver.resolve_parameter_values(
                stack_name, stack_config, self.cli_parameters)

            stack = CloudFormationStack(
                template=template,
                parameters=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,
                failure_action=stack_config.failure_action)

            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)
Exemplo n.º 10
0
    def handle_file_value(value, working_dir):
        components = value.split('|', 3)

        if len(components) == 3:
            url = components[2]
            return FileLoader.get_file(url, working_dir)
        elif len(components) == 4:
            url = components[2]
            pattern = components[3]
            file_content = FileLoader.get_yaml_or_json_file(url, working_dir)
            try:
                return jmespath.search(pattern, file_content)
            except JMESPathError as e:
                raise CfnSphereException(e)
        else:
            raise CfnSphereException(
                "Invalid format for |File| macro, it must be |File|<path>[|<pattern>]"
            )
Exemplo n.º 11
0
    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)

            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

            template = TemplateHandler.get_template(stack_config.template_url, stack_config.working_dir)
            parameters = self.parameter_resolver.resolve_parameter_values(stack_name, stack_config, self.cli_parameters)

            stack = CloudFormationStack(
                template=template,
                parameters=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,
                failure_action=stack_config.failure_action,
            )

            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)
Exemplo n.º 12
0
 def test_get_yaml_or_json_file_accepts_yaml_with_cfn_join_constructor_tag(self, get_file_mock):
     get_file_mock.return_value = "myKey: !Join [ b, [ a, c] ]"
     result = FileLoader.get_yaml_or_json_file("my-template.yaml", None)
     self.assertEqual({"myKey": {"Fn::Join": ["b", ["a", "c"]]}}, result)
Exemplo n.º 13
0
 def test_get_yaml_or_json_file_accepts_yaml_template_with_ref_constructor_tag(self, get_file_mock):
     get_file_mock.return_value = "myKey: !Ref myResource"
     result = FileLoader.get_yaml_or_json_file("my-template.yaml", None)
     self.assertEqual({"myKey": {"Ref": "myResource"}}, result)
Exemplo n.º 14
0
 def test_get_yaml_or_json_file_accepts_yaml_template_with_getatt_constructor_tag(self, get_file_mock):
     get_file_mock.return_value = "myKey: !GetAtt myResource.attributeName"
     result = FileLoader.get_yaml_or_json_file("my-template.yaml", None)
     self.assertEqual({"myKey": {"Fn::GetAtt": ["myResource", "attributeName"]}}, result)
Exemplo n.º 15
0
 def test_get_yaml_or_json_file_accepts_yaml_with_cfn_join_constructor_tag(
         self, get_file_mock):
     get_file_mock.return_value = "myKey: !Join [ b, [ a, c] ]"
     result = FileLoader.get_yaml_or_json_file("my-template.yaml", None)
     self.assertEqual({"myKey": {"Fn::Join": ["b", ["a", "c"]]}}, result)
Exemplo n.º 16
0
    def test_get_yaml_or_json_file_parses_yaml_on_yml_suffix(self, get_file_mock, yaml_mock):
        get_file_return_value = Mock()
        get_file_mock.return_value = get_file_return_value

        FileLoader.get_yaml_or_json_file('foo.yml', 'baa')
        yaml_mock.load.assert_called_once_with(get_file_return_value)
Exemplo n.º 17
0
 def test_get_yaml_or_json_file_accepts_yaml_template_with_ref_constructor_tag(
         self, get_file_mock):
     get_file_mock.return_value = "myKey: !Ref myResource"
     result = FileLoader.get_yaml_or_json_file("my-template.yaml", None)
     self.assertEqual({"myKey": {"Ref": "myResource"}}, result)
Exemplo n.º 18
0
    def test_get_yaml_or_json_file_raises_exception_on_json_error(
            self, _, json_mock):
        json_mock.loads.side_effect = ValueError()

        with self.assertRaises(CfnSphereException):
            FileLoader.get_yaml_or_json_file('foo.json', 'baa')
Exemplo n.º 19
0
    def test_get_yaml_or_json_file_raises_exception_on_yaml_error(
            self, _, yaml_mock):
        yaml_mock.load.side_effect = ScannerError()

        with self.assertRaises(CfnSphereException):
            FileLoader.get_yaml_or_json_file('foo.yml', 'baa')
Exemplo n.º 20
0
 def test_get_yaml_or_json_file_raises_exception_invalid_file_extension(
         self, _):
     with self.assertRaises(CfnSphereException):
         FileLoader.get_yaml_or_json_file('foo.foo', 'baa')
Exemplo n.º 21
0
 def test_get_yaml_or_json_file_accepts_yaml_with_nested_constructor_tags(self, get_file_mock):
     get_file_mock.return_value = "myKey: !Join [ b, [ !ref a, !ref b] ]"
     result = FileLoader.get_yaml_or_json_file("my-template.yaml", None)
     self.assertEqual({"myKey": {"Fn::Join": ["b", [{"Ref": "a"}, {"Ref": "b"}]]}}, result)
Exemplo n.º 22
0
 def test_get_yaml_or_json_file_raises_exception_invalid_file_extension(self, _):
     with self.assertRaises(CfnSphereException):
         FileLoader.get_yaml_or_json_file('foo.foo', 'baa')
Exemplo n.º 23
0
    def test_get_yaml_or_json_file_raises_exception_on_json_error(self, _, json_mock):
        json_mock.loads.side_effect = ValueError()

        with self.assertRaises(CfnSphereException):
            FileLoader.get_yaml_or_json_file('foo.json', 'baa')
Exemplo n.º 24
0
    def test_get_yaml_or_json_file_raises_exception_on_yaml_error(self, _, yaml_mock):
        yaml_mock.load.side_effect = ScannerError()

        with self.assertRaises(CfnSphereException):
            FileLoader.get_yaml_or_json_file('foo.yml', 'baa')