Writes hunt results from a given client as part of a given hunt.
498028
def WriteHuntResults(client_id, hunt_id, responses):
  """"""

  if not hunt.IsLegacyHunt(hunt_id):
    data_store.REL_DB.WriteFlowResults(responses)

    hunt.StopHuntIfCPUOrNetworkLimitsExceeded(hunt_id)
    return

  hunt_id_urn = rdfvalue.RDFURN("hunts").Add(hunt_id)

  msgs = []
  for response in responses:
    if isinstance(response, rdf_flow_objects.FlowStatus):
      continue

    msgs.append(
        rdf_flows.GrrMessage(payload=response.payload, source=client_id))

  with data_store.DB.GetMutationPool() as pool:
    for msg in msgs:
      hunts_results.HuntResultCollection.StaticAdd(
          hunt_id_urn.Add("Results"), msg, mutation_pool=pool)

    for msg in msgs:
      multi_type_collection.MultiTypeCollection.StaticAdd(
          hunt_id_urn.Add("ResultsPerType"), msg, mutation_pool=pool)

  stats_collector_instance.Get().IncrementCounter(
      "hunt_results_added", delta=len(responses))
814132
def WriteClientSnapshot(self, snapshot, cursor=None):
    """"""
    insert_history_query = (
        "INSERT INTO client_snapshot_history(client_id, timestamp, "
        "client_snapshot) VALUES (%s, FROM_UNIXTIME(%s), %s)")
    insert_startup_query = (
        "INSERT INTO client_startup_history(client_id, timestamp, "
        "startup_info) VALUES(%s, FROM_UNIXTIME(%s), %s)")

    now = rdfvalue.RDFDatetime.Now()

    client_platform = snapshot.knowledge_base.os
    current_timestamp = mysql_utils.RDFDatetimeToTimestamp(now)
    client_info = {
        "last_snapshot_timestamp": current_timestamp,
        "last_startup_timestamp": current_timestamp,
        "last_version_string": snapshot.GetGRRVersionString(),
        "last_platform_release": snapshot.Uname(),
    }
    update_clauses = [
        "last_snapshot_timestamp = FROM_UNIXTIME(%(last_snapshot_timestamp)s)",
        "last_startup_timestamp = FROM_UNIXTIME(%(last_startup_timestamp)s)",
        "last_version_string = %(last_version_string)s",
        "last_platform_release = %(last_platform_release)s",
    ]
    if client_platform:
      client_info["last_platform"] = client_platform
      update_clauses.append("last_platform = %(last_platform)s")

    update_query = (
        "UPDATE clients SET {} WHERE client_id = %(client_id)s".format(
            ", ".join(update_clauses)))

    int_client_id = db_utils.ClientIDToInt(snapshot.client_id)
    client_info["client_id"] = int_client_id

    startup_info = snapshot.startup_info
    snapshot.startup_info = None
    try:
      cursor.execute(
          insert_history_query,
          (int_client_id, current_timestamp, snapshot.SerializeToString()))
      cursor.execute(
          insert_startup_query,
          (int_client_id, current_timestamp, startup_info.SerializeToString()))
      cursor.execute(update_query, client_info)
    except MySQLdb.IntegrityError as e:
      raise db.UnknownClientError(snapshot.client_id, cause=e)
    finally:
      snapshot.startup_info = startup_info
896577
def ReadHuntLogEntries(self, hunt_id, offset, count, with_substring=None):
    """"""
    all_entries = []
    for flow_obj in self._GetHuntFlows(hunt_id):
      for entry in self.ReadFlowLogEntries(
          flow_obj.client_id,
          flow_obj.flow_id,
          0,
          sys.maxsize,
          with_substring=with_substring):

        all_entries.append(
            rdf_flow_objects.FlowLogEntry(
                hunt_id=hunt_id,
                client_id=flow_obj.client_id,
                flow_id=flow_obj.flow_id,
                timestamp=entry.timestamp,
                message=entry.message))

    return sorted(all_entries, key=lambda x: x.timestamp)[offset:offset + count]
