コード例 #1
0
 def update_service_container_metrics(self, id, device_id, end_time):
     coll = self.get_collection('service-container-metric')
     coll = coll['serviceContainerMetrics']
     device_id = "device/{0}".format(device_id)
     end_time = float(end_time) // 1000000000
     end_time = datetime.utcfromtimestamp(end_time)
     mlsec = end_time.microsecond
     json_end_time = end_time.strftime(
         '%Y-%m-%dT%H:%M:%S.%f{:02d}Z'.format(mlsec))
     scm_id = None
     for item in coll:
         dev_id = item['device_id']['href']
         cont_id = item['container_id']
         if dev_id == device_id and cont_id == id:
             scm_id = item['id']
             break
     if scm_id:
         url = self.cimi_url + '/' + scm_id
         data = {'stop_time': json_end_time}
         res = requests.put(url,
                            headers=CIMI_SEC_HEADERS,
                            verify=SSL_VERIFY,
                            json=data)
         if res.status_code != 200:
             LOG.error(res.json())
         return res
     else:
         return ""
コード例 #2
0
def get_subgraph(node_id):
    """
    Returns the subgraph using a node id as the start.
    """
    LOG.info("Retrieving Subgraph with url %s", request.url)
    timestamp = request.args.get("timestamp")
    time_frame = request.args.get("timeframe", 0)
    geo = _bool(request.args.get("geo", False))

    # filter arguments.
    filter_these = _bool(request.args.get("filter-these", True))
    filter_node = request.args.get("filter-nodes", [])

    # Fetch the subgraph.
    subgraph = LANDSCAPE.graph_db.get_subgraph(node_id,
                                               timestmp=timestamp,
                                               timeframe=time_frame)

    if not subgraph:
        err_msg = "Node with ID '{}', not in the landscape.".format(node_id)
        LOG.error(err_msg)
        abort(400, err_msg)
    if filter_node:
        filter_node = ast.literal_eval(filter_node)
        subgraph = util_graph.filter_nodes(subgraph, filter_node, filter_these)
    if geo:
        subgraph = Geo.extract_geo(subgraph)

    return Response(subgraph, mimetype=MIME)
コード例 #3
0
    def get_collection(self,
                       collection,
                       from_date=None,
                       limit=None,
                       updates=False):
        # try:
        fieldName = "created"
        if updates is True:
            fieldName = "updated"
        date_filter = ""
        if from_date:
            date_filter = '&$filter=' + fieldName + '>"%s"' % from_date
        limit_filter = ""
        if limit:
            limit_filter = "&$last={}".format(limit)
        url = self.cimi_url + '/' + collection + '?$orderby=' + \
            fieldName + ':desc' + date_filter + limit_filter
        # print url
        res = requests.get(url,
                           headers={'slipstream-authn-info': 'internal ADMIN'},
                           verify=SSL_VERIFY)

        if res.status_code == 200:
            return res.json()

        LOG.error("Request failed: " + str(res.status_code))
        LOG.error("Response: " + str(res.json()))
        return dict()
コード例 #4
0
def add_new_device():
    """
    Adds a new device to the physical layer
    """
    LOG.info("Accessing URL %s", request.url)
    now_ts = time.time()
    error_log = []
    if not request.data:
        err_msg = "No device data in body"
        abort(400, err_msg)

    LOG.debug(request.data)
    data = ast.literal_eval(request.data)

    # get config manager
    from landscaper.utilities import configuration
    conf_manager = configuration.ConfigurationManager()
    conf_manager.add_section('physical_layer')
    conf_manager.add_section('general')

    # save file to disk
    from landscaper.collector.cimi_physicalhost_collector import CimiPhysicalCollector
    cimi_updater = CimiPhysicalCollector(None, conf_manager, None, None)
    cimi_updater.generate_files(data)

    if error_log:
        err_msg = "Error with the following nodes:" + str(error_log)
        abort(400, err_msg)

    return Response(status=201, mimetype=MIME)
