예제 #1
0
파일: Parser.py 프로젝트: DRArpitha/splunk
def parseSearchToXML(search, hostPath=None, sessionKey=None, parseOnly='t', namespace=None, owner=None):
    """
        Given a valid search string, return the XML from the splunk parsing endpoint that
        represents the search.
    """

    if search == None or len(search) == 0:
        return None
    
    if not owner: owner = auth.getCurrentUser()['name']
    
    uri = entity.buildEndpoint('/search/parser', namespace=namespace, owner=owner)
    if hostPath:
        uri = splunk.mergeHostPath(hostPath) + uri

    args = {
        'q'             : search,
        'parse_only'    : parseOnly
    }

    serverResponse, serverContent = rest.simpleRequest(uri, getargs=args, sessionKey=sessionKey)
    #print "SERVERCONTENT:", serverContent
    # normal messages from splunkd are propogated via SplunkdException;
    if 400 <= serverResponse.status < 500:
        root = et.fromstring(serverContent)
        extractedMessages = rest.extractMessages(root)
        for msg in extractedMessages:
            raise splunk.SearchException, msg['text']

    return serverContent
예제 #2
0
    def getPanel(self, namespace, view_id, panel_type, panel_sequence,
                 **unused):
        '''
        Returns a dashboard panel config
        
        GET /<namespace>/<view_id>/panel/<panel_sequence>
            --> panel config for panel at <panel_sequence>
            
            ==> returns a JSON response
        '''

        output = jsonresponse.JsonResponse()

        try:
            username = cherrypy.session['user'].get('name')
            dash_id = en.buildEndpoint(VIEW_ENTITY_CLASS,
                                       view_id,
                                       namespace=namespace,
                                       owner=username)
            dashObject = Dashboard.get(dash_id)
            output.data = dashObject.get_panel(panel_sequence)

        except IndexError, e:
            cherrypy.response.status = 404
            output.success = False
            output.addError(
                _('Requested panel %s does not exist') % panel_sequence)
예제 #3
0
    def streamingExport(self, job, outputMode, **kwargs):
        ns = job.eaiacl['app']
        sid = job.sid
        owner = job.eaiacl['owner']
        request = {}
        request['output_mode'] = outputMode
        if ('fields' in kwargs):
            request['f'] = kwargs['fields']

        postProcess = kwargs.get("search", False)
        if (postProcess):
            request['search'] = postProcess

        if 'output_time_format' in kwargs:
            request['output_time_format'] = kwargs['output_time_format']
        else:
            request['output_time_format'] = i18n.ISO8609_MICROTIME

        # We're not going to read/write further from the user's session at this point
        # and streaming may take a while, so release the session read lock
        cherrypy.session.release_lock()
        # Don't buffer the (potentially sizeable) result in memory
        cherrypy.response.stream = True

        uri = en.buildEndpoint('search/jobs/%s/results/export' % job.sid,
                               namespace=ns,
                               owner=owner)

        stream = splunk.rest.streamingRequest(uri,
                                              getargs=request,
                                              postargs=None)
        return stream.readall()  # returns a generator
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
예제 #5
0
파일: rcUtils.py 프로젝트: DRArpitha/splunk
def quick_and_dirty_call(uri, type, getargs, postargs, namespace, owner, method='GET', sessionKey=''):
   """"""
   qad_uri = buildEndpoint(uri, entityName='', namespace=namespace, owner=owner)

   try:
      serverResponse, serverContent = simpleRequest(qad_uri, sessionKey=sessionKey, getargs=getargs, postargs=postargs, method=method)
   except Exception, e:
      logger.debug('Could not construct quick_and_dirty uri: %s, %s' % (str(qad_uri), str(e)))
      raise CliArgError, 'Could not get app context'
예제 #6
0
파일: search.py 프로젝트: mealy/splunk
    def streamJobExport(self, job, assetType, **kwargs):
        """
        Stream exported job results to the client (does not buffer the whole result in memory)
        """
        ns = job.eaiacl["app"]
        sid = job.sid
        owner = job.eaiacl["owner"]
        uri = en.buildEndpoint("search/jobs/export", namespace=ns, owner=owner)
        request = {}
        request["output_mode"] = kwargs["outputMode"]
        request["f"] = kwargs["field_list"]
        try:
            count = int(kwargs.get("count"))
            if count > 0:
                request["count"] = count
        except ValueError:
            console.warn("Failed to parse count field for export count=%s" % count)
            pass

        # We're not going to read/write further from the user's session at this point
        # and streaming may take a while, so release the session read lock
        cherrypy.session.release_lock()

        # Don't buffer the (potentially sizeable) result in memory
        cherrypy.response.stream = True

        postargs = getargs = None
        if job.reportSearch is None and job.eventIsTruncated and (count == 0 or count > job.eventAvailableCount):
            # re-run the search to get the complete results
            uri = en.buildEndpoint("search/jobs/export", namespace=ns, owner=owner)
            request.update(job.request)
            if count > 0:
                request["search"] += "|head %s" % count
            postargs = request
        elif assetType == "event":
            # non-reporting search
            uri = en.buildEndpoint("search/jobs/%s/events/export" % job.sid, namespace=ns, owner=owner)
            getargs = request
        else:
            uri = en.buildEndpoint("search/jobs/%s/results/export" % job.sid, namespace=ns, owner=owner)
            getargs = request

        stream = rest.streamingRequest(uri, getargs=getargs, postargs=postargs)
        return stream.readall()  # returns a generator
예제 #7
0
    def setPanel(self,
                 namespace,
                 view_id,
                 panel_type,
                 panel_sequence,
                 panel_class=None,
                 action='edit',
                 **panel_definition):
        '''
        Provides management for view panel objects
        
        The HTTP signature for this method expects standard form params to match
        the property names used in the panel objects.  All form params are
        inserted into a dict and passed into the panel object for processing
        
        POST /<namespace>/<view_id>/panel/<panel_sequence>
            &action=edit
            --> updates the existing panel at <panel_sequence>
            &action=delete
            --> deletes the panel at <panel_sequence>
            
            ==> returns JSON response
        '''

        output = jsonresponse.JsonResponse()

        self.collatePanelOptions(panel_definition)

        try:
            username = cherrypy.session['user'].get('name')
            dash_id = en.buildEndpoint(VIEW_ENTITY_CLASS,
                                       view_id,
                                       namespace=namespace,
                                       owner=username)
            dashObject = Dashboard.get(dash_id)

            if action == 'edit':
                dashObject.set_panel(panel_sequence, panel_class,
                                     **panel_definition)

            elif action == 'delete':
                dashObject.delete_panel(panel_sequence)

            else:
                raise ValueError, 'Unknown action requested: %s' % action

            dashObject.save()
            output.addInfo(_('Successfully updated %s' % view_id))

        except Exception, e:
            logger.exception(e)
            output.success = False
            output.addError(
                _('Unable to update panel at sequence %s: %s') %
                (panel_sequence, e))
예제 #8
0
    def listJobs(self,
                 restrictToSession=True,
                 nocache=False,
                 s=None,
                 cachebuster=None,
                 wait=True):
        '''
        Returns a listing of jobs that the client needs to be aware of;
        listing is restricted by user session, and optionally filtered by
        a whitelist provided by the client
        '''

        resp = JsonResponse()

        # dump out if no jobs are specified
        if not s:
            resp.data = []
            return self.render_json(resp)

        if 0:
            uri = en.buildEndpoint('search/jobs', '')
            logger.error("uri: %s" % uri)
            serverResponse, serverContent = rest.simpleRequest(
                uri, getargs={
                    'id': s,
                    'output_mode': 'json'
                })

            return serverContent

        # normalize a single string into a list
        if isinstance(s, basestring): s = [s]

        # bypass the legacy sdk blocking for RUNNING state
        wait = splunk.util.normalizeBoolean(wait)

        # loop over all all requested jobs and ask server for status
        listing = []
        for requestSID in s:
            try:
                job = splunk.search.getJob(requestSID, waitForRunning=wait)
                listing.append(job.toJsonable())

            except splunk.ResourceNotFound:
                listing.append({'sid': requestSID, '__notfound__': True})
                nocache = True  # ensure we always bust the cache otherwise, multiple requests may not find out that the job doesn't exist
                resp.addError(
                    _('Splunk could not find a job with sid=%s.') % requestSID)

            except Exception, e:
                logger.exception(e)
                resp.success = False
                resp.addError(str(e))
                return self.render_json(resp)