885770
def _RunActions(self, rule, client_id):
    
    actions_count = 0

    for action in rule.actions:
      try:
        # Say this flow came from the foreman.
        token = self.token.Copy()
        token.username = "Foreman"

        if action.HasField("hunt_id"):
          if self._CheckIfHuntTaskWasAssigned(client_id, action.hunt_id):
            logging.info(
                "Foreman: ignoring hunt %s on client %s: was started "
                "here before", client_id, action.hunt_id)
          else:
            logging.info("Foreman: Starting hunt %s on client %s.",
                         action.hunt_id, client_id)

            flow_cls = registry.AFF4FlowRegistry.FlowClassByName(
                action.hunt_name)
            flow_cls.StartClients(action.hunt_id, [client_id])
            actions_count += 1
        else:
          flow.StartAFF4Flow(
              client_id=client_id,
              flow_name=action.flow_name,
              token=token,
              **action.argv.ToDict())
          actions_count += 1
      # There could be all kinds of errors we don't know about when starting the
      # flow/hunt so we catch everything here.
      except Exception as e:  # pylint: disable=broad-except
        logging.exception("Failure running foreman action on client %s: %s",
                          action.hunt_id, e)

    return actions_count
1162551
public final void writeAndFlushToAllExcept(Packet packet, Collection<? extends Client> clients) {
        writeHelper(packet::writeAndFlush, clients);
    }
321728
def WriteClientSnapshotHistory(self, clients, cursor=None):
    """"""
    client_id = clients[0].client_id
    latest_timestamp = max(client.timestamp for client in clients)

    query = ""
    params = {
        "client_id": db_utils.ClientIDToInt(client_id),
        "latest_timestamp": mysql_utils.RDFDatetimeToTimestamp(latest_timestamp)
    }

    for idx, client in enumerate(clients):
      startup_info = client.startup_info
      client.startup_info = None

      query += """
      INSERT INTO client_snapshot_history (client_id, timestamp,
                                           client_snapshot)
      VALUES (%(client_id)s, FROM_UNIXTIME(%(timestamp_{idx})s),
              %(client_snapshot_{idx})s);

      INSERT INTO client_startup_history (client_id, timestamp,
                                          startup_info)
      VALUES (%(client_id)s, FROM_UNIXTIME(%(timestamp_{idx})s),
              %(startup_info_{idx})s);
      """.format(idx=idx)

      params.update({
          "timestamp_{idx}".format(idx=idx):
              mysql_utils.RDFDatetimeToTimestamp(client.timestamp),
          "client_snapshot_{idx}".format(idx=idx):
              client.SerializeToString(),
          "startup_info_{idx}".format(idx=idx):
              startup_info.SerializeToString(),
      })

      client.startup_info = startup_info

    query += """
    UPDATE clients
       SET last_snapshot_timestamp = FROM_UNIXTIME(%(latest_timestamp)s)
     WHERE client_id = %(client_id)s
       AND (last_snapshot_timestamp IS NULL OR
            last_snapshot_timestamp < FROM_UNIXTIME(%(latest_timestamp)s));

    UPDATE clients
       SET last_startup_timestamp = FROM_UNIXTIME(%(latest_timestamp)s)
     WHERE client_id = %(client_id)s
       AND (last_startup_timestamp IS NULL OR
            last_startup_timestamp < FROM_UNIXTIME(%(latest_timestamp)s));
    """

    try:
      cursor.execute(query, params)
    except MySQLdb.IntegrityError as error:
      raise db.UnknownClientError(client_id, cause=error)
