%!
import splunk
import logging
import hashlib
import os.path
import splunk.appserver.mrsparkle.lib.i18n as i18n
import splunk.appserver.mrsparkle.lib.filechain as filechain
import cherrypy
from mako.exceptions import RichTraceback
from splunk.appserver.mrsparkle.lib import util
from splunk.appserver.mrsparkle.lib.eai import cpQuoteEntity
logger = logging.getLogger('splunk.appserver.templates.lib')
import splunk.appserver.mrsparkle.lib.module as module
modules = module.moduleMapper.getInstalledModules()
%>
<%namespace name="helpers" file="//view/_helpers.html" import="*"/>
<%def name="add_script_block()">
<%
if attributes.get('script_blocks', None) is None:
attributes['script_blocks'] = []
attributes['script_blocks'].append(capture(caller.body))
%>
%def>
<%def name="fillform(form_defaults, form_errors)">
<%
from formencode import htmlfill
context.write(htmlfill.render(capture(caller.body), form_defaults, form_errors, auto_insert_errors=False))
%>
%def>
<%def name="get_script_blocks()">
% if attributes.get('script_blocks'):
% endif
%def>
## DO NOT USE compile flag - here only to maintain compatibility with customer templates
<%def name="script_tags(files, compile=False)">
<% seen = attributes.setdefault('script_tags_seen', set()) %>
<%
disable_messenger = cherrypy.session.get('sessionKey', None) is None
minify_js = splunk.util.normalizeBoolean(cherrypy.config.get('minify_js'))
%>
% for file in files:
% if minify_js and not file.startswith('/static/app/') and not file.startswith('/config?') and not file.endswith('init.js') and not file.endswith('highcharts.js'):
% if 'common.min.js' not in seen:
% if disable_messenger:
% endif
\
<% seen.add('common.min.js') %>
% endif
% if '/modules/' in file:
<%
basename = 'modules-' + filechain.generate_file_list_hash(files) + '.min.js'
%>
% if basename not in seen:
<% filechain.chain_modules_js(files) %>
\
<% seen.add(basename) %>
% endif
% endif
% elif file not in seen:
\
<% seen.add(file) %>
% endif
% endfor
%def>
## DO NOT USE compile flag - here only to maintain compatibility with customer templates
<%def name="stylesheet_tags(files, compile=False, media=None)">
<%
seen = attributes.setdefault('stylesheet_tags_seen', set())
minify_css = splunk.util.normalizeBoolean(cherrypy.config.get('minify_css'))
%>
% for file in files:
% if minify_css and '/modules/' in file:
<%
basename = 'modules-' + filechain.generate_file_list_hash(files) + '.min.css'
%>
% if basename not in seen:
<% filechain.chain_modules_css(files) %>
\
<% seen.add(basename) %>
% endif
% elif file not in seen:
\
<% seen.add(file) %>
% endif
% endfor
%def>
<%def name="traceback(header=None, parent_element_class_name='traceback', row_highlight_class_name='active', max_lines=5)">
<%
tback = RichTraceback()
line = tback.lineno
if tback.source:
lines = tback.source.split('\n')
else:
lines = None
%>
% for index in range(max(0, line-(max_lines-1)), min(len(lines), line+max_lines)):
${index + 1}
${lines[index] | h}
% endfor
% endif
% for (filename, lineno, function, line) in tback.reverse_traceback:
${filename}, line ${lineno}:
${line | h}
% endfor
%def>
<%def name="generate_select_options(optionArray, selectedValue=None)">
% for pair in optionArray:
<% sel = ' selected="1"' if selectedValue != None and unicode(pair[0], 'utf-8') == unicode(selectedValue, 'utf-8') else '' %> \
\
% endfor
%def>
<%def name="getSavedSearch(module, savedSearchName, useHistory=False, namespace=None, owner=None, nativeObjectMode=None)">
<%
jsonSearch = None
jobNotFoundMessage = 'Module %(module)s: Could not find a previously run search for saved search "%(savedSearchName)s".'
savedSearchNotFoundMessage = 'Module %(module)s: Could not find a saved search named "%(savedSearchName)s".'
quoteExceededMessage = 'Module %(module)s: There are too many searches running; unable to dispatch "%(savedSearchName)s".'
try :
savedSearchObject = splunk.search.getSavedSearch(
label = savedSearchName,
namespace = namespace,
owner = owner
)
# if decomp isn't supported, return decomp fail
if not splunk.util.normalizeBoolean(cherrypy.config.get('support_decomposition')):
q = util.layPiping(savedSearchObject["qualifiedSearch"])
jsonSearch = {
"fullSearch" : q,
"baseSearch" : q,
"intentions": [],
"decompositionFailed": True,
"s": savedSearchObject.name,
"earliest": savedSearchObject.get('dispatch.earliest_time'),
"latest": savedSearchObject.get('dispatch.latest_time')
}
else:
jsonSearch = splunk.appserver.mrsparkle.util.resurrectFromSavedSearch(
savedSearchObject = savedSearchObject,
hostPath = splunk.mergeHostPath(),
namespace = namespace,
owner = owner
)
useHistory = unicode(useHistory).capitalize()
if (useHistory in ["Auto", "None", "True"]) :
if useHistory == "None":
logger.warn("useHistory == None is being depreciated, please use Auto instead.")
historySearch = 'name=scheduler* OR name=rt_scheduler*'
# for real-time, not scheduled searches try to use an already running instance of the search
if not splunk.util.normalizeBoolean(savedSearchObject.get('is_scheduled')) and \
savedSearchObject.get('dispatch.earliest_time') and \
savedSearchObject.get('dispatch.earliest_time').startswith('rt') :
historySearch = 'isDone=0 AND isRealTimeSearch=1 AND isZombie=0 AND isFinalized=0'
try:
# Note that we never submit anything other than useHistory="true".
# this is because its problematic to let the python dispatch the search for us.
# instead if there's no job run by the scheduler, we return the other context data and let the
# client dispatch the search itself.
job = splunk.search.getJobForSavedSearch(
savedSearchName,
useHistory="True",
namespace=namespace,
owner=owner,
search=historySearch,
historyURI= savedSearchObject.getLink("history")
)
if (job) :
jsonSearch["job"] = job.toJsonable(timeFormat='unix')
elif useHistory == "True":
helpers.message('error', jobNotFoundMessage % {'savedSearchName': savedSearchName, 'module': module['id']})
except splunk.RESTException, e:
# Payment Required!
# Get a job by using useHistory = True
if e.statusCode == 402:
logger.warn("Could not retrieve the job history for the saved search '%s' because the current license does not allow it." % savedSearchName)
helpers.message("info", _("This view references scheduled searches that do not run automatically in Free Splunk. Please wait while they run now."))
else:
raise e
except splunk.BadRequest, e:
logger.exception(e)
if len(e.extendedMessages) > 0:
for msg in e.extendedMessages:
logger.error(msg['text'])
helpers.message(msg['type'].lower(), msg['text'])
else:
helpers.message('error', jobNotFoundMessage % {'savedSearchName': savedSearchName, 'module': module['id']})
except splunk.ResourceNotFound, e:
logger.exception(e)
if nativeObjectMode!='SimpleDashboard':
helpers.message('error', savedSearchNotFoundMessage % {'savedSearchName': savedSearchName, 'module': module['id']})
except splunk.QuotaExceededException, e:
logger.warn(str(e))
helpers.message('warn', quoteExceededMessage % {'searchName': savedSearchName, 'module': module['id']})
%>
<%call expr="add_script_block()">
% if jsonSearch:
Splunk.Module.loadParams.${module['id']}.jsonSearch = ${jsonify(jsonSearch)};
% else:
Splunk.Module.loadParams.${module['id']}.jsonSearch = null;
% endif
%call>
%def>
<%def name="csrf_hidden_input()">
%def>
<%def name="render_exception(e)">
${e.msg if hasattr(e, 'msg') else e | h}
% if hasattr(e, 'extendedMessages') and e.extendedMessages:
—
% for item in e.extendedMessages:
${item['text'] | h}
% endfor
% endif
%def>
<%def name="manager_save_search_link(namespace, id, name, label=None)">
${label or name | h}.
%def>
<%def name="wizard_errors(header, errors)">
% if len(errors)>0:
${header|h}
% for error in errors:
${error|h}
% endfor
% endif
%def>
<%def name="wizard_save_search_form(app, saved_search, display_share=True)">
<%self:wizard_errors header="${_('Your search could not be saved.')}" errors='${saved_search.errors}'/>
<%self:csrf_hidden_input/>
% if saved_search.id:
% endif
${_("-1d (one day ago), now (triggering time)")}
${_("rt-1d (one day ago in real-time), rt(triggering time)")}
${_("Time specifiers: y, mon, d, h, m, s")}
${_('Learn more')}