from zentral.core.events import BaseEvent, EventMetadata, EventRequest, register_event_type logger = logging.getLogger('zentral.contrib.osquery.events') __all__ = ['OsqueryEnrollmentEvent', 'OsqueryResultEvent', 'OsqueryStatusEvent'] class OsqueryEvent(BaseEvent): pass class OsqueryEnrollmentEvent(OsqueryEvent): event_type = "osquery_enrollment" register_event_type(OsqueryEnrollmentEvent) class OsqueryRequestEvent(OsqueryEvent): event_type = "osquery_request" register_event_type(OsqueryRequestEvent) class OsqueryResultEvent(OsqueryEvent): event_type = "osquery_result" def __init__(self, *args, **kwargs): super(OsqueryResultEvent, self).__init__(*args, **kwargs) self._set_probe_and_query_from_payload()
from zentral.contrib.santa import probes_lookup_dict from zentral.core.events import BaseEvent, EventMetadata, EventRequest, register_event_type logger = logging.getLogger('zentral.contrib.santa.events') __all__ = ['post_santa_events', 'post_santa_preflight', 'SantaEventEvent', 'SantaPreflightEvent'] class SantaBaseEvent(BaseEvent): pass class SantaPreflightEvent(SantaBaseEvent): event_type = "santa_preflight" register_event_type(SantaPreflightEvent) class SantaEventEvent(SantaBaseEvent): event_type = "santa_event" def __init__(self, *args, **kwargs): super(SantaBaseEvent, self).__init__(*args, **kwargs) self.rule_probes = self._get_rule_probes() def _get_rule_probes(self): """Find the probes that could have triggered the event.""" # TODO: the whole zentral contrib app works only with sha256 # TODO: we could do a better job and try to match the policy # with the santa event "decision" attr and remove some extra matching probes
import logging from zentral.core.events import BaseEvent, EventMetadata, EventRequest, register_event_type logger = logging.getLogger('zentral.contrib.jss.events') class JSSEvent(BaseEvent): event_type = "jss_event" register_event_type(JSSEvent) def post_jss_event(msn, user_agent, ip, data): metadata = EventMetadata(JSSEvent.event_type, machine_serial_number=msn, request=EventRequest(user_agent, ip)) event = JSSEvent(metadata, data) event.post()
logger = logging.getLogger('zentral.contrib.nagios.events') ALL_EVENTS_SEARCH_DICT = {"tag": "nagios"} class NagiosEvent(BaseEvent): tags = ["nagios"] class NagiosHostEvent(NagiosEvent): event_type = "nagios_host_event" register_event_type(NagiosHostEvent) class NagiosServiceEvent(NagiosEvent): event_type = "nagios_service_event" register_event_type(NagiosServiceEvent) def post_nagios_event(nagios_instance, user_agent, ip, data): event_type = data.pop("event_type", None) if not event_type: logger.warning("Missing event_type in nagios event payload") return elif event_type not in ['nagios_host_event', 'nagios_service_event']:
import logging from zentral.core.events import event_cls_from_type, register_event_type from zentral.core.events.base import BaseEvent, EventMetadata logger = logging.getLogger('zentral.contrib.inventory.events') ALL_EVENTS_SEARCH_DICT = {"tag": "inventory_update"} class InventoryMachineAdded(BaseEvent): event_type = 'inventory_machine_added' register_event_type(InventoryMachineAdded) class InventoryHeartbeat(BaseEvent): event_type = 'inventory_heartbeat' tags = ['heartbeat'] register_event_type(InventoryHeartbeat) # Inventory update events for attr in ('reference', 'machine', 'link', 'business_unit', 'group', 'os_version', 'system_info', 'network_interface', 'osx_app_instance', 'deb_package', 'teamviewer', 'puppetdb_inventory'): event_type = 'inventory_{}_update'.format(attr) event_class_name = "".join(s.title() for s in event_type.split('_')) event_class = type(event_class_name, (BaseEvent, ), {
} for jamf_event, (event_subtype, is_heartbeat, heartbeat_timeout) in JAMF_EVENTS.items(): event_type = 'jamf_{}'.format(event_subtype) event_class_name = "".join(s.title() for s in event_type.split('_')) tags = ['jamf', 'jamf_webhook'] if is_heartbeat: tags.append('heartbeat') event_class = type( event_class_name, (BaseEvent, ), { 'event_type': event_type, 'tags': tags, 'heartbeat_timeout': heartbeat_timeout }) register_event_type(event_class) class JAMFChangeManagementEvent(BaseEvent): event_type = "jamf_change_management" tags = ["jamf", "jamf_beat"] payload_aggregations = [ ("jamf_instance.host", { "type": "terms", "bucket_number": 10, "label": "Hosts" }), ("action", { "type": "terms", "bucket_number": 10, "label": "Actions"
"RestAPIOperation": ("rest_api_operation", False, None), "SCEPChallenge": ("scep_challenge", False, None), "SmartGroupComputerMembershipChange": ("smart_group_computer_membership_change", False, None), "SmartGroupMobileDeviceMembershipChange": ("smart_group_mobile_device_membership_change", False, None) } for jss_event, (event_subtype, is_heartbeat, heartbeat_timeout) in JSS_EVENTS.items(): event_type = 'jss_{}'.format(event_subtype) event_class_name = "".join(s.title() for s in event_type.split('_')) tags = ['jss'] if is_heartbeat: tags.append('heartbeat') event_class = type( event_class_name, (BaseEvent, ), { 'event_type': event_type, 'tags': tags, 'heartbeat_timeout': heartbeat_timeout }) register_event_type(event_class) def post_jss_event(user_agent, ip, data): event_cls = event_cls_from_type('jss_{}'.format( JSS_EVENTS[data["webhook"]["webhookEvent"]][0])) payload = data["event"] msn = payload.get("serialNumber", None) event_cls.post_machine_request_payloads(msn, user_agent, ip, [payload])
import logging from dateutil import parser from zentral.core.events import BaseEvent, EventMetadata, EventRequest, register_event_type logger = logging.getLogger("zentral.contrib.munki.events") class MunkiEvent(BaseEvent): event_type = "munki_event" register_event_type(MunkiEvent) def post_munki_events(msn, user_agent, ip, data): for report in data: events = report.pop("events") metadata = EventMetadata(MunkiEvent.event_type, machine_serial_number=msn, request=EventRequest(user_agent, ip)) for index, (created_at, payload) in enumerate(events): metadata.index = index metadata.created_at = parser.parse(created_at) payload.update(report) event = MunkiEvent(metadata, payload) event.post()
import logging from zentral.core.events import register_event_type from zentral.core.events.base import BaseEvent logger = logging.getLogger('zentral.contrib.mdm.events') ALL_EVENTS_SEARCH_DICT = {"tag": "mdm"} class OTAEnrollmentRequestEvent(BaseEvent): event_type = "ota_enrollment_request" tags = ["mdm", "heartbeat"] register_event_type(OTAEnrollmentRequestEvent) class MDMRequestEvent(BaseEvent): event_type = "mdm_request" tags = ["mdm", "heartbeat"] register_event_type(MDMRequestEvent)
import logging import re from zentral.core.events import BaseEvent, EventMetadata, EventRequest, register_event_type, CommandEvent COMMAND_RE = re.compile(r"zentral\$(?P<command>[a-zA-Z_]+)\$" "(?P<serial_numbers>(?:[a-zA-Z0-9]+\$)+)+" "(?P<arg>[a-zA-Z0-9]+)") logger = logging.getLogger('zentral.contrib.zendesk.events') class ZendeskTicketCreationEvent(BaseEvent): event_type = "zendesk_ticket_creation" register_event_type(ZendeskTicketCreationEvent) class ZendeskCommentCreationEvent(BaseEvent): event_type = "zendesk_comment_creation" register_event_type(ZendeskCommentCreationEvent) def post_zendesk_event(user_agent, ip, data): data_type = data['type'] data = data['data'] if data_type == 'ticket': event_class = ZendeskTicketCreationEvent elif data_type == 'comment': event_class = ZendeskCommentCreationEvent if not data['is_public']:
keys = {} pk = self.payload.get("pk") if pk: keys["incident"] = [(pk, )] machine_incident_pk = self.payload.get("machine_incident", {}).get("pk") if machine_incident_pk: keys["machine_incident"] = [(machine_incident_pk, )] return keys class IncidentCreatedEvent(BaseIncidentEvent): event_type = 'incident_created' register_event_type(IncidentCreatedEvent) class IncidentSeverityUpdatedEvent(BaseIncidentEvent): event_type = 'incident_severity_updated' register_event_type(IncidentSeverityUpdatedEvent) class IncidentStatusUpdatedEvent(BaseIncidentEvent): event_type = 'incident_status_updated' register_event_type(IncidentStatusUpdatedEvent)
"ComputerPolicyFinished": "computer_policy_finished", "ComputerPushCapabilityChanged": "computer_push_capability_changed", "JSSShutdown": "shutdown", "JSSStartup": "startup", "MobileDeviceCheckIn": "mobile_device_checkin", "MobileDeviceCommandCompleted": "mobile_device_command_completed", "MobileDeviceEnrolled": "mobile_device_enrolled", "MobileDevicePushSent": "mobile_device_push_sent", "MobileDeviceUnEnrolled": "mobile_device_unenrolled", "PatchSoftwareTitleUpdated": "patch_software_title_updated", "PushSent": "push_sent", "RestAPIOperation": "rest_api_operation", "SCEPChallenge": "scep_challenge", "SmartGroupComputerMembershipChange": "smart_group_computer_membership_change", "SmartGroupMobileDeviceMembershipChange": "smart_group_mobile_device_membership_change", } for jss_event, event_subtype in JSS_EVENTS.items(): event_type = "jss_{}".format(event_subtype) event_class_name = "".join(s.title() for s in event_type.split("_")) event_class = type(event_class_name, (BaseEvent,), {"event_type": event_type, "tags": ["jss"]}) register_event_type(event_class) def post_jss_event(user_agent, ip, data): event_cls = event_cls_from_type("jss_{}".format(JSS_EVENTS[data["webhook"]["webhookEvent"]])) payload = data["event"] msn = payload.get("serialNumber", None) event_cls.post_machine_request_payloads(msn, user_agent, ip, [payload])
namespace = "wsone_event" tags = ["wsone", "wsone_event"] def get_linked_objects_keys(self): keys = {} observer = self.metadata.observer if observer and observer.content_type == "wsone.instance" and observer.pk: keys["wsone_instance"] = [(observer.pk, )] return keys class WSOneComplianceStatusChanged(BaseWSOneEvent): event_type = "wsone_compliance_status_changed" register_event_type(WSOneComplianceStatusChanged) class WSOneCompromisedStatusChanged(BaseWSOneEvent): event_type = "wsone_compromised_status_changed" register_event_type(WSOneCompromisedStatusChanged) class WSOneMDMEnrollmentComplete(BaseWSOneEvent): event_type = "wsone_mdm_enrollment_complete" register_event_type(WSOneMDMEnrollmentComplete)
import logging from zentral.core.events import BaseEvent, EventMetadata, event_cls_from_type, register_event_type logger = logging.getLogger('zentral.contrib.inventory.events') class InventoryMachineAdded(BaseEvent): event_type = 'inventory_machine_added' register_event_type(InventoryMachineAdded) # Inventory update events for attr in ('reference', 'machine', 'link', 'business_unit', 'group', 'os_version', 'system_info', 'osx_app_instance', 'teamviewer'): event_type = 'inventory_{}_update'.format(attr) event_class_name = "".join(s.title() for s in event_type.split('_')) event_class = type(event_class_name, (BaseEvent,), {'event_type': event_type}) register_event_type(event_class) def post_inventory_events(msn, events, uuid, index): for event_type, data in events:
from zentral.core.events import register_event_type from zentral.core.events.base import BaseEvent, EventMetadata, EventObserver, EventRequest, EventRequestGeo logger = logging.getLogger('zentral.contrib.okta.events') ALL_EVENTS_SEARCH_DICT = {"tag": "okta"} class OktaUserSessionStart(BaseEvent): event_type = "okta_user_session_start" tags = ["okta"] register_event_type(OktaUserSessionStart) class OktaUserSessionEnd(BaseEvent): event_type = "okta_user_session_end" tags = ["okta"] register_event_type(OktaUserSessionEnd) def post_okta_events(event_hook, data): event_observer = EventObserver(**event_hook.observer_dict()) for event in data["data"]["events"]: event_type = event["eventType"] if event_type == "user.session.start":
"SCEPChallenge": ("scep_challenge", False, None), "SmartGroupComputerMembershipChange": ("smart_group_computer_membership_change", False, None), "SmartGroupMobileDeviceMembershipChange": ("smart_group_mobile_device_membership_change", False, None)} for jamf_event, (event_subtype, is_heartbeat, heartbeat_timeout) in JAMF_EVENTS.items(): event_type = 'jamf_{}'.format(event_subtype) event_class_name = "".join(s.title() for s in event_type.split('_')) tags = ['jamf', 'jamf_webhook'] if is_heartbeat: tags.append('heartbeat') event_class = type(event_class_name, (BaseEvent,), {'event_type': event_type, 'tags': tags, 'heartbeat_timeout': heartbeat_timeout}) register_event_type(event_class) class JAMFChangeManagementEvent(BaseEvent): event_type = "jamf_change_management" tags = ["jamf", "jamf_beat"] payload_aggregations = [ ("jamf_instance.host", {"type": "terms", "bucket_number": 10, "label": "Hosts"}), ("action", {"type": "terms", "bucket_number": 10, "label": "Actions"}), ("object.type", {"type": "terms", "bucket_number": 10, "label": "Object types"}), ] register_event_type(JAMFChangeManagementEvent)
from zentral.core.events.base import BaseEvent logger = logging.getLogger('zentral.contrib.nagios.events') ALL_EVENTS_SEARCH_DICT = {"tag": "nagios"} class NagiosEvent(BaseEvent): tags = ["nagios"] class NagiosHostEvent(NagiosEvent): event_type = "nagios_host_event" register_event_type(NagiosHostEvent) class NagiosServiceEvent(NagiosEvent): event_type = "nagios_service_event" register_event_type(NagiosServiceEvent) def post_nagios_event(nagios_instance, user_agent, ip, data): event_type = data.pop("event_type", None) if not event_type: logger.warning("Missing event_type in nagios event payload") return elif event_type not in ['nagios_host_event', 'nagios_service_event']:
import json import unittest import redis from zentral.core.events import EventMetadata, EventRequest, BaseEvent, register_event_type from zentral.core.queues.backends.redisq import EventQueues class TestQueueEvent(BaseEvent): event_type = "event_test_queue" register_event_type(TestQueueEvent) class TestEventQueues(unittest.TestCase): CONFIG = {'db': 1, 'host': 'redis', 'stores': ['postgres']} EVENT = TestQueueEvent(EventMetadata(TestQueueEvent.event_type, machine_serial_number='012356789', request=EventRequest("python_unittest_useragent", "10.0.0.1")), {'payload': 'ok'}) def setUp(self): self.r = redis.Redis(host='redis', port=6379, db=self.CONFIG['db']) self.rq = EventQueues(self.CONFIG) def test_post_event(self): event_id = self.rq.post_event(self.EVENT) self.assertEqual(json.loads(self.r.get(event_id).decode('utf-8')), self.EVENT.serialize())
logger = logging.getLogger('zentral.contrib.inventory.events') ALL_EVENTS_SEARCH_DICT = {"tag": "machine"} # Inventory update events class InventoryHeartbeat(BaseEvent): event_type = 'inventory_heartbeat' namespace = "inventory" tags = ['heartbeat', 'machine'] register_event_type(InventoryHeartbeat) class AddMachine(BaseEvent): event_type = 'add_machine' namespace = "inventory" tags = ['machine'] register_event_type(AddMachine) for attr in ('link', 'business_unit', 'group', 'os_version',
from zentral.core.events import BaseEvent, EventMetadata, register_event_type class InventoryUpdateEvent(BaseEvent): event_type = "inventory_update" register_event_type(InventoryUpdateEvent) def post_inventory_event(msn, data, uuid, index): event_cls = InventoryUpdateEvent metadata = EventMetadata(event_cls.event_type, machine_serial_number=msn, uuid=uuid, index=index) event = event_cls(metadata, data) event.post()
import logging from zentral.core.events import register_event_type from zentral.core.events.base import BaseEvent from zentral.core.queues import queues logger = logging.getLogger('zentral.contrib.puppet.events') ALL_EVENTS_SEARCH_DICT = {"tag": "puppet"} class PuppetReportEvent(BaseEvent): event_type = "puppet_report" tags = ["puppet"] register_event_type(PuppetReportEvent) def post_puppet_report(instance, user_agent, ip, report): raw_event = { "request": { "user_agent": user_agent, "ip": ip }, "event_type": PuppetReportEvent.event_type, "puppet_instance": instance, "puppet_report": report } queues.post_raw_event("puppet_reports", raw_event)
import logging from zentral.core.events import register_event_type from zentral.core.events.base import BaseEvent logger = logging.getLogger('zentral.contrib.mdm.events') ALL_EVENTS_SEARCH_DICT = {"tag": "mdm"} class DEPEnrollmentRequestEvent(BaseEvent): event_type = "dep_enrollment_request" tags = ["mdm", "dep", "heartbeat"] register_event_type(DEPEnrollmentRequestEvent) class OTAEnrollmentRequestEvent(BaseEvent): event_type = "ota_enrollment_request" tags = ["mdm", "ota", "heartbeat"] register_event_type(OTAEnrollmentRequestEvent) class UserEnrollmentRequestEvent(BaseEvent): event_type = "user_enrollment_request" tags = ["mdm"] register_event_type(UserEnrollmentRequestEvent)
from zentral.core.events import EventMetadata, EventRequest, BaseEvent, register_event_type class TestEvent1(BaseEvent): event_type = "event_type_1" register_event_type(TestEvent1) class TestEvent2(BaseEvent): event_type = "event_type_2" register_event_type(TestEvent2) def make_event(idx=0, first_type=True, with_request=True): if first_type: event_cls = TestEvent1 else: event_cls = TestEvent2 if with_request: request = EventRequest("python_unittest_useragent", "10.0.0.1") else: request = None return event_cls(EventMetadata(event_cls.event_type, machine_serial_number='012356789', request=request), {'idx': idx})
import logging import uuid from zentral.core.events import register_event_type from zentral.core.events.base import BaseEvent, EventMetadata logger = logging.getLogger('zentral.contrib.incidents.events') ALL_EVENTS_SEARCH_DICT = {"tag": "incident"} class IncidentEvent(BaseEvent): event_type = 'incident' tags = ["incident"] register_event_type(IncidentEvent) class MachineIncidentEvent(BaseEvent): event_type = 'machine_incident' tags = ["incident"] register_event_type(MachineIncidentEvent) def build_incident_events(incident_event_payloads, machine_serial_number=None, request=None): incident_events_uuid = uuid.uuid4() for incident_event_index, incident_event_payload in enumerate(
import logging from zentral.core.events import event_cls_from_type, register_event_type from zentral.core.events.base import BaseEvent, EventMetadata, EventRequest logger = logging.getLogger('zentral.contrib.inventory.events') ALL_EVENTS_SEARCH_DICT = {"tag": "inventory_update"} class InventoryMachineAdded(BaseEvent): event_type = 'inventory_machine_added' register_event_type(InventoryMachineAdded) class InventoryHeartbeat(BaseEvent): event_type = 'inventory_heartbeat' tags = ['heartbeat'] register_event_type(InventoryHeartbeat) class EnrollmentSecretVerificationEvent(BaseEvent): event_type = 'enrollment_secret_verification' register_event_type(EnrollmentSecretVerificationEvent)