import logging import socket from celery import shared_task from opcua import Client from incident.models import Incident from incident_export.models import SyslogReceiver, OpcuaReceiver from incident_export.services.export import incident_to_cef _log = logging.getLogger(__name__) def export_incident_syslog(incident): """ Function for sending event (incident for now) to syslog receivers :param incident: Incident object for sending """ protocol_socktype_map = { 'UDP': socket.SOCK_DGRAM, 'TCP': socket.SOCK_STREAM, } # Getting syslog receivers syslog_receivers = SyslogReceiver.objects.all() my_logger = logging.getLogger('ARMASyslogExportLogger') # We will pass the message as INFO my_logger.setLevel(logging.INFO) # Forming incident string cef_message = incident_to_cef(incident) for receiver in syslog_receivers: if not receiver.receiver.export_status: continue socktype = protocol_socktype_map.get(receiver.protocol, socket.SOCK_DGRAM) try: handler = logging.handlers.SysLogHandler(address=(receiver.host, receiver.port), socktype=socktype) my_logger.addHandler(handler) my_logger.info(cef_message) my_logger.removeHandler(handler) except Exception as e: _log.error( f"Following error occurred during event export to syslog host {receiver.host}:{receiver.port} [{e}]") def export_incident_opcua(incident): """ Function for sending event (incident for now) to opcua receivers :param incident: Incident object for sending """ opcua_receivers = OpcuaReceiver.objects.all() cef_message = incident_to_cef(incident) for receiver in opcua_receivers: if receiver.receiver.export_status: host_address = 'opc.tcp://' + str(receiver.host) + ':' + str(receiver.port) client = Client(host_address) try: client.connect() server_objects = client.get_objects_node() server_childs = server_objects.get_children() last_inc = server_childs[1] last_inc_value = last_inc.get_children()[0] last_inc_value.set_value(cef_message) client.disconnect() except Exception as e: _log.error( f"Following error occurred during event export to opcua host {receiver.host}:{receiver.port} : [{e}]") @shared_task def export_incident(incident_pk): """ Task for exporting incidents @param incident_pk: PK Incident instance, which will be exported """ try: incident_instance = Incident.objects.get(pk=incident_pk) except Incident.DoesNotExist: _log.warning(f'Incident with id {incident_pk} not found') return export_incident_syslog(incident_instance) export_incident_opcua(incident_instance)