def dispatchSavedSearch(savedSearchName, sessionKey=None, namespace=None, owner=None, hostPath=None, now=0, triggerActions=0, **kwargs):
    """Initiates a new job based on a saved search."""

    uri = entity.buildEndpoint(['saved', 'searches', savedSearchName, 'dispatch'], namespace=namespace, owner=owner)
    if hostPath:
        uri = splunk.mergeHostPath(hostPath) + uri
        
    args = {
        'now': now,
        'trigger_actions' : triggerActions
    }
    
    for key, val in kwargs.items():
        if key in SAVED_SEARCH_DISPATCH_ARG_MAP:
            args[SAVED_SEARCH_DISPATCH_ARG_MAP[key]] = val
        # Pass through for dispatch.* formated kwargs
        elif key.startswith('dispatch.'):
            args[key] = val

    serverResponse, serverContent = rest.simpleRequest(uri, postargs=args, sessionKey=sessionKey)
    root = et.fromstring(serverContent)

    # normal messages from splunkd are propogated via SplunkdException;
    if not 201 == serverResponse.status:

        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
    return splunk.search.SearchJob(sid, hostPath, sessionKey, namespace, owner)
def createConf(confName,
               namespace=None,
               owner=None,
               sessionKey=None,
               hostPath=None):
    '''
    Creates a new conf file.  Returns a conf instance of the newly created
    .conf file.
    '''

    uri = entity.buildEndpoint('properties',
                               namespace=namespace,
                               owner=owner,
                               hostPath=hostPath)
    postargs = {'__conf': confName}

    status, response = rest.simpleRequest(uri,
                                          postargs=postargs,
                                          sessionKey=sessionKey,
                                          raiseAllErrors=True)

    # Expect 201 on creation or 200 on preexisting file (automatic handling of 303 redirect).
    if not ((status.status == 201) or
            (status.previous is not None and status.status == 200)):
        logger.error(
            'createConf - unexpected server response while creating conf file "%s"; HTTP=%s'
            % (confName, status.status))

    return getConf(confName,
                   namespace=namespace,
                   owner=owner,
                   sessionKey=sessionKey,
                   hostPath=hostPath)
Exemple #3
0
def dispatchSavedSearch(savedSearchName, sessionKey=None, namespace=None, owner=None, hostPath=None, now=0, triggerActions=0, **kwargs):
    """Initiates a new job based on a saved search."""

    uri = entity.buildEndpoint(['saved', 'searches', savedSearchName, 'dispatch'], namespace=namespace, owner=owner)
    if hostPath:
        uri = splunk.mergeHostPath(hostPath) + uri
        
    args = {
        'now': now,
        'trigger_actions' : triggerActions
    }
    
    for key, val in kwargs.items():
        if key in SAVED_SEARCH_DISPATCH_ARG_MAP:
            args[SAVED_SEARCH_DISPATCH_ARG_MAP[key]] = val
        # Pass through for dispatch.* formated kwargs
        elif key.startswith('dispatch.'):
            args[key] = val

    serverResponse, serverContent = rest.simpleRequest(uri, postargs=args, sessionKey=sessionKey)
    root = et.fromstring(serverContent)

    # normal messages from splunkd are propogated via SplunkdException;
    if not 201 == serverResponse.status:

        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
    return splunk.search.SearchJob(sid, hostPath, sessionKey, namespace, owner)
Exemple #4
0
def getConf(confName, sessionKey=None, namespace=None, owner=None, overwriteStanzas=False, hostPath=None):
    '''
    Parses a logical bundle file and returns a Conf() object

    If namespace=None, then the behavior is 3.2-style, where all writes are 
    done to conf files in etc/system/local.  All reads will merge every conf
    file that is accessible in etc/system and etc/apps/*.  If a namespace is 
    provided, then writes are done in etc/apps/<namespace>/local/, and reads 
    are restricted to values in etc/apps/<namespace>/(default|local).  If
    overwriteStanzas is true, old keys in edited stanzas will not be preserved.

    For the 3.2-style reading, the endpoint uses the following priority:
        system/local
        apps/<namespace>/local
        apps/<namespace>/default
        system/default
    '''

    # fallback to current user
    if not owner:
        owner = auth.getCurrentUser()['name']
    
    uri = entity.buildEndpoint(entityClass='properties', entityName=confName, namespace=namespace, 
                               owner=owner, hostPath=hostPath)
    
    # the fillcontents arg will push all stanza keys down in 1 request instead
    # of iterating over all stanzas
    serverResponse, serverContent = rest.simpleRequest(uri, getargs={'fillcontents':1}, sessionKey=sessionKey)
    
    if serverResponse.status != 200:
        logger.info('getConf - server returned status=%s when asked for conf=%s' % (serverResponse.status, confName))
        
    # convert the atom feed into dict
    confFeed = rest.format.parseFeedDocument(serverContent)
    stanzas = confFeed.toPrimitive()
    
    # create Conf/Stanzas
    output = Conf(confName, namespace=namespace, owner=owner, overwriteStanzas=overwriteStanzas)
    output.sessionKey = sessionKey
    output.isImportMode = True
    for name in stanzas:
        stanza = output.createStanza(name)
        stanza.needsPopulation = False
        for k in stanzas[name]:
            if stanzas[name][k] == None:
                stanza[k] = ''
            else:
                stanza[k] = stanzas[name][k]
        
    output.isImportMode = False

    return output
