Example #1
0
def get_api_config(api):
    if api == 'kobotoolbox':
        url_field = 'kobo_api_url'
        username_field = 'kobo_api_username'
        credential_entity = 'kobo_api_password'
    if api == 'splunk':
        url_field = 'splunk_ec_url'
        credential_entity = 'splunk_ec_token'

    username = ''

    try:
        kobotoolbox_config = entity.getEntity(['admin', 'conf-app'],
                                              'kobotoolbox',
                                              namespace='TA-kobotoolbox',
                                              owner='nobody',
                                              sessionKey=session_key)
        credential = entity.getEntity(['admin', 'passwords'],
                                      credential_entity,
                                      namespace='TA-kobotoolbox',
                                      owner='nobody',
                                      sessionKey=session_key)

        url = kobotoolbox_config[url_field]

        if api == 'kobotoolbox':
            username = kobotoolbox_config[username_field]

    except Exception, e:
        print_status('ERROR',
                     "Could not get API config for %s: %s" % (api, str(e)))
        sys.exit()
    def disableIndexAndForward(cls, sessionKey):

        try:
            # Try to get the existing entry
            indexAndForward_entity = en.getEntity(
                'configs/conf-outputs',
                "indexAndForward",
                namespace=ConfigCEFApp.DEFAULT_NAMESPACE,
                owner=ConfigCEFApp.DEFAULT_OWNER,
                sessionKey=sessionKey)

        except splunk.ResourceNotFound:

            # Otherwise, create a new one
            indexAndForward_entity = en.getEntity(
                'configs/conf-outputs',
                "_new",
                namespace=ConfigCEFApp.DEFAULT_NAMESPACE,
                owner=ConfigCEFApp.DEFAULT_OWNER,
                sessionKey=sessionKey)

            indexAndForward_entity.namespace = ConfigCEFApp.DEFAULT_NAMESPACE
            indexAndForward_entity.owner = ConfigCEFApp.DEFAULT_OWNER
            indexAndForward_entity['name'] = "indexAndForward"

        indexAndForward_entity['index'] = 0
        en.setEntity(indexAndForward_entity, sessionKey=sessionKey)
Example #3
0
    def save(self, new=False, session_key=None, namespace=None, owner=None):
        """
        Saves the notable event status. If an ID is set, then the existing status will be updated. Otherwise, a new one will be created.
        """
        
        ## Get the owner and namespace
        if namespace is None:
            namespace = NotableEventSuppression.DEFAULT_NAMESPACE
            
        if owner is None:
            owner = NotableEventSuppression.DEFAULT_OWNER
        
        ## Try to get the session key if not provided
        session_key = NotableEventSuppression.__get_session_key__(session_key)

        ## If the ID is not set, create a new entry
        if new:
            ## Get the default entity
            notable_suppression = en.getEntity(NotableEventSuppression.EVENTTYPES_REST_URL, '_new', sessionKey=session_key)
        
        ## Otherwise, edit the existing entity
        else:
            ## Get the existing entity
            notable_suppression = en.getEntity(NotableEventSuppression.EVENTTYPES_REST_URL, self.id, namespace=namespace, owner=owner, sessionKey=session_key)
                
        ## Update the entity
        notable_suppression = self.__populate_entity__(notable_suppression, new)
                
        ## Save the entity
        en.setEntity(notable_suppression, sessionKey=session_key)
            
        return True
    def pdf(self):
        '''
        Provides debug services for PDF server
        '''

        status = {
            'pdfIsInstalled': False,
            'pdfIsEnabled': False,
            'smtpIsSet': False,
            'configuration': {}
        }

        # check that PDF app is installed
        try:
            if comm.isWindows:
                en.getEntity('/pdfserver', 'renderpdf')
            else:
                en.getEntity('admin/localapps',
                             'pdfserver',
                             namespace='search')
            status['pdfIsInstalled'] = True
        except splunk.ResourceNotFound:
            pass
        except Exception, e:
            logger.exception(e)
            status['pdfIsInstalled'] = e
Example #5
0
    def is_enabled(self):
        """
        Determine whether the PDF server is installed and enabled for the current user
        """
        try:
            installed = False
            settings = en.getEntity(ALERT_ACTIONS_ENTITY, 'email')
            serverURL = settings.get('reportServerURL') or ''
            if serverURL.strip() == '':
                # if reportServerURL is blank then this system should actually have the app installed; check for that.
                # will raise a ResourceNotFound exception if not installed
                if comm.isWindows:
                    # will raise a ResourceNotFound exception if our PDF driver is not installed
                    en.getEntity('/pdfserver', 'renderpdf')
                else:
                    en.getEntity('/apps/local', 'pdfserver')
                installed = True

            # next check that it's actually turned on in email settings;
            # on Windows, ther server is always enabled
            status = 'enabled' if comm.isWindows or splunk.util.normalizeBoolean(
                settings.get('reportServerEnabled')) else 'disabled'
        except splunk.ResourceNotFound:
            status = 'notinstalled'
        except splunk.AuthorizationFailed:
            status = 'denied'
        except splunk.LicenseRestriction:
            status = 'denied'
        response = {'installed': installed, 'status': status}
        return self.render_json(response)
Example #6
0
    def is_enabled(self):
        """
        Determine whether the PDF server is installed and enabled for the current user
        """
        try:
            installed = False
            settings = en.getEntity(ALERT_ACTIONS_ENTITY, 'email')
            serverURL = settings.get('reportServerURL') or ''
            if serverURL.strip() == '':
                # if reportServerURL is blank then this system should actually have the app installed; check for that.
                # will raise a ResourceNotFound exception if not installed
                if comm.isWindows:
                    # will raise a ResourceNotFound exception if our PDF driver is not installed
                    en.getEntity('/pdfserver', 'renderpdf')
                else:
                    en.getEntity('/apps/local', 'pdfserver')
                installed = True

            # next check that it's actually turned on in email settings;
            # on Windows, ther server is always enabled
            status = 'enabled' if comm.isWindows or splunk.util.normalizeBoolean(settings.get('reportServerEnabled')) else 'disabled'
        except splunk.ResourceNotFound:
            status = 'notinstalled'
        except splunk.AuthorizationFailed:
            status = 'denied'
        except splunk.LicenseRestriction:
            status = 'denied'
        response = {
            'installed': installed,
            'status': status
        }
        return self.render_json(response)