コード例 #5
0
    def get_swarm_manager(docker_conf):
        """
        Retrieves Docker client object or error
        :return client object or error
        """
        # if docker_conf[2] and docker_conf[3]:
        #     tls_config = docker.tls.TLSConfig(
        #         client_cert=(docker_conf[2], docker_conf[3])
        #     )
        # else:
        #     tls_config = False
        #
        # manager_address = ContainerCollectorV1.get_connection_string(docker_conf)
        # client = docker.DockerClient(base_url=manager_address, tls=tls_config)
        client = docker.from_env()

        try:
            if client.swarm.init():
                LOG.info("Node joined swarm")
        except docker.errors.APIError:
            LOG.info("Node already part of swarm")

        try:
            return client
        except KeyError as err:
            raise err
コード例 #6
0
ファイル: neo4j_db.py プロジェクト: rlquinn/landscaper
    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
コード例 #7
0
    def init_graph_db(self):
        """
        Adds all neutron ports, nets and subnets to the graph database.
        """
        LOG.info("[NEUTRON] Adding Neutron components to the landscape.")
        now_ts = time.time()
        # Collect Networks
        networks = self.neutron.list_networks()
        for net in networks.get('networks', list()):
            net_id = net.get('id', "UNDEFINED")
            net_name = net.get('name', "UNDEFINED")
            self._add_network(net_id, net_name, now_ts)

        # Collect subnets
        subnets = self.neutron.list_subnets()
        for subnet in subnets.get('subnets', list()):
            subnet_id = subnet.get('id', "UNDEFINED")
            cidr = subnet.get('cidr', "UNDEFINED")
            network_id = subnet.get('network_id', "UNDEFINED")
            self._add_subnet(subnet_id, cidr, network_id, now_ts)

        # Collect ports
        ports = self.neutron.list_ports()
        for port in ports.get('ports', list()):
            port_id = port.get("id", "UNDEFINED")
            mac, fixed_ip, device_id, net_id = self._get_port_info(port)
            self._add_port(port_id, mac, fixed_ip, device_id, net_id, now_ts)
コード例 #8
0
 def _remove_physical_machine(self, machine, timestamp):
     identity = self.graph_db.get_node_by_uuid(machine)
     if identity:
         self.graph_db.delete_node(identity, timestamp)
         LOG.info("Machine : %s deleted from landscape", machine)
     else:
         LOG.error("Machine : %s not in the landscape to delete!", machine)
コード例 #9
0
def put_geolocation():
    """
    Stores the geolocation of the nodes to the database
    """
    LOG.info("Accessing URL %s", request.url)
    now_ts = time.time()
    error_log = []
    if not request.data:
        err_msg = "No coordinate data"
        abort(400, err_msg)

    data = ast.literal_eval(request.data)

    for obj in data:
        LOG.info("Updating coordinates of nodes %s", obj['id'])
        geo_string = json.dumps(obj['geo'])
        attrs = {"geo": geo_string}
        updated, msg = LANDSCAPE.graph_db.update_node(obj['id'],
                                                      now_ts,
                                                      extra_attrs=attrs)
        if not updated:
            error_log.append((obj["id"], msg))

    if error_log:
        err_msg = "Error with the following nodes:" + str(error_log)
        abort(400, err_msg)

    return Response(status=200, mimetype=MIME)
コード例 #10
0
ファイル: openstack.py プロジェクト: sandlbn/landscaper
def _get_session_keystone_v3():
    """
    Returns a keystone session variable.
    """
    from keystoneauth1.identity import v3
    from keystoneauth1 import session
    from keystoneclient.v3 import client

    user, password, auth_uri, project_name, project_id, user_domain_name = _get_connection_info(
        '3')

    auth = v3.Password(auth_url=auth_uri,
                       username=user,
                       password=password,
                       project_id=project_id,
                       user_domain_name=user_domain_name)
    envs = [
        user, password, auth_uri, project_name, project_id, user_domain_name
    ]
    msg = "AUTH with user ({e[0]}), password (****), auth_uri ({e[2]}), " \
          " project_name ({e[3]}), project_id ({e[4]}) " \
          "and user_domain_name ({e[5]}).".format(e=envs)
    LOG.info(msg)
    sess = session.Session(auth=auth)

    return sess