Exemple #5
0
def createConf(confName, namespace=None, owner=None, sessionKey=None, hostPath=None):
    '''
    Creates a new conf file.  Returns a conf instance of the newly created
    .conf file.
    '''
    
    uri = entity.buildEndpoint('properties', namespace=namespace, owner=owner, hostPath=hostPath)
    postargs = {'__conf': confName}
    
    status, response = rest.simpleRequest(uri, postargs=postargs, sessionKey=sessionKey, raiseAllErrors=True)
    
    # Expect 201 on creation or 200 on preexisting file (automatic handling of 303 redirect).
    if not ((status.status == 201) or (status.previous is not None and status.status == 200)):
        logger.error('createConf - unexpected server response while creating conf file "%s"; HTTP=%s' % (confName, status.status))
    
    return getConf(confName, namespace=namespace, owner=owner, sessionKey=sessionKey, hostPath=hostPath)
Exemple #6
0
    def getEndpointPath(self, conf=None, stanza=None, key=None):
        '''
        Returns the splunkd URI for the specified combination of conf file,
        stanza, and key name.  The namespace and owner context are pulled from
        the current Conf() instance.
        '''
        
        path = [entity.buildEndpoint('properties', namespace=self.namespace, owner=self.owner)]

        parts = []
        if conf: 
            parts.append(conf)
            if stanza:
                parts.append(stanza)
                if key:
                    parts.append(key)
        
        path.extend([util.safeURLQuote(shard, '') for shard in parts])
        
        return '/'.join(path)
    def getEndpointPath(self, conf=None, stanza=None, key=None):
        '''
        Returns the splunkd URI for the specified combination of conf file,
        stanza, and key name.  The namespace and owner context are pulled from
        the current Conf() instance.
        '''

        path = [
            entity.buildEndpoint('properties',
                                 namespace=self.namespace,
                                 owner=self.owner)
        ]

        parts = []
        if conf:
            parts.append(conf)
            if stanza:
                parts.append(stanza)
                if key:
                    parts.append(key)

        path.extend([util.safeURLQuote(shard, '') for shard in parts])

        return '/'.join(path)
def getConf(confName,
            sessionKey=None,
            namespace=None,
            owner=None,
            overwriteStanzas=False,
            hostPath=None):
    '''
    Parses a logical bundle file and returns a Conf() object

    If namespace=None, then the behavior is 3.2-style, where all writes are 
    done to conf files in etc/system/local.  All reads will merge every conf
    file that is accessible in etc/system and etc/apps/*.  If a namespace is 
    provided, then writes are done in etc/apps/<namespace>/local/, and reads 
    are restricted to values in etc/apps/<namespace>/(default|local).  If
    overwriteStanzas is true, old keys in edited stanzas will not be preserved.

    For the 3.2-style reading, the endpoint uses the following priority:
        system/local
        apps/<namespace>/local
        apps/<namespace>/default
        system/default
    '''

    # fallback to current user
    if not owner:
        owner = auth.getCurrentUser()['name']

    uri = entity.buildEndpoint(entityClass='properties',
                               entityName=confName,
                               namespace=namespace,
                               owner=owner,
                               hostPath=hostPath)

    # the fillcontents arg will push all stanza keys down in 1 request instead
    # of iterating over all stanzas
    serverResponse, serverContent = rest.simpleRequest(
        uri, getargs={'fillcontents': 1}, sessionKey=sessionKey)

    if serverResponse.status != 200:
        logger.info(
            'getConf - server returned status=%s when asked for conf=%s' %
            (serverResponse.status, confName))

    # convert the atom feed into dict
    confFeed = rest.format.parseFeedDocument(serverContent)
    stanzas = confFeed.toPrimitive()

    # create Conf/Stanzas
    output = Conf(confName,
                  namespace=namespace,
                  owner=owner,
                  overwriteStanzas=overwriteStanzas)
    output.sessionKey = sessionKey
    output.isImportMode = True
    for name in stanzas:
        stanza = output.createStanza(name)
        stanza.needsPopulation = False
        for k in stanzas[name]:
            if stanzas[name][k] == None:
                stanza[k] = ''
            else:
                stanza[k] = stanzas[name][k]

    output.isImportMode = False

    return output