Example #7
0
    def create_new_scripted_inputs(self, data):

        inputdata = entity.getEntity('data/inputs/script',
                                     '_new',
                                     sessionKey=self.getSessionKey())

        inputdata[
            "name"] = '$SPLUNK_HOME\\etc\\apps\\TA-CMX\\bin\\Server.py' \
            if platform.system().lower() == 'windows' else '$SPLUNK_HOME/etc/apps/TA-CMX/bin/Server.py'

        inputdata["interval"] = ["0"]
        inputdata["disabled"] = ["false"]
        inputdata["passAuth"] = ["splunk-system-user"]
        inputdata.namespace = "TA-CMX"
        entity.setEntity(inputdata, sessionKey=self.getSessionKey())

        index = data["INDEX"][0] if data["INDEX"] else "main"

        inputdata = entity.getEntity('data/inputs/script',
                                     '_new',
                                     sessionKey=self.getSessionKey())
        inputdata[
            "name"] = '$SPLUNK_HOME\\etc\\apps\\TA-CMX\\bin\\CMXRestAPIMAP.py' \
            if platform.system().lower() == 'windows' else '$SPLUNK_HOME/etc/apps/TA-CMX/bin/CMXRestAPIMAP.py'
        inputdata["interval"] = ["86400"]
        inputdata["disabled"] = ["false"]
        inputdata["index"] = [index]
        inputdata["sourcetype"] = ["cmxmap"]
        inputdata["passAuth"] = ["splunk-system-user"]
        inputdata.namespace = "TA-CMX"
        entity.setEntity(inputdata, sessionKey=self.getSessionKey())

        inputdata = entity.getEntity('data/inputs/script',
                                     '_new',
                                     sessionKey=self.getSessionKey())
        inputdata[
            "name"] = '$SPLUNK_HOME\\etc\\apps\\TA-CMX\\bin\\CMXRestAPIAnalytics.py' \
            if platform.system().lower() == 'windows' else '$SPLUNK_HOME/etc/apps/TA-CMX/bin/CMXRestAPIAnalytics.py'
        inputdata["interval"] = ["540"]
        inputdata["disabled"] = ["false"]
        inputdata["index"] = [index]
        inputdata["sourcetype"] = ["cmxanalytics"]
        inputdata["passAuth"] = ["splunk-system-user"]
        inputdata.namespace = "TA-CMX"
        entity.setEntity(inputdata, sessionKey=self.getSessionKey())

        inputdata = entity.getEntity('data/inputs/script',
                                     '_new',
                                     sessionKey=self.getSessionKey())
        inputdata[
            "name"] = '$SPLUNK_HOME\\etc\\apps\\TA-CMX\\bin\\CMXRestAPIActive.py' \
            if platform.system().lower() == 'windows' else '$SPLUNK_HOME/etc/apps/TA-CMX/bin/CMXRestAPIActive.py'
        inputdata["interval"] = ["960"]
        inputdata["disabled"] = ["false"]
        inputdata["index"] = [index]
        inputdata["sourcetype"] = ["cmxactive"]
        inputdata["passAuth"] = ["splunk-system-user"]
        inputdata.namespace = "TA-CMX"
        entity.setEntity(inputdata, sessionKey=self.getSessionKey())
def getCredentials(sessionKey):
        try:
           api_obj = entity.getEntity('scalr_setup/api_input', 'api', namespace=myapp, owner='nobody', sessionKey=sessionKey)
           api_secret = entity.getEntity('storage/passwords', 'api:secret', namespace=myapp, owner='nobody', sessionKey=sessionKey)
        except Exception as e:
           sys.stderr.write("DATALOADER_SCRIPT_ERROR - Could not get Scalr API Credentials from Splunk. Exception: %s\n" % (str(e)))
           exit(2)

        #print(api_obj)
        #print(api_secret)
        return api_obj['url'], api_obj['key'], api_secret['clear_password'], str2bool(api_obj['verify_ssl'])
Example #9
0
def check_restart_required():
    '''
    Indicates if splunkd has raised the restart flag as a result of new
    configuration changes.
    '''
    
    try:
        en.getEntity('messages', 'restart_required')
        return True
    except splunk.ResourceNotFound:
        return False
    except Exception, e:
        logger.warn('unable to determine if restart is required: %s' % e)
    def setIndexers(cls, indexers, sessionKey):

        # Validate the input
        cls.validateIndexers(indexers)

        # Get the default output group in tcpout
        defaultOutput = cls.getDefaultOutputGroup(sessionKey)

        # No group is defined, make it
        defaultGroupSet = True

        if defaultOutput is None:
            defaultGroupSet = False

            # See if the default group already exists
            #defaultOutput = Output.search('name=tcpout:indexCluster"', count_per_req=100, sessionKey=sessionKey)
            try:
                defaultOutput = en.getEntity('admin/conf-outputs',
                                             "tcpout:indexCluster",
                                             sessionKey=sessionKey)
            except splunk.ResourceNotFound:
                defaultOutput = None

            if defaultOutput is not None:
                pass

            # Otherwise, make the new group
            else:
                #defaultOutput = Output(ConfigCEFApp.DEFAULT_NAMESPACE, ConfigCEFApp.DEFAULT_OWNER, "tcpout:indexCluster")
                defaultOutput = en.getEntity('admin/conf-outputs',
                                             '_new',
                                             sessionKey=sessionKey)

                defaultOutput.namespace = ConfigCEFApp.DEFAULT_NAMESPACE
                defaultOutput.owner = ConfigCEFApp.DEFAULT_OWNER
                defaultOutput['name'] = "tcpout:indexCluster"

        # Update and save the entry
        #defaultOutput.server = indexers
        #defaultOutput.save()
        defaultOutput['server'] = indexers
        defaultOutput.namespace = ConfigCEFApp.DEFAULT_NAMESPACE
        defaultOutput.owner = ConfigCEFApp.DEFAULT_OWNER
        en.setEntity(defaultOutput, sessionKey=sessionKey)

        # Set this as the default group
        if not defaultGroupSet:
            cls.setDefaultTcpOutGroup(defaultOutput.name, sessionKey)

        # Disable local indexing
        cls.disableIndexAndForward(sessionKey)
def which_pdf_service(sessionKey, viewId=None, owner=None, namespace=None):
    pdfService = "none"

    if is_pdfgen_available():
        if viewId is None or (len(viewId) == 0):
            pdfService = "pdfgen"
        else:
            import lxml.etree as et

            # this is either a simple dashboard, simple form, or advanced XML view
            # get the entity of the view and then check the root node
            entityId = entity.buildEndpoint('data/ui/views',
                                            viewId,
                                            namespace=namespace,
                                            owner=owner)
            viewEntity = entity.getEntity('data/ui/views',
                                          None,
                                          sessionKey=sessionKey,
                                          uri=entityId)
            data = viewEntity['eai:data']
            if data:
                root = et.fromstring(unicode(data).encode('utf-8'))
                if root.tag == "dashboard":
                    pdfService = "pdfgen"
                else:
                    pdfService = "deprecated"
    else:
        pdfService = "deprecated"

    if pdfService is "deprecated" and not is_deprecated_service_available(
            sessionKey):
        pdfService = "none"

    return pdfService
Example #12
0
def generateBaseLink():
    """
    Construct a link suitable for giving to the PDF server
    Utilize the configured link hostname if available, else use the
    url from this instance of splunkweb
    """
    settings = en.getEntity('/configs/conf-alert_actions', 'email', namespace='system')
    linkhost = settings.get('hostname')
    if linkhost:
        linkhost = linkhost.strip()
    if not linkhost:
        result = cherrypy.request.base
    elif linkhost.startswith('http://') or linkhost.startswith('https://'):
        result = linkhost
    else:
        port = cherrypy.request.local.port
        hasport = False
        if '[' in linkhost:
            addrend = linkhost.find(']')
            if addrend < 2:
                raise ValueError('Incorrect IPv6 address specified for link hostname')
            hasport =  len(linkhost) > (addrend + 3) and linkhost[addrend+1] == ':'
        elif ':' in linkhost:
            addrend = linkhost.find(':')
            hasport = len(linkhost) > (addrend + 3)
        result = cherrypy.request.scheme + '://' + linkhost
        if not hasport and port not in (80, 443):
            result += ':%s' % port
    return result
Example #13
0
    def _initAlertActionsDefaults(self):
        """ use alertActions entity to determine default papersize
            return in form of "<size>" or "<size>-landscape"
        """
        paperSize = DEFAULT_PAPER_SIZE
        paperOrientation = DEFAULT_PAPER_ORIENTATION
        try:
            # SPL-107168 Passing namespace and owner to generate context specifc endpoint
            settings = entity.getEntity(self.ALERT_ACTIONS_ENTITY, 'email', namespace=self._namespace, owner=self._owner, sessionKey=self.sessionKey)
            # paperSize is 'letter', 'legal', 'A4', etc
            paperSize = settings.get('reportPaperSize') or DEFAULT_PAPER_SIZE
            # paperOrientation is 'portrait' or 'landscape'
            paperOrientation = settings.get('reportPaperOrientation') or DEFAULT_PAPER_ORIENTATION
            self._includeSplunkLogo = normalizeBoolean(settings.get('reportIncludeSplunkLogo', self._includeSplunkLogo))
            cidFontListString = settings.get('reportCIDFontList', '') or ''
            self._cidFontList = cidFontListString.split(' ')
            self._fileNamePattern = settings.get('reportFileName')            

            # retrieve pdf settings
            for k, v in settings.iteritems():
                if k.startswith(pdfrenderer.SETTING_PREFIX):
                    self._pdfSettings[k] = v
                    keyNoPrefix = k[len(pdfrenderer.SETTING_PREFIX):len(k)]
                    # SSL settings are stored in pdf namespace, but the ssl_context
                    # won't find these settings if they are prefixed w/ pdf
                    self._requestSettings['pdf'][keyNoPrefix] = v

        except Exception as e:
            logger.error("Could not access or parse email stanza of alert_actions.conf. Error=%s" % str(e))

        if paperOrientation == 'landscape':
            self._paperSize = paperSize + '-landscape'
        else:    
            self._paperSize = paperSize
Example #14
0
    def controlJob(self, sid, ctl, action, wait=True, ttl=None):
        '''
        Executes control for a given job
        '''
        resp = JsonResponse()

        # SDK does not have any functionality to change ACLs, so i have
        # had to add these custom actions for now.
        # TODO - if/when SDK has support for changing ACL's,  rewrite this
        # code to not use the Entity class.
        if (action == "makeWorldReadable" or action == "undoWorldReadable"):
            jobPath = "search/jobs/" + sid
            entityName = "acl"
            aclEntity = en.getEntity(
                jobPath,
                entityName,
                namespace="system",
                owner=splunk.auth.getCurrentUser()['name'])

            if (action == "makeWorldReadable"):
                aclEntity.properties['perms.read'] = ["*"]
            else:
                aclEntity.properties['perms.read'] = []
            try:
                result = en.setEntity(aclEntity, uri=jobPath + "/acl")
            except Exception, e:
                logger.exception(e)
                resp.addError(
                    _("Splunk could not update permissions for this job"))

            return self.render_json(resp)
Example #15
0
def setSharing(viewstate, shareMode):
    '''
    Sets the sharing mode: 'global', 'app', 'user'
    '''
    
    if not isinstance(viewstate, Viewstate):
        raise ValueError, 'Cannot update viewstate; Only viewstate objects supported'
    
    # first fetch all the ACL data    
    vsACL = en.getEntity(
        VIEWSTATE_ENTITY_CLASS + '/' + buildStanzaName(viewstate.view, viewstate.id), 
        'acl', 
        namespace=viewstate.namespace, 
        owner=viewstate.owner
    )
    
    # create new object and update mininum set of properties to support sharing
    aclWrapper = en.Entity(
        VIEWSTATE_ENTITY_CLASS + '/' + buildStanzaName(viewstate.view, viewstate.id), 
        'acl', 
        namespace=viewstate.namespace, 
        owner=viewstate.owner
    )
    aclWrapper['owner'] = viewstate.owner
    aclWrapper['sharing'] = shareMode
    
    # commit
    en.setEntity(aclWrapper)
    
    return True
Example #16
0
    def update(self, **params):
        app, user = self._namespace_and_owner()

        ent = en.getEntity(self._endpoint,
                           self.callerArgs.id,
                           namespace=app,
                           owner=user,
                           sessionKey=self.getSessionKey())

        for arg in params.keys():
            if arg in self._required_args + self._optional_args:
                ent[arg] = params[arg]

        #check which args are allowed to be posted
        allowedArgs = []
        if 'eai:attributes' in ent and 'requiredFields' in ent[
                'eai:attributes'] and 'optionalFields' in ent['eai:attributes']:
            allowedArgs = ent['eai:attributes']['requiredFields'] + ent[
                'eai:attributes']['optionalFields']

        #filter out args that aren't allowed
        for arg in ent.keys():
            if arg not in allowedArgs:
                del ent.properties[arg]

        en.setEntity(ent, sessionKey=self.getSessionKey())
Example #17
0
    def controlJob(self, sid, ctl, action, ttl=None):
        """
        Executes control for a given job
        """
        resp = JsonResponse()

        # SDK does not have any functionality to change ACLs, so i have
        # had to add these custom actions for now.
        # TODO - if/when SDK has support for changing ACL's,  rewrite this
        # code to not use the Entity class.
        if action == "makeWorldReadable" or action == "undoWorldReadable":
            jobPath = "search/jobs/" + sid
            entityName = "acl"
            aclEntity = en.getEntity(
                jobPath, entityName, namespace="system", owner=splunk.auth.getCurrentUser()["name"]
            )

            if action == "makeWorldReadable":
                aclEntity.properties["perms.read"] = ["*"]
            else:
                aclEntity.properties["perms.read"] = []
            try:
                result = en.setEntity(aclEntity, uri=jobPath + "/acl")
            except Exception, e:
                logger.exception(e)
                resp.addError(_("Splunk could not update permissions for this job"))

            return self.render_json(resp)
Example #18
0
    def getMailSettings(self):

        import splunk.entity as entity

        try:
            namespace = "search"
            ent = entity.getEntity('admin/alert_actions',
                                   'email',
                                   namespace=namespace,
                                   owner='nobody',
                                   sessionKey=self.sessionKey)

            self.server = ent['mailserver']
            self.sender = ent['from']
            if ent['use_ssl'] == "1":
                self.use_ssl = True
            else:
                self.use_ssl = False

            if ent['use_tls'] == "1":
                self.use_tls = True
            else:
                self.use_tls = False

            if 'auth_username' in ent and 'clear_password' in ent:
                self.username = ent['auth_username']
                self.password = ent['clear_password']
        except Exception, e:
            raise Exception, "Could not get email settings from splunk. SessionKey=%s Error: %s" % (
                self.sessionKey, str(e))
    def _initAlertActionsDefaults(self):
        """ use alertActions entity to determine default papersize
            return in form of "<size>" or "<size>-landscape"
        """
        paperSize = DEFAULT_PAPER_SIZE
        paperOrientation = DEFAULT_PAPER_ORIENTATION
        try:
            settings = entity.getEntity(self.ALERT_ACTIONS_ENTITY,
                                        'email',
                                        sessionKey=self.sessionKey)
            # paperSize is 'letter', 'legal', 'A4', etc
            paperSize = settings.get('reportPaperSize') or DEFAULT_PAPER_SIZE
            # paperOrientation is 'portrait' or 'landscape'
            paperOrientation = settings.get(
                'reportPaperOrientation') or DEFAULT_PAPER_ORIENTATION
            self._includeSplunkLogo = normalizeBoolean(
                settings.get('reportIncludeSplunkLogo',
                             self._includeSplunkLogo))
            cidFontListString = settings.get('reportCIDFontList', '') or ''
            self._cidFontList = cidFontListString.split(' ')
        except Exception as e:
            logger.error(
                "Could not access or parse email stanza of alert_actions.conf. Error=%s"
                % str(e))

        if paperOrientation == 'landscape':
            self._paperSize = paperSize + '-landscape'
        else:
            self._paperSize = paperSize
Example #20
0
    def getViewObject(self, view_id, namespace, outputEntity=False):
        '''
        Returns a native ViewObject version of the requested view_id
        '''

        viewEntity = en.getEntity(VIEW_ENTITY_CLASS,
                                  view_id,
                                  namespace=namespace)

        parser = et.XMLParser(remove_blank_text=True,
                              remove_comments=True,
                              remove_pis=True)
        root = et.XML(viewEntity[en.EAI_DATA_KEY], parser)

        if root.tag == 'dashboard':
            objectClass = dashboard.SimpleDashboard(
                isStorm=splunk.util.normalizeBoolean(
                    cherrypy.config.get('storm_enabled')))
        elif root.tag == 'form':
            objectClass = form.SimpleForm()
        else:
            raise NotImplementedError, 'Cannot manage view object of type: %s' % root.tag

        objectClass.fromXml(root)

        if outputEntity:
            return objectClass, viewEntity
        else:
            return objectClass
Example #21
0
    def get_rest_info(self, session_key=None, namespace=None):
        """
        Returns a session key, namespace and owner (in that order). The namespace and owner will be
        populated with default values if they do not have a value already.
        """

        # Try to get the session key if not provided
        session_key = CorrelationSearch.__get_session_key__(session_key)

        # If this is an existing search, get the namespace
        if self.sid:
            try:
                saved_search = en.getEntity(
                    CorrelationSearch.SAVED_SEARCHES_REST_URL,
                    self.sid,
                    sessionKey=session_key)
                namespace = saved_search.get('eai:acl').get('app')
            except Exception:
                pass

        # Validate the namespace
        namespace = self.validate_namespace(session_key, namespace)
        self.namespace = namespace

        # Force user to "nobody" to permit role-based editing.
        owner = 'nobody'
        self.owner = owner

        return session_key, namespace, owner
    def getDefaultOutputGroup(cls, sessionKey):

        # Get the default group
        output = cls.getMainOutput(sessionKey)

        if 'defaultGroup' in output:
            defaultGroup = output['defaultGroup']
        else:
            return None

        # No group is defined
        if defaultGroup is None:
            return None

        # Get the default group
        #defaultOutput = Output.get(Output.build_id("tcpout:" + defaultGroup, None, None), sessionKey=sessionKey)
        try:
            defaultOutput = en.getEntity('admin/conf-outputs',
                                         "tcpout:" + defaultGroup,
                                         sessionKey=sessionKey)
        except splunk.ResourceNotFound:
            return None

        # Return the indexers
        return defaultOutput
Example #23
0
 def getRemoteAppEntry(self, appid):
     """
     Used to determine whether the app is available on Splunkbase and whether splunkd can even talk to Splunkbase
     """
     return en.getEntity('/apps/remote/entriesbyid',
                         appid,
                         sessionKey=cherrypy.session['sessionKey'])
    def handleEdit(self, confInfo):

        name = self.callerArgs.id

        ent = en.getEntity(ENDPOINT, name,
                              namespace=self.appName,
                              owner=self.userName,
                              sessionKey=self.getSessionKey())
                              
        for arg in optional_args:
            try:
                if arg in ['disabled']:
                    continue 
                ent[arg] = self.callerArgs[arg]
            except:
                pass

        for arg in required_args:
            try:
                if arg in ['disabled']:
                    continue 
                ent[arg] = self.callerArgs[arg] 
            except: 
                pass

        en.setEntity(ent, sessionKey=self.getSessionKey())
    def edit(self, app, viewName, **params):
        owner = splunk.auth.getCurrentUser()['name']

        pdfPreviewUrl = None
        if "pdfPreviewUrl" in params:
            pdfPreviewUrl = params.get('pdfPreviewUrl')

        viewLabel = viewName
        if "viewLabel" in params:
            viewLabel = params.get('viewLabel')

        id = ScheduledView.build_id(name=viewName, owner=owner, namespace=app)
        scheduled_view = ScheduledView.get(id)
        if scheduled_view.schedule.cron_schedule == None:
            scheduled_view.schedule.cron_schedule = '*/30 * * * *'
        frequency, manual_cron = self._cronSchedule_to_UI(scheduled_view.schedule.cron_schedule)

        # TODO: refactor out to share code with pdfgen_endpoint
        ALERT_ACTIONS_ENTITY="/configs/conf-alert_actions"
        settings = entity.getEntity(ALERT_ACTIONS_ENTITY, 'email')

        # paperSize is 'letter', 'legal', 'A4', etc
        paperSize = settings.get('reportPaperSize') or 'letter'
        # paperOrientation is 'portrait' or 'landscape'
        paperOrientation = settings.get('reportPaperOrientation') or 'portrait'

        if scheduled_view.action.email.papersize == None:
            scheduled_view.action.email.papersize = paperSize
        paperSize = scheduled_view.action.email.papersize
        
        if scheduled_view.action.email.paperorientation == None:
            scheduled_view.action.email.paperorientation = paperOrientation
        paperOrientation = scheduled_view.action.email.paperorientation

        return self.render_template('scheduledview/edit.html', dict(app=app, scheduled_view=scheduled_view, frequency=frequency, manual_cron=manual_cron, paperSize=paperSize, paperOrientation=paperOrientation, pdfPreviewUrl=pdfPreviewUrl, viewLabel=viewLabel))
Example #26
0
    def handleEdit(self, confInfo):

        name = self.callerArgs.id

        ent = en.getEntity(ENDPOINT,
                           name,
                           namespace=self.appName,
                           owner=self.userName,
                           sessionKey=self.getSessionKey())

        for arg in optional_args:
            try:
                if arg in ['disabled']:
                    continue
                ent[arg] = self.callerArgs[arg]
            except:
                pass

        for arg in required_args:
            try:
                if arg in ['disabled']:
                    continue
                ent[arg] = self.callerArgs[arg]
            except:
                pass

        en.setEntity(ent, sessionKey=self.getSessionKey())
    def _initWebDefaults(self):
        defaultSplunkdConnectionTimeout = 30
        try:

            # SPL-107168 Passing namespace and owner to generate context specifc endpoint

            settings = entity.getEntity(self.WEB_ENTITY,
                                        'settings',
                                        namespace=self._namespace,
                                        owner=self._owner,
                                        sessionKey=self.sessionKey)
            splunkdConnectionTimeout = \
                int(settings.get('splunkdConnectionTimeout',
                    defaultSplunkdConnectionTimeout))
            if splunkdConnectionTimeout \
                < defaultSplunkdConnectionTimeout:
                splunkdConnectionTimeout = \
                    defaultSplunkdConnectionTimeout

            splunk.rest.SPLUNKD_CONNECTION_TIMEOUT = \
                splunkdConnectionTimeout
        except Exception, e:
            logger.error(
                'Exception while trying to get splunkdConnectionTimeout from web.conf e=%s'
                % e)
            splunk.rest.SPLUNKD_CONNECTION_TIMEOUT = \
                defaultSplunkdConnectionTimeout
Example #28
0
def setSharing(viewstate, shareMode):
    '''
    Sets the sharing mode: 'global', 'app', 'user'
    '''

    if not isinstance(viewstate, Viewstate):
        raise ValueError, 'Cannot update viewstate; Only viewstate objects supported'

    # first fetch all the ACL data
    vsACL = en.getEntity(VIEWSTATE_ENTITY_CLASS + '/' +
                         buildStanzaName(viewstate.view, viewstate.id),
                         'acl',
                         namespace=viewstate.namespace,
                         owner=viewstate.owner)

    # create new object and update mininum set of properties to support sharing
    aclWrapper = en.Entity(VIEWSTATE_ENTITY_CLASS + '/' +
                           buildStanzaName(viewstate.view, viewstate.id),
                           'acl',
                           namespace=viewstate.namespace,
                           owner=viewstate.owner)
    aclWrapper['owner'] = viewstate.owner
    aclWrapper['sharing'] = shareMode

    # commit
    en.setEntity(aclWrapper)

    return True
Example #29
0
    def _initWebDefaults(self):
        defaultSplunkdConnectionTimeout = 30
        try:
            # SPL-107168 Passing namespace and owner to generate context specifc endpoint
            settings = entity.getEntity(self.WEB_ENTITY,
                                        'settings',
                                        namespace=self._namespace,
                                        owner=self._owner,
                                        sessionKey=self.sessionKey)
            self._enableInsecurePdfgen = normalizeBoolean(
                settings.get('enable_insecure_pdfgen',
                             self._enableInsecurePdfgen))
            splunkdConnectionTimeout = int(
                settings.get('splunkdConnectionTimeout',
                             defaultSplunkdConnectionTimeout))
            if splunkdConnectionTimeout < defaultSplunkdConnectionTimeout:
                splunkdConnectionTimeout = defaultSplunkdConnectionTimeout

            splunk.rest.SPLUNKD_CONNECTION_TIMEOUT = splunkdConnectionTimeout
        except Exception as e:
            logger.error(
                "Could not access or parse settings stanza of web.conf. Error=%s"
                % e)
            splunk.rest.SPLUNKD_CONNECTION_TIMEOUT = defaultSplunkdConnectionTimeout
        finally:
            logger.info("splunkdConnectionTimeout=%s" %
                        splunk.rest.SPLUNKD_CONNECTION_TIMEOUT)
def getEntity(entityPath,
              name,
              namespace=None,
              owner=None,
              sessionKey=None,
              hostPath=None,
              available=True):
    conn = en.getEntity(entityPath,
                        name,
                        namespace=namespace,
                        owner=owner,
                        sessionKey=sessionKey,
                        hostPath=hostPath)

    params = conn.properties

    if available:
        for n, v in params.items():
            if n in ["disabled"] and util.normalizeBoolean(v):
                raise ResourceNotFound(msg="%s Resource is disabled." % name)
            elif n.endswith(".disabled"):
                if v in ["-1"]:
                    raise ResourceNotFound(msg="%s in %s Resource not found." %
                                           (n[:len(n) - 9], name))
                elif util.normalizeBoolean(v):
                    raise ResourceNotFound(
                        msg="%s in %s Resource is disabled." %
                        (n[:len(n) - 9], name))

    return conn
Example #31
0
def getCredentials(sessionKey, namespace):
   try:
      ent = entity.getEntity('admin/alert_actions', 'email', namespace=namespace, owner='nobody', sessionKey=sessionKey)
      if 'auth_username' in ent and 'clear_password' in ent:
          return ent['auth_username'], ent['clear_password']
   except Exception, e:
      logger.error("Could not get email credentials from splunk, using no credentials. Error: %s" % (str(e)))
Example #32
0
        def instrumentation_eligibility(self, optInVersion=None, **kwargs):
            '''
            Determines whether the UI for the instrumentation app should be visible,
            including the initial opt-in modal and all settings/logs pages.
            This is determined by user capabilities, license type, and server roles.
            '''

            cherrypy.response.headers['Content-Type'] = 'application/json'

            services = ServiceBundle(Splunkd(**self.splunkrc()))

            currentOptInVersion = services.telemetry_conf_service.content.get('optInVersion')

            if optInVersion != '*' and optInVersion != currentOptInVersion:
                return json.dumps({
                    'is_eligible': False,
                    'reason': 'UNAUTHORIZED',
                })

            # If we're not running on a free license (where there are no users),
            # first validate that the user has the requisite capabilities.
            if services.server_info_service.content.get('isFree', '0') != '1':
                user = en.getEntity('authentication/users', cherrypy.session['user']['name'])
                if 'edit_telemetry_settings' not in user.properties['capabilities']:
                    return json.dumps({
                        'is_eligible': False,
                        'reason': 'UNAUTHORIZED'
                    })

            # Now check the server roles, etc
            eligibility = client_eligibility.get_ui_eligibility(services)
            return json.dumps(eligibility)
Example #33
0
    def getMailSettings(self):

        import splunk.entity as entity

        try:
            namespace = "search"
            ent = entity.getEntity(
                "admin/alert_actions", "email", namespace=namespace, owner="nobody", sessionKey=self.sessionKey
            )

            self.server = ent["mailserver"]
            self.sender = ent["from"]
            if ent["use_ssl"] == "1":
                self.use_ssl = True
            else:
                self.use_ssl = False

            if ent["use_tls"] == "1":
                self.use_tls = True
            else:
                self.use_tls = False

            if "auth_username" in ent and "clear_password" in ent:
                self.username = ent["auth_username"]
                self.password = ent["clear_password"]
        except Exception, e:
            raise Exception, "Could not get email settings from splunk. SessionKey=%s Error: %s" % (
                self.sessionKey,
                str(e),
            )
Example #34
0
    def get(self):
        app, user = self._namespace_and_owner()

        return en.getEntity(self._endpoint,
                            self.callerArgs.id,
                            namespace=app,
                            owner=user,
                            sessionKey=self.getSessionKey())
 def get(self, name):
     user, app = self.user_app()
     ent = entity.getEntity(self.endpoint,
                            name,
                            namespace=app,
                            owner=user,
                            sessionKey=self.getSessionKey())
     return self.decode(name, ent)
Example #36
0
 def get_notable_suppression(id=id, session_key=None):
     """
     Get the given notable event suppression.
     """
     
     notable_suppression = en.getEntity(NotableEventSuppression.EVENTTYPES_REST_URL, id, namespace=NotableEventSuppression.DEFAULT_NAMESPACE, owner=NotableEventSuppression.DEFAULT_OWNER, sessionKey=session_key)
     
     return NotableEventSuppression.__create_from_dict__(id, notable_suppression)
Example #37
0
    def get(self):
        app, user = self._namespace_and_owner()

        return en.getEntity(self._endpoint,
                            self.callerArgs.id,
                            namespace=app,
                            owner=user,
                            sessionKey=self.getSessionKey())
 def get(self):
     return en.getEntity(
         self._endpoint,
         self.callerArgs.id,
         namespace=self.appName,
         owner=self.userName,
         sessionKey=self.getSessionKey(),
     )
Example #39
0
def get_total_event_count( server, index, username, password ):
    from splunk import entity, auth, mergeHostPath
    mergeHostPath( server, True )
    auth.getSessionKey( username=username, password=password )
    properties = entity.getEntity( entityPath='/data/indexes', entityName=index ).properties
    if 'totalEventCount' in properties:
        return int( properties['totalEventCount'] )
    else:
        return 0
Example #40
0
def getCredentials(sessionKey, namespace):
    try:
        ent = entity.getEntity(
            "admin/alert_actions", "email", namespace=namespace, owner="nobody", sessionKey=sessionKey
        )
        if "auth_username" in ent and "clear_password" in ent:
            return ent["auth_username"], ent["clear_password"]
    except Exception, e:
        logger.error("Could not get email credentials from splunk, using no credentials. Error: %s" % (str(e)))
Example #41
0
 def _initLimitsDefaults(self):
     """ use limits entity to determine defaults
     """
     try:
         settings = entity.getEntity(self.LIMITS_ENTITY, 'pdf', sessionKey=self.sessionKey)
         logger.debug("limitsPDFStanza=%s" % (str(settings)))
         self._maxRowsPerTable = int(settings.get('max_rows_per_table', self._maxRowsPerTable))
         self._timeoutDuration = int(settings.get('render_endpoint_timeout', self._timeoutDuration))
     except Exception as e:
         logger.error("Could not access or parse pdf stanza of limits.conf. Error=%s" % str(e))
Example #42
0
def addInput(sessionKey, source, namespace, owner, sourcetype, index):
    mon = en.getEntity('/data/inputs/monitor/','_new', sessionKey=sessionKey)
    mon["name"] = source
    if sourcetype != None:
        mon["sourcetype"] = sourcetype
    if index != None:
        mon["index"] = index
    mon.namespace = namespace
    mon.owner = owner
    en.setEntity(mon, sessionKey=sessionKey)
    def update(self, **params):
        ent = en.getEntity(
            self._endpoint, self.callerArgs.id, namespace=self.appName, owner="nobody", sessionKey=self.getSessionKey()
        )

        for arg in params.keys():
            if arg in self._required_args + self._optional_args:
                ent[arg] = params[arg]

        en.setEntity(ent, sessionKey=self.getSessionKey())
    def _getAppData(self, app):
        output = {app:{}}

        try:
            appData = en.getEntity('apps/local', app, namespace=app)
            output[app]['label'] = _(appData.get('label'))
        except splunk.ResourceNotFound:
            logger.error("Unable to retrieve apps/local/%s" % app)

        return output
    def _hasReadPerms(self):
        '''
        Use services/server/settings as a proxy for read permissions.
        '''

        # NOTE:Due SPL-21113 BETA: unify ACL actions to read/write we cannot use the settings endpoint defer to user admin for now.
        return True if 'admin' == au.getCurrentUser()['name'] else False

        entity = None
        try:
            entity = en.getEntity('/server/', 'settings', namespace=splunk.getDefault('namespace'))
        except Exception, e:
            return False
    def pdf(self):
        '''
        Provides debug services for PDF server
        '''

        status = {
            'pdfIsInstalled': False,
            'pdfIsEnabled': False,
            'smtpIsSet': False,
            'configuration': {}
        }

        # check that PDF app is installed
        try:
            if comm.isWindows:
                en.getEntity('/pdfserver', 'renderpdf')
            else:
                en.getEntity('admin/localapps', 'pdfserver', namespace='search')
            status['pdfIsInstalled'] = True
        except splunk.ResourceNotFound:
            pass
        except Exception, e:
            logger.exception(e)
            status['pdfIsInstalled'] = e
