%!
import logging
# uiHelper requires splunk.util to be imported.
import splunk.util
from splunk import auth
#needed for views page
import lxml.etree as et
from xml.sax.saxutils import quoteattr
import re
import splunk.entity as en
from splunk.appserver.mrsparkle.lib.eai import cpQuoteEntity
import urllib
import time
logger = logging.getLogger('splunk.appserver.templates.admin._helpers')
sharing_names = {'user' : _("Private"),
'app' : _("App"),
'global' : _("Global"),
'system' : _("Global")}
action_names = {'disable' : _("Disable"),
'enable' : _("Enable"),
'remove' : _("Delete")}
year = time.strftime('%Y')
%>
<%def name="renderContextSwitcher()">
<%
from lib.util import current_url_path
from urlparse import parse_qs
from urllib import urlencode
showAppSwitcher = True
url = current_url_path(include_qs=True)
urlParts = url.split("?")
path = urlParts[0]
try:
qstring = urlParts[1]
except IndexError:
qstring = ""
try:
qsdict = parse_qs(qstring)
except Exception, e:
qsdict = {}
"""
logger.debug("\n\n")
logger.debug("urlParts ['path','qs'] :: %s" % urlParts)
logger.debug("qsdict: %s" % qsdict)
logger.debug("\n\n")
"""
pathParts = path.split("/")
# show the switcher, or just the label?
# check if this is the permissions page.
if pathParts[3] == "permissions":
showAppSwitcher = False
namespace = pathParts[4]
else:
namespace = pathParts[3]
try:
section = pathParts[4]
if section in ["apps","accesscontrols","authoverview","authentication","distsearch","data","datainputstats","control","forwardreceive","licensestats","systemsettings"]:
showAppSwitcher = False
except Exception, e:
pass
# determine if this is an edit, if so disable the switcher.
# the values for qsdict are in a list
actionList = qsdict.get("action")
if actionList != None:
if qsdict.get("action")[0] == "edit":
showAppSwitcher = False
if showAppSwitcher:
# build the list of apps for the context switcher.
# set the namespace path part to %s
pathParts[3] = "%s"
strReplUrl = "/".join(pathParts)
if len(qstring) > 0:
qstring = "?%s" % qstring
appOptionList = [ { 'label': '(All Apps)', 'uri': (strReplUrl % '-') + qstring , 'id': '' }, { 'divider': 'actionsMenuDivider' } ]
try:
appList = en.getEntities("apps/local", search=['disabled=false','visible=true'], count=-1)
except Exception, e:
logger.error("exception accessing apps local endpoint.")
logger.error("Exception string e: %s" % e)
try:
manageableAppOptionList = [ {'label': '%s' % ( appList[x].get('label', appList[x].name) ), 'uri': (strReplUrl % appList[x].name ) + qstring } for x in appList ]
appOptionList.extend( manageableAppOptionList )
except Exception, e:
logger.error("exception building appOptionList.")
logger.error("Exception string e: %s" % e)
endif
%>
% if showAppSwitcher:
<%
if namespace == "-":
switcherActivatorLabel = "All Apps"
else:
switcherActivatorLabel = APP['label']
endif
%>
${_(switcherActivatorLabel)}
% else:
${_(APP['label'])} » \
% endif
%def>
<%def name="renderBreadcrumbs(breadcrumb)">
% if breadcrumb:
${_(breadcrumb[-1][0])|h}
% endif
% if breadcrumb and len(breadcrumb) > 2:
\
% for i, (title, url) in enumerate(breadcrumb):
<% made_url = None %>
% if url :
<% made_url = make_url(url) %>
% endif
% if made_url and (re.search('/manager/?\w*/?$', made_url) == None) :
${_(title) | h} \
» \
% elif not url:
${_(title)|h} \
% endif
% endfor
\
% endif
%def>
<%def name="message(content=None, level='info', msg_obj=None)">
% if msg_obj:
% endif
% if content:
% if isinstance(content, basestring):
- ${content|h}
% elif isinstance(content, list):
% for x in content:
- ${x|h}
% endfor
% else:
- ${_('Invalid message type:')} ${content|h}
% endif
% endif
%def>
<%def name="generateFormRow(element, eaiAttributes, form_defaults)">
<%
widget = element['type'] if 'type' in element else 'textfield'
widgetstyle = ''
depends = element.get('hideUnlessFieldSet')
hidetype = 'hideUnlessFieldSet' if element.has_key('hideUnlessFieldSet') else None
if not hidetype:
hidetype = 'nullUnlessFieldSet' if element.has_key('nullUnlessFieldSet') else None
if hidetype:
depends = element[hidetype]
depends = depends if isinstance(depends, list) else [ depends ]
for depend in depends:
if not form_defaults.get(depend, ''):
if hidetype == 'nullUnlessFieldSet':
widget = 'hidden'
else:
widgetstyle = 'style="display: none"'
%>
<%include file="/admin/widgets/${widget}.html" args="element=element, eaiAttributes=eaiAttributes, widgetstyle=widgetstyle" />
%def>
<%def name="makeSortHeading(elementLabel, elementName, kwargs)">
<%
sort_key = kwargs.get("sort_key", None)
sort_dir = kwargs.get("sort_dir", None)
import copy
qs = copy.deepcopy(kwargs)
qs['sort_key'] = elementName
isSorted = (sort_key == elementName)
if sort_dir == None :
sort_dir = "asc"
sort_class = "splSortNone"
elif sort_dir == "desc":
sort_dir = "asc"
sort_class = "splSortDesc"
else:
sort_dir = "desc"
sort_class = "splSortAsc"
qs['sort_dir'] = sort_dir
%>
${elementLabel|h}
% if isSorted:
% else :
% endif
%def>
<%!
## global col count var
countCols = 0
countRows = 0
%>
<%def name="genListRows(namespace, uiHelper, entities, endpoint_path, kwargs=None)">
<%
global countCols
global countRows
isAppList = True if endpoint_path == 'apps/local' else False
isForwardingServer = True if endpoint_path == 'data/outputs/tcp/server' else False
isDeploymentserverclass = True if endpoint_path == 'deployment/serverclass' else False
isSavedsearches = True if endpoint_path == 'saved/searches' else False
isLDAP = True if endpoint_path == 'authentication/providers/LDAP' else False
isViews = True if endpoint_path == 'data/ui/views' else False
isClonable = False if endpoint_path in ['data/outputs/tcp/group','data/inputs/win-event-log-collections','data/lookup-table-files','data/indexes','data/props/extractions', 'authorization/roles', 'search/distributed/peers'] else True
isEnablable = True
showEnabledColumn = False if uiHelper.get('hideEnabledColumn') else True
showPermissionsColumn = False if uiHelper.get('hidePermissionsColumn') else True
showActionsColumn = False if uiHelper.get('hideActionsColumn') else True
showAppContext = True if splunk.util.normalizeBoolean(uiHelper.get("showAppContext", "")) else False
displayNameField = uiHelper.get('displayNameField')
%>
<%
from urllib import quote
from lib.eai import cpQuoteEntity
countRows = 0
countCols = 0
try:
hasCreateLink = filter((lambda x: x[0] == 'create'), entities.links)
except:
hasCreateLink = False
%>
<%def name="genDataCells(elements, entity_endpoint_path, headerRow=False)">
<%
global countCols
global countRows
%>
% for element in elements:
<%
showSummarizationColumn = True if isSavedsearches and element.get("elementName") == "name" else False
%>
% if headerRow:
% if "list" in element.get("showInView", []):
% if "elements" in element:
<%call expr="genDataCells(element['elements'], entity_endpoint_path, headerRow)"/>
% endif
<%
elementLabel = None
sortable = splunk.util.normalizeBoolean(element.get('labelListSortable', 'True'))
if "labelList" in element:
elementLabel = _(element["labelList"])
elif "label" in element:
elementLabel = _(element["label"])
elif element["type"] != "fieldset":
elementLabel = element["elementName"]
else:
continue
%>
% if showSummarizationColumn:
<% countCols += 1 %>
|
% endif
<% countCols += 1 %>
% if sortable:
<%call expr="makeSortHeading(elementLabel, element['elementName'], kwargs)"/>
% else:
${_(elementLabel)}
% endif
|
% endif
% else:
% if "list" in element.get("showInView", []):
% if "elements" in element:
<%call expr="genDataCells(element['elements'], entity_endpoint_path, headerRow)"/>
% endif
% if element.get("type") != "fieldset":
% if showSummarizationColumn:
<% countCols += 1 %>
% if entity.get('auto_summarize','') == '1':
<% qs={'savedsearch': cpQuoteEntity(entity.name, urlquote=False)} %>
% endif
|
% endif
<% countCols += 1 %>
% if element.get("elementName") == "name":
<%
qs = {'action':'edit'}
if entity['eai:acl']['app']:
qs['ns'] = entity['eai:acl']['app']
for key in kwargs:
if key in ('pwnr', 'ns', 'search', 'offset', 'count', 'sort_key', 'sort_dir') or key.lower().startswith('api.'):
qs['f_'+key] = kwargs[key]
list_links = filter((lambda x: x[0] == 'list'), entity.links)
%>
% if list_links and not isAppList and not isForwardingServer:
<% qs['uri'] = list_links[0][1] %>
${entity.name | h}
% else:
${entity.name | h}
% endif
% else:
<%
# apply any transformations defined in uiHelper
value = entity.get(element['elementName'], '')
processed_value = None
if element.has_key('processValueList'):
try:
processed_value = eval(element['processValueList'])
except Exception, e:
logger.error('uiHelper processValueList operator failed for endpoint_path=%s elementName=%s: %s' % (endpoint_path, element['elementName'], str(e)))
processed_value = '[PROCESSING ERROR]'
%>
% if element.has_key('showRSSLink'):
% if value == "1":
% endif
% elif element.has_key('showAlertsLink'):
% if len(value)>0:
<%
alerts_id = None
for link in entity.links:
if link[0]=='alerts':
alerts_id = urllib.quote_plus(link[1])
break
%>
% if alerts_id:
${i18n.format_number(int(value))|h}
% else:
${i18n.format_number(int(value))|h}
% endif
% else:
${_('0')}
% endif
% elif processed_value is None:
${value|h}
% else:
${processed_value|h}
% endif
<%
update_link = filter((lambda x: x[0] == 'update'), entity.links)
implicit_id_required = splunk.util.normalizeBoolean(entity.get('update.implicit_id_required', None))
if implicit_id_required:
update_link_text = 'Overwrite with'
else:
update_link_text = 'Update to'
endif
%>
% if isAppList and (element.get('elementName') == 'version') and update_link:
|
${_('%s %s' % (update_link_text, entity['update.version']))}
% endif
% endif
|
% endif
% endif
% endif
% endfor
%def>
% if len(entities) == 0:
<%
if endpoint_path=='authentication/users':
no_entities_msg = _('User "%s" was not found. Click the "New" button to create a new user.') % kwargs.get("search")
else:
no_entities_msg = _('There are no configurations of this type. ') + (showNewButton and _('Click the "New" button to create a new configuration.') or "")
%>
<%doc>TRANS: Displayed if no admin entities exist to list%doc>${no_entities_msg |h} |
% endif
<%
visibleApps = en.getEntities("apps/local", search=['visible=true'], count=-1)
%>
% for entity in entities.values():
<%
isDeletable = False if ((endpoint_path in ['data/inputs/win-wmi-collections'] and (entity.name in ['CPUTime', 'FreeDiskSpace', 'LocalNetwork', 'Memory', 'LocalProcesses', 'LocalPhysicalDisk'])) or (endpoint_path in ['data/inputs/win-event-log-collections'] and entity.name=='localhost') ) else True
_isClonable = isClonable and (endpoint_path not in ['authentication/users' ] or entity['type'] == 'Splunk')
entityDisplayName = entity[displayNameField] if displayNameField else entity.name
%>
% if "elements" in uiHelper:
<%
headerRow = False
if countRows == 0:
headerRow = True
isModifiable = True if entity['eai:acl']['modifiable']=="1" else False
isScheduled = True if entity.get('is_scheduled')=="1" else False
%>
% if headerRow:
<%call expr="genDataCells(uiHelper['elements'], endpoint_path, headerRow)"/>
% if showPermissionsColumn:
% if isModifiable:
<% countCols += 1 %>
<%call expr="makeSortHeading(_('Sharing'), 'eai:acl.sharing', kwargs)"/>
|
% endif
%endif
% if showEnabledColumn:
<% countCols += 1 %>
<%call expr="makeSortHeading(_('Status'), 'disabled', kwargs)"/>
|
% endif
% if showActionsColumn:
<% countCols += 1 %>
${_('Actions')} |
% endif
<%
## the header has been created, proceed...
headerRow = False
countCols = 0
countRows += 1
%>
% endif
<% entity_endpoint_path = entity.get('endpoint_base', endpoint_path) %>
<%call expr="genDataCells(uiHelper['elements'], entity_endpoint_path, headerRow)"/>
% if showPermissionsColumn:
% if isModifiable:
<% countCols += 1 %>
<% list_links = filter((lambda x: x[0] == 'list'), entity.links) %>
${sharing_names.get(entity['eai:acl']['sharing'], "")}
% if list_links and (entity['eai:acl'].get('sharing', None) != 'user' or entity['eai:acl'].get('can_share_app', None) == '1'):
<% qs = {'uri': list_links[0][1]} %>
| ${_("Permissions")}
% endif
|
% endif
%endif
% if showEnabledColumn:
<% countCols += 1 %>
% if isEnablable:
<%
if not splunk.util.normalizeBoolean(entity.get('disabled',None)):
enabledState = _("Enabled")
else:
enabledState = _("Disabled")
endif
%>
${enabledState}
% if entity['eai:acl']['can_write']=='1':
% for ctrl in ('disable', 'enable'):
<% ctrl_links = filter((lambda x: x[0] == ctrl), entity.links) %>
% if ctrl_links:
<% jscall = "doObjectAction('%s', '%s', '%s'); return false;" % ( ctrl.replace("'","\\'"), ctrl_links[0][1].replace("'","\\'"), entityDisplayName.replace("\\","\\\\").replace("'","\\'") ) %>
|
<% all_tags = _(' all tags for pair') if endpoint_path == 'saved/fvtags' else '' %>
${_(action_names[ctrl]) + all_tags}
<% needs_sep = True %>
% endif
% endfor
% endif
% endif
|
% endif
% if showActionsColumn:
<% countCols += 1 %>
<% needs_sep = False %>
% if (isSavedsearches and isScheduled):
% if needs_sep:
|
<% needs_sep = False %>
% endif
${_("View recent")}
<% needs_sep = True %>
% endif
% if (isSavedsearches):
% if needs_sep:
|
<% needs_sep = False %>
% endif
<% qs = {'s':entity.getLink("alternate")} %>
${_("Run")}
<% needs_sep = True %>
% endif
% if isLDAP and ('disabled' not in entity or entity['disabled'] == '0'):
% if needs_sep:
|
<% needs_sep = False %>
% endif
<% qs = {'api.strategy':entity.name} %>
${_("Map groups")}
<% needs_sep = True %>
% endif
% if isViews and (entity['eai:acl']['app'] in visibleApps) and ('disabled' not in entity or entity['disabled'] == '0'):
% if needs_sep:
|
<% needs_sep = False %>
% endif
${_("Open")}
<% needs_sep = True %>
% endif
% if isDeploymentserverclass:
% if needs_sep:
|
<% needs_sep = False %>
% endif
<%
link_url = filter((lambda x: x[0] == "status"), entity.links)[0][1]
link_url_parts = link_url.split('/')
status_link = ""
if link_url_parts[1] == "servicesNS":
# for servicesNS, remove the app and user parts + deployment since that is where we are.
status_link = link_url_parts[5:]
else:
# for services, there are no app and user parts to remove
status_link = link_url_parts[2:]
%>
${_('Status')}
<% needs_sep = True %>
% endif
% if isAppList:
<% hasSetup = False %>
% if needs_sep:
|
<% needs_sep = False %>
% endif
% if filter((lambda x: x[0] == 'setup'), entity.links):
<% qs = {'action':'edit'} %>
<%
hasSetup = True
if entity.name == "windows":
qs["redirect_override"]="/app/windows"
endif
%>
${_("Set up")}
<% needs_sep = True %>
% endif
% if (entity['visible'] == '1') and (entity['disabled'] == '0') and not ((entity['configured'] == '0') and hasSetup):
% if needs_sep:
|
<% needs_sep = False %>
% endif
${_("Launch app")}
<% needs_sep = True %>
% endif
% if entity['disabled'] == '0':
% if needs_sep:
|
<% needs_sep = False %>
% endif
<% qs = {'action':'edit'} %>
${_("Edit properties")}
<% needs_sep = True %>
% endif
% if entity['disabled'] == '0':
% if needs_sep:
|
<% needs_sep = False %>
% endif
<% qs = {'ns':entity.name, 'app_only':'1'} %>
${_("View objects")}
<% needs_sep = True %>
% endif
% if 'details' in entity:
% if needs_sep:
|
<% needs_sep = False %>
% endif
${_("View details on SplunkApps")}
<% needs_sep = True %>
% endif
% else:
<% list_links = filter((lambda x: x[0] == 'list'), entity.links) %>
% if _isClonable and list_links and hasCreateLink:
% if needs_sep:
|
<% needs_sep = False %>
% endif
<% needs_sep = True %>
<%doc>TRANS: Clicked to clone an existing enity%doc>${_('Clone')}
% endif
% if hasCreateLink and showAppContext:
<% move_link = filter((lambda x: x[0] == 'move'), entity.links) %>
% if move_link:
% if needs_sep:
|
<% needs_sep = False %>
% endif
<% needs_sep = True %>
<%
if entity['eai:acl']['sharing']=='user':
owner = entity.owner
else:
owner = "nobody"
endif
jscall = "moveObjectToApp(%s,%s,%s); return false;" % (jsonify(move_link[0][1]), jsonify(entityDisplayName), jsonify(owner))
%>
<%doc>TRANS: Clicked to move an existing enity to a different namespace%doc>${_('Move')}
% endif
% endif
<% ctrl_links = filter((lambda x: x[0] == 'remove'), entity.links) %>
% if isDeletable and ctrl_links:
% if needs_sep:
|
% endif
<% jscall = "doObjectAction('remove', %s, %s);" % ( jsonify(ctrl_links[0][1]), jsonify(entityDisplayName) ) %>
${_(action_names['remove'])}
% endif
% endif
|
% endif
<% countCols = 0 %>
% endif
<% countRows += 1 %>
% endfor
%def>
<%def name="menulist(namespace, menuDict)">
<%
label = menuDict.get("label", None)
menuItems = menuDict.get("menuItems",[]) # menu items is a list of dicts.
%>
% if label:
${_(label)}
% endif
% for item in menuItems:
<%
itemLabel = item.get("label", "A label is required for this item.")
itemUrl = item.get("url", None)
itemDescription = item.get("description", None)
links = item.get("links", None)
currentUser=auth.getCurrentUser()['name']
itemId=item.get("id", "default")
%>
-
% if itemUrl:
${_(itemLabel)}
% else:
${_(itemLabel)}
% endif
% if links:
% for link in links:
<%
label = link.get("label", "label is required and not provided")
url = "#"
localUrl = link.get("local-url", None)
remoteUrl = link.get("remote-url", None)
if remoteUrl != None:
url = remoteUrl
target = "_blank"
## local url's win if both are defined
if localUrl != None:
url = make_url(localUrl % dict(namespace=cpQuoteEntity(namespace),currentUser=cpQuoteEntity(currentUser)))
target = "_top"
%>
|${_(label)}
% endfor
% endif
% if itemDescription:
- ${_(itemDescription)}
% endif
% endfor
%def>
## used by admin/EAI to hook events into widgets
<%def name="wireElementEvents(element, eltype=None)">
<%
eltype = eltype if eltype else element['type']
%>
% if element.has_key('onChange') and eltype in ('select', 'multiselect', 'hidden', 'text'):
onchange="${'Splunk.EAI.getInstance().doElementOnChange(this, %s)' % (jsonify(element['elementName']).replace('"', "'"))}"
% endif
% if element.has_key('onChange') and eltype in ('radio','checkbox','button') :
onclick="${'Splunk.EAI.getInstance().doElementOnChange(this, %s)' % (jsonify(element['elementName']).replace('"', "'"))}"
% endif
%def>
<%def name="header(namespace)">
%def>
<%def name="displayrestartbutton(displayRestartButton=True, return_to='')">
% if displayRestartButton:
<%doc>TRANS: Clicked to restart splunkd%doc>${_('Restart Splunk')}
% endif
%def>