import time import logging import argparse import requests import xml.dom.minidom max_iter = 30 SleepS = 60 SplkConf = { 'url': '[BASE URL(8089)]', 'search': '', 'user_id': None, 'patient_id': None } SplkTok = { 'Authorization': ( 'Splunk [INSERT TOKEN]' )} Proxy = { 'http': None, 'https': None } # Parse Splunk search job xml data for a couple of relevant datapoints def getNodeValue(name, resp_text): dom = xml.dom.minidom.parseString(resp_text) if name == 'sid': return dom.getElementsByTagName(name)[0].firstChild.nodeValue keys = dom.getElementsByTagName('s:key') for n in keys: if n.getAttribute('name') == name: return n.childNodes[0].nodeValue def startSavedSearch(user=None, patient=None): args = [f'{k}={v}' for k, v in SplkConf.items() if 'user_id' in k or 'patient_id' in k and v is not None][0] data = {'search': f'| savedsearch "{SplkConf["search"]}" {args}'} resp = requests.post(f'{SplkConf["url"]}/servicesNS/alteryx_rest/nyp_privacy_calc_fields/search/jobs', data=data, headers=SplkTok, proxies=Proxy) return getNodeValue('sid', resp.text) def getSearchStatus(sid): resp = requests.get(f'{SplkConf["url"]}/services/search/jobs/{sid}', headers=SplkTok, proxies=Proxy) return getNodeValue('dispatchState', resp.text) # Wait for search job to complete & return response object when 'DONE' (or None) def getSearchResults(sid): resp = None data = {'output_mode': 'csv'} i = 0 while i < max_iter: i = i + 1 status = getSearchStatus(sid) logging.info(f'getSearchStatus() sid={sid} returned: status={status}') if status is None: break if status == 'DONE': resp = requests.get(f'{SplkConf["url"]}/services/search/jobs/{sid}/results?count=0', data=data, headers=SplkTok, proxies=Proxy) break else: time.sleep(SleepS) return resp def main(): # Set logging format and set our default loglevel to INFO (raise this to suppress output) logging.basicConfig(datefmt='%c %z', format='%(asctime)s [%(levelname)s]: %(message)s', level=logging.INFO) parser = argparse.ArgumentParser(description='Run a saved Splunk search') parser.add_argument('-u', '--user_id', help='Supply a User ID', nargs='?', default=None) parser.add_argument('-p', '--patient_id', help='Supply a Patient ID', nargs='?', default=None) args = parser.parse_args() rc = 0 if args.user_id is None and args.patient_id is None: logging.error('Must supply a CWID or MRN') rc = 2 else: SplkConf['user_id'] = args.user_id SplkConf['patient_id'] = args.patient_id sid = startSavedSearch() logging.info(f'startSavedSearch() returned: sid={sid}') try: resp = getSearchResults(sid) lc = resp.text.count('\n') logging.info(f'getSearchResults() sid={sid} returned: status_code={resp.status_code} line_count={lc}') print(resp.text) except Exception as e: logging.info(f'Encountered error while attempting to fetch search results: sid={sid} err={e}') rc = 1 return rc if __name__ == '__main__': rc = main() exit(rc)