Created
May 10, 2019 16:12
-
-
Save kanazux/cda5a0c90577440a68eab3506344d52b to your computer and use it in GitHub Desktop.
spl pd alert for splunk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python2.7 | |
# -*- coding: utf-8 -*- | |
import sys | |
import json | |
import time | |
import base64 | |
import requests | |
from datetime import datetime | |
from collections import defaultdict | |
class pd_message(object): | |
""" | |
Create a message object to be send to a PagerDuty server. | |
Validate fields and create a json object. | |
""" | |
def __init__(self, _payload): | |
""" | |
Define some vars and initiate the class | |
:_payload: message data received to validate fields and create json | |
""" | |
self.msg = None | |
self.hash = None | |
self.pd_key = None | |
self.result = None | |
self.severity = None | |
self.incident = None | |
self.log_result = None | |
self.log_payload = None | |
self.results_link = None | |
self.payload = _payload | |
self.time = datetime.strftime(datetime.now(), "%H:%M:%S %d-%m-%Y") | |
def validate_payload(self): | |
""" | |
Validate if payload is a valid json data. | |
""" | |
try: | |
return json.loads(self.payload) | |
except ValueError: | |
self.msg = "ERROR {} Payload data is not a json object".format(self.time) | |
return False | |
def validate_incident(self, _incident): | |
""" | |
Validate incident identification. | |
:_incident: incident name passed by splunk | |
""" | |
if len(_incident) > 0 and self.incident is None: | |
self.incident = _incident.encode() | |
def validate_pdkey(self, _pd_key): | |
""" | |
Validate the PD key to send message. | |
:_pd_key: PD key passed into a result data or default configuration | |
""" | |
if len(_pd_key) == 32 and self.pd_key is None: | |
self.pd_key = _pd_key.encode() | |
def validate_severity(self, _severity): | |
""" | |
Get severity for syslogd log data. | |
:_severity: severity passed on resulta data or default configuration. | |
""" | |
if len(_severity) > 0 and self.severity is None: | |
self.severity = _severity.encode() | |
def validate_result(self, _result): | |
""" | |
Validate result data to be send as payload into a post request. | |
""" | |
if isinstance(_result, (dict)): | |
self.result = _result | |
if 'PD_key' in self.result.keys(): | |
self.validate_pdkey(self.result['PD_key']) | |
del self.result['PD_key'] | |
if 'PD_incident' in self.result.keys(): | |
self.validate_incident(self.result['PD_incident']) | |
if 'PD_severity' in self.result.keys(): | |
self.validate_severity(self.result['PD_severity']) | |
def validate_results_link(self, _link): | |
""" | |
Validate results link to send to a PagerDuty server. | |
:_link: link sended by splunk into a json data | |
""" | |
if len(_link) > 0: | |
self.results_link = _link | |
def validate_fields(self): | |
""" | |
Validate fields necessary to send data to a Pageruty server. | |
Check if result is a dict with data to send as payload in the post request. | |
If PD_key, PD_incident and PD_severity are not in result, use the default | |
configuration to get this data. | |
""" | |
self.hash = base64.b64encode("{} {}".format(self.time, self.incident).encode()) | |
_json_data = self.validate_payload() | |
if _json_data: | |
_conf = _json_data['configuration'] | |
self.validate_incident(_conf['integration_incident']) | |
if self.incident != None: | |
self.hash = base64.b64encode("{} {}".format(self.time, self.incident).encode()) | |
self.validate_result(_json_data['result']) | |
self.validate_pdkey(_conf['integration_key_override']) | |
self.validate_severity(_conf['integration_severity_override']) | |
if _conf['integration_log_payload'] == "activate": | |
self.log_payload = True | |
if _conf['integration_log_resultset'] == "activate": | |
self.log_result = True | |
if 'search_name' in _json_data.keys(): | |
self.validate_incident(_json_data['search_name']) | |
if 'results_link' in _json_data.keys(): | |
self.validate_results_link(_json_data['results_link']) | |
class pd_send(object): | |
def __init__(self, _payload): | |
""" | |
Init some variables to send data to PagerDuty. | |
:_payload: json data to be validate and used to send data to PagerDuty. | |
""" | |
self.payload = pd_message(_payload) | |
self.payload.validate_fields() | |
if self.payload.msg != None: | |
print >> sys.stderr, "{}, #hash_key={}".format(self.payload.msg, self.payload.hash) | |
self.url = "https://events.pagerduty.com/v2/enqueue" | |
self.content_type = {"Content-Type": "application/json"} | |
self.data = None | |
print >> sys.stderr, "DEBUG Sending incident with default settings, #hash_key={}".format(self.payload.hash) | |
def create_data(self): | |
""" | |
Create json data to be send as custom details to the PagerDuty API. | |
""" | |
_data = dict() | |
_data['event_action'] = "trigger" | |
_data['routing_key'] = self.payload.pd_key.decode() | |
_data['payload'] = dict() | |
_data['payload']['summary'] = self.payload.incident.decode() | |
_data['payload']['severity'] = self.payload.severity.decode() | |
_data['payload']['source'] = self.payload.results_link | |
_data['payload']['custom_details'] = self.payload.result | |
self.data = _data | |
def send_data(self): | |
""" | |
Send data to PagerDuty and return some messages to stderr. | |
""" | |
self.create_data() | |
if self.payload.log_payload: | |
print >> sys.stderr, "INFO PagerDuty Payload: {}, #hash_key={}".format(self.data, self.payload.hash) | |
if self.payload.log_result: | |
print >> sys.stderr, "INFO PagerDuty Query Payload: {}, #hash_key={}".format(self.data, self.payload.hash) | |
try: | |
print(self.data) | |
response = requests.post(self.url, data=json.dumps(self.data), headers=self.content_type, verify=False) | |
json_response = response.json() | |
if json_response["status"] == "success": | |
print >> sys.stderr, "INFO PagerDuty server response: success, #status_code={}, #hash_key={}".format( | |
response.status_code, self.payload.hash) | |
print >> sys.stderr, "INFO Incident alert notification successfully sent, #hash_key={}".format( | |
self.payload.hash) | |
else: | |
if "errors" in json_response and isinstance(json_response['errors'], (list)): | |
for error in json_response['errors']: | |
print >> sys.stderr, "ERROR Server Error: {}, #hash_key={}".format(error, self.payload.hash) | |
print sys.stderr, "ERROR Server response: {}, #status_code={}, #hash_key={}".format( | |
json_response['status'], response.status_code, self.payload.hash) | |
return True | |
except Exception as error: | |
print >> sys.stderr, "ERROR Server Request Error: {}, #hash_key={}".format(error, self.payload.hash) | |
return False | |
# -*- coding: utf-8 -*- | |
read_data = sys.stdin.read() | |
for t in range(3): | |
if pd_send(read_data).send_data(): | |
sys.exit(0) | |
else: | |
time.sleep(60) | |
sys.exit(2) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment