예제 #1
0
    def get_task_arn(self):
        """
        Checks if the current or desired state definitions have a startedBy key which means the task has been
        initialized. If this key if found this calls boto3 list tasks and filters for tasks that match the startBy key
        and cluster name. If only one task matches then this returns the taskArn otherwise returns None.

        Returns:
             ECS Task Arn or None
        """
        if self.get_attribute_value("taskArn"):
            return self.get_attribute_value("taskArn")

        if not pcf_util.get_item_from_dicts("startedBy", self.current_state_definition, self.desired_state_definition):
            return None

        list_task_request = {
            "startedBy": pcf_util.get_item_from_dicts("startedBy", self.current_state_definition, self.desired_state_definition),
            "cluster": self.get_ecs_cluster_arn()
        }

        task_arns = []
        resps = []

        for status in ["RUNNING", "PENDING", "STOPPED"]:
            resp = self.client.list_tasks(**list_task_request, desiredStatus=status)
            resps.append(resp)
            task_arns += resp.get("taskArns", [])

        if len(task_arns) == 1:
            return task_arns[0]
        elif len(task_arns) > 1:
            error_msg = "there are more than 1 ecs task matching the criteria: {}".format(resps)
            raise Exception(error_msg)
        else:
            return None
예제 #2
0
    def get_task_definition_id(self):
        """
        Parses the current and desired state definition and returns the family. If there is a revision it appends
        it to the family.

        Returns:
             task definition id
        """
        task_definition_family = pcf_util.get_item_from_dicts("family", self.current_state_definition, self.get_desired_state_definition())
        task_definition_revision = pcf_util.get_item_from_dicts("revision", self.current_state_definition, self.get_desired_state_definition())

        if task_definition_revision:
            return "{}:{}".format(task_definition_family, task_definition_revision)
        else:
            return task_definition_family
    def _get_arn(self):
        """
        Looks for the parrent ec2 particle and uses the ec2 instance id as the key in boto3 list_attributes(). The response
        of list_attributes() is then parsed for the targetId which is used

        Returns:
            ECS Instance arn
        """
        if len(self.parents) > 0:
            # TODO - this is a hack to make up for the lack of particle families
            ec2_instance_parents = list(
                filter(lambda x: 'ec2_instance' in x.flavor, self.parents))

            if len(ec2_instance_parents) == 1:
                ec2_instance_particle = ec2_instance_parents[0]
                ec2_instance_particle.sync_state()
                try:
                    ec2_instance_id = ec2_instance_particle.get_instance_id()
                except NoResourceException:
                    ec2_instance_id = None
            else:
                raise Exception(
                    "ecs_instance requires exactly 1 ec2_instance as the parent"
                )

        if not ec2_instance_id:
            return None

        ecs_instance_attributes = pcf_util.get_item_from_dicts(
            "attributes", self.current_state_definition,
            self.desired_state_definition)

        attributes_resp = self.client.list_attributes(
            cluster=self.get_cluster_name(),
            targetType='container-instance',
            attributeName='instance-id',
            attributeValue=ec2_instance_id,
        )['attributes']

        if len(attributes_resp) == 0:
            return None
        elif len(attributes_resp) == 1:
            return attributes_resp[0]['targetId']
        else:
            error_msg = "found more than one instance with the same attribute: {}".format(
                attributes_resp)
            raise Exception(error_msg)
예제 #4
0
    def get_attribute_value(self,
                            attribute_key,
                            state_definition_to_use="c>d",
                            default=None):
        definitions_to_use = state_definition_to_use.split(">")
        definitions = []

        for definition_to_use in definitions_to_use:
            if definition_to_use and definition_to_use.lower()[0] == "d":
                definitions.append(self.get_desired_state_definition())
            elif definition_to_use and definition_to_use.lower()[0] == "c":
                definitions.append(self.get_current_state_definition())

        value = pcf_util.get_item_from_dicts(attribute_key, *definitions)
        if value is not None:
            return value
        else:
            return default
예제 #5
0
 def get_service_name(self):
     service_name = pcf_util.get_item_from_dicts(
         "serviceName", self.current_state_definition,
         self.desired_state_definition)
     return service_name