Beispiel #1
0
 def update_graph_db(self, event, body):
     """
     Updates the heat elements in the graph database.
     :param event: The event that has occurred.
     :param body: The details of the event that occurred.
     """
     from heatclient.exc import NotFound
     LOG.info("[HEAT] Processing event received: %s", event)
     now_ts = time.time()
     uuid = body.get('payload', dict()).get('stack_identity', 'UNDEFINED')
     if '/' in uuid:
         uuid = uuid.rsplit('/', 1)[1]
     try:
         stack = self.heat.stacks.get(uuid)
         if event in ADD_EVENTS:
             LOG.info("HEAT: Adding stack: %s", stack)
             self._add_stack(stack, now_ts)
         elif event in UPDATE_EVENTS:
             LOG.info("HEAT: Updating stack: %s", stack)
             self._update_stack(stack, now_ts)
         elif event in DELETE_EVENTS:
             LOG.info("HEAT: deleting stack: %s", stack)
             self._delete_stack(uuid, now_ts)
     except NotFound:
         LOG.warn("HEAT: Stack with UUID %s not found", uuid)
Beispiel #2
0
    def add_node(self, node_id, identity, state, timestmp):
        """
        Add a node to the Neo4j database, which involves adding the identity
        node and also the state node and then creating a relationship between
        them.
        :param node_id: The id of the identity node.
        :param identity: The identity node.
        :param state: State node.
        :param timestmp: Epoch timestamp of when the node was created.
        :return: An instance of the py2neo neo4j node.
        """
        identity = _format_node(identity)
        identity['name'] = node_id
        iden_node = Node(identity.get('category', 'UNDEFINED'), **identity)
        existing_node = self.get_node_by_uuid(node_id)
        if existing_node:
            LOG.warn("Node with UUID: %s already stored in DB", node_id)
            return existing_node

        # Store nodes to the database.
        transaction = self.graph_db.begin()
        state = _format_node(state)
        state_label = identity.get('category', 'UNDEFINED') + '_state'
        state_node = Node(state_label, **state)
        state_rel = self._create_edge(iden_node, state_node, timestmp, "STATE")
        transaction.create(iden_node)
        transaction.create(state_node)
        transaction.create(state_rel)
        transaction.commit()

        return iden_node
Beispiel #3
0
 def _add_task(self, task, timestamp):
     """
     Adds a Docker task node to the graph database.
     :param task: Docker task object.
     :param timestamp: timestamp.
     """
     LOG.info("[DOCKER] Adding a task node the Graph")
     if task['DesiredState'] == 'running':
         identity, state = self._create_docker_task_nodes(task)
         uuid = task["ID"]
         node_id = task["NodeID"]
         container_id = task["Status"]['ContainerStatus']['ContainerID']
         service_id = task["ServiceID"]
         task_node = self.graph_db.add_node(uuid, identity, state,
                                            timestamp)
         LOG.warn(task_node)
         if task_node is not None:
             docker_node = self.graph_db.get_node_by_uuid(node_id)
             container_node = self.graph_db.get_node_by_uuid(container_id)
             service_node = self.graph_db.get_node_by_uuid(service_id)
             if docker_node and container_node:
                 self.graph_db.add_edge(container_node, docker_node,
                                        timestamp, RELS['docker_container'])
             if container_node and task_node:
                 self.graph_db.add_edge(task_node, container_node,
                                        timestamp, RELS['container_task'])
             if task_node and service_node:
                 self.graph_db.add_edge(service_node, task_node, timestamp,
                                        RELS['task_service'])
Beispiel #4
0
 def _create_docker_container_nodes(self, container, metadata):
     """
     Creates the identity and state nodes for an individual docker container
     :param container: docker container.
     :return: Identity and state node.
     """
     identity = IDEN_ATTR.copy()
     identity['type'] = 'docker_container'
     state = metadata.copy()
     uuid = container.attrs["Id"]
     LOG.warn("Creating container nodes for container: " + container.attrs["Id"])
     # TODO: why can it have multiple names?
     state['container_name'] = container.attrs["Name"][0].replace('/', '')
     #state['template'] = container
     return identity, state
Beispiel #5
0
def get_node_by_properties():
    """
    Returns a graph containing just the nodes that match the properties.
    """
    LOG.info("Retrieving node by props with url %s", request.url)
    timestamp = request.args.get("timestamp") or time.time()
    properties_string = request.args.get("properties")
    if not properties_string:
        err_msg = "Properties must be specified."
        LOG.warn(err_msg)
        abort(400, err_msg)
    properties = ast.literal_eval(properties_string)
    graph = LANDSCAPE.graph_db.get_node_by_properties_web(
        properties, timestamp)
    return Response(graph, mimetype=MIME)
Beispiel #6
0
def get_service_instances():
    """
    Returns the service instances that match the properties provided
    """
    LOG.info("Accessing URL %s", request.url)
    properties_string = request.args.get("properties")
    timestamp = request.args.get("timestamp") or 0
    timeframe = request.args.get("timeframe") or int(time.time()) * -1
    if not properties_string:
        err_msg = "Properties must be specified."
        LOG.warn(err_msg)
        abort(400, err_msg)
    properties = ast.literal_eval(properties_string)
    graph = LANDSCAPE.graph_db.get_node_by_properties_web(
        properties, timestamp, timeframe)
    return Response(graph, mimetype=MIME)