114909
def WriteFlowRequests(self, requests, cursor=None):
    """"""
    args = []
    templates = []
    flow_keys = []
    needs_processing = {}

    for r in requests:
      if r.needs_processing:
        needs_processing.setdefault((r.client_id, r.flow_id), []).append(r)

      flow_keys.append((r.client_id, r.flow_id))
      templates.append("(%s, %s, %s, %s, %s)")
      args.extend([
          db_utils.ClientIDToInt(r.client_id),
          db_utils.FlowIDToInt(r.flow_id), r.request_id, r.needs_processing,
          r.SerializeToString()
      ])

    if needs_processing:
      flow_processing_requests = []
      nr_conditions = []
      nr_args = []
      for client_id, flow_id in needs_processing:
        nr_conditions.append("(client_id=%s AND flow_id=%s)")
        nr_args.append(db_utils.ClientIDToInt(client_id))
        nr_args.append(db_utils.FlowIDToInt(flow_id))

      nr_query = ("SELECT client_id, flow_id, next_request_to_process "
                  "FROM flows WHERE ")
      nr_query += " OR ".join(nr_conditions)

      cursor.execute(nr_query, nr_args)

      db_result = cursor.fetchall()
      for client_id_int, flow_id_int, next_request_to_process in db_result:
        client_id = db_utils.IntToClientID(client_id_int)
        flow_id = db_utils.IntToFlowID(flow_id_int)
        candidate_requests = needs_processing.get((client_id, flow_id), [])
        for r in candidate_requests:
          if next_request_to_process == r.request_id:
            flow_processing_requests.append(
                rdf_flows.FlowProcessingRequest(
                    client_id=client_id,
                    flow_id=flow_id,
                    delivery_time=r.start_time))

      if flow_processing_requests:
        self._WriteFlowProcessingRequests(flow_processing_requests, cursor)

    query = ("INSERT INTO flow_requests "
             "(client_id, flow_id, request_id, needs_processing, request) "
             "VALUES ")
    query += ", ".join(templates)
    try:
      cursor.execute(query, args)
    except MySQLdb.IntegrityError as e:
      raise db.AtLeastOneUnknownFlowError(flow_keys, cause=e)
436272
@Override
    public void write(Iterable<QueryResult> results) {
        logger.debug("Export to '{}', proxy {} metrics {}", url, proxy, results);

        List<QueryResult> counters = new ArrayList<QueryResult>();
        List<QueryResult> gauges = new ArrayList<QueryResult>();
        for (QueryResult result : results) {
            if (METRIC_TYPE_GAUGE.equals(result.getType())) {
                gauges.add(result);
            } else if (METRIC_TYPE_COUNTER.equals(result.getType())) {
                counters.add(result);
            } else if (null == result.getType()) {
                logger.info("Unspecified type for result {}, export it as counter");
                counters.add(result);
            } else {
                logger.info("Unsupported metric type '{}' for result {}, export it as counter", result.getType(), result);
                counters.add(result);
            }
        }


        HttpURLConnection urlConnection = null;
        try {
            if (proxy == null) {
                urlConnection = (HttpURLConnection) url.openConnection();
            } else {
                urlConnection = (HttpURLConnection) url.openConnection(proxy);
            }
            urlConnection.setRequestMethod("POST");
            urlConnection.setDoInput(true);
            urlConnection.setDoOutput(true);
            urlConnection.setReadTimeout(libratoApiTimeoutInMillis);
            urlConnection.setRequestProperty("content-type", "application/json; charset=utf-8");
            urlConnection.setRequestProperty("Authorization", "Basic " + basicAuthentication);
            urlConnection.setRequestProperty("User-Agent", httpUserAgent);

            serialize(counters, gauges, urlConnection.getOutputStream());
            int responseCode = urlConnection.getResponseCode();
            if (responseCode != 200) {
                exceptionCounter.incrementAndGet();
                logger.warn("Failure {}:'{}' to send result to Librato server '{}' with proxy {}, user {}", responseCode, urlConnection.getResponseMessage(), url, proxy, user);
            }
            if (logger.isTraceEnabled()) {
                IoUtils2.copy(urlConnection.getInputStream(), System.out);
            }
        } catch (Exception e) {
            exceptionCounter.incrementAndGet();
            logger.warn("Failure to send result to Librato server '{}' with proxy {}, user {}", url, proxy, user, e);
        } finally {
            if (urlConnection != null) {
                try {
                    InputStream in = urlConnection.getInputStream();
                    IoUtils2.copy(in, IoUtils2.nullOutputStream());
                    IoUtils2.closeQuietly(in);
                    InputStream err = urlConnection.getErrorStream();
                    if (err != null) {
                        IoUtils2.copy(err, IoUtils2.nullOutputStream());
                        IoUtils2.closeQuietly(err);
                    }
                } catch (IOException e) {
                    logger.warn("Exception flushing http connection", e);
                }
            }

        }
    }
