def simple_request_eai(self, url, action, method, params=None, get_args=None): """ Returns the payload response from a simpleRequest call Arguments url -- The REST handler endpoint to use in the simpleRequest params -- The parameters sent in the POST body of the simpleRequest """ if not params: params = {} default_get_args = dict(output_mode='json') if get_args: default_get_args.update(get_args) logger.info('%s request %s' % (method, url)) try: response, content = rest.simpleRequest(url, getargs=default_get_args, postargs=params, method=method, sessionKey=self.getSessionKey()) except Exception as e: logger.error(e) raise admin.ServiceUnavailableException('Unable to %s %s entry.' % (action, url)) try: payload = json.loads(content) except Exception as e: logger.error(e) raise admin.InternalException('Unable to parse %s response payload.' % url) if response.status not in [200, 201]: message = self.simple_request_messages_to_str(response.messages) logger.error( 'handler_message="request failed, status code not in successful range" status="%s" params="%s" splunkd_message="%s"' % ( response.status, params, message)) raise admin.AlreadyExistsException( 'Unable to %s %s entry. %s' % (action, url, message)) return payload
def handleCreate(self, confInfo): logger.debug("In handleCreate") # Refresh self.handleReload() name = self.callerArgs.id args = self.callerArgs.data # Make sure the name is not empty if not name or len(name) == 0: raise admin.ArgValidationException("The stanza name must not be empty") # Make sure the item does not already exist if name in self.readConf("log_review"): raise admin.AlreadyExistsException("A entry already exists for %s" % (name)) # Get the field values # TODO: obtain the values of the fields into Python variables debug = _getFieldValue( args, self.PARAM_DEBUG, default_value='false' ) comment_minimum_length = _getFieldValue( args, self.PARAM_COMMENT_MINIMUM_LENGTH, default_value=self.DEFAULT_COMMENT_LENGTH ) comment_required = _getFieldValue( args, self.PARAM_COMMENT_REQUIRED, default_value=self.DEFAULT_COMMENT_REQUIRED ) ir_header_labels = _getFieldValue( args, self.PARAM_TABLE_LABELS, default_value=self.DEFAULT_TABLE_LABELS ) ir_header_fields = _getFieldValue( args, self.PARAM_TABLE_FIELDS, default_value=self.DEFAULT_TABLE_FIELDS ) ir_attribute_labels = _getFieldValue( args, self.PARAM_ATTRIBUTE_LABELS, default_value=self.DEFAULT_ATTRIBUTE_LABELS ) ir_attribute_fields = _getFieldValue( args, self.PARAM_ATTRIBUTE_FIELDS, default_value=self.DEFAULT_ATTRIBUTE_FIELDS ) # Add the field values to a configuration dictionary (that will be verified) conf = entity.getEntity('configs/conf-log_review', '_new', sessionKey=self.getSessionKey()) conf.namespace = self.appName # always save things to SOME app context. conf.owner = self.context == admin.CONTEXT_APP_AND_USER and self.userName or "-" conf['name'] = name _addToDictIfNonNull(conf, self.PARAM_DEBUG, debug) _addToDictIfNonNull(conf, self.PARAM_COMMENT_MINIMUM_LENGTH, comment_minimum_length) _addToDictIfNonNull(conf, self.DEFAULT_COMMENT_REQUIRED, comment_required) _addToDictIfNonNull(conf, self.DEFAULT_TABLE_LABELS, ir_header_labels) _addToDictIfNonNull(conf, self.DEFAULT_TABLE_FIELDS, ir_header_fields) _addToDictIfNonNull(conf, self.DEFAULT_ATTRIBUTE_LABELS, ir_attribute_labels) _addToDictIfNonNull(conf, self.DEFAULT_ATTRIBUTE_FIELDS, ir_attribute_fields) # Check the configuration try: self.checkConf(conf, name) except InvalidConfigException as e: logger.error( "The configuration for '%s' is invalid and could not be created: %s" % ( name, str(e)) ) raise admin.ArgValidationException( str(e) ) # Write out an update to the config file entity.setEntity(conf, sessionKey=self.getSessionKey()) # Refresh self.handleReload()
def createApp(appName, template, **kwargs): appPath = _getAppPath(appName) if os.path.exists(appPath): raise admin.AlreadyExistsException( _("App '%s' already exists. Nothing was created.") % appName) if template not in getTemplates(): raise admin.ArgValidationException( _("Template '%s' does not exist.") % template) # Make sure we don't mess the app.conf file - add a backslash at the eol kwargs['description'] = kwargs['description'].replace('\n', '\\\n') # Generate files for the app bundle_paths.maybe_makedirs(appPath) os.chdir(appPath) templatePath = os.path.join(TEMPLATES_PATH, template) for root, dirs, files in os.walk(templatePath): # determine relative path relPath = root[len(templatePath) + 1:] # create subdirs for dir in dirs: bundle_paths.maybe_makedirs(os.path.join(relPath, dir)) # Read template files and apply param values then save for fn in files: try: # use params to create custom file names inFilePath = os.path.join(root, fn) # filter by file type fn, isText = _isTextFile(fn) outFilePath = os.path.join(appPath, relPath, fn) if not isText: comm.copyItem(inFilePath, outFilePath) continue with open(inFilePath, 'r') as f_in: content = f_in.read() content = SafeTemplate(content).substitute(kwargs) with open(outFilePath, 'w') as f_out: f_out.write(content) except: print traceback.print_exc(file=sys.stderr) pass return '%s/app/%s' % (_getSplunkWebUri(), appName)
def handleCreate(self, confInfo): logger.debug('handleCreate is called. -- action = %s, id = %s' % (self.customAction, self.callerArgs.id)) try: args = self.getCallerArgs() self.create(**args) except BaseException as ex: logger.exception( 'handleCreate Failed - arguments = %s, exception = %s' % (self.callerArgs, ex)) #raise an exception when we fail to create! raise admin.AlreadyExistsException('Failed to create model: %s' % (self.callerArgs.id)) self.handleList(confInfo)
def installApp(location, force=False): installer = bundle_paths.BundleInstaller() location = location.strip() try: if location.startswith('http'): req = urllib2.Request(url=location) return installer.install_from_url(req, force) else: return installer.install_from_tar(location, force) except splunk.ResourceNotFound, e: raise admin.ArgValidationException(e.msg) except splunk.RESTException, e: if e.statusCode == 409: raise admin.AlreadyExistsException(e.msg) raise admin.InternalException(e.msg) except Exception, e: raise admin.InternalException(e) ''' Merges local and default parts of an app into default Returns the path to the merged app. ''' def mergeApp(appName): appPath = _getAppPath(appName, True) if not appPath: return None
def handleCreate(self, confInfo): '''Handles creation of a suppression.''' # Get requested action actionStr = str(self.requestedAction) if actionStr in Suppressions.REQUESTED_ACTIONS: actionStr = Suppressions.REQUESTED_ACTIONS[actionStr] logger.info('Entering %s', actionStr) # Refresh self.handleReload() name = self.callerArgs.id args = self.callerArgs.data # Make sure the name is not empty if not name or len(name) == 0: raise admin.ArgValidationException( "The name of the suppression must not be empty") # Make sure the name follows the convention nameMatch = NotableEventSuppression.suppressionRE.match(name) if not nameMatch: raise admin.ArgValidationException( "The name of the suppression must follow proper convention") # Make sure the item does not already exist if name in self.readConf('eventtypes'): raise admin.AlreadyExistsException( "A suppression entry already exists for %s" % (name)) # Get the field values disabled = _getFieldValue(args, Suppressions.PARAM_DISABLED) search = _getFieldValue(args, Suppressions.PARAM_SEARCH) description = _getFieldValue(args, Suppressions.PARAM_DESCRIPTION) # Add the field values to a configuration dictionary (that will be verified) conf = entity.getEntity('saved/eventtypes', '_new', sessionKey=self.getSessionKey()) conf.namespace = self.appName # always save things to SOME app context. conf.owner = self.context == admin.CONTEXT_APP_AND_USER and self.userName or "-" conf['name'] = name _addToDictIfNonNull(conf, Suppressions.PARAM_DISABLED, disabled) _addToDictIfNonNull(conf, Suppressions.PARAM_SEARCH, search) _addToDictIfNonNull(conf, Suppressions.PARAM_DESCRIPTION, description) ## Notable Suppression Audit Log Data log_data = { 'action': 'create', 'suppression': conf['name'][len(NotableEventSuppression.SUPPRESSION_START):], 'user': conf['eai:acl']['owner'], 'status': 'success', 'signature': 'Notable event suppression successfully created' } # Check the configuration try: Suppressions.checkConf(conf, name) except InvalidConfigException as e: e = "The configuration for the new suppression '%s' is invalid and could not be created: %s" % ( name, str(e)) logger.error(e) log_data['status'] = 'failure' log_data['signature'] = 'Unable to save the event suppression' logger.error( 'SuppressionAudit - suppression={suppression}; action={action}; status={status}; signature={signature}; user={user};' .format(**log_data)) raise admin.ArgValidationException(e) # Write out an update to the eventtypes config file entity.setEntity(conf, sessionKey=self.getSessionKey()) logger.info('Successfully added suppression: %s', name) # Reload suppressions self.handleReload() logger.info('%s completed successfully', actionStr) logger.info( 'SuppressionAudit - suppression={suppression}; action={action}; status={status}; signature={signature}; user={user};' .format(**log_data))
def handleCreate(self, confInfo): """ Handles creation of a governance configuration """ ## Get requested action actionStr = str(self.requestedAction) if Governance.REQUESTED_ACTIONS.has_key(actionStr): actionStr = Governance.REQUESTED_ACTIONS[actionStr] logger.info('Entering %s' % (actionStr)) ## Refresh self.handleReload(makeKVS=False) name = self.callerArgs.id args = self.callerArgs.data # Make sure the name is not empty if not name or len(name) == 0: raise admin.ArgValidationException( "The name of the governance configuration must not be empty") # Make sure the item does not already exist if name in self.readConf('governance'): raise admin.AlreadyExistsException( "A governance configuration already exists for %s" % (name)) ## Get a new entry from the conf-postprocess interface conf = entity.getEntity('configs/conf-governance', '_new', sessionKey=self.getSessionKey()) conf.namespace = self.appName # always save things to SOME app context. conf.owner = self.context == admin.CONTEXT_APP_AND_USER and self.userName or "-" conf['name'] = name for arg in args: governanceMatch = Governance.governanceRE.match(arg) controlMatch = Governance.controlRE.match(arg) tagMatch = Governance.tagRE.match(arg) ## Add the field values to a configuration dictionary (that will be verified) if governanceMatch or controlMatch or tagMatch or arg in Governance.VALID_PARAMS: _addToDictIfNonNull(conf, arg, args[arg][0]) ## Check the configuration try: Governance.checkConf(conf, name) except InvalidConfigException as e: e = "The configuration for the new governance entry '%s' is invalid and could not be created: %s" % ( name, str(e)) logger.error(e) raise admin.ArgValidationException(e) ## Write out an update to the reviewstatuses config file entity.setEntity(conf, sessionKey=self.getSessionKey()) logger.info('Successfully added governance configuration: %s' % (name)) ## Reload governance (makeKVS) self.handleReload() logger.info('%s completed successfully' % (actionStr))
def handleCreate(self, confInfo): """ Handles creation of a correlation search """ ## Get requested action actionStr = str(self.requestedAction) if actionStr in CorrelationSearches.REQUESTED_ACTIONS: actionStr = CorrelationSearches.REQUESTED_ACTIONS[actionStr] logger.info('Entering %s', actionStr) ## Refresh self.handleReload(makeKVS=False) reviewstatusesDict = self.readConf('reviewstatuses') correlationsDict = self.readConf('correlationsearches') # Get list of valid Splunk users users = NotableOwner.getOwners(self.getSessionKey()) name = self.callerArgs.id args = self.callerArgs.data # Make sure the name is not empty if not name: raise admin.ArgValidationException( 'The name of the correlation search must not be empty') # Make sure the item does not already exist elif name in correlationsDict: raise admin.AlreadyExistsException( 'A correlation search entry already exists for %s' % name) # Get the field values (these are written to conf file) rule_name = _getFieldValue(args, CorrelationSearches.PARAM_RULE_NAME) description = _getFieldValue(args, CorrelationSearches.PARAM_DESCRIPTION) search = _getFieldValue(args, CorrelationSearches.PARAM_SEARCH) related_search_name = _getFieldValue( args, CorrelationSearches.PARAM_DEPENDENT_SEARCH) related_search_name_0 = _getFieldValue( args, CorrelationSearches.PARAM_DEPENDENT_SEARCH_0) related_search_name_1 = _getFieldValue( args, CorrelationSearches.PARAM_DEPENDENT_SEARCH_1) related_search_name_2 = _getFieldValue( args, CorrelationSearches.PARAM_DEPENDENT_SEARCH_2) related_search_name_3 = _getFieldValue( args, CorrelationSearches.PARAM_DEPENDENT_SEARCH_3) related_search_name_4 = _getFieldValue( args, CorrelationSearches.PARAM_DEPENDENT_SEARCH_4) security_domain = _getFieldValue( args, CorrelationSearches.PARAM_SECURITY_DOMAIN) severity = _getFieldValue(args, CorrelationSearches.PARAM_SEVERITY) rule_title = _getFieldValue(args, CorrelationSearches.PARAM_RULE_TITLE) rule_description = _getFieldValue( args, CorrelationSearches.PARAM_RULE_DESCRIPTION) nes_fields = _getFieldValue(args, CorrelationSearches.PARAM_NES_FIELDS) drilldown_name = _getFieldValue( args, CorrelationSearches.PARAM_DRILLDOWN_NAME) drilldown_search = _getFieldValue( args, CorrelationSearches.PARAM_DRILLDOWN_SEARCH) drilldown_earliest_offset = _getFieldValue( args, CorrelationSearches.PARAM_DRILLDOWN_EARLIEST_OFFSET) drilldown_latest_offset = _getFieldValue( args, CorrelationSearches.PARAM_DRILLDOWN_LATEST_OFFSET) default_status = _getFieldValue( args, CorrelationSearches.PARAM_DEFAULT_STATUS) default_owner = _getFieldValue(args, CorrelationSearches.PARAM_DEFAULT_OWNER) next_steps = _getFieldValue(args, CorrelationSearches.PARAM_NEXT_STEPS) recommended_actions = _getFieldValue( args, CorrelationSearches.PARAM_RECOMMENDED_ACTIONS) # Add the field values to a configuration dictionary (that will be verified) conf = entity.getEntity('configs/conf-correlationsearches', '_new', sessionKey=self.getSessionKey()) conf.namespace = self.appName # always save things to SOME app context. conf.owner = ((self.context == admin.CONTEXT_APP_AND_USER) and self.userName) or "-" conf['name'] = name _addToDictIfNonNull(conf, CorrelationSearches.PARAM_RULE_NAME, rule_name) _addToDictIfNonNull(conf, CorrelationSearches.PARAM_DESCRIPTION, description) _addToDictIfNonNull(conf, CorrelationSearches.PARAM_SEARCH, search) _addToDictIfNonNull(conf, CorrelationSearches.PARAM_DEPENDENT_SEARCH, related_search_name) _addToDictIfNonNull(conf, CorrelationSearches.PARAM_DEPENDENT_SEARCH_0, related_search_name_0) _addToDictIfNonNull(conf, CorrelationSearches.PARAM_DEPENDENT_SEARCH_1, related_search_name_1) _addToDictIfNonNull(conf, CorrelationSearches.PARAM_DEPENDENT_SEARCH_2, related_search_name_2) _addToDictIfNonNull(conf, CorrelationSearches.PARAM_DEPENDENT_SEARCH_3, related_search_name_3) _addToDictIfNonNull(conf, CorrelationSearches.PARAM_DEPENDENT_SEARCH_4, related_search_name_4) _addToDictIfNonNull(conf, CorrelationSearches.PARAM_SECURITY_DOMAIN, security_domain) _addToDictIfNonNull(conf, CorrelationSearches.PARAM_SEVERITY, severity) _addToDictIfNonNull(conf, CorrelationSearches.PARAM_RULE_TITLE, rule_title) _addToDictIfNonNull(conf, CorrelationSearches.PARAM_RULE_DESCRIPTION, rule_description) _addToDictIfNonNull(conf, CorrelationSearches.PARAM_NES_FIELDS, nes_fields) _addToDictIfNonNull(conf, CorrelationSearches.PARAM_DRILLDOWN_NAME, drilldown_name) _addToDictIfNonNull(conf, CorrelationSearches.PARAM_DRILLDOWN_SEARCH, drilldown_search) _addToDictIfNonNull( conf, CorrelationSearches.PARAM_DRILLDOWN_EARLIEST_OFFSET, drilldown_earliest_offset) _addToDictIfNonNull(conf, CorrelationSearches.PARAM_DRILLDOWN_LATEST_OFFSET, drilldown_latest_offset) _addToDictIfNonNull(conf, CorrelationSearches.PARAM_DEFAULT_STATUS, default_status) _addToDictIfNonNull(conf, CorrelationSearches.PARAM_DEFAULT_OWNER, default_owner) _addToDictIfNonNull(conf, CorrelationSearches.PARAM_NEXT_STEPS, next_steps) _addToDictIfNonNull(conf, CorrelationSearches.PARAM_RECOMMENDED_ACTIONS, recommended_actions) # Check the configuration try: CorrelationSearches.checkConf(conf, name, users=users, reviewstatuses=reviewstatusesDict) except InvalidConfigException as e: e = "The configuration for the new correlation search '%s' is invalid and could not be created: %s" % ( name, str(e)) logger.error(e) raise admin.ArgValidationException(e) # Write out an update to the reviewstatuses config file entity.setEntity(conf, sessionKey=self.getSessionKey()) logger.info('Successfully added correlation search: %s', name) # Reload correlationsearches (makeKVS) self.handleReload(reloadReviewStatuses=False)
default_get_args = dict(output_mode='json') if get_args: default_get_args.update(get_args) logger.info('%s request %s' % (method, url)) try: response, content = rest.simpleRequest( url, getargs=default_get_args, postargs=params, method=method, sessionKey=self.getSessionKey()) except Exception, e: logger.error(e) raise admin.ServiceUnavailableException('Unable to %s %s entry.' % (action, url)) try: payload = json.loads(content) except Exception, e: logger.error(e) raise admin.InternalException( 'Unable to parse %s response payload.' % url) if response.status not in [200, 201]: message = self.simple_request_messages_to_str(response.messages) logger.error( 'handler_message="request failed, status code not in successful range" status="%s" params="%s" splunkd_message="%s"' % (response.status, params, message)) raise admin.AlreadyExistsException('Unable to %s %s entry. %s' % (action, url, message)) return payload