You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
6.0 KiB

7 months ago
# Version 4.0
import os, sys, time, random
import splunk.Intersplunk, splunk.mining.dcutils as dcu
from splunk.util import format_local_tzoffset
from xml.sax import saxutils
from stat import *
import re
# Create an rss file with the appropriate path
logger = dcu.getLogger()
graceful = 0
def writeRSSItem(path, rss_header, item, rss_footer):
# nothing todo
if len(item) == 0 and os.path.exists(path):
return
wrote_item = False
# needed to ensure no two SH are writing into the same temp file
tmp_path = path + ".tmp." + str(random.randint(0, 100000))
# if file exists, start looking for existing items
if os.path.exists(path) and os.stat(path)[ST_SIZE] > 0:
rssfile = open(path, "r")
tmprssfile = open(tmp_path, "w+")
foundFirstItem = 0
itemCount = 1
skipItem = 0
for line in rssfile.readlines():
lineTmp = line.strip()
if lineTmp == '<item>':
# print("itemcount: %d, thresh: %d" % (itemCount, thresh))
if itemCount < thresh:
itemCount = itemCount+1
if foundFirstItem == 0:
# found the first item, add the new one first
tmprssfile.write(item)
tmprssfile.write(line)
foundFirstItem = 1
else:
tmprssfile.write(line)
else:
skipItem = 1
elif lineTmp == '</item>':
if skipItem == 0:
tmprssfile.write(line)
else:
skipItem = 0
else:
if skipItem == 0:
tmprssfile.write(line)
rssfile.close()
tmprssfile.close()
wrote_item = foundFirstItem == 1
if not wrote_item:
# make parent dirs if they don't exist
try:
os.makedirs(os.path.dirname(path))
except OSError as e:
pass
tmprssfile = open(tmp_path, "w")
tmprssfile.write(rss_header)
tmprssfile.write(item)
tmprssfile.write(rss_footer)
tmprssfile.close()
logger.info("Atomically updating RSS feed: " + str(path))
try:
os.rename(tmp_path, path)
except OSError as e:
try: # remove path and retry
os.unlink(path)
os.rename(tmp_path, path)
except OSError as e:
logger.error("Could not rename %s to %s. Error message: %s" % (str(tmp_path), str(path), str(e)))
splunk.Intersplunk.generateErrorResults("Could not rename %s to %s. Error message: %s" % (str(tmp_path), str(path), str(e)))
def trimQuotes(str):
if len(str) == 0:
return str
if str.startswith("'") and str.endswith("'"):
str = str[1:-1]
if str.startswith('"') and str.endswith('"'):
str = str[1:-1]
return str
results,dummyresults,settings = splunk.Intersplunk.getOrganizedResults()
keywords, args = splunk.Intersplunk.getKeywordsAndOptions() # args = dcu.getArgValues()
if(len(sys.argv) < 5):
results = dcu.getErrorResults(results, graceful, 'Usage: createrss <path = rss path> <name = name/title of the rss item> <link = rss item link> <descr = rss item description> <count = maximum number of items> [graceful = (1|0)]')
splunk.Intersplunk.outputResults( results )
sys.exit()
path = trimQuotes(args["path"] ) if "path" in args else ""
name = trimQuotes(args["name"] ) if "name" in args else ""
link = trimQuotes(args["link"] ) if "link" in args else ""
desc = trimQuotes(args["descr"]) if "descr" in args else ""
thresh = int(args["count"]) if "count" in args else 100
graceful = 0
if("graceful" in args):
graceful = int(args["graceful"])
# ensure nothing dangerous
if ".." in path or "/" in path or "\\" in path:
results = dcu.getErrorResults(results, graceful, 'createrss Path location cannot contain "..", "/", or "\\". Path was "' + str(path) + '".')
splunk.Intersplunk.outputResults( results )
sys.exit()
path_rx = re.compile('^[A-Za-z0-9_.-]+\.xml$')
if not path_rx.match(path):
msg = """createrss Path must end in ".xml" and can only contain the period, dash, underscore, and alphanumeric characters."""
results = dcu.getErrorResults(results, graceful, msg)
splunk.Intersplunk.outputResults( results )
sys.exit()
sharedStorage = settings.get('sharedStorage', splunk.Intersplunk.splunkHome())
baseStorage = os.path.join(sharedStorage, 'var', 'run', 'splunk')
path = os.path.join(baseStorage, 'rss', path)
rss_header = """<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>Alert: %s</title>
<link>%s</link>
<description>Saved Searches Feed for saved search %s</description>
""" % ( saxutils.escape(name), # <title>
saxutils.escape(link), # <link>
saxutils.escape(name)) # <description>
rss_footer =""" </channel>
</rss>
"""
correct_tz_time = time.strftime("%a, %d %b %Y %H:%M:%S ") + format_local_tzoffset()
item = """ <item>
<title>%s</title>
<link>%s</link>
<description>%s</description>
<pubDate>%s</pubDate>
</item>
""" % ( saxutils.escape(name), # <item><title>
saxutils.escape(link), # <item><link>
saxutils.escape(desc), # <item><desc>
correct_tz_time) # <item><pubDate>
if len(link) == 0:
item = ''
writeRSSItem(path, rss_header, item, rss_footer)
splunk.Intersplunk.outputResults( results )

Powered by BW's shoe-string budget.