Ejemplo n.º 1
0
def post_results(msn, user_agent, ip, results):
    event_uuid = uuid.uuid4()
    if user_agent or ip:
        request = EventRequest(user_agent, ip)
    else:
        request = None
    cc_status_agg = ComplianceCheckStatusAggregator(msn)
    for index, result in enumerate(_iter_cleaned_up_records(results)):
        try:
            event_time = _get_record_created_at(result)
        except Exception:
            logger.exception("Could not extract osquery result time")
            event_time = None
        metadata = EventMetadata(uuid=event_uuid,
                                 index=index,
                                 machine_serial_number=msn,
                                 request=request,
                                 created_at=event_time)
        event = OsqueryResultEvent(metadata, result)
        event.post()
        snapshot = event.payload.get("snapshot")
        if snapshot is None:
            # no snapshot, cannot be a compliance check
            continue
        try:
            _, query_pk, query_version = event.parse_result_name()
        except ValueError as e:
            logger.warning(str(e))
            continue
        cc_status_agg.add_result(query_pk, query_version, event_time, snapshot)
    cc_status_agg.commit_and_post_events()
Ejemplo n.º 2
0
    def do_node_post(self):
        results = self.data.get("queries", {})
        statuses = self.data.get("statuses", {})
        messages = self.data.get("messages", {})
        dqm_pk_set = set(chain(results.keys(), statuses.keys(), messages.keys()))
        if not dqm_pk_set:
            return {}
        dqm_cache = {str(dqm.pk): dqm
                     for dqm in DistributedQueryMachine.objects
                                                       .select_related("distributed_query__query__compliance_check")
                                                       .filter(pk__in=dqm_pk_set)}

        # update distributed query machines
        for dqm_pk, dqm in dqm_cache.items():
            status = statuses.get(dqm_pk)
            if status is None:
                logger.warning("Missing status for DistributedQueryMachine %s", dqm_pk)
                status = 999  # TODO: better?
            dqm.status = status
            dqm.error_message = messages.get(dqm_pk)
            dqm.save()

        # save_results
        dq_results = (
            DistributedQueryResult(
                distributed_query=dqm.distributed_query,
                serial_number=self.machine.serial_number,
                row=remove_null_character(row)
            )
            for dqm_pk, dqm in dqm_cache.items()
            for row in results.get(dqm_pk, [])
        )
        while True:
            batch = list(islice(dq_results, self.batch_size))
            if not batch:
                break
            DistributedQueryResult.objects.bulk_create(batch, self.batch_size)

        # process compliance checks
        cc_status_agg = ComplianceCheckStatusAggregator(self.machine.serial_number)
        status_time = datetime.utcnow()  # TODO: how to get a better time? add ztl_status_time = now() to the query?
        for dqm_pk, dqm in dqm_cache.items():
            distributed_query = dqm.distributed_query
            query = distributed_query.query
            if not query or not query.compliance_check:
                continue
            cc_status_agg.add_result(
                query.pk,
                distributed_query.query_version,
                status_time,
                results.get(dqm_pk, []),
                distributed_query.pk
            )
        cc_status_agg.commit_and_post_events()

        return {}