Beispiel #1
0
def _GetLastContactFromFleetspeak(client_ids):
    """Fetches last contact times for the given clients from Fleetspeak.

  Args:
    client_ids: Iterable containing GRR client ids.

  Returns:
    A dict mapping the given client ids to timestamps representing when
    Fleetspeak last contacted the clients.
  """
    if not fleetspeak_connector.CONN or not fleetspeak_connector.CONN.outgoing:
        logging.warning(
            "Tried to get last-contact timestamps for Fleetspeak clients "
            "without an active connection to Fleetspeak.")
        return {}
    fs_ids = [fleetspeak_utils.GRRIDToFleetspeakID(cid) for cid in client_ids]
    fs_result = fleetspeak_connector.CONN.outgoing.ListClients(
        admin_pb2.ListClientsRequest(client_ids=fs_ids))
    if len(client_ids) != len(fs_result.clients):
        logging.error("Expected %d results from Fleetspeak; got %d instead.",
                      len(client_ids), len(fs_result.clients))
    last_contact_times = {}
    for fs_client in fs_result.clients:
        grr_id = fleetspeak_utils.FleetspeakIDToGRRID(fs_client.client_id)
        last_contact_times[grr_id] = fleetspeak_utils.TSToRDFDatetime(
            fs_client.last_contact_time)
    return last_contact_times
Beispiel #2
0
def UpdateClientsFromFleetspeak(clients):
  """Updates ApiClient records to include info from Fleetspeak."""
  if not fleetspeak_connector.CONN or not fleetspeak_connector.CONN.outgoing:
    # FS not configured, or an outgoing connection is otherwise unavailable.
    return
  id_map = {}
  for client in clients:
    if client.fleetspeak_enabled:
      id_map[fleetspeak_utils.GRRIDToFleetspeakID(client.client_id)] = client
  if not id_map:
    return
  res = fleetspeak_connector.CONN.outgoing.ListClients(
      admin_pb2.ListClientsRequest(client_ids=list(iterkeys(id_map))))
  for read in res.clients:
    api_client = id_map[read.client_id]
    api_client.last_seen_at = fleetspeak_utils.TSToRDFDatetime(
        read.last_contact_time)
    api_client.last_clock = fleetspeak_utils.TSToRDFDatetime(read.last_clock)
Beispiel #3
0
    def Run(self):
        if not fleetspeak_connector.CONN or not fleetspeak_connector.CONN.outgoing:
            # Nothing to do if Fleetspeak is not enabled.
            self.Log("Fleetspeak has not been initialized. Will do nothing.")
            return

        if not data_store.RelationalDBWriteEnabled():
            raise NotImplementedError(
                "Cronjob does not support the legacy datastore.")

        age_threshold = config.CONFIG["Server.fleetspeak_last_ping_threshold"]
        max_last_ping = rdfvalue.RDFDatetime.Now() - age_threshold
        last_pings = data_store.REL_DB.ReadClientLastPings(
            max_last_ping=max_last_ping, fleetspeak_enabled=True)

        num_clients_updated = 0
        batch_size = config.CONFIG["Server.fleetspeak_list_clients_batch_size"]
        for client_ids in collection.Batch(iterkeys(last_pings), batch_size):
            fs_ids = [
                fleetspeak_utils.GRRIDToFleetspeakID(i) for i in client_ids
            ]
            request_start = rdfvalue.RDFDatetime.Now()
            fs_result = fleetspeak_connector.CONN.outgoing.ListClients(
                admin_pb2.ListClientsRequest(client_ids=fs_ids))
            latency = rdfvalue.RDFDatetime.Now() - request_start
            logging.info("Fleetspeak ListClients() took %s.", latency)
            stats_collector_instance.Get().RecordEvent(
                "fleetspeak_last_ping_latency_millis", latency.milliseconds)

            for fs_client in fs_result.clients:
                grr_id = fleetspeak_utils.FleetspeakIDToGRRID(
                    fs_client.client_id)
                new_last_ping = fleetspeak_utils.TSToRDFDatetime(
                    fs_client.last_contact_time)
                if last_pings[grr_id] is None or last_pings[
                        grr_id] < new_last_ping:
                    data_store.REL_DB.WriteClientMetadata(
                        grr_id, last_ping=new_last_ping)
                    num_clients_updated += 1

            self.Log("Updated timestamps for %d clients.", num_clients_updated)