Beispiel #1
0
    def _get_simplified_status(status):
        """
        Returns the simplified Stack Status.

        The simplified Stack status is represented by the struct
        ``sceptre.StackStatus()`` and can take one of the following options:

        * complete
        * in_progress
        * failed

        :param status: The CloudFormation Stack status to simplify.
        :type status: str
        :returns: The Stack's simplified status
        :rtype: sceptre.stack_status.StackStatus
        """
        if status.endswith("ROLLBACK_COMPLETE"):
            return StackStatus.FAILED
        elif status.endswith("_COMPLETE"):
            return StackStatus.COMPLETE
        elif status.endswith("_IN_PROGRESS"):
            return StackStatus.IN_PROGRESS
        elif status.endswith("_FAILED"):
            return StackStatus.FAILED
        else:
            raise UnknownStackStatusError("{0} is unknown".format(status))
Beispiel #2
0
    def launch(self):
        """
        Launches the Stack.

        If the Stack status is create_failed or rollback_complete, the
        Stack is deleted. Launch then tries to create or update the Stack,
        depending if it already exists. If there are no updates to be
        performed, launch exits gracefully.

        :returns: The Stack's status.
        :rtype: sceptre.stack_status.StackStatus
        """
        self._protect_execution()
        self.logger.info("%s - Launching Stack", self.stack.name)
        try:
            existing_status = self._get_status()
        except StackDoesNotExistError:
            existing_status = "PENDING"

        self.logger.info(
            "%s - Stack is in the %s state", self.stack.name, existing_status
        )

        if existing_status == "PENDING":
            status = self.create()
        elif existing_status in ["CREATE_FAILED", "ROLLBACK_COMPLETE"]:
            self.delete()
            status = self.create()
        elif existing_status.endswith("COMPLETE"):
            try:
                status = self.update()
            except botocore.exceptions.ClientError as exp:
                error_message = exp.response["Error"]["Message"]
                if error_message == "No updates are to be performed.":
                    self.logger.info(
                        "%s - No updates to perform.", self.stack.name
                    )
                    status = StackStatus.COMPLETE
                else:
                    raise
            status = status
        elif existing_status.endswith("IN_PROGRESS"):
            self.logger.info(
                "%s - Stack action is already in progress state and cannot "
                "be updated", self.stack.name
            )
            status = StackStatus.IN_PROGRESS
        elif existing_status.endswith("FAILED"):
            status = StackStatus.FAILED
            raise CannotUpdateFailedStackError(
                "'{0}' is in a the state '{1}' and cannot be updated".format(
                    self.stack.name, existing_status
                )
            )
        else:
            raise UnknownStackStatusError(
                "{0} is unknown".format(existing_status)
            )
        return status
Beispiel #3
0
    def launch(self, wait_action):
        """
        Launches the Stack.

        If the Stack status is create_failed or rollback_complete, the
        Stack is deleted. Launch then tries to create or update the Stack,
        depending if it already exists. If there are no updates to be
        performed, launch exits gracefully.

        :returns: The Stack's status.
        :rtype: sceptre.stack_status.StackStatus
        """
        self._protect_execution()
        self.logger.info("%s - Launching Stack", self.stack.name)
        try:
            existing_status = self._get_status()
        except StackDoesNotExistError:
            existing_status = "PENDING"

        self.logger.info("%s - Stack is in the %s state", self.stack.name,
                         existing_status)

        if existing_status.endswith(
                "UPDATE_IN_PROGRESS") or existing_status.endswith(
                    "CREATE_IN_PROGRESS") or existing_status.endswith(
                        "UPDATE_ROLLBACK_IN_PROGRESS"
                    ) or existing_status.endswith(
                        "CLEANUP_IN_PROGRESS") or existing_status.endswith(
                            "DELETE_IN_PROGRESS") or existing_status.endswith(
                                "ROLLBACK_IN_PROGRESS"):
            # wait until it finalize then lets proceed..
            self.logger.info(
                "%s - Stack is %s, waiting before launching stack action.",
                self.stack.name, existing_status)
            existing_status = self._wait_for_completion()

            try:
                existing_status = self._get_status()
                time.sleep(4)
                existing_status = self._get_status()
            except StackDoesNotExistError:
                existing_status = "PENDING"

            self.logger.info(
                "%s - Stack is now in the following state: %s. Will proceed with command action.",
                self.stack.name, existing_status)

            if existing_status.endswith("ROLLBACK_COMPLETE"):
                existing_status = "PENDING"
            elif existing_status.endswith("DELETE_IN_PROGRESS"):
                # Force dlete / create
                existing_status = "PENDING"
            elif existing_status.endswith("CREATE_IN_PROGRESS"):
                existing_status = "CREATE_IN_PROGRESS"
            elif existing_status.endswith("UPDATE_IN_PROGRESS"):
                existing_status = "UPDATE_IN_PROGRESS"
            else:
                existing_status = "UPDATE_ROLLBACK_COMPLETE"

        if existing_status == "PENDING":
            status = self.create(wait_action)
        elif existing_status in [
                "CREATE_FAILED", "ROLLBACK_COMPLETE", "ROLLBACK_FAILED"
        ]:
            self.delete()
            status = self.create(wait_action)
        elif existing_status.endswith("COMPLETE") or (
                existing_status.endswith("IN_PROGRESS")
                and wait_action == 'wait_only'):
            try:
                status = self.update(wait_action)
            except botocore.exceptions.ClientError as exp:
                error_message = exp.response["Error"]["Message"]
                if error_message == "No updates are to be performed.":
                    self.logger.info("%s - No updates to perform.",
                                     self.stack.name)
                    status = StackStatus.COMPLETE
                else:
                    raise
        #    status = self.create()
        #elif existing_status.endswith("COMPLETE"):
        #    status = self.update()
        elif existing_status.endswith("IN_PROGRESS"):
            self.logger.info(
                "%s - Stack action is already in progress state and cannot "
                "be updated", self.stack.name)
            status = StackStatus.IN_PROGRESS
        elif existing_status.endswith("FAILED"):
            status = StackStatus.FAILED
            raise CannotUpdateFailedStackError(
                "'{0}' is in a the state '{1}' and cannot be updated".format(
                    self.stack.name, existing_status))
        else:
            raise UnknownStackStatusError(
                "{0} is unknown".format(existing_status))
        return status