Example #47
0
def reap(reap_list, token):
    ''' reap all jobs in given list '''

    if not reap_list:
        return
    
    logger.info('attempting to reap %i job(s)' % len(reap_list))

    for job in reap_list:
        en = entity.getEntity(ENTITY_PATH, job, namespace=APP_NAME,
                              owner='nobody', sessionKey=token)
        if en['status'] and en['status'] != 2:
            logger.warning('job %s cannot be reaped - status is %s' % (job, en['status']))
            next
        entity.deleteEntity(ENTITY_PATH, job, APP_NAME, 'nobody', sessionKey=token)
        logger.info('successfully reaped job %s' % job)
Example #48
0
def set_status(job_list, status, token):

    if job_list and (len(job_list) < 1 or not isinstance(job_list, list)):
        return

    try:
        status = int(status)
    except:
        logger.error('set_status will only accept status integers')
        sys.exit()

    if status < 0 or status > 2:
        logger.error('set_status will only accept status integers between 0 and 2')

    for job in job_list:
        en = entity.getEntity(ENTITY_PATH, job, namespace=APP_NAME,
                              owner='nobody', sessionKey=token)
        en['status'] = status
        entity.setEntity(en, sessionKey=token)
Example #49
0
    def update(self, **params):
        app, user = self._namespace_and_owner()

        ent = en.getEntity(
            self._endpoint, self.callerArgs.id, namespace=app, owner=user, sessionKey=self.getSessionKey()
        )

        for arg in self._optional_args:
            if arg in ["disabled"]:
                continue
            try:
                ent[arg] = params[arg]
            except:
                pass

        for arg in self._required_args:
            if arg in ["disabled"]:
                continue
            ent[arg] = params[arg]

        en.setEntity(ent, sessionKey=self.getSessionKey())
Example #50
0
    def _initAlertActionsDefaults(self):
        """ use alertActions entity to determine default papersize
            return in form of "<size>" or "<size>-landscape"
        """
        paperSize = DEFAULT_PAPER_SIZE
        paperOrientation = DEFAULT_PAPER_ORIENTATION
        try:
            settings = entity.getEntity(self.ALERT_ACTIONS_ENTITY, 'email', sessionKey=self.sessionKey)
            # paperSize is 'letter', 'legal', 'A4', etc
            paperSize = settings.get('reportPaperSize') or DEFAULT_PAPER_SIZE
            # paperOrientation is 'portrait' or 'landscape'
            paperOrientation = settings.get('reportPaperOrientation') or DEFAULT_PAPER_ORIENTATION
            self._includeSplunkLogo = normalizeBoolean(settings.get('reportIncludeSplunkLogo', self._includeSplunkLogo))
            cidFontListString = settings.get('reportCIDFontList', '') or ''
            self._cidFontList = cidFontListString.split(' ')
        except Exception as e:
            logger.error("Could not access or parse email stanza of alert_actions.conf. Error=%s" % str(e))

        if paperOrientation == 'landscape':
            self._paperSize = paperSize + '-landscape'
        else:    
            self._paperSize = paperSize
    def getViewObject(self, view_id, namespace, outputEntity=False):
        '''
        Returns a native ViewObject version of the requested view_id
        '''
        
        viewEntity = en.getEntity(VIEW_ENTITY_CLASS, view_id, namespace=namespace)
        
        parser = et.XMLParser(remove_blank_text=True, remove_comments=True, remove_pis=True)
        root = et.XML(viewEntity[en.EAI_DATA_KEY], parser)

        if root.tag == 'dashboard':
            objectClass = dashboard.SimpleDashboard(isStorm=splunk.util.normalizeBoolean(cherrypy.config.get('storm_enabled')))
        elif root.tag == 'form':
            objectClass = form.SimpleForm()
        else:
            raise NotImplementedError, 'Cannot manage view object of type: %s' % root.tag

        objectClass.fromXml(root)
        
        if outputEntity:
            return objectClass, viewEntity
        else:
            return objectClass
Example #52
0
def generateSelfHelpLink(context=None):
    '''
    Generates the contexual URI to the splunk.com help system
    '''
    import i18n, urllib
    locale = i18n.current_lang_url_component()

    if not context:
        # generate standard help link by passing a keyword that is composed
        # of a cleansed URI (remove locale and namespace)
        context = cherrypy.request.path_info.strip('/').split('/')
        appContext = ''
        if context[0].startswith(locale):
            context.pop(0)
        if context[0] in ('manager'):
            context.pop(1)
        if context[0] in ('app'):
            appName = context[1]
            entity = en.getEntity('apps/local', appName)
            if filter((lambda x: x[0] == 'disable'), entity.links):
                # make sure it's not an internal Splunk app
                appVersion = entity.get('version')
                appContext = '[%s:%s]' % (appName, appVersion)
        context = appContext + '.'.join(context)

    uri = make_url('/help')
    params = {
        'license': 'free' if cherrypy.config.get('is_free_license') else 'pro',
        'installType': 'trial' if cherrypy.config.get('is_trial_license') else 'prod',
        'versionNumber': cherrypy.config.get('version_label'),
        'location': context,
        'skin': 'default',
        'locale': locale
    }

    return uri + '?' + urllib.urlencode(params)
Example #53
0
    def update(self, **params):
        app, user = self._namespace_and_owner()
        
        ent = en.getEntity(self._endpoint, 
                           self.callerArgs.id, 
                           namespace=app,
                           owner=user,
                           sessionKey=self.getSessionKey())
            
        for arg in params.keys():
            if arg in self._required_args + self._optional_args:
                ent[arg] = params[arg] 

        #check which args are allowed to be posted
        allowedArgs = []
        if 'eai:attributes' in ent and 'requiredFields' in ent['eai:attributes'] and 'optionalFields' in ent['eai:attributes']:
            allowedArgs = ent['eai:attributes']['requiredFields'] + ent['eai:attributes']['optionalFields']

        #filter out args that aren't allowed
        for arg in ent.keys():
            if arg not in allowedArgs:
                del ent.properties[arg]

        en.setEntity(ent, sessionKey=self.getSessionKey())
Example #54
0
        def avro_decorated(*args, **argv):
            # find the rpc port from inputs config.
            port = 9998
            
            if hasattr(avro_decorated, "_sessionKey_"):
                import splunk.entity as en
                ent = en.getEntity("/configs/conf-inputs", "rpcstart://default", namespace="splunk-demo-opcda", sessionKey=avro_decorated._sessionKey_, owner="nobody")
                port = ent["port"]
                logger.debug("ent=%s" %ent)
            
            server_addr = ("localhost", port)
            # server_addr = load_server_addr(argv, f._sessionKey_)
            client = ipc.HTTPTransceiver(server_addr[0], server_addr[1])

            requestor = ipc.Requestor(load_protocol(), client)
            
            def call(*argus):
                sn, val = schema.items()[0]
                
                params = {}
                reqs = val["request"]
                for i in range(len(reqs)):
                    k = reqs[i]["name"]
                    if len(argus) > i:
                        params[k] = argus[i]
                        
                logger.debug("sn=%s, parameters = %s" % (sn, params))
                
                ret = requestor.request(sn , params)

                return ret 
            
            avro_decorated.call = call
            avro_decorated.__name__ = f.__name__
            
            return f(*args, **argv)
Example #55
0
 def load_server_addr(argv, sessionKey):
     import splunk.entity as en
     ent = en.getEntity("/configs/conf-inputs", "rpcstart://default", sessionKey=sessionKey)
     logger.debug("ent=%s" %ent)
     
     return ("localhost", 9998)
    def pdf_echo_loopback(self):
        '''
        Adjunct endpoint used with above PDF test echo page that proxies the
        generated PDF back to the test page
        '''

        # set default PDF server URI
        pdfServerUri = '%s://%s/services/pdfserver/renderpdf' % (splunk.getDefault('protocol'), cherrypy.config.get('mgmtHostPort'))

        # get alternate PDF server URI; values seem to be varied so we normalize
        alertSettings = en.getEntity('configs/conf-alert_actions', 'email', namespace='search')
        if alertSettings.get('reportServerURL') and alertSettings['reportServerURL'].strip():
            pdfServerUri = alertSettings['reportServerURL'].strip()
            url = urlsplit(pdfServerUri)
            if len(url.path)<2:
                url = url._asdict()
                url['path'] = '/services/pdfserver/renderpdf'
                pdfServerUri = urlunsplit(SplitResult(**url))

        # determine the external address that is most likely accessible
        urlparts = urlparse.urlparse(pdfServerUri)

        ai = socket.getaddrinfo(urlparts.hostname, int(urlparts.port or 80), socket.AF_UNSPEC, socket.SOCK_STREAM, 0, socket.AI_PASSIVE)[0]
        af, socktype, proto, canonname, hostport = ai

        appserverHost = alertSettings.get('hostname') and alertSettings['hostname'].strip()
        if appserverHost:
            logger.info('using configured appserver hostname "%s"' % appserverHost)
        else:
            s = socket.socket(af, socktype, proto)
            s.connect(hostport)
            sockname = s.getsockname()
            logger.info('most promising interface looks like %s' % sockname[0])
            appserverHost = sockname[0]

        appserverProtocol = 'https' if splunk.util.normalizeBoolean(cherrypy.config.get('enableSplunkWebSSL', False)) else 'http'

        # create a fake sso-bypass session utilizing the user's current sessionKey
        active_session = cherrypy.serving.session
        session_args = ('timeout', 'clean_freq', 'storage_path', 'servers')
        args = dict([ (arg_name, getattr(active_session, arg_name)) for arg_name in session_args if hasattr(active_session, arg_name)])
        fake_session = cherrypy.serving.session.__class__(**args)
        fake_session['sessionKey'] = cherrypy.session['sessionKey']
        fake_session['SSO_DISABLE'] = 1
        fake_session.save()
        fake_session.release_lock()

        cherrypy.session.release_lock()

        # set GET args
        args = {
            'target': '%s://%s:%s%s/debug/pdf_echo' % (
                appserverProtocol,
                appserverHost if af == socket.AF_INET else '[%s]' % appserverHost,
                cherrypy.config['httpport'],
                cherrypy.request.script_name
                ),
            'mode': 'default',
            'session': fake_session.id
        }

        # fetch the SSL certificate, if any
        cert = cherrypy.request.app.root.report.get_cert()
        if cert:
            args['cert'] = cert

        logger.info('Testing PDF server=%s on URI=%s' % (pdfServerUri, args['target']))

        # make a request to the registered PDF server for the echo page
        timeout = 20
        h = httplib2.Http(timeout=timeout, disable_ssl_certificate_validation=True)
        start = time.time()
        try:
            serverResponse, serverContent = h.request(pdfServerUri, method='POST', body=urllib.urlencode(args))
        except:
            if time.time() - start > (timeout-1):
                cherrypy.response.headers['content-type'] = 'text/plain'
                return "Timed out while waiting for a response"
            raise

        cherrypy.response.headers['content-type'] = 'application/pdf'
        return serverContent
        # check that PDF app is installed
        try:
            if comm.isWindows:
                en.getEntity('/pdfserver', 'renderpdf')
            else:
                en.getEntity('admin/localapps', 'pdfserver', namespace='search')
            status['pdfIsInstalled'] = True
        except splunk.ResourceNotFound:
            pass
        except Exception, e:
            logger.exception(e)
            status['pdfIsInstalled'] = e

        # check for enabled, SMTP, and PDF config
        try:
            alertSettings = en.getEntity('configs/conf-alert_actions', 'email', namespace='search')
            status['pdfIsEnabled'] = splunk.util.normalizeBoolean(alertSettings.get('reportServerEnabled'))
            status['smtpIsSet'] = True if alertSettings.get('mailserver') else False
            for k in alertSettings:
                if k.startswith('report'):
                    status['configuration'][k] = alertSettings[k]
        except Exception, e:
            logger.exception(e)
            status['pdfIsInstalled'] = e

        return self.render_template('debug/pdf.html', {'status': status})


    @expose_page()
    def pdf_echo(self):
        '''