Beispiel #7
0
    def add_edge(self, src_node, dest_node, timestamp, label=None):
        """
        Add an edge between two nodes and attach timestamp details as an
        attribute, which details when the pointed to node was created, updated
        or deleted.
        :param src_node: The source node.
        :param dest_node: The destination node.
        :param timestamp: The epoch timestamp of when this edge was created.
        :param label: Description of the edge.
        :return: Instance of an edge.
        """
        # Add link between src and dst nodes.
        edge = self._create_edge(src_node, dest_node, timestamp, label)

        if edge is not None and self.graph_db.exists(edge):
            LOG.warn("Trying to add a relation already stored in the DB")
            return edge
        transaction = self.graph_db.begin()
        transaction.create(edge)
        transaction.commit()
        return edge
Beispiel #8
0
    def update_node(self, node_id, timestamp, state=None, extra_attrs=None):
        """
        Updating a node in the database involves expiring the old state node
        and then creating a new state node and linking it to identity node
        which is being updated.
        :param additional_attributes:
        :param node_id: The identity node id.
        :param state:  The new state.
        :param timestamp: Epoch timestamp of when the update occurred.
        :return:  Instance of the identity node.
        """
        state_attrs = None
        identity = self.get_node_by_uuid(node_id)

        if not identity:
            umsg = "Node: %s. Node not in the landscape." % node_id
            LOG.warn(umsg)
            return (None, umsg)

        if not state and not extra_attrs:
            umsg = "Node: %s. No attributes supplied for update." % node_id
            LOG.warn(umsg)
            return (identity, umsg)

        if state:
            state_attrs = state

        old_state = self._get_state_node(identity, time.time())
        if not old_state:
            umsg = "Can't update node: %s, as it is already expired." % node_id
            LOG.warn(umsg)
            return (identity, umsg)

        old_node, old_edge = old_state

        if extra_attrs:
            if state_attrs:
                state_attrs.update(extra_attrs)
            else:
                state_attrs = dict(old_node)
                state_attrs.update(extra_attrs)

        if state_attrs == dict(old_node):
            umsg = "Node: %s. No update. Current state is identical" % node_id
            LOG.warn(umsg)
            return (identity, umsg)

        # Create new state and edge to identity.
        state_label = identity.get('category', 'UNDEFINED') + '_state'
        state_node = Node(state_label, **state_attrs)
        new_edge = self._create_edge(identity, state_node, timestamp, 'STATE')

        # Expire old edge between identity and state.
        self._expire_edge(old_edge, timestamp)

        # Commit it all
        self.graph_db.push(old_edge)
        transaction = self.graph_db.begin()
        transaction.create(new_edge)
        transaction.commit()

        umsg = "Node %s updated successfully" % node_id
        return (identity, umsg)
Beispiel #9
0
    def update_graph_db(self, event, body):
        """
        Updates the heat elements in the graph database.
        :param event: The event that has occurred.
        :param body: The details of the event that occurred.
        """
        now_ts = time.time()
        uuid = body.get("Actor", dict()).get('ID', 'UNDEFINED')
        event_source = body.get("Type", None)
        LOG.info("[SWARM] Processing event received: %s", event)
        LOG.info("SWARM-----UUID----- %s", uuid)
        try:
            if event in ADD_EVENTS:
                time.sleep(2)
                if body['Type'] == 'service':
                    stack = next((x
                                  for x in self.swarm_manager.services.list()
                                  if x.attrs['ID'] == uuid), None)
                    self._add_service(stack, now_ts)
                if body['Type'] == 'container':
                    if body['Action'] == 'create':
                        container = next(
                            (x for x in self.swarm_manager.containers.list()
                             if x.attrs['Id'] == uuid), None)
                        self._add_container(container, now_ts)
                    if body['Action'] == 'start':
                        task_id = body['Actor']['Attributes'][
                            'com.docker.swarm.task.id']
                        service = self.swarm_manager.services.get(
                            body['Actor']['Attributes']
                            ['com.docker.swarm.service.id'])
                        #service = next((x for x in self.swarm_manager.services.list() if
                        #          x.attrs['ID'] == uuid), None)
                        task = next(
                            (x for x in service.tasks() if x['ID'] == task_id),
                            None)
                        self._add_task(task, now_ts)
            elif event in DELETE_EVENTS:
                LOG.info("SWARM: deleting stack:\n")
                if body['Type'] == 'container':
                    # delete the adjoining task
                    if 'com.docker.swarm.task.id' in body['Actor'][
                            'Attributes']:
                        task_id = body['Actor']['Attributes'][
                            'com.docker.swarm.task.id']
                        self._delete_node(task_id, now_ts)
                self._delete_node(uuid, now_ts)
            elif event in UPDATE_EVENTS:
                if event_source == 'service':
                    LOG.info("SWARM: updating service: " + body['Actor']['ID'])
                    service = self.swarm_manager.services.get(
                        body['Actor']['ID'])
                    #service = next((x for x in self.swarm_manager.services() if
                    #              x.attrs['ID'] == uuid), None)
                    self._update_service(service, now_ts, body)

        except docker.errors.NotFound:
            #DEBUG code
            if event in ADD_EVENTS:
                # self._add_stack(stack, now_ts)
                LOG.warn("[SWARM] Missed stack into openstack\n EVENT:")
                LOG.warn(event)
                for s in self.swarm_manager.services.list():
                    LOG.warn("Stacks into heat openstack %s\n", s.id)
                LOG.warn("\n\n BODY:\n")
                LOG.warn(body)
                #LOG.warn("\n\nCurrent state of stack: \n")
                #LOG.warn(stack)
                #END DEBUG code
                LOG.warn("SWARM: Stack with UUID %s not found", uuid)
            elif event in DELETE_EVENTS:
                #stack = self.heat.stacks.get(uuid)
                LOG.warn("SWARM: deleting stack:\n")
                self._delete_node(uuid, now_ts)