예제 #9
0
 def __init__(self):
     self.logger = log()
     self.session = requestsbak.Session()
     self.session.trust_env = False
     self.kvstoreUri = entity.buildEndpoint(
         entityClass=["storage", "collections", "data"],
         entityName="credentials",
         owner="nobody",
         namespace="SplunkAppForWazuh",
         hostPath=rest.makeSplunkdUri().strip("/"))
     self.sessionKey = splunk.getSessionKey()
 def createTestUser(tz, sessionKey):
     uri = entity.buildEndpoint('authentication', 'users')
     userName = str(uuid.uuid1())
     postargs = {
         "name": userName,
         "password": "******",
         "roles": "user",
         "tz": tz
         }
     (response, content) = rest.simpleRequest(uri, postargs=postargs, sessionKey=sessionKey)        
     return userName
 def delegate(self, delegate_endpoint, confInfo, method='POST', customAction='', args={}):
     user = self.context == admin.CONTEXT_APP_AND_USER and self.userName or "nobody"
 
     if self.requestedAction == admin.ACTION_CREATE:
        uri = en.buildEndpoint(delegate_endpoint, namespace=self.appName, owner=user)
        args['name'] = self.callerArgs.id
     else:
        uri = en.buildEndpoint(delegate_endpoint, entityName=self.callerArgs.id, namespace=self.appName, owner=self.userName)
 
     if len(customAction) > 0:
        uri += '/' + customAction
 
     # replace None with empty string to avoid being ignored by python rest api. SPL-57111
     for k,v in self.callerArgs.items():
         if k.startswith('_'):
            continue
         if isinstance(v, list):
            args[k] = v[0] if v[0] != None else ''
         else:
            args[k] = v if v != None else ''
 
     if method == 'GET':
        app  = self.context != admin.CONTEXT_NONE         and self.appName  or "-"
        user = self.context == admin.CONTEXT_APP_AND_USER and self.userName or "-"
        
        thing = self.getEntities(None, None, uri, -1, app, user)
        for name, obj in thing.items():
            ci = confInfo[name]
            for key, val in obj.items():
                if not key.startswith('eai:'):
                   ci[key] = str(val) if val else ''
           
            # fix perms
            if 'perms' in obj['eai:acl'] and not obj['eai:acl']['perms']:
               obj['eai:acl']['perms'] = {}
 
            ci.copyMetadata(obj)
     else:
        serverResponse, serverContent = self.simpleRequest(uri, method, args)
 def createTestUser(tz, sessionKey):
     uri = entity.buildEndpoint('authentication', 'users')
     userName = str(uuid.uuid1())
     postargs = {
         "name": userName,
         "password": "******",
         "roles": "user",
         "tz": tz
     }
     (response, content) = rest.simpleRequest(uri,
                                              postargs=postargs,
                                              sessionKey=sessionKey)
     return userName
예제 #13
0
    def getPreviewEvents(self, eventdata, stanza, attrs):
        filename = None
        try:
            f = tempfile.NamedTemporaryFile(delete=False)
            filename = f.name
            f.write(eventdata)
            f.close()

            # prefix all stanza attributes with 'props.'
            # give default sourcetype that prevents it from learning sourcetypes
            kwargs = {
                'input.path': filename,
                'output_mode': 'json',
                'props.sourcetype': 'default'
            }
            for a, v in attrs.items():
                if a == 'count': continue
                kwargs['props.%s' % a] = v

            uri = entity.buildEndpoint("indexing/preview",
                                       namespace=self._mynamespace,
                                       owner=self._owner)

            print "\tURL: %s ARGS: %s" % (uri, kwargs)
            serverResponse, serverContent = rest.simpleRequest(
                uri,
                method='POST',
                postargs=kwargs,
                sessionKey=self._sessionKey,
                raiseAllErrors=True)
            if serverResponse.status not in [200, 201]:
                raise Exception(serverResponse.status, serverResponse.messages)

            # {"messages":[{"type":"INFO","text":"1367872459.2"}]}
            json_content = json.loads(serverContent)
            jobid = json_content["messages"][0]["text"]

            job = splunk.search.getJob(jobid, sessionKey=self._sessionKey)
            events = job.events

            #print "\tJOB:", job
            #if len(events) == 0:
            #    print "\tNO EVENTS!"
            #else:
            #    print "\tEVENTS:", events[0]
            return events
        finally:
            if filename:
                os.unlink(filename)
예제 #14
0
 def __init__(self):
     """Constructor."""
     try:
         self.logger = log()
         self.session = requestsbak.Session()
         self.session.trust_env = False
         self.kvstoreUri = entity.buildEndpoint(
             entityClass=["storage", "collections", "data"],
             entityName="jobs",
             owner="nobody",
             namespace="SplunkAppForWazuh",
             hostPath=rest.makeSplunkdUri().strip("/")
         )
         self.sessionKey = splunk.getSessionKey()
     except Exception as e:
         self.logger.error("bin.jobs_queu: Error in queue module constructor: %s" % (e))
예제 #15
0
    def move(self, confInfo, **params):
        user, app = self.user_app()
        args = self.getCallerArgs()
        if hasattr(self, "encode"):
            args = self.encode(args)

        postArgs = {"app": args["app"], "user": args["user"]}
        path = entity.buildEndpoint(
            self.endpoint, entityName=self.callerArgs.id, namespace=app, owner=user
        )
        path += "/move"

        response, _ = rest.simpleRequest(
            path, sessionKey=self.getSessionKey(), method="POST", postargs=postArgs
        )
        if response.status != 200:
            exc = RESTException(response.status, response.messages)
            RH_Err.ctl(-1, exc, logLevel=logging.INFO)
예제 #16
0
파일: search.py 프로젝트: mealy/splunk
    def listJobs(self, restrictToSession=True, nocache=False, s=None, cachebuster=None):
        """
        Returns a listing of jobs that the client needs to be aware of;
        listing is restricted by user session, and optionally filtered by
        a whitelist provided by the client
        """

        resp = JsonResponse()

        # dump out if no jobs are specified
        if not s:
            resp.data = []
            return self.render_json(resp)

        if 0:
            uri = en.buildEndpoint("search/jobs", "")
            logger.error("uri: %s" % uri)
            serverResponse, serverContent = rest.simpleRequest(uri, getargs={"id": s, "output_mode": "json"})

            return serverContent

        # normalize a single string into a list
        if isinstance(s, basestring):
            s = [s]

        # loop over all all requested jobs and ask server for status
        listing = []
        for requestSID in s:
            try:
                job = splunk.search.getJob(requestSID)
                listing.append(job.toJsonable())

            except splunk.ResourceNotFound:
                listing.append({"sid": requestSID, "__notfound__": True})
                nocache = (
                    True
                )  # ensure we always bust the cache otherwise, multiple requests may not find out that the job doesn't exist
                resp.addError(_("Splunk could not find a job with sid=%s.") % requestSID)

            except Exception, e:
                logger.exception(e)
                resp.success = False
                resp.addError(str(e))
                return self.render_json(resp)
    def listJobs(self, restrictToSession=True, nocache=False, s=None, cachebuster=None, wait=True):
        '''
        Returns a listing of jobs that the client needs to be aware of;
        listing is restricted by user session, and optionally filtered by
        a whitelist provided by the client
        '''

        resp = JsonResponse()
        
        # dump out if no jobs are specified
        if not s:
            resp.data = []
            return self.render_json(resp)

        if 0:
            uri = en.buildEndpoint('search/jobs', '')
            logger.error("uri: %s" % uri)
            serverResponse, serverContent = rest.simpleRequest(uri, getargs={'id':s, 'output_mode':'json'})
            
            return serverContent
            
        # normalize a single string into a list
        if isinstance(s, basestring): s = [s]
        
        # bypass the legacy sdk blocking for RUNNING state
        wait = splunk.util.normalizeBoolean(wait)
        
        # loop over all all requested jobs and ask server for status
        listing = []
        for requestSID in s:
            try:
                job = splunk.search.getJob(requestSID, waitForRunning=wait)
                listing.append(job.toJsonable())
                
            except splunk.ResourceNotFound:
                listing.append({'sid': requestSID, '__notfound__': True})
                nocache = True # ensure we always bust the cache otherwise, multiple requests may not find out that the job doesn't exist
                resp.addError(_('Splunk could not find a job with sid=%s.') % requestSID)
                
            except Exception, e:
                logger.exception(e)
                resp.success = False
                resp.addError(str(e))
                return self.render_json(resp)
예제 #18
0
    def _apply(self, migration, force=False):
        """
        invokes validate() and teardown() of an available migration plugin instance
        """
        try:
            migration.validate()
            migration.teardown()
        except Exception as e:
            self.rollback()
            raise e
        else:
            # migration.dst is the resulting entity after the migration is applied
            dst_entity = migration.dst

            entity_path = self.migration_conf.dest_conf

            update = False
            uri = en.buildEndpoint(entity_path, entityName=dst_entity.name, namespace=NAMESPACE, owner=OWNER)

            if self._check_resource_exists(uri, sessionKey=self.session_key):
                if force:
                    update = True
                else:
                    raise ResourceExistsException

            if update:
                entity = en.Entity(entity_path, dst_entity.name,
                                   namespace=NAMESPACE,
                                   contents=dst_entity.content,
                                   owner=OWNER)
            else:
                entity = en.Entity(entity_path, '_new',
                                   namespace=NAMESPACE,
                                   contents=dst_entity.content,
                                   owner=OWNER)
                entity['name'] = dst_entity.name

            # to bypass a funny check in splunk.entity.getFullPath()
            entity['eai:acl'] = {}

            en.setEntity(entity, sessionKey=self.session_key)

            self.migration_conf.update_state(self.resource_url, migration.migration_level)