コード例 #11
0
ファイル: openstack.py プロジェクト: sandlbn/landscaper
def _check_conn_variables(user, password, auth_uri, project_name, project_id,
                          user_domain_name, keystone_ver):
    """
    Check that the environment variables have been found.  Without connection
    variables to the openstack testbed it is impossible to build a landscape
    any openstack components and so an exception is thrown.
    :param user: Username.
    :param password: Password.
    :param auth_uri: URI to the Openstack testbed.
    :param project_name: Tenant Name.
    :param project_id: Project ID.
    :param user_domain_name: User domain name.
    """

    envs = [
        OS_USERNAME, OS_PASSWORD, OS_PROJECT_NAME, OS_PROJECT_ID, OS_AUTH_URL,
        OS_USER_DOMAIN_NAME
    ]
    msg = ""
    if keystone_ver == '3':
        #print [user, password, auth_uri, project_name, project_id, user_domain_name]
        if not user or not password or not auth_uri or not project_name or not project_id or not user_domain_name:
            msg = "Environment variables {e[0]}, {e[1]}, {e[2]}, {e[3]}, {e[4]} " \
                  "and {e[5]} are required".format(e=envs)
    else:
        #print [user, password, auth_uri, project_name]
        if not user or not password or not auth_uri or not project_name:
            msg = "Environment variables {e[0]}, {e[1]}, {e[2]} and {e[3]} are required".format(
                e=envs)
    if len(msg) > 0:
        LOG.error(msg)
        raise ValueError(msg)
コード例 #12
0
 def init_graph_db(self):
     """
     Adds the instances to the graph database and connects them to the
     relevant machine nodes.
     """
     LOG.info(
         "ContainerCollector - Adding Docker infrastructure components to the landscape."
     )
     now_ts = time.time()
     nodes = [
         x for x in self.swarm_manager.nodes.list()
         if x.attrs["Status"]["State"] == 'ready'
     ]
     for node in nodes:
         node_id = node.attrs["ID"]
         hostname = node.attrs['Description']['Hostname']
         if 'ManagerStatus' in node.attrs:
             addr = node.attrs['ManagerStatus']['Addr']
         else:
             addr = node.attrs['Status']['Addr']
         state_attributes = self._get_instance_info(node)
         self._add_instance(node_id, addr, hostname, state_attributes,
                            now_ts)
     LOG.info(
         "ContainerCollector - Docker infrastructure components added.")
コード例 #13
0
ファイル: docker_collector.py プロジェクト: mF2C/landscaper
 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'])
コード例 #14
0
ファイル: heat_collector.py プロジェクト: sandlbn/landscaper
 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)
コード例 #15
0
    def update_graph_db(self, event, body):
        """
        Updates, adds and deletes cinder volumes based on the event type.
        :param event: Event type.
        :param body: Event details.
        """
        LOG.info("[CINDER] Cinder event received: %s.", event)
        now_ts = time.time()
        uuid = body.get("payload", dict()).get("volume_id", "UNDEFINED")
        size = body.get("payload", dict()).get("size", "UNDEFINED")
        hostname = body.get("payload", dict()).get("host", "UNDEFINED")
        if hostname:
            if "#" in hostname:
                hostname = hostname.split("#")[0]
            if "@" in hostname:
                hostname = hostname.split('@')[0]

        attachments = body.get("payload", dict()).get('volume_attachment', [])

        vm_id = "UNDEFINED"
        for attachment in attachments:
            attach_status = attachment.get("attach_status", "UNDEFINED")
            if attach_status == "attached":
                vm_id = attachment.get('instance_uuid', "UNDEFINED")

        if event in DELETE_EVENTS:
            self._delete_volume(uuid, now_ts)
        elif event in UPDATE_EVENTS:
            self._update_volume(uuid, size, hostname, vm_id, now_ts)
        elif event in ADD_EVENTS:
            self._add_volume(uuid, size, hostname, vm_id, now_ts)
