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
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