1082595
def Start(self):
    """"""
    # We are already running.
    if self.hunt_obj.Get(self.hunt_obj.Schema.STATE) == "STARTED":
      return

    # Determine when this hunt will expire.
    self.context.duration = self.runner_args.expiry_time

    # When the next client can be scheduled. Implements gradual client
    # recruitment rate according to the client_rate.
    self.context.next_client_due = rdfvalue.RDFDatetime.Now()

    self._CreateAuditEvent("HUNT_STARTED")

    # Start the hunt.
    self.hunt_obj.Set(self.hunt_obj.Schema.STATE("STARTED"))
    self.hunt_obj.Flush()

    if self.runner_args.add_foreman_rules:
      self._AddForemanRule()
835111
def ProcessHuntClientCrash(flow_obj, client_crash_info):
  """"""

  if not hunt.IsLegacyHunt(flow_obj.parent_hunt_id):
    hunt.StopHuntIfCrashLimitExceeded(flow_obj.parent_hunt_id)
    return

  hunt_urn = rdfvalue.RDFURN("hunts").Add(flow_obj.parent_hunt_id)

  with aff4.FACTORY.Open(hunt_urn, mode="rw") as fd:
    # Legacy AFF4 code expects token to be set.
    fd.token = access_control.ACLToken(username=fd.creator)
    fd.RegisterCrash(client_crash_info)
308757
def send_results(self, client, addr, results):
        
        json_results = json.dumps(results)
        json_results = json_results.encode()

        sent = 0
        total_len = len(json_results)
        got_error = False
        while (sent < total_len):
            this_sent = client.send(json_results[sent:])
            if this_sent == 0:
                got_error = True
                break
            sent += this_sent
        if got_error or sent != total_len:
            self.log_error("(%s:%s) Failed to send back results to client, "
                           "results: %s" % (addr[0], addr[1], json_results))
        else:
            self.log_debug("(%s:%s) Results sent back to client successfully."
                           % (addr[0], addr[1]))
892440
def ReadHuntOutputPluginLogEntries(self,
                                     hunt_id,
                                     output_plugin_id,
                                     offset,
                                     count,
                                     with_type=None,
                                     cursor=None):
    """"""
    query = ("SELECT client_id, flow_id, log_entry_type, message, "
             "UNIX_TIMESTAMP(timestamp) "
             "FROM flow_output_plugin_log_entries "
             "FORCE INDEX (flow_output_plugin_log_entries_by_hunt) "
             "WHERE hunt_id = %s AND output_plugin_id = %s ")
    args = [
        db_utils.HuntIDToInt(hunt_id),
        db_utils.OutputPluginIDToInt(output_plugin_id)
    ]

    if with_type is not None:
      query += "AND log_entry_type = %s "
      args.append(int(with_type))

    query += "ORDER BY log_id ASC LIMIT %s OFFSET %s"
    args.append(count)
    args.append(offset)

    cursor.execute(query, args)

    ret = []
    for (client_id_int, flow_id_int, log_entry_type, message,
         timestamp) in cursor.fetchall():
      ret.append(
          rdf_flow_objects.FlowOutputPluginLogEntry(
              hunt_id=hunt_id,
              client_id=db_utils.IntToClientID(client_id_int),
              flow_id=db_utils.IntToFlowID(flow_id_int),
              output_plugin_id=output_plugin_id,
              log_entry_type=log_entry_type,
              message=message,
              timestamp=mysql_utils.TimestampToRDFDatetime(timestamp)))

    return ret