コード例 #16
0
 def init_graph_db(self):
     LOG.info("[PHYS NETWORK] Adding physical network.")
     net_description = self._network_description(paths.NETWORK_DESCRIPTION)
     # Use two loops for inter switch connections.
     for switch, switch_info in net_description.iteritems():
         self._add_switch(switch, switch_info, time.time())
     for switch, switch_info in net_description.iteritems():
         self._connect_switches(switch, switch_info, time.time())
コード例 #17
0
 def on_connection_revived(self):
     """
     Method called when a connection to the broker is successfully made.
     """
     super(OSMQueueConsumer, self).on_connection_revived()
     self.retry_tracker = 0
     info_msg = "Connected to Openstack message queue at address: %s."
     LOG.info(info_msg, self.connection.as_uri())
コード例 #18
0
 def init_graph_db(self):
     """
     Add Volume nodes to the landscape.
     """
     LOG.info("[CINDER] Adding Cinder components to the landscape.")
     now_ts = time.time()
     for volume in self.cinder.volumes.list():
         volume_id, size, hostname, vm_id = self._get_volume_info(volume)
         self._add_volume(volume_id, size, hostname, vm_id, now_ts)
コード例 #19
0
 def update_graph_db(self, event, body):
     """
     Updates instances.  This method is called by the events manager.
     :param event: The event that has occurred.
     :param body: The details of the event that occurred.
     """
     LOG.info("Processing event received: %s", event)
     now_ts = time.time()
     self._process_event(now_ts, event, body)
コード例 #20
0
 def init_graph_db(self):
     """
     Build the physical layer machines and constituent components and add to
     the graph database.
     """
     LOG.info("Adding physical machines to the landscape...")
     now_ts = time.time()
     machines = self.conf_mgr.get_machines()
     self._add_physical_machine_threads(machines, now_ts)
     LOG.info("Finished adding physical machines to the landscape.")
コード例 #21
0
 def init_graph_db(self):
     """
     Adds the instances to the graph database and connects them to the
     relevant machine nodes.
     """
     LOG.info("[EDISK] Adding ephemeral_disk components to the landscape.")
     now_ts = time.time()
     self._retrieve_instance_disks()
     for instance_id, disk_obj in self.instance_disks.iteritems():
         self.attach_disk_to_instance(instance_id, disk_obj, now_ts)
コード例 #22
0
 def _add_service(self, service, timestamp):
     """
     Adds a Docker service node to the graph database.
     :param service: Docker Service object.
     :param timestamp: timestamp.
     """
     LOG.info("[DOCKER] Adding a service node the Graph")
     identity, state = self._create_docker_service_nodes(service)
     uuid = service.attrs["ID"] # WHY IS THIS DIFFERENT TO CONT? WHY DOCKER WHY?
     service_node = self.graph_db.add_node(uuid, identity, state, timestamp)
コード例 #23
0
ファイル: nova_collector.py プロジェクト: rlquinn/landscaper
 def init_graph_db(self):
     """
     Adds the instances to the graph database and connects them to the
     relevant machine nodes.
     """
     LOG.info("[NOVA] Adding Nova components to the landscape.")
     now_ts = time.time()
     for instance in self.nova.servers.list():
         vcpus, mem, name, hostname = self._get_instance_info(instance)
         self._add_instance(instance.id, vcpus, mem, name, hostname, now_ts)
コード例 #24
0
 def _connect_switches(self, switch_id, switch_info, timestamp):
     switch = self.graph_db.get_node_by_uuid(switch_id)
     for dev_id in switch_info.get('connected-devices', []):
         device = self._the_node(dev_id)
         if device:
             self.graph_db.add_edge(device, switch, timestamp,
                                    "COMMUNICATES")
         else:
             LOG.warning("Couldn't connect device '%s' to switch '%s'",
                         dev_id, switch_id)
コード例 #25
0
    def _consume_notifications(self):
        """
        Consume notification from Swarm notification queue.
        """
        LOG.info("Attempting to connect to address: %s",
                 self.connection_string)
        client = self._get_leader_client()

        for event in client.events():
            self._cb_event(event)
        return
コード例 #26
0
ファイル: heat_collector.py プロジェクト: sandlbn/landscaper
    def init_graph_db(self):
        """
        Adds stack nodes to the graph database and connects them to the
        stack's vms.
        """

        LOG.info("[HEAT] Adding Heat components to the landscape.")
        now_ts = time.time()
        for stack in self.heat.stacks.list():
            if stack.stack_status == 'CREATE_COMPLETE':
                self._add_stack(stack, now_ts)
コード例 #27
0
 def on_connection_error(self, exc, interval):
     """
     Method called when there is a connection problem.
     :param exc: The connection exception.
     :param interval: The interval until the next reconnect attempt is made.
     """
     super(OSMQueueConsumer, self).on_connection_error(exc, interval)
     self.retry_tracker += 1
     err_msg = "Broker connection error: %s. Attempting reconnect " \
               "(%s/%s) in %ss."
     LOG.warning(err_msg, exc, self.retry_tracker, self.connect_max_retries,
                 interval)
コード例 #28
0
 def listen_for_events(self):
     """
     Entry point for the child event listener.
     """
     msg = "Connecting to Openstack message queue at address: %s."
     with Connection(self.connection_string) as conn:
         consumer = OSMQueueConsumer(conn, self._queues(), self._cb_event)
         try:
             LOG.info(msg, self.connection_string)
             consumer.run()
         except exceptions.KombuError as exc:
             LOG.error(exc, exc_info=1)
コード例 #29
0
    def generate_files(self, device, dynamic={}):
        """
        Queries the hwloc and cpuinfo methods and writes them to a file
        :param device: CIMI Device object containing hwloc and cpu_info methods
        :param dynamic: CIMI device-dynamic object pertaining to the device object
        :return: True if file successfully saved and hostname, False if errors encountered
        """
        hostname = ""
        device_id = device['id']
        try:
            hwloc = device.get("hwloc")
            if hwloc is None:
                LOG.error("hwLoc data has not been set for this device: " +
                          device_id + ". No HwLoc file will be saved.")
                return False

            cpu_info = device.get("cpuinfo")
            if cpu_info is None:
                LOG.error("CPU_info data has not been set for this device: " +
                          device_id + ". No CPU_info file will be saved.")

            if dynamic:
                hwloc, hostname = self._parse_hwloc(device, hwloc, dynamic)
                LOG.info("Dynamic data has been set for this device: " +
                         device_id)
            else:
                hwloc, hostname = self._parse_hwloc(device, hwloc)
                LOG.error("Dynamic data has not been set for this device: " +
                          device_id + ". No dynamic file will be saved.")

            self.device_dict[device_id] = hostname
            # save the dynamic info to file
            if dynamic:
                dynamic_path = os.path.join(paths.DATA_DIR,
                                            hostname + "_dynamic.add")
                self._write_to_file(dynamic_path, json.dumps(dynamic))

            # save the cpu info to file
            if cpu_info:
                cpu_path = os.path.join(paths.DATA_DIR,
                                        hostname + "_cpuinfo.txt")
                self._write_to_file(cpu_path, cpu_info)

            # save the hwloc to file
            hwloc_path = os.path.join(paths.DATA_DIR, hostname + "_hwloc.xml")
            self._write_to_file(hwloc_path, hwloc)

        except Exception as ex:
            LOG.error(
                "General Error hwloc/cpuinfo for device: {} - Error message: {}"
                .format(device['id'], ex.message))
            return False, None
        return True, hostname
コード例 #30
0
    def _consume_notifications(self):
        """
        Consume notification from Swarm notification queue.
        """
        LOG.info("Subscribing to Docker events...")
        client = self._get_leader_client()

        for event in client.events():
            LOG.info(event)
            self._cb_event(event)

        return