"""Send json response data to Splunk via the HTTP Event Collector... important:: This module requires the general :ref:`Splunk setup <splunk-setup>`.Run a test by using ``salt-call test.ping --return splunk``Written by Scott Pack (github.com/scottjpack)"""importloggingimportsocketimporttimeimportrequestsimportsalt.utils.json# pylint: disable=invalid-name_max_content_bytes=100000http_event_collector_debug=Falselog=logging.getLogger(__name__)__virtualname__="splunk"def__virtual__():return__virtualname__
[docs]defreturner(ret):""" Send a message to Splunk via the HTTP Event Collector. Requires the Splunk HTTP Event Collector running on port 8088. This is available on Splunk Enterprise version 6.3 or higher. """# Get Splunk Optionsopts=_get_options()log.info("Options: %s",salt.utils.json.dumps(opts),)http_collector=_create_http_event_collector(opts)payload=_prepare_splunk_payload(ret,opts)http_collector.sendEvent(payload)returnTrue
[docs]defevent_return(events):""" Return events to Splunk via the HTTP Event Collector. Requires the Splunk HTTP Event Collector running on port 8088. This is available on Splunk Enterprise version 6.3 or higher. """# Get Splunk Optionsopts=_get_options()log.info("Options: %s",salt.utils.json.dumps(opts),)http_collector=_create_http_event_collector(opts)foreventinevents:payload=_prepare_splunk_payload(event,opts)http_collector.sendEvent(payload)returnTrue
def_get_options():try:token=__salt__["config.get"]("splunk_http_forwarder:token")indexer=__salt__["config.get"]("splunk_http_forwarder:indexer")sourcetype=__salt__["config.get"]("splunk_http_forwarder:sourcetype")index=__salt__["config.get"]("splunk_http_forwarder:index")verify_ssl=__salt__["config.get"]("splunk_http_forwarder:verify_ssl",default=True)exceptException:# pylint: disable=broad-exceptlog.error("Splunk HTTP Forwarder parameters not present in config.")returnNonesplunk_opts={"token":token,"indexer":indexer,"sourcetype":sourcetype,"index":index,"verify_ssl":verify_ssl,}returnsplunk_optsdef_create_http_event_collector(opts):""" Prepare a connection to the Splunk HTTP event collector. """http_event_collector_key=opts["token"]http_event_collector_host=opts["indexer"]http_event_collector_verify_ssl=opts["verify_ssl"]# Return the collectorreturnhttp_event_collector(http_event_collector_key,http_event_collector_host,verify_ssl=http_event_collector_verify_ssl,)def_prepare_splunk_payload(event,opts):""" Prepare a payload for submission to the Splunk HTTP event collector. """# Get Splunk Optionsopts=_get_options()# init the payloadpayload={}# Set up the event metadatapayload.update({"index":opts["index"]})payload.update({"sourcetype":opts["sourcetype"]})# Add the eventpayload.update({"event":event})log.info("Payload: %s",salt.utils.json.dumps(payload),)returnpayload# Thanks to George Starcher for the http_event_collector class (https://github.com/georgestarcher/)classhttp_event_collector:def__init__(self,token,http_event_server,host="",http_event_port="8088",http_event_server_ssl=True,max_bytes=_max_content_bytes,verify_ssl=True,):self.token=tokenself.batchEvents=[]self.maxByteLength=max_bytesself.currentByteLength=0self.verify_ssl=verify_ssl# Set host to specified value or default to localhostname if no value providedifhost:self.host=hostelse:self.host=socket.gethostname()# Build and set server_uri for http event collector# Defaults to SSL if flag not passed# Defaults to port 8088 if port not passedifhttp_event_server_ssl:buildURI=["https://"]else:buildURI=["http://"]foriin[http_event_server,":",http_event_port,"/services/collector/event"]:buildURI.append(i)self.server_uri="".join(buildURI)ifhttp_event_collector_debug:log.debug(self.token)log.debug(self.server_uri)defsendEvent(self,payload,eventtime=""):# Method to immediately send an event to the http event collectorheaders={"Authorization":"Splunk "+self.token}# If eventtime in epoch not passed as optional argument use current system time in epochifnoteventtime:eventtime=str(int(time.time()))# Fill in local hostname if not manually populatedif"host"notinpayload:payload.update({"host":self.host})# Update time value on payload if need to use system timedata={"time":eventtime}data.update(payload)# send event to http event collectorr=requests.post(self.server_uri,data=salt.utils.json.dumps(data),headers=headers,verify=self.verify_ssl,timeout=120,)# Print debug info if flag setifhttp_event_collector_debug:log.debug(r.text)log.debug(data)