예제 #19
0
    def migrate(self, src_endpoint, migration_ids, filter=None, force=False):
        entities = en.getEntities(src_endpoint,
                                  namespace='dbx',
                                  owner='nobody',
                                  search=filter,
                                  count=0)

        if not entities:
            print "No entity found"
            return

        # iterate source entires
        for key, entity in entities.iteritems():
            for migration_id in migration_ids:

                path = en.buildEndpoint(entity.path,
                                        entityName=entity.name,
                                        namespace='dbx',
                                        owner='nobody')
                controller = MigrationController(migration_id, path,
                                                 self.session_key)

                try:
                    result = controller.migrate(force=force)
                    if result is None:
                        print "{} of {} has been migrated already. Use --force to overwrite.".format(
                            migration_id, path)
                    else:
                        print "{} of {} has been migrated with following attributes:\n".format(
                            migration_id, path)
                        self.pretty_print(result)

                except ResourceExistsException:
                    print "{} already exists in {} for DB Connect 2. Use --force to overwrite.".format(
                        key, migration_id)

                except EntityCanNotBeMigrated:
                    pass

                except Exception as e:
                    print "an exception occurred while migrating {} from {}: {}".format(
                        migration_id, path, e)
예제 #20
0
파일: sendemail.py 프로젝트: torstefan/derp
def realize(valuesForTemplate, ssContent, sessionKey, namespace, owner, argvals):
    stringsForPost = {}
    if ssContent.get('action.email.message'):
        stringsForPost['action.email.message'] = ssContent['action.email.message']

    if ssContent.get('action.email.cc'):
        stringsForPost['action.email.cc'] = ssContent['action.email.cc']

    if ssContent.get('action.email.bcc'):
        stringsForPost['action.email.bcc'] = ssContent['action.email.bcc']

    if ssContent.get('action.email.to'):
        stringsForPost['action.email.to'] = ssContent['action.email.to']

    if ssContent.get('action.email.subject'):
        stringsForPost['action.email.subject'] = ssContent['action.email.subject']

    if ssContent.get('action.email.footer.text'):
        stringsForPost['action.email.footer.text'] = ssContent['action.email.footer.text']
    
    realizeURI = entity.buildEndpoint([ 'template', 'realize' ])

    postargs = valuesForTemplate
    postargs['output_mode'] = 'json'
    postargs['conf.recurse'] = 0
    try:
        for key, value in stringsForPost.iteritems():
            postargs['name'] = value
            headers, body = simpleRequest(
                realizeURI, 
                method='POST', 
                postargs=postargs, 
                sessionKey=sessionKey
            )
            body = json.loads(body)
            ssContent[key] = body['entry'][0]['content']['eai:data']
    except Exception, e:
        logger.error(e)
        # SPL-96721: email subject didn't get replaced, reset it to ssname
        if ssContent.get('action.email.subject') == stringsForPost.get('action.email.subject'):
            ssContent['action.email.subject'] = "Splunk Alert:"+argvals['ssname']
            ssContent['action.email.message'] = ssContent['action.email.message'] + "\n\nNOTE: The dynamic substitution of the email subject failed because of failed token substitution. A generic subject has been used instead. Please check splunkd.log for additional details."
    def setPanel(self, namespace, view_id, panel_type, panel_sequence, panel_class=None, action='edit', **panel_definition):
        '''
        Provides management for view panel objects
        
        The HTTP signature for this method expects standard form params to match
        the property names used in the panel objects.  All form params are
        inserted into a dict and passed into the panel object for processing
        
        POST /<namespace>/<view_id>/panel/<panel_sequence>
            &action=edit
            --> updates the existing panel at <panel_sequence>
            &action=delete
            --> deletes the panel at <panel_sequence>
            
            ==> returns JSON response
        '''

        output = jsonresponse.JsonResponse()

        self.collatePanelOptions(panel_definition)

        try:
            username = cherrypy.session['user'].get('name')
            dash_id = en.buildEndpoint(VIEW_ENTITY_CLASS, view_id, namespace=namespace, owner=username)
            dashObject = Dashboard.get(dash_id)
        
            if action == 'edit':
                dashObject.set_panel(panel_sequence, panel_class, **panel_definition)
        
            elif action == 'delete':
                dashObject.delete_panel(panel_sequence)

            else:
                raise ValueError, 'Unknown action requested: %s' % action

            dashObject.save()
            output.addInfo(_('Successfully updated %s' % view_id))

        except Exception, e:
            logger.exception(e)
            output.success = False
            output.addError(_('Unable to update panel at sequence %s: %s') % (panel_sequence, e))
예제 #22
0
    def createPanel(self, namespace, view_id, panel_type, panel_class,
                    **panel_definition):
        '''
        Create a new panel to add to an existing dashboard
        
        POST /<namespace>/<view_id>/<panel_type=panel>
            &panel_class={table | chart | html | event | list}
            &<panel_property>=<property_value>
                --> creates a new panel
                
            the <panel_property> is a direct map to the panel XML data
            
            ==> returns a JSON response
        '''

        output = jsonresponse.JsonResponse()

        try:

            if panel_type != 'panel':
                raise ValueError, 'Only panel type "panel" is currently supported'

            # support all options
            self.collatePanelOptions(panel_definition)

            # get dashboard and create panel
            username = cherrypy.session['user'].get('name')
            dash_id = en.buildEndpoint(VIEW_ENTITY_CLASS,
                                       view_id,
                                       namespace=namespace,
                                       owner=username)
            dashObject = Dashboard.get(dash_id)

            dashObject.create_panel(type=panel_class, **panel_definition)

            dashObject.save()

        except Exception, e:
            logger.exception(e)
            output.success = False
            output.addError(_('Unable to add panel: %s') % e)
예제 #23
0
def parseSearchToXML(search,
                     hostPath=None,
                     sessionKey=None,
                     parseOnly='t',
                     timeline=None,
                     namespace=None,
                     owner=None):
    """
        Given a valid search string, return the XML from the splunk parsing endpoint that
        represents the search.
    """

    if search == None or len(search) == 0:
        return None

    if not owner: owner = auth.getCurrentUser()['name']

    uri = entity.buildEndpoint('/search/parser',
                               namespace=namespace,
                               owner=owner)
    if hostPath:
        uri = splunk.mergeHostPath(hostPath) + uri

    args = {'q': search, 'parse_only': parseOnly}

    if timeline is not None:
        args['timeline'] = timeline

    serverResponse, serverContent = rest.simpleRequest(uri,
                                                       getargs=args,
                                                       sessionKey=sessionKey)
    #print "SERVERCONTENT:", serverContent
    # normal messages from splunkd are propogated via SplunkdException;
    if 400 <= serverResponse.status < 500:
        root = et.fromstring(serverContent)
        extractedMessages = rest.extractMessages(root)
        for msg in extractedMessages:
            raise splunk.SearchException, msg['text']

    return serverContent
    def getPanel(self, namespace, view_id, panel_type, panel_sequence, **unused):
        '''
        Returns a dashboard panel config
        
        GET /<namespace>/<view_id>/panel/<panel_sequence>
            --> panel config for panel at <panel_sequence>
            
            ==> returns a JSON response
        '''
        
        output = jsonresponse.JsonResponse()

        try:
            username = cherrypy.session['user'].get('name')
            dash_id = en.buildEndpoint(VIEW_ENTITY_CLASS, view_id, namespace=namespace, owner=username)
            dashObject = Dashboard.get(dash_id)
            output.data = dashObject.get_panel(panel_sequence)

        except IndexError, e:
            cherrypy.response.status = 404
            output.success = False
            output.addError(_('Requested panel %s does not exist') % panel_sequence)
    def createPanel(self, namespace, view_id, panel_type, panel_class, **panel_definition):
        '''
        Create a new panel to add to an existing dashboard
        
        POST /<namespace>/<view_id>/<panel_type=panel>
            &panel_class={table | chart | html | event | list}
            &<panel_property>=<property_value>
                --> creates a new panel
                
            the <panel_property> is a direct map to the panel XML data
            
            ==> returns a JSON response
        '''
        
        output = jsonresponse.JsonResponse()

        try:
            
            if panel_type != 'panel':
                raise ValueError, 'Only panel type "panel" is currently supported'
                
            # support all options
            self.collatePanelOptions(panel_definition)

            # get dashboard and create panel
            username = cherrypy.session['user'].get('name')
            dash_id = en.buildEndpoint(VIEW_ENTITY_CLASS, view_id, namespace=namespace, owner=username)
            dashObject = Dashboard.get(dash_id)

            dashObject.create_panel(
                type=panel_class,
                **panel_definition)

            dashObject.save()

        except Exception, e:
            logger.exception(e)
            output.success = False
            output.addError(_('Unable to add panel: %s') % e)
예제 #26
0
def realize(valuesForTemplate, ssContent, sessionKey, namespace, owner):
    stringsForPost = {}
    if ssContent.get('action.email.message'):
        stringsForPost['action.email.message'] = ssContent[
            'action.email.message']

    if ssContent.get('action.email.cc'):
        stringsForPost['action.email.cc'] = ssContent['action.email.cc']

    if ssContent.get('action.email.bcc'):
        stringsForPost['action.email.bcc'] = ssContent['action.email.bcc']

    if ssContent.get('action.email.to'):
        stringsForPost['action.email.to'] = ssContent['action.email.to']

    if ssContent.get('action.email.subject'):
        stringsForPost['action.email.subject'] = ssContent[
            'action.email.subject']

    if ssContent.get('action.email.footer.text'):
        stringsForPost['action.email.footer.text'] = ssContent[
            'action.email.footer.text']

    realizeURI = entity.buildEndpoint(['template', 'realize'])

    postargs = valuesForTemplate
    postargs['output_mode'] = 'json'
    postargs['conf.recurse'] = 0
    try:
        for key, value in stringsForPost.iteritems():
            postargs['name'] = value
            headers, body = simpleRequest(realizeURI,
                                          method='POST',
                                          postargs=postargs,
                                          sessionKey=sessionKey)
            body = json.loads(body)
            ssContent[key] = body['entry'][0]['content']['eai:data']
    except Exception, e:
        logger.info(e)
