Пример #1
0
    def send_data_to_wdb(data, timeout):
        """Send chunks of data to Wazuh-db socket.

        Parameters
        ----------
        data : dict
            Dict containing command and list of chunks to be sent to wazuh-db.
        timeout : int
            Seconds to wait before stopping the task.

        Returns
        -------
        result : dict
            Dict containing number of updated chunks, error messages (if any) and time spent.
        """
        result = {
            'updated_chunks': 0,
            'error_messages': {
                'chunks': [],
                'others': []
            },
            'time_spent': 0
        }
        wdb_conn = WazuhDBConnection()
        before = datetime.utcnow().timestamp()

        try:
            with utils.Timeout(timeout):
                for i, chunk in enumerate(data['chunks']):
                    try:
                        wdb_conn.send(f"{data['set_data_command']} {chunk}",
                                      raw=True)
                        result['updated_chunks'] += 1
                    except TimeoutError:
                        raise e
                    except Exception as e:
                        result['error_messages']['chunks'].append((i, str(e)))
        except TimeoutError:
            result['error_messages']['others'].append(
                'Timeout while processing agent-info chunks.')
        except Exception as e:
            result['error_messages']['others'].append(
                f'Error while processing agent-info chunks: {e}')

        result['time_spent'] = datetime.utcnow().timestamp() - before
        wdb_conn.close()
        return result
Пример #2
0
    async def sync_wazuh_db_info(self, task_id: bytes):
        """Iterate and update in the local wazuh-db the chunks of data received from a worker.

        Parameters
        ----------
        task_id : bytes
            ID of the string where the JSON chunks are stored.

        Returns
        -------
        result : bytes
            Worker's response after finishing the synchronization.
        """
        logger = self.task_loggers['Agent-info sync']
        logger.info(f"Starting")
        date_start_master = datetime.now()
        wdb_conn = WazuhDBConnection()
        result = {'updated_chunks': 0, 'error_messages': list()}

        try:
            # Chunks were stored under 'task_id' as an string.
            received_string = self.in_str[task_id].payload
            data = json.loads(received_string.decode())
        except KeyError as e:
            await self.send_request(command=b'syn_m_a_err',
                                    data=f"error while trying to access string under task_id {str(e)}.".encode())
            raise exception.WazuhClusterError(3035, extra_message=f"it should be under task_id {str(e)}, but it's empty.")
        except ValueError as e:
            await self.send_request(command=b'syn_m_a_err', data=f"error while trying to load JSON: {str(e)}".encode())
            raise exception.WazuhClusterError(3036, extra_message=str(e))

        # Update chunks in local wazuh-db
        before = time()
        for i, chunk in enumerate(data['chunks']):
            try:
                logger.debug2(f"Sending chunk {i+1}/{len(data['chunks'])} to wazuh-db: {chunk}")
                response = wdb_conn.send(f"{data['set_data_command']} {chunk}", raw=True)
                if response[0] != 'ok':
                    result['error_messages'].append(response)
                    logger.error(f"Response for chunk {i}/{len(data['chunks'])} was not 'ok': {response}")
                else:
                    result['updated_chunks'] += 1
            except Exception as e:
                result['error_messages'].append(str(e))
        logger.debug(f"All chunks updated in wazuh-db in {(time() - before):3f}s.")

        # Send result to worker
        response = await self.send_request(command=b'syn_m_a_e', data=json.dumps(result).encode())
        self.sync_agent_info_status.update({'date_start_master': date_start_master, 'date_end_master': datetime.now(),
                                            'n_synced_chunks': result['updated_chunks']})
        logger.info("Finished in {:.3f}s ({} chunks updated).".format((self.sync_agent_info_status['date_end_master'] -
                                                                       self.sync_agent_info_status['date_start_master'])
                                                                      .total_seconds(), result['updated_chunks']))

        return response