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)
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
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)
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