Beispiel #1
0
class StackActionHandler(object):
    def __init__(self, config, dry_run=False):
        self.logger = get_logger(root=True)
        self.config = config
        self.cfn = CloudFormation(region=self.config.region, dry_run=dry_run)
        self.parameter_resolver = ParameterResolver(self.cfn,
                                                    region=self.config.region)
        self.cli_parameters = config.cli_params

    def execute_change_set(self):
        print('executing change set')
        print(self.config.change_set)

        change_set = self.cfn.get_change_set(self.config.change_set)

        if change_set is None:
            raise CfnStackActionFailedException(
                "Could not execute change set {0}: Does not exist or is in an invalid state."
                .format(self.config.change_set))

        stack_name = self.cfn.get_stack_name_by_arn(change_set['StackId'])
        stack = self.cfn.get_stack(stack_name)

        if not self.cfn.change_set_is_executable(change_set):
            raise CfnStackActionFailedException(
                "Could not execute change set {0}: Does not exist or is in an invalid state."
                .format(self.config.change_set))
        else:
            self.cfn.execute_change_set(stack, self.config.change_set)

    def create_change_set(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,
                self.config.region, stack_config.package_bucket)
            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.create_change_set(stack, 'UPDATE')
            else:
                self.cfn.create_change_set(stack, 'CREATE')

    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,
                self.config.region, stack_config.package_bucket)
            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)

    def delete_stacks(self):
        existing_stacks = self.cfn.get_stack_names()
        stacks = self.config.stacks

        stack_processing_order = DependencyResolver().get_stack_order(stacks)
        stack_processing_order.reverse()

        self.logger.info(
            "Will delete 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_name in existing_stacks:
                stack = CloudFormationStack(
                    None,
                    None,
                    stack_name,
                    None,
                    None,
                    service_role=stack_config.service_role)
                self.cfn.validate_stack_is_ready_for_action(stack)
                self.cfn.delete_stack(stack)
            else:
                self.logger.info(
                    "Stack {0} is already deleted".format(stack_name))