Ejemplo n.º 1
0
 def test_get_last_event_time(self):
     timestamp = datetime.utcnow()
     self.deployer._client.describe_stack_events = MagicMock(
         return_value={"StackEvents": [{
             "Timestamp": timestamp
         }]})
     self.assertEqual(self.deployer.get_last_event_time("test"),
                      utc_to_timestamp(timestamp))
Ejemplo n.º 2
0
    def describe_stack_events(self, stack_name, time_stamp_marker, **kwargs):
        """
        Calls CloudFormation to get current stack events
        :param stack_name: Name or ID of the stack
        :param time_stamp_marker: last event time on the stack to start streaming events from.
        :return:
        """

        stack_change_in_progress = True
        events = set()
        retry_attempts = 0

        while stack_change_in_progress and retry_attempts <= self.max_attempts:
            try:

                # Only sleep if there have been no retry_attempts
                time.sleep(self.client_sleep if retry_attempts == 0 else 0)
                describe_stacks_resp = self._client.describe_stacks(
                    StackName=stack_name)
                paginator = self._client.get_paginator("describe_stack_events")
                response_iterator = paginator.paginate(StackName=stack_name)
                stack_status = describe_stacks_resp["Stacks"][0]["StackStatus"]
                for event_items in response_iterator:
                    for event in event_items["StackEvents"]:
                        if event["EventId"] not in events and utc_to_timestamp(
                                event["Timestamp"]) > time_stamp_marker:
                            events.add(event["EventId"])
                            row_color = self.deploy_color.get_stack_events_status_color(
                                status=event["ResourceStatus"])
                            pprint_columns(
                                columns=[
                                    event["ResourceStatus"],
                                    event["ResourceType"],
                                    event["LogicalResourceId"],
                                    event.get("ResourceStatusReason", "-"),
                                ],
                                width=kwargs["width"],
                                margin=kwargs["margin"],
                                format_string=
                                DESCRIBE_STACK_EVENTS_FORMAT_STRING,
                                format_args=kwargs["format_args"],
                                columns_dict=DESCRIBE_STACK_EVENTS_DEFAULT_ARGS
                                .copy(),
                                color=row_color,
                            )

                if self._check_stack_complete(stack_status):
                    stack_change_in_progress = False
                    break
            except botocore.exceptions.ClientError:
                retry_attempts = retry_attempts + 1
                if retry_attempts > self.max_attempts:
                    raise
                # Sleep in exponential backoff mode
                time.sleep(math.pow(self.backoff, retry_attempts))
Ejemplo n.º 3
0
 def get_last_event_time(self, stack_name):
     """
     Finds the last event time stamp thats present for the stack, if not get the current time
     :param stack_name: Name or ID of the stack
     :return: unix epoch
     """
     try:
         return utc_to_timestamp(
             self._client.describe_stack_events(
                 StackName=stack_name)["StackEvents"][0]["Timestamp"])
     except KeyError:
         return time.time()
Ejemplo n.º 4
0
    def describe_stack_events(self, stack_name, time_stamp_marker, **kwargs):
        """
        Calls CloudFormation to get current stack events
        :param stack_name: Name or ID of the stack
        :param time_stamp_marker: last event time on the stack to start streaming events from.
        :param kwargs: Other arguments to pass to pprint_columns()
        """

        stack_change_in_progress = True
        events = set()
        retry_attempts = 0

        while stack_change_in_progress and retry_attempts <= self.max_attempts:
            try:
                # Only sleep if there have been no retry_attempts
                time.sleep(0 if retry_attempts else self.client_sleep)
                describe_stacks_resp = self._client.describe_stacks(
                    StackName=stack_name)
                paginator = self._client.get_paginator("describe_stack_events")
                response_iterator = paginator.paginate(StackName=stack_name)
                stack_status = describe_stacks_resp["Stacks"][0]["StackStatus"]
                latest_time_stamp_marker = time_stamp_marker
                for event_items in response_iterator:
                    for event in event_items["StackEvents"]:
                        if event["EventId"] not in events and utc_to_timestamp(
                                event["Timestamp"]) > time_stamp_marker:
                            events.add(event["EventId"])
                            latest_time_stamp_marker = max(
                                latest_time_stamp_marker,
                                utc_to_timestamp(event["Timestamp"]))
                            row_color = self.deploy_color.get_stack_events_status_color(
                                status=event["ResourceStatus"])
                            pprint_columns(
                                columns=[
                                    event["ResourceStatus"],
                                    event["ResourceType"],
                                    event["LogicalResourceId"],
                                    event.get("ResourceStatusReason", "-"),
                                ],
                                width=kwargs["width"],
                                margin=kwargs["margin"],
                                format_string=
                                DESCRIBE_STACK_EVENTS_FORMAT_STRING,
                                format_args=kwargs["format_args"],
                                columns_dict=DESCRIBE_STACK_EVENTS_DEFAULT_ARGS
                                .copy(),
                                color=row_color,
                            )
                        # Skip already shown old event entries
                        elif utc_to_timestamp(
                                event["Timestamp"]) <= time_stamp_marker:
                            time_stamp_marker = latest_time_stamp_marker
                            break
                    else:  # go to next loop if not break from inside loop
                        time_stamp_marker = latest_time_stamp_marker  # update marker if all events are new
                        continue
                    break  # reached here only if break from inner loop!

                if self._check_stack_complete(stack_status):
                    stack_change_in_progress = False
                    break
            except botocore.exceptions.ClientError as ex:
                retry_attempts = retry_attempts + 1
                if retry_attempts > self.max_attempts:
                    LOG.error("Describing stack events for %s failed: %s",
                              stack_name, str(ex))
                    return
                # Sleep in exponential backoff mode
                time.sleep(math.pow(self.backoff, retry_attempts))
Ejemplo n.º 5
0
 def test_convert_utc_to_timestamp(self):
     timestamp = time.time()
     utc = datetime.datetime.utcfromtimestamp(timestamp)
     # compare in milliseconds
     self.assertEqual(int(timestamp * 1000), utc_to_timestamp(utc))