<%! 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"), 'unembed' : _("Disable Embed")} 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 name="renderBreadcrumbs(breadcrumb)"> <% if endpoint_path and endpoint_path.startswith("data/inputs/tcp/raw"): hostAndPort = resolveTcpInputName(breadcrumb[-1][0]) if hostAndPort['host'] is not None: pageTitle = _("%(port)s (restricted to host %(host)s)") % {'port' : hostAndPort['port'], 'host' : hostAndPort['host']} else: pageTitle = hostAndPort['port'] endif else: if breadcrumb: pageTitle = breadcrumb[-1][0] endif %> % if breadcrumb:

${pageTitle|h}

% endif % if breadcrumb and len(breadcrumb) > 2: \ % endif <%def name="message(content=None, level='info', msg_obj=None)"> % if msg_obj: % endif % if content:
    % if isinstance(content, basestring):
  1. ${content|h}
  2. % elif isinstance(content, list): % for x in content:
  3. ${x|h}
  4. % endfor % else:
  5. ${_('Invalid message type:')} ${content|h}
  6. % endif
% endif <%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 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 <%! ## global col count var countCols = 0 countRows = 0 %> <%def name="resolveTcpInputName(name)"> <% if name: nameParts = name.split(":") if len(nameParts) == 2: return {'host' : nameParts[0], 'port' : nameParts[1]} endif return {'host' : None, 'port' : name} %> <%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 isTcpInput = True if endpoint_path == 'data/inputs/tcp/raw' else False 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) %> <% entityName = entity.name if isTcpInput: entityName = resolveTcpInputName(entityName)['port'] endif %> % if list_links and not isAppList and not isForwardingServer: <% qs['uri'] = list_links[0][1] %> ${entityName | h} % else: ${entityName | 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 % 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${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', 'data/inputs/tcp/cooked'] or ('type' in entity and 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${_('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${_('Move')} % endif % endif % if (isSavedsearches): <% unembed_link = filter((lambda x: x[0] == 'unembed'), entity.links) %> % if (unembed_link): % if needs_sep: | <% needs_sep = False %> % endif <% jscall = "doObjectAction('unembed', %s, %s);" % ( jsonify(unembed_link[0][1]), jsonify(entityDisplayName) ) %> ${_(action_names['unembed'])} <% needs_sep = True %> % 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 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
## 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 name="header(namespace)">

${ _("Copyright © 2005-%(year)s Splunk Inc. All rights reserved.") % dict(year=year)}
${_('version %(version)s, build %(build_number)s') % dict(version=cherrypy.config.get('version_label'), build_number=cherrypy.config.get('build_number'))}

##

${ _("Current app: %s" % APP['label']) | h}

<%def name="displayrestartbutton(displayRestartButton=True, return_to='')"> % if displayRestartButton: <%doc>TRANS: Clicked to restart splunkd${_('Restart Splunk')} % endif