11247
def ProcessHuntFlowLog(flow_obj, log_msg):
  """"""

  if not hunt.IsLegacyHunt(flow_obj.parent_hunt_id):
    return

  hunt_urn = rdfvalue.RDFURN("hunts").Add(flow_obj.parent_hunt_id)
  flow_urn = hunt_urn.Add(flow_obj.flow_id)
  log_entry = rdf_flows.FlowLog(
      client_id=flow_obj.client_id,
      urn=flow_urn,
      flow_name=flow_obj.flow_class_name,
      log_message=log_msg)
  with data_store.DB.GetMutationPool() as pool:
    grr_collections.LogCollection.StaticAdd(
        hunt_urn.Add("Logs"), log_entry, mutation_pool=pool)
458105
def ReadHuntLogEntries(self,
                         hunt_id,
                         offset,
                         count,
                         with_substring=None,
                         cursor=None):
    """"""
    hunt_id_int = db_utils.HuntIDToInt(hunt_id)

    query = ("SELECT client_id, flow_id, message, UNIX_TIMESTAMP(timestamp) "
             "FROM flow_log_entries "
             "FORCE INDEX(flow_log_entries_by_hunt) "
             "WHERE hunt_id = %s AND flow_id = hunt_id ")

    args = [hunt_id_int]

    if with_substring is not None:
      query += "AND message LIKE %s "
      args.append("%" + db_utils.EscapeWildcards(with_substring) + "%")

    query += "ORDER BY timestamp ASC LIMIT %s OFFSET %s"

    args.append(count)
    args.append(offset)

    cursor.execute(query, args)

    flow_log_entries = []
    for client_id_int, flow_id_int, message, timestamp in cursor.fetchall():
      flow_log_entries.append(
          rdf_flow_objects.FlowLogEntry(
              client_id=db_utils.IntToClientID(client_id_int),
              flow_id=db_utils.IntToFlowID(flow_id_int),
              hunt_id=hunt_id,
              message=message,
              timestamp=mysql_utils.TimestampToRDFDatetime(timestamp)))

    return flow_log_entries
329836
def WriteClientActionRequests(self, requests, cursor=None):
    """"""

    query = ("INSERT IGNORE INTO client_action_requests "
             "(client_id, flow_id, request_id, timestamp, request) "
             "VALUES %s ON DUPLICATE KEY UPDATE "
             "timestamp=VALUES(timestamp), request=VALUES(request)")
    now = mysql_utils.RDFDatetimeToTimestamp(rdfvalue.RDFDatetime.Now())

    value_templates = []
    args = []
    for r in requests:
      args.extend([
          db_utils.ClientIDToInt(r.client_id),
          db_utils.FlowIDToInt(r.flow_id), r.request_id, now,
          r.SerializeToString()
      ])
      value_templates.append("(%s, %s, %s, FROM_UNIXTIME(%s), %s)")

    query %= ",".join(value_templates)
    try:
      cursor.execute(query, args)
    except MySQLdb.IntegrityError as e:
      request_keys = [(r.client_id, r.flow_id, r.request_id) for r in requests]
      raise db.AtLeastOneUnknownRequestError(request_keys=request_keys, cause=e)
161470
void writeResult(final RpcResult<?, ?> result, final HttpServletResponse resp)
			throws IOException {
		if (result.isSuccess()) {
			resp.setStatus(HttpServletResponse.SC_OK);
			resp.setContentType(JSON_CONTENT_TYPE);
		} else {
			resp.setStatus(APPLICATION_EXC_STATUS);
			resp.setContentType(JSON_CONTENT_TYPE);
		}

		PrintWriter writer = resp.getWriter();
		result.toJson(writer, true);
		writer.flush();
	}
903305
def UpdateHunt(hunt_id, client_limit=None, client_rate=None, duration=None):
  """"""

  hunt_obj = data_store.REL_DB.ReadHuntObject(hunt_id)
  if hunt_obj.hunt_state != hunt_obj.HuntState.PAUSED:
    raise OnlyPausedHuntCanBeModifiedError(hunt_obj)

  data_store.REL_DB.UpdateHuntObject(
      hunt_id,
      client_limit=client_limit,
      client_rate=client_rate,
      duration=duration)
  return data_store.REL_DB.ReadHuntObject(hunt_id)