예제 #27
0
def realize(valuesForTemplate, ssContent, sessionKey, namespace, owner):
    stringsForPost = {}
    if ssContent.get('action.email.message'):
        stringsForPost['action.email.message'] = ssContent['action.email.message']

    if ssContent.get('action.email.cc'):
        stringsForPost['action.email.cc'] = ssContent['action.email.cc']

    if ssContent.get('action.email.bcc'):
        stringsForPost['action.email.bcc'] = ssContent['action.email.bcc']

    if ssContent.get('action.email.to'):
        stringsForPost['action.email.to'] = ssContent['action.email.to']

    if ssContent.get('action.email.subject'):
        stringsForPost['action.email.subject'] = ssContent['action.email.subject']

    if ssContent.get('action.email.footer.text'):
        stringsForPost['action.email.footer.text'] = ssContent['action.email.footer.text']
    
    realizeURI = entity.buildEndpoint([ 'template', 'realize' ])

    postargs = valuesForTemplate
    postargs['output_mode'] = 'json'
    postargs['conf.recurse'] = 0
    try:
        for key, value in stringsForPost.iteritems():
            postargs['name'] = value
            headers, body = simpleRequest(
                realizeURI, 
                method='POST', 
                postargs=postargs, 
                sessionKey=sessionKey
            )
            body = json.loads(body)
            ssContent[key] = body['entry'][0]['content']['eai:data']
    except Exception, e:
        logger.info(e)
예제 #28
0
def quick_and_dirty_call(uri,
                         type,
                         getargs,
                         postargs,
                         namespace,
                         owner,
                         method='GET',
                         sessionKey=''):
    """"""
    qad_uri = buildEndpoint(uri,
                            entityName='',
                            namespace=namespace,
                            owner=owner)

    try:
        serverResponse, serverContent = simpleRequest(qad_uri,
                                                      sessionKey=sessionKey,
                                                      getargs=getargs,
                                                      postargs=postargs,
                                                      method=method)
    except Exception, e:
        logger.debug('Could not construct quick_and_dirty uri: %s, %s' %
                     (str(qad_uri), str(e)))
        raise CliArgError, 'Could not get app context'
예제 #29
0
    def getContainer(self, namespace, view_id, mode='', **unused):
        '''
        Renders the dashboard edit page
        
        GET /<namespace>/<view_id>
            ==> HTML form page with dashboard edit form (labels, panels) and
                master panel edit form (hidden)
            
        GET /api/<namespace>/<view_id>
            ==> JSON structure of dashboard config (unused?)
        '''

        # serve data feed
        output = jsonresponse.JsonResponse()

        try:
            username = cherrypy.session['user'].get('name')
            dash_id = en.buildEndpoint(VIEW_ENTITY_CLASS,
                                       view_id,
                                       namespace=namespace,
                                       owner=username)
            dashObject = Dashboard.get(dash_id)
            output.data = dashObject._obj.toJsonable()

        except splunk.ResourceNotFound:
            cherrypy.response.status = 404
            output.success = False
            output.addError(_('View %s was not found') % view_id)
            return self.render_json(output)

        # serve template page
        if cherrypy.request.is_api:
            return self.render_json(output)
        else:
            cherrypy.response.headers['content-type'] = MIME_HTML

            # get supporting assets

            savedSearches = en.getEntities('saved/searches',
                                           namespace=namespace,
                                           count=-1,
                                           search="is_visible=1")

            for savedSearch in savedSearches:
                acl = savedSearches[savedSearch]['eai:acl']
                if dashObject.metadata.sharing == 'user':
                    continue
                if dashObject.metadata.sharing == 'app' and acl[
                        'sharing'] == 'user':
                    savedSearches[savedSearch]['dq'] = True
                    continue
                if dashObject.metadata.sharing == 'global' and acl[
                        'sharing'] != 'global':
                    savedSearches[savedSearch]['dq'] = True
                    continue
                if dashObject.metadata.perms['read'].count(
                        '*') > 0 and acl['perms']['read'].count('*') == 0:
                    savedSearches[savedSearch]['dq'] = True
                    continue

            #dashboardObject = splunk.entity.getEntity('data/ui/views', view_id, namespace=APP['id'], owner=cherrypy.session['user'].get('name'))
            #dashOwner = dashboardObject['eai:acl'].get('owner', 'nobody')

            editLink = self.make_url(
                ['manager', namespace, 'data/ui/views', view_id],
                _qs=dict(action='edit',
                         url=self.make_url(['app', namespace, view_id]),
                         redirect_override="/app/%s/%s" %
                         (namespace, view_id)))

            permissionsLink = self.make_url(
                [
                    'manager', 'permissions', namespace, 'data/ui/views',
                    view_id
                ],
                _qs=dict(
                    uri=en.buildEndpoint('data/ui/views',
                                         view_id,
                                         namespace=namespace,
                                         owner=dashObject.metadata.owner)))

            return self.render_template(
                'viewmaster/edit_dashboard.html', {
                    'namespace': namespace,
                    'view_id': view_id,
                    'view_object': dashObject._obj,
                    'APP': {
                        'id': namespace
                    },
                    'savedSearches': savedSearches,
                    'editLink': editLink,
                    'permissionsLink': permissionsLink,
                    'mode': mode,
                })
예제 #30
0
    def createContainer(self,
                        namespace,
                        view_id='',
                        view_label='',
                        container_type='dashboard'):
        '''
        Handles dashboard creation
        
        GET /<namespace>
            ==> HTML template form to input create data
            
        POST /<namespace>
            ==> Saves the HTML input values from GET
            
            == returns JSON response
        '''

        #
        # serve template
        #

        if cherrypy.request.method == 'GET':
            return self.render_template('viewmaster/create_dashboard.html',
                                        {'namespace': namespace})

        #
        # handle create view
        #

        output = jsonresponse.JsonResponse()

        # clean inputs
        view_id = re.sub(r'[^\w]', '', view_id)
        view_label = view_label.strip() or view_id

        if view_id == '':
            output.success = False
            output.addError(_('Dashboard ID cannot be empty'))
            return self.render_json(output)

        # check that view doesn't already exist
        try:
            username = cherrypy.session['user'].get('name')
            dash_id = en.buildEndpoint(VIEW_ENTITY_CLASS,
                                       view_id,
                                       namespace=namespace,
                                       owner=username)
            Dashboard.get(dash_id)
            output.success = False
            output.addError(
                _('Cannot create new %(container_type)s: %(view_id)s already exists') \
                % {'container_type': container_type, 'view_id': view_id})
            return self.render_json(output)

        except splunk.ResourceNotFound:
            pass

        # generate new
        try:
            view = Dashboard(namespace, username, view_id)
            view.label = view_label
            view.save()

            output.data = {'view_id': view_id, 'view_label': view_label}
            output.addInfo(_('Successfully created new %(container_type)s: %(view_id)s') \
                % {'container_type': container_type, 'view_id': view_id})
            logger.info('Created new %s: namespace=%s id=%s label=%s' %
                        (container_type, namespace, view_id, view_label))

        except Exception, e:
            logger.exception(e)
            output.success = False
            output.addError(_('Unable to create dashboard: %s') % e)
    def streamJobExport(self, job, assetType, **kwargs):
        """
        Stream exported job results to the client (does not buffer the whole result in memory)
        """
        ns = job.eaiacl['app']
        sid = job.sid
        owner = job.eaiacl['owner']
        request = {}
        request['output_mode'] = kwargs['outputMode']
        # SPL-79832 when exporting xml splunkd requires additional request argument
        # to generate valid xml
        if request['output_mode'] == "xml":
            request['export_xml_with_wrapper'] = 1


        request['f'] = kwargs['field_list']
        if 'output_time_format' in kwargs:
            request['output_time_format'] = kwargs['output_time_format']
        else:
            request['output_time_format'] = i18n.ISO8609_MICROTIME

        try:
            count = int(kwargs.get('count'))
            if count>0:
                request['count'] = count
        except ValueError:
            logger.warn("Failed to parse count field for export count=%s" % count)
            pass

        # We're not going to read/write further from the user's session at this point
        # and streaming may take a while, so release the session read lock
        cherrypy.session.release_lock()

        # Don't buffer the (potentially sizeable) result in memory
        cherrypy.response.stream = True

        postargs = getargs = None
        if job.reportSearch is None and ((job.eventIsTruncated and (count == 0 or count > job.eventAvailableCount)) or job.isRemoteTimeline or not job.isDone):
            # re-run the search to get the complete results
            uri = en.buildEndpoint('search/jobs/export', namespace=ns, owner=owner)
            request.update(job.request)
            if count > 0:
                request['search'] += '|head %s' % count
            postargs = request

            # if re-running the search for exporting events, 
            # ensure we do not run the search with following arguments
            ignoreArgs = ['auto_cancel', 'max_count']
            for iarg in ignoreArgs:
                if iarg in postargs:
                    logger.debug("Dropping argument %s from postargs" % iarg)
                    del postargs[iarg]

        elif assetType == 'event': 
            # non-reporting search
            uri = en.buildEndpoint('search/jobs/%s/events/export' % job.sid, namespace=ns, owner=owner)
            getargs = request
        else:
            uri = en.buildEndpoint('search/jobs/%s/results/export' % job.sid, namespace=ns, owner=owner)
            getargs = request
        
        export_timeout =  cherrypy.config.get('export_timeout')
        
        logger.debug('Export timeout =%s' % export_timeout)

        if (export_timeout != None) :
            export_timeout = int(export_timeout)

        stream = rest.streamingRequest(uri, getargs=getargs, postargs=postargs, timeout=export_timeout)
        return stream.readall() # returns a generator
예제 #32
0
        for ph in prehooks:
            rcHooks.__dict__[ph](cmd, obj, argList)

        eaiArgsList = rcHooks.map_args_cli_2_eai(args, {}, argList)

        logger.debug('after prehooks, eaiArgsList: %s' % str(eaiArgsList))

        #first check if the eai_id needs to be obtained by another request!!!
        if type(lf_eai_id) == types.DictType:
            #oh crappp...
            eai_id_uri = buildEndpoint(lf_eai_id['uri'],
                                       entityName='',
                                       namespace=namespace,
                                       owner=owner,
                                       search=search,
                                       count=count,
                                       offset=offset,
                                       sort_key=sort_key,
                                       sort_dir=sort_dir)
            eai_id_method = GLOBAL_ACTIONS['%s' % lf_eai_id['type']]

            try:
                eai_id_serverResponse, eai_id_serverContent = simpleRequest(
                    eai_id_uri,
                    sessionKey=sessionKey,
                    getargs='',
                    postargs='',
                    method=eai_id_method)
            except Exception, e:
                logger.debug(
예제 #33
0
def sendEmail(results, settings):
    keywords, argvals = splunk.Intersplunk.getKeywordsAndOptions()

    for key in argvals:
        argvals[key] =  unquote(argvals[key])

    namespace       = settings['namespace']
    owner           = settings['owner']
    sessionKey      = settings['sessionKey']
    sid             = settings['sid']
    ssname          = argvals.get('ssname')
    isScheduledView = False

    if ssname: 
        # populate content with savedsearch
        if '_ScheduledView__' in ssname or argvals.get('pdfview'):
            if '_ScheduledView__' in ssname:
                ssname = ssname.replace('_ScheduledView__', '')
            else:
                ssname = argvals.get('pdfview')

            uri = entity.buildEndpoint(
                [ 'scheduled', 'views', ssname], 
                namespace=namespace, 
                owner=owner
            )
            isScheduledView = True

        else: 
            uri = entity.buildEndpoint(
                [
                    'saved', 
                    'searches', 
                    ssname
                ], 
                namespace=namespace, 
                owner=owner
            )

        responseHeaders, responseBody = simpleRequest(uri, method='GET', getargs={'output_mode':'json'}, sessionKey=sessionKey)

        savedSearch = json.loads(responseBody)
        ssContent = savedSearch['entry'][0]['content']

        # set type of saved search
        if isScheduledView: 
            ssContent['type']  = 'view'
        elif savedSearchJSONIsAlert(savedSearch):
            ssContent['type']  = 'alert'
        else:
            ssContent['type']  = 'report'

        # remap needed attributes that are not already on the content
        ssContent['name']                 = ssname
        ssContent['app']                  = savedSearch['entry'][0]['acl'].get('app')
        ssContent['owner']                = savedSearch['entry'][0]['acl'].get('owner')

        # The footer.text key will always exist for type alert and report. 
        # It may not exist for scheduled views created before 6.1 therefore the schedule view default footer.text 
        # should be set if the key does not exist.
        # This can be removed once migration has happened to ensure scheduled views always have the footer.text attribute
        ssContent['action.email.footer.text'] = ssContent.get('action.email.footer.text', "If you believe you've received this email in error, please see your Splunk administrator.\r\n\r\nsplunk > the engine for machine data")

        # The message key will always exist for type alert and report. 
        # It may not exist for scheduled views created before 6.1 therefore the schedule view default message 
        # should be set if the key does not exist.
        # This can be removed once migration has happened to ensure scheduled views always have the message.view attribute
        ssContent['action.email.message'] = ssContent.get('action.email.message.' + ssContent.get('type'), 'A PDF was generated for $name$')
        if normalizeBoolean(ssContent.get('action.email.useNSSubject', False)):
            ssContent['action.email.subject'] = ssContent['action.email.subject.' + ssContent.get('type')]

        # prior to 6.1 the results link was sent as the argval sslink, must check both results_link
        # and sslink for backwards compatibility
        ssContent['results_link'] = argvals.get('results_link', argvals.get('sslink', ''))
        if normalizeBoolean(ssContent['results_link']) and normalizeBoolean(ssContent['type']):
            split_results_path = urllib.splitquery(ssContent.get('results_link'))[0].split('/')
            view_path = '/'.join(split_results_path[:-1]) + '/'
            ssType = ssContent.get('type')
            if ssType == 'alert':
                ssContent['view_link'] = view_path + 'alert?' + urllib.urlencode({'s': savedSearch['entry'][0]['links'].get('alternate')})
            elif ssType == 'report':
                ssContent['view_link'] = view_path + 'report?' + urllib.urlencode({'s': savedSearch['entry'][0]['links'].get('alternate'), 'sid': sid})
            elif ssType == 'view':
                ssContent['view_link'] = view_path + ssContent['name']
            else:
                ssContent['view_link'] = view_path + 'search'
    else:
        #assumes that if no ssname then called from searchbar
        ssContent = {
            'type': 'searchCommand',
            'view_link': '',
            'action.email.sendresults': False,
            'action.email.sendpdf': False,
            'action.email.sendcsv': False,
            'action.email.inline': True,
            'action.email.format': 'table',
            'action.email.subject': 'Splunk Results',
            'action.email.footer.text': "If you believe you've received this email in error, please see your Splunk administrator.\r\n\r\nsplunk > the engine for machine data"
        }

    ssContent['trigger_date'] = None
    ssContent['trigger_timeHMS'] = None
    ssContent['trigger_time'] = argvals.get('trigger_time')
    ssContent
    if normalizeBoolean(ssContent['trigger_time']):
        try:
            triggerSeconds = time.localtime(float(ssContent['trigger_time']))
            ssContent['trigger_date'] = time.strftime("%B %d, %Y", triggerSeconds)
            ssContent['trigger_timeHMS'] = time.strftime("%I:%M:%S", triggerSeconds)
        except Exception, e:
            logger.info(e)
 def deleteTestUser(userName, sessionKey):
     uri = entity.buildEndpoint(['authentication', 'users'], userName)
     (response, content) = rest.simpleRequest(uri,
                                              sessionKey=sessionKey,
                                              method="DELETE")
def streamJobExport(job, kwargs):
    """
    Stream exported job results to the client (does not buffer the whole result in memory)
    """
    ns = job.eaiacl['app']
    owner = job.eaiacl['owner']
    uri = en.buildEndpoint('search/jobs/export', namespace=ns, owner=owner)
    request = {}
    request['output_mode'] = kwargs['output_mode']

    try:
        count = int(kwargs.get('count'))
        if count > 0:
            request['count'] = count
    except ValueError:
        logger.warn("Failed to parse count field for export, count=%s" %
                    str(kwargs.get('count')))
        pass

    try:
        if 'offset' in kwargs:
            offset = int(kwargs.get('offset'))
            request['offset'] = offset
    except ValueError:
        logger.warn("Failed to parse offset field for export, offset=%s" %
                    str(kwargs.get('offset')))
        pass

    try:
        if 'field_list' in kwargs:
            request['f'] = kwargs.get('field_list')
    except:
        logger.warn(
            "Failed to parse field_list field for export, field_list=%s" %
            str(kwargs.get('field_list')))

    postargs = getargs = None
    #SPL-51662
    if job.reportSearch is None and (
        (job.eventIsTruncated and
         (count == 0 or count > job.eventAvailableCount))
            or splunk.util.normalizeBoolean(job.isRemoteTimeline)):
        # re-run the search to get the complete results
        uri = en.buildEndpoint('search/jobs/export', namespace=ns, owner=owner)
        request.update(job.request)
        if count > 0:
            request['search'] += '|head %s' % count
        postargs = request
    elif job.reportSearch:
        uri = en.buildEndpoint('search/jobs/%s/results/export' % job.sid,
                               namespace=ns,
                               owner=owner)
        getargs = request
    else:
        uri = en.buildEndpoint('search/jobs/%s/events/export' % job.sid,
                               namespace=ns,
                               owner=owner)
        getargs = request

    stream = rest.streamingRequest(uri, getargs=getargs, postargs=postargs)
    return stream.readall()  # returns a generator
    def createContainer(self, namespace, view_id='', view_label='', container_type='dashboard'):
        '''
        Handles dashboard creation
        
        GET /<namespace>
            ==> HTML template form to input create data
            
        POST /<namespace>
            ==> Saves the HTML input values from GET
            
            == returns JSON response
        '''

        #
        # serve template
        #
        
        if cherrypy.request.method == 'GET':
            return self.render_template('viewmaster/create_dashboard.html', {'namespace': namespace})
        
            
        #
        # handle create view
        #
        
        output = jsonresponse.JsonResponse()

        # clean inputs
        view_id = re.sub(r'[^\w]', '', view_id)
        view_label = view_label.strip() or view_id
        
        if view_id == '':
            output.success = False
            output.addError(_('Dashboard ID cannot be empty'))
            return self.render_json(output)
            
        # check that view doesn't already exist
        try:
            username = cherrypy.session['user'].get('name')
            dash_id = en.buildEndpoint(VIEW_ENTITY_CLASS, view_id, namespace=namespace, owner=username)
            Dashboard.get(dash_id)
            output.success = False
            output.addError(
                _('Cannot create new %(container_type)s: %(view_id)s already exists') \
                % {'container_type': container_type, 'view_id': view_id})
            return self.render_json(output)

        except splunk.ResourceNotFound:
            pass

        # generate new
        try:
            view = Dashboard(namespace, username, view_id)
            view.label = view_label
            view.save()

            output.data = {'view_id': view_id, 'view_label': view_label}
            output.addInfo(_('Successfully created new %(container_type)s: %(view_id)s') \
                % {'container_type': container_type, 'view_id': view_id})
            logger.info('Created new %s: namespace=%s id=%s label=%s' % (container_type, namespace, view_id, view_label))

        except Exception, e:
            logger.exception(e)
            output.success = False
            output.addError(_('Unable to create dashboard: %s') % e)
예제 #37
0
import argparse
import getpass
import xml.etree.ElementTree as ET

import splunk.entity as entity
import splunk.rest as rest

parser = argparse.ArgumentParser(description='GT LDAP')
parser.add_argument(
    '--update',
    action='store_true',
)
args = parser.parse_args()
u = raw_input("Splunk User:"******"username": u,
                              "password": p
                          })
root = ET.fromstring(c)
sessionkey = root[0].text
uri = entity.buildEndpoint(['storage', 'passwords'])
user = raw_input("REST User:"******"REST Host:")
password = getpass.getpass(prompt="REST Password:"******"name": user, "realm": host, "password": password}
if args.update:
    uri = entity.buildEndpoint(
        ['storage', 'passwords',
         "%s:%s:" % (host, user)])
예제 #38
0
def sendEmail(results, settings):
    keywords, argvals = splunk.Intersplunk.getKeywordsAndOptions()

    for key in argvals:
        argvals[key] = unquote(argvals[key])

    namespace = settings['namespace']
    owner = settings['owner']
    sessionKey = settings['sessionKey']
    sid = settings['sid']
    ssname = argvals.get('ssname')
    isScheduledView = False

    if ssname:
        # populate content with savedsearch
        if '_ScheduledView__' in ssname or argvals.get('pdfview'):
            if '_ScheduledView__' in ssname:
                ssname = ssname.replace('_ScheduledView__', '')
            else:
                ssname = argvals.get('pdfview')

            uri = entity.buildEndpoint(['scheduled', 'views', ssname],
                                       namespace=namespace,
                                       owner=owner)
            isScheduledView = True

        else:
            uri = entity.buildEndpoint(['saved', 'searches', ssname],
                                       namespace=namespace,
                                       owner=owner)

        responseHeaders, responseBody = simpleRequest(
            uri,
            method='GET',
            getargs={'output_mode': 'json'},
            sessionKey=sessionKey)

        savedSearch = json.loads(responseBody)
        ssContent = savedSearch['entry'][0]['content']

        # set type of saved search
        if isScheduledView:
            ssContent['type'] = 'view'
        elif savedSearchJSONIsAlert(savedSearch):
            ssContent['type'] = 'alert'
        else:
            ssContent['type'] = 'report'

        # remap needed attributes that are not already on the content
        ssContent['name'] = ssname
        ssContent['app'] = savedSearch['entry'][0]['acl'].get('app')
        ssContent['owner'] = savedSearch['entry'][0]['acl'].get('owner')

        # The footer.text key will always exist for type alert and report.
        # It may not exist for scheduled views created before 6.1 therefore the schedule view default footer.text
        # should be set if the key does not exist.
        # This can be removed once migration has happened to ensure scheduled views always have the footer.text attribute
        ssContent['action.email.footer.text'] = ssContent.get(
            'action.email.footer.text',
            "If you believe you've received this email in error, please see your Splunk administrator.\r\n\r\nsplunk > the engine for machine data"
        )

        # The message key will always exist for type alert and report.
        # It may not exist for scheduled views created before 6.1 therefore the schedule view default message
        # should be set if the key does not exist.
        # This can be removed once migration has happened to ensure scheduled views always have the message.view attribute
        ssContent['action.email.message'] = ssContent.get(
            'action.email.message.' + ssContent.get('type'),
            'A PDF was generated for $name$')
        if normalizeBoolean(ssContent.get('action.email.useNSSubject', False)):
            ssContent['action.email.subject'] = ssContent[
                'action.email.subject.' + ssContent.get('type')]

        # prior to 6.1 the results link was sent as the argval sslink, must check both results_link
        # and sslink for backwards compatibility
        ssContent['results_link'] = argvals.get('results_link',
                                                argvals.get('sslink', ''))
        if normalizeBoolean(ssContent['results_link']) and normalizeBoolean(
                ssContent['type']):
            split_results_path = urllib.splitquery(
                ssContent.get('results_link'))[0].split('/')
            view_path = '/'.join(split_results_path[:-1]) + '/'
            ssType = ssContent.get('type')
            if ssType == 'alert':
                ssContent[
                    'view_link'] = view_path + 'alert?' + urllib.urlencode({
                        's':
                        savedSearch['entry'][0]['links'].get('alternate')
                    })
            elif ssType == 'report':
                ssContent[
                    'view_link'] = view_path + 'report?' + urllib.urlencode({
                        's':
                        savedSearch['entry'][0]['links'].get('alternate'),
                        'sid':
                        sid
                    })
            elif ssType == 'view':
                ssContent['view_link'] = view_path + ssContent['name']
            else:
                ssContent['view_link'] = view_path + 'search'
    else:
        #assumes that if no ssname then called from searchbar
        ssContent = {
            'type':
            'searchCommand',
            'view_link':
            '',
            'action.email.sendresults':
            False,
            'action.email.sendpdf':
            False,
            'action.email.sendcsv':
            False,
            'action.email.inline':
            True,
            'action.email.format':
            'table',
            'action.email.subject':
            'Splunk Results',
            'action.email.footer.text':
            "If you believe you've received this email in error, please see your Splunk administrator.\r\n\r\nsplunk > the engine for machine data"
        }

    ssContent['trigger_date'] = None
    ssContent['trigger_timeHMS'] = None
    ssContent['trigger_time'] = argvals.get('trigger_time')
    ssContent
    if normalizeBoolean(ssContent['trigger_time']):
        try:
            triggerSeconds = time.localtime(float(ssContent['trigger_time']))
            ssContent['trigger_date'] = time.strftime("%B %d, %Y",
                                                      triggerSeconds)
            ssContent['trigger_timeHMS'] = time.strftime(
                "%I:%M:%S", triggerSeconds)
        except Exception, e:
            logger.info(e)
예제 #39
0
        ssContent['action.email.use_tls'] = normalizeBoolean(
            argvals.get('use_tls'))

    ssContent['graceful'] = normalizeBoolean(argvals.get('graceful', 0))

    #if there is no results_link then do not incude it
    if not normalizeBoolean(ssContent.get('results_link')):
        ssContent['action.email.include.results_link'] = False

    #need for backwards compatibility
    format = ssContent.get('action.email.format')
    if format == 'html' or format == 'plain' or format == 'text':
        ssContent['action.email.format'] = 'table'

    #fetch server info
    uriToServerInfo = entity.buildEndpoint(['server', 'info'])
    serverInfoHeaders, serverInfoBody = simpleRequest(
        uriToServerInfo,
        method='GET',
        getargs={'output_mode': 'json'},
        sessionKey=sessionKey)

    serverInfo = json.loads(serverInfoBody)
    serverInfoContent = serverInfo['entry'][0]['content']

    #fetch job info
    jobResponseHeaders = {}
    jobResponseBody = {'entry': [{'content': {}}]}
    if sid:
        uriToJob = entity.buildEndpoint(['search', 'jobs', sid],
                                        namespace=namespace,
예제 #40
0
def dispatchSavedSearch(searchName,
                        namespace=None,
                        owner=None,
                        hostPath=None,
                        sessionKey=None,
                        forceHistoricSearch=False,
                        overrideNowTime=None):
    """ start a saved search
        returns a tuple (sid, dispatchedJob)
        dispatchedJob is true unless the saved search job id returned is the historical artifact of a scheduled search """

    savedSearchModel = getSavedSearch(searchName,
                                      namespace=namespace,
                                      owner=owner,
                                      sessionKey=sessionKey)

    # check for scheduled saved search
    if savedSearchModel.schedule and savedSearchModel.schedule.is_scheduled:
        historicJob = saved.getJobForSavedSearch(searchName,
                                                 namespace=namespace,
                                                 owner=owner,
                                                 hostPath=hostPath,
                                                 sessionKey=sessionKey,
                                                 useHistory=True)

        if historicJob != None:
            return (historicJob, False)

    args = {}
    if forceHistoricSearch:
        # don't dispatch a RT search. override dispatch arguments with non-RT timerange
        logger.debug("dispatchSavedSearch namespace=%s owner=%s" %
                     (namespace, owner))
        if savedSearchModel.dispatch and savedSearchModel.dispatch.earliest_time:
            args[
                'dispatch.earliest_time'] = savedSearchModel.dispatch.earliest_time.replace(
                    u'rt', '')
        if savedSearchModel.dispatch and savedSearchModel.dispatch.latest_time:
            args[
                'dispatch.latest_time'] = savedSearchModel.dispatch.latest_time.replace(
                    u'rt', '')
        logger.debug("dispatchSavedSearch args=%s" % str(args))

    if overrideNowTime != None:
        args['dispatch.now'] = int(overrideNowTime)

    # assemble params
    uri = entity.buildEndpoint(SAVED_SEARCH_ENTITY_CLASS, searchName,
                               namespace, owner)
    uri = uri + "/dispatch"
    logger.debug("dispatchSavedSearch> uri: " + uri)

    serverResponse, serverContent = rest.simpleRequest(uri,
                                                       method="POST",
                                                       sessionKey=sessionKey,
                                                       rawResult=True,
                                                       postargs=args)

    logger.debug("dispatchSavedSearch> serverResponse: " + str(serverResponse))
    logger.debug("dispatchSavedSearch> serverContent: " + str(serverContent))

    root = et.fromstring(serverContent)

    # catch quota overage; TODO: do something nicer
    if serverResponse.status == 503:
        extractedMessages = rest.extractMessages(root)
        for msg in extractedMessages:
            raise splunk.QuotaExceededException, msg['text']

    # normal messages from splunkd are propogated via SplunkdException;
    if 400 <= serverResponse.status < 600:
        extractedMessages = rest.extractMessages(root)
        for msg in extractedMessages:
            raise splunk.SearchException, msg['text']

    # get the search ID
    sid = root.findtext('sid').strip()

    # instantiate result object
    result = splunk.search.SearchJob(sid,
                                     hostPath,
                                     sessionKey,
                                     namespace,
                                     owner,
                                     dispatchArgs=args)

    return (result, True)
예제 #41
0
    if argvals.get('use_tls'):
        ssContent['action.email.use_tls'] = normalizeBoolean(argvals.get('use_tls'))
    
    ssContent['graceful'] = normalizeBoolean(argvals.get('graceful', 0))

    #if there is no results_link then do not incude it
    if not normalizeBoolean(ssContent.get('results_link')):
        ssContent['action.email.include.results_link'] = False

    #need for backwards compatibility 
    format = ssContent.get('action.email.format')
    if format == 'html' or format == 'plain' or format == 'text':
        ssContent['action.email.format'] = 'table'

    #fetch server info
    uriToServerInfo = entity.buildEndpoint(['server', 'info'])
    serverInfoHeaders, serverInfoBody = simpleRequest(uriToServerInfo, method='GET', getargs={'output_mode':'json'}, sessionKey=sessionKey)
    
    serverInfo        = json.loads(serverInfoBody)
    serverInfoContent = serverInfo['entry'][0]['content']

    #fetch job info
    jobResponseHeaders = {} 
    jobResponseBody = { 
        'entry': [
            {
                'content': {}
            }
        ]
    }
    if sid: 
 def deleteTestUser(userName, sessionKey):
     uri = entity.buildEndpoint(['authentication', 'users'], userName)
     (response, content) = rest.simpleRequest(uri, sessionKey=sessionKey, method="DELETE")        
예제 #43
0
    def setContainer(self, namespace, view_id, action, view_json=None):
        '''
        Provides support to modify dashboard configs
        
        POST /<namespace>/<view_id>
            &action=delete
                --> deletes the current view
            &action=edit
                --> updates the current view config (view JSON object)
                
            ==> returns a JSON response
        '''

        output = jsonresponse.JsonResponse()

        try:

            username = cherrypy.session['user'].get('name')
            dash_id = en.buildEndpoint(VIEW_ENTITY_CLASS,
                                       view_id,
                                       namespace=namespace,
                                       owner=username)
            dashObject = Dashboard.get(dash_id)

            if action == 'delete':
                dashObject.delete()
                output.addInfo(_('Successfully deleted %s') % view_id)

            elif action == 'edit':

                # convert incoming JSON to native struct; clean strings,
                view_json = json.loads(view_json)

                if view_json.get('label'):
                    dashObject.label = view_json['label'].strip()
                if view_json.get('refresh'):
                    dashObject.refresh = int(view_json['refresh'].strip())

                # handle panel reordering; wrap number of columns to the max
                # column constraint
                newPanelDefinition = []
                for row in view_json['new_panel_sequence']:
                    newRow = []
                    for seq in row:
                        newRow.append(dashObject._obj.getPanelBySequence(seq))
                        if len(
                                newRow
                        ) >= splunk.models.dashboard.MAX_DASHBOARD_ROW_SIZE:
                            newPanelDefinition.append(newRow)
                            newRow = []
                    if len(row) > 0:
                        newPanelDefinition.append(newRow)
                dashObject._obj.rows = newPanelDefinition

                # ensure that the row grouping array is synced
                if len(dashObject._obj.rowGrouping) < len(
                        dashObject._obj.rows):
                    dashObject._obj.rowGrouping.extend(
                        [None] * (len(dashObject._obj.rows) -
                                  len(dashObject._obj.rowGrouping)))

                # commit
                dashObject.save()
                output.addInfo(_('Successfully updated %s') % view_id)

            else:
                output.success = False
                output.addError(
                    _('Unrecognized dashboard action: %s; cannot process') %
                    action)
                logger.error(
                    'Unrecognized dashboard action: %s; cannot process' %
                    action)

        except splunk.ResourceNotFound:
            cherrypy.response.status = 404
            output.addWarn(_('"%s" was not found; no action taken') % view_id)

        except Exception, e:
            output.success = False
            output.addError(_('Unable to update view %s: %s') % (view_id, e))
            logger.exception(e)
예제 #44
0
    def streamJobExport(self, job, assetType, **kwargs):
        """
        Stream exported job results to the client (does not buffer the whole result in memory)
        """
        ns = job.eaiacl['app']
        sid = job.sid
        owner = job.eaiacl['owner']
        request = {}
        request['output_mode'] = kwargs['outputMode']
        # SPL-79832 when exporting xml splunkd requires additional request argument
        # to generate valid xml
        if request['output_mode'] == "xml":
            request['export_xml_with_wrapper'] = 1

        request['f'] = kwargs['field_list']
        if 'output_time_format' in kwargs:
            request['output_time_format'] = kwargs['output_time_format']
        else:
            request['output_time_format'] = i18n.ISO8609_MICROTIME

        try:
            count = int(kwargs.get('count'))
            if count > 0:
                request['count'] = count
        except ValueError:
            logger.warn("Failed to parse count field for export count=%s" %
                        count)
            pass

        # We're not going to read/write further from the user's session at this point
        # and streaming may take a while, so release the session read lock
        cherrypy.session.release_lock()

        # Don't buffer the (potentially sizeable) result in memory
        cherrypy.response.stream = True

        postargs = getargs = None
        if job.reportSearch is None and (
            (job.eventIsTruncated and
             (count == 0 or count > job.eventAvailableCount))
                or job.isRemoteTimeline or not job.isDone):
            # re-run the search to get the complete results
            uri = en.buildEndpoint('search/jobs/export',
                                   namespace=ns,
                                   owner=owner)
            request.update(job.request)
            if count > 0:
                request['search'] += '|head %s' % count
            postargs = request

            # if re-running the search for exporting events,
            # ensure we do not run the search with following arguments
            ignoreArgs = ['auto_cancel', 'max_count']
            for iarg in ignoreArgs:
                if iarg in postargs:
                    logger.debug("Dropping argument %s from postargs" % iarg)
                    del postargs[iarg]

        elif assetType == 'event':
            # non-reporting search
            uri = en.buildEndpoint('search/jobs/%s/events/export' % job.sid,
                                   namespace=ns,
                                   owner=owner)
            getargs = request
        else:
            uri = en.buildEndpoint('search/jobs/%s/results/export' % job.sid,
                                   namespace=ns,
                                   owner=owner)
            getargs = request

        export_timeout = cherrypy.config.get('export_timeout')

        logger.debug('Export timeout =%s' % export_timeout)

        if (export_timeout != None):
            export_timeout = int(export_timeout)

        stream = rest.streamingRequest(uri,
                                       getargs=getargs,
                                       postargs=postargs,
                                       timeout=export_timeout)
        return stream.readall()  # returns a generator
    def getContainer(self, namespace, view_id, mode='', **unused):
        '''
        Renders the dashboard edit page
        
        GET /<namespace>/<view_id>
            ==> HTML form page with dashboard edit form (labels, panels) and
                master panel edit form (hidden)
            
        GET /api/<namespace>/<view_id>
            ==> JSON structure of dashboard config (unused?)
        '''
        
        # serve data feed
        output = jsonresponse.JsonResponse()

        try:
            username = cherrypy.session['user'].get('name')
            dash_id = en.buildEndpoint(VIEW_ENTITY_CLASS, view_id, namespace=namespace, owner=username)
            dashObject = Dashboard.get(dash_id)
            output.data = dashObject._obj.toJsonable()

        except splunk.ResourceNotFound:
            cherrypy.response.status = 404
            output.success = False
            output.addError(_('View %s was not found') % view_id)
            return self.render_json(output)


        # serve template page
        if cherrypy.request.is_api:
            return self.render_json(output)
        else:
            cherrypy.response.headers['content-type'] = MIME_HTML

            # get supporting assets
            
            savedSearches = en.getEntities('saved/searches', 
                namespace=namespace, 
                count=-1, 
                search="is_visible=1")
            
            for savedSearch in savedSearches:
                acl = savedSearches[savedSearch]['eai:acl']
                if dashObject.metadata.sharing=='user':
                    continue
                if dashObject.metadata.sharing=='app' and acl['sharing']=='user':
                    savedSearches[savedSearch]['dq'] = True
                    continue
                if dashObject.metadata.sharing=='global' and acl['sharing']!='global':
                    savedSearches[savedSearch]['dq'] = True
                    continue
                if hasattr(dashObject.metadata.perms, 'read') and hasattr(acl['perms'], 'read'):
                    if dashObject.metadata.perms['read'].count('*')>0 and acl['perms']['read'].count('*')==0:
                        savedSearches[savedSearch]['dq'] = True
                        continue
                  
            #dashboardObject = splunk.entity.getEntity('data/ui/views', view_id, namespace=APP['id'], owner=cherrypy.session['user'].get('name'))
            #dashOwner = dashboardObject['eai:acl'].get('owner', 'nobody')

            editLink = self.make_url(
                ['manager', namespace, 'data/ui/views', view_id], 
                _qs=dict(
                    action='edit', 
                    url=self.make_url(['app', namespace, view_id]), 
                    redirect_override="/app/%s/%s" % (namespace, view_id)
                )
            )
            
            permissionsLink = self.make_url(
                ['manager', 'permissions', namespace, 'data/ui/views', view_id], 
                _qs=dict(
                    uri=en.buildEndpoint('data/ui/views', view_id, namespace=namespace, 
                    owner=dashObject.metadata.owner)
                )
            ) 

            return self.render_template('viewmaster/edit_dashboard.html', 
                {
                    'namespace': namespace,
                    'view_id': view_id,
                    'view_object': dashObject._obj,
                    'APP': {'id': namespace},
                    'savedSearches': savedSearches,
                    'editLink': editLink,
                    'permissionsLink': permissionsLink,
                    'mode': mode,
                })
예제 #46
0
파일: rcUtils.py 프로젝트: DRArpitha/splunk
      #eaiArgsList will eventually become the getargs or postargs to send as part of the REST call

      prehooks = layeredFind(endpoint, cmd, obj, 'prehooks') or []

      for ph in prehooks:
         rcHooks.__dict__[ph](cmd, obj, argList)

      eaiArgsList = rcHooks.map_args_cli_2_eai(args, {}, argList)

      logger.debug('after prehooks, eaiArgsList: %s' % str(eaiArgsList))


      #first check if the eai_id needs to be obtained by another request!!!
      if type(lf_eai_id) == types.DictType:
         #oh crappp...
         eai_id_uri = buildEndpoint(lf_eai_id['uri'], entityName='', namespace=namespace, owner=owner, search=search, count=count, offset=offset, sort_key=sort_key, sort_dir=sort_dir)
         eai_id_method = GLOBAL_ACTIONS['%s' % lf_eai_id['type']]

         try:
            eai_id_serverResponse, eai_id_serverContent = simpleRequest(eai_id_uri, sessionKey=sessionKey, getargs='', postargs='', method=eai_id_method)
         except Exception, e:
            logger.debug('Could not construct eai_id: %s, %s' % str(lf_eai_id), str(e))
            raise CliArgError, 'Could not construct eai_id'

         #check the returned status code if it is ok
         try: 
            checkStatus(type=lf_eai_id['type'], serverResponse=eai_id_serverResponse)
         except Exception, e:
            logger.debug('Could not construct eai_id: %s, %s' % (str(lf_eai_id), str(e)))
            raise CliArgError, 'Could not construct eai_id'
    def setContainer(self, namespace, view_id, action, view_json=None):
        '''
        Provides support to modify dashboard configs
        
        POST /<namespace>/<view_id>
            &action=delete
                --> deletes the current view
            &action=edit
                --> updates the current view config (view JSON object)
                
            ==> returns a JSON response
        '''

        output = jsonresponse.JsonResponse()

        try:

            username = cherrypy.session['user'].get('name')
            dash_id = en.buildEndpoint(VIEW_ENTITY_CLASS, view_id, namespace=namespace, owner=username)
            dashObject = Dashboard.get(dash_id)

            if action == 'delete':
                dashObject.delete()
                output.addInfo(_('Successfully deleted %s') % view_id)

            elif action == 'edit':

                # convert incoming JSON to native struct; clean strings, 
                view_json = json.loads(view_json)

                if view_json.get('label'):
                    dashObject.label = view_json['label'].strip()
                if view_json.get('refresh'):
                    dashObject.refresh = int(view_json['refresh'].strip())
                    
                # handle panel reordering; wrap number of columns to the max
                # column constraint
                newPanelDefinition = []
                for row in view_json['new_panel_sequence']:
                    newRow = []
                    for seq in row:
                        newRow.append(dashObject._obj.getPanelBySequence(seq))
                        if len(newRow) >= splunk.models.dashboard.MAX_DASHBOARD_ROW_SIZE:
                            newPanelDefinition.append(newRow)
                            newRow = []
                    if len(row) > 0:
                        newPanelDefinition.append(newRow)
                dashObject._obj.rows = newPanelDefinition
                
                # ensure that the row grouping array is synced
                if len(dashObject._obj.rowGrouping) < len(dashObject._obj.rows):
                    dashObject._obj.rowGrouping.extend([None] * (len(dashObject._obj.rows) - len(dashObject._obj.rowGrouping)))

                # commit
                dashObject.save()
                output.addInfo(_('Successfully updated %s') % view_id)

            else:
                output.success = False
                output.addError(_('Unrecognized dashboard action: %s; cannot process') % action)
                logger.error('Unrecognized dashboard action: %s; cannot process' % action)

        except splunk.ResourceNotFound:
            cherrypy.response.status = 404
            output.addWarn(_('"%s" was not found; no action taken') % view_id)

        except Exception, e:
            output.success = False
            output.addError(_('Unable to update view %s: %s') % (view_id, e))
            logger.exception(e)
예제 #48
0
def get_tokens(searchinfo):
    tokens = {}
    # Get the host of the splunkd service
    splunkd_host = searchinfo.splunkd_uri[searchinfo.splunkd_uri.index("//") +
                                          2:searchinfo.splunkd_uri.rindex(":")]
    splunkd_port = searchinfo.splunkd_uri[searchinfo.splunkd_uri.rindex(":") +
                                          1:]

    tokens = {'splunkd_host': splunkd_host, 'splunkd_port': splunkd_port}

    # Get the search job attributes
    if searchinfo.sid:
        job_uri = en.buildEndpoint(['search', 'jobs', searchinfo.sid],
                                   namespace=searchinfo.app,
                                   owner=searchinfo.owner)
        job_response = simpleRequest(job_uri,
                                     method='GET',
                                     getargs={'output_mode': 'json'},
                                     sessionKey=searchinfo.session_key)[1]
        search_job = json.loads(job_response)
        job_content = search_job['entry'][0]['content']
    else:
        job_content = {}

    for key, value in list(job_content.items()):
        if value is not None:
            tokens['job.' + key] = json.dumps(value,
                                              default=lambda o: o.__dict__)
    #eprint("job_content=" + json.dumps(job_content))

    if 'label' in list(job_content.keys()):
        tokens['name'] = job_content['label']

        # Get the saved search properties
        entityClass = ['saved', 'searches']
        uri = en.buildEndpoint(entityClass,
                               namespace=searchinfo.app,
                               owner=searchinfo.owner)

        responseBody = simpleRequest(uri,
                                     method='GET',
                                     getargs={'output_mode': 'json'},
                                     sessionKey=searchinfo.session_key)[1]

        saved_search = json.loads(responseBody)
        ss_content = saved_search['entry'][0]['content']
        #eprint("SSContent=" + json.dumps(ss_content))

        for key, value in list(ss_content.items()):
            if not key.startswith('display.'):
                if value is not None:
                    tokens[key] = json.dumps(value,
                                             default=lambda o: o.__dict__)

    tokens['owner'] = searchinfo.owner
    tokens['app'] = searchinfo.app
    #tokens['results_link'] = 'http://127.0.0.1:8000/en-US/app/search/search?sid=1622650709.10799'

    # Parse all of the nested objects (recursive function)
    for t, tv in list(tokens.items()):
        tokens = merge_two_dicts(tokens, parse_nested_json(t, tv))

    #for t, tv in list(tokens.items()):
    #	if type(tv) == str:
    #		eprint(t + '=' + tv)
    #	else:
    #		eprint(t + "(type " + str(type(tv)) + ") = " + str(tv))
    return tokens
예제 #49
0
 def _build_endpoint_uri(self, entities):
     return entity.buildEndpoint(entities,
                                 namespace=self._app_name,
                                 owner="nobody")