def handleEdit(self, confInfo): name = self.callerArgs.id ent = en.getEntity(ENDPOINT, name, namespace=self.appName, owner=self.userName, sessionKey=self.getSessionKey()) for arg in optional_args: try: if arg in ['disabled']: continue ent[arg] = self.callerArgs[arg] except: pass for arg in required_args: try: if arg in ['disabled']: continue ent[arg] = self.callerArgs[arg] except: pass en.setEntity(ent, sessionKey=self.getSessionKey())
def disableIndexAndForward(cls, sessionKey): try: # Try to get the existing entry indexAndForward_entity = en.getEntity( 'configs/conf-outputs', "indexAndForward", namespace=ConfigCEFApp.DEFAULT_NAMESPACE, owner=ConfigCEFApp.DEFAULT_OWNER, sessionKey=sessionKey) except splunk.ResourceNotFound: # Otherwise, create a new one indexAndForward_entity = en.getEntity( 'configs/conf-outputs', "_new", namespace=ConfigCEFApp.DEFAULT_NAMESPACE, owner=ConfigCEFApp.DEFAULT_OWNER, sessionKey=sessionKey) indexAndForward_entity.namespace = ConfigCEFApp.DEFAULT_NAMESPACE indexAndForward_entity.owner = ConfigCEFApp.DEFAULT_OWNER indexAndForward_entity['name'] = "indexAndForward" indexAndForward_entity['index'] = 0 en.setEntity(indexAndForward_entity, sessionKey=sessionKey)
def setSharing(viewstate, shareMode): ''' Sets the sharing mode: 'global', 'app', 'user' ''' if not isinstance(viewstate, Viewstate): raise ValueError, 'Cannot update viewstate; Only viewstate objects supported' # first fetch all the ACL data vsACL = en.getEntity(VIEWSTATE_ENTITY_CLASS + '/' + buildStanzaName(viewstate.view, viewstate.id), 'acl', namespace=viewstate.namespace, owner=viewstate.owner) # create new object and update mininum set of properties to support sharing aclWrapper = en.Entity(VIEWSTATE_ENTITY_CLASS + '/' + buildStanzaName(viewstate.view, viewstate.id), 'acl', namespace=viewstate.namespace, owner=viewstate.owner) aclWrapper['owner'] = viewstate.owner aclWrapper['sharing'] = shareMode # commit en.setEntity(aclWrapper) return True
def setSharing(viewstate, shareMode): ''' Sets the sharing mode: 'global', 'app', 'user' ''' if not isinstance(viewstate, Viewstate): raise ValueError, 'Cannot update viewstate; Only viewstate objects supported' # first fetch all the ACL data vsACL = en.getEntity( VIEWSTATE_ENTITY_CLASS + '/' + buildStanzaName(viewstate.view, viewstate.id), 'acl', namespace=viewstate.namespace, owner=viewstate.owner ) # create new object and update mininum set of properties to support sharing aclWrapper = en.Entity( VIEWSTATE_ENTITY_CLASS + '/' + buildStanzaName(viewstate.view, viewstate.id), 'acl', namespace=viewstate.namespace, owner=viewstate.owner ) aclWrapper['owner'] = viewstate.owner aclWrapper['sharing'] = shareMode # commit en.setEntity(aclWrapper) return True
def removeDefaultOutputGroup(cls, sessionKey): output = cls.getMainOutput(sessionKey) """ # Data models sux output.defaultGroup = '' output.save() """ output['defaultGroup'] = "" output.namespace = ConfigCEFApp.DEFAULT_NAMESPACE output.owner = ConfigCEFApp.DEFAULT_OWNER en.setEntity(output, sessionKey=sessionKey) # Update tcpout cls.setDefaultTcpOutGroup("", sessionKey) # Remove the default output group defaultOutput = cls.getDefaultOutputGroup(sessionKey) if not defaultOutput: return False elif not defaultOutput.passive_delete(): raise Exception("Default output could not be deleted") return True
def update(self, **params): app, user = self._namespace_and_owner() ent = en.getEntity(self._endpoint, self.callerArgs.id, namespace=app, owner=user, sessionKey=self.getSessionKey()) for arg in params.keys(): if arg in self._required_args + self._optional_args: ent[arg] = params[arg] #check which args are allowed to be posted allowedArgs = [] if 'eai:attributes' in ent and 'requiredFields' in ent[ 'eai:attributes'] and 'optionalFields' in ent['eai:attributes']: allowedArgs = ent['eai:attributes']['requiredFields'] + ent[ 'eai:attributes']['optionalFields'] #filter out args that aren't allowed for arg in ent.keys(): if arg not in allowedArgs: del ent.properties[arg] en.setEntity(ent, sessionKey=self.getSessionKey())
def commit(viewstate): ''' Persists a viewstate object. ''' if not isinstance(viewstate, Viewstate): raise ValueError, 'Cannot commit viewstate; Only viewstate objects supported' # check required properties for k in ['namespace', 'owner', 'view']: getattr(viewstate, k) # assert that the viewstate_id is not a hash if viewstate.id.find(':') > -1: raise ValueError, 'Cannot commit viewstate: viewstate_id contains a colon: %s' % viewstate.id entityWrapper = en.Entity( VIEWSTATE_ENTITY_CLASS, buildStanzaName(viewstate.view, viewstate.id), namespace=viewstate.namespace, owner=viewstate.owner ) for module_name in sorted(viewstate.modules): for param_name in sorted(viewstate.modules[module_name]): entityWrapper[buildParamName(module_name, param_name)] = viewstate.modules[module_name][param_name] en.setEntity(entityWrapper) return True
def save(self, new=False, session_key=None, namespace=None, owner=None): """ Saves the notable event status. If an ID is set, then the existing status will be updated. Otherwise, a new one will be created. """ ## Get the owner and namespace if namespace is None: namespace = NotableEventSuppression.DEFAULT_NAMESPACE if owner is None: owner = NotableEventSuppression.DEFAULT_OWNER ## Try to get the session key if not provided session_key = NotableEventSuppression.__get_session_key__(session_key) ## If the ID is not set, create a new entry if new: ## Get the default entity notable_suppression = en.getEntity(NotableEventSuppression.EVENTTYPES_REST_URL, '_new', sessionKey=session_key) ## Otherwise, edit the existing entity else: ## Get the existing entity notable_suppression = en.getEntity(NotableEventSuppression.EVENTTYPES_REST_URL, self.id, namespace=namespace, owner=owner, sessionKey=session_key) ## Update the entity notable_suppression = self.__populate_entity__(notable_suppression, new) ## Save the entity en.setEntity(notable_suppression, sessionKey=session_key) return True
def handleACL(self, confInfo): try: ent = self.get() meta = ent[admin.EAI_ENTRY_ACL] # for POST acl only. if self.requestedAction in [admin.ACTION_CREATE, admin.ACTION_EDIT] and len(self.callerArgs.data) > 0: # control only update acl data, no more other fields ent.properties = dict() ent["sharing"] = meta["sharing"] ent["owner"] = meta["owner"] ent["perms.read"] = [None] ent["perms.write"] = [None] # user should not POST non acl related fields, if so, it will throw errors anyway. for k, v in self.callerArgs.data.items(): ent[k] = v en.setEntity(ent, self.getSessionKey(), uri=ent.id + "/acl") ent = self.get() confItem = confInfo[self.callerArgs.id] acl = copy.deepcopy(meta) confItem.actions = self.requestedAction confItem.setMetadata(admin.EAI_ENTRY_ACL, acl) except splunk.ResourceNotFound as ex: logger.exception("handleACL Failed - arguments = %s, exception = %s" % (self.callerArgs, ex))
def handleACL(self, confInfo): try: ent = self.get() meta = ent[admin.EAI_ENTRY_ACL] if self.requestedAction in [admin.ACTION_CREATE, admin.ACTION_EDIT] and len(self.callerArgs.data) > 0: ent.properties = dict() ent['sharing'] = meta['sharing'] ent['owner'] = meta['owner'] ent['perms.read'] = ['*'] ent['perms.write'] = ['*'] ent["owner"] = "nobody" ent["sharing"] = "global" en.setEntity(ent, self.getSessionKey(), uri=ent.id + '/acl') ent = self.get() confItem = confInfo[self.callerArgs.id] acl = copy.deepcopy(meta) confItem.actions = self.requestedAction confItem.setMetadata(admin.EAI_ENTRY_ACL, acl) except splunk.ResourceNotFound as ex: logger.exception('handleACL Failed - arguments = %s, exception = %s' % (self.callerArgs, ex))
def handleACL(self, confInfo): try: ent = self.get() meta = ent[admin.EAI_ENTRY_ACL] # for POST acl only. if self.requestedAction in [admin.ACTION_CREATE, admin.ACTION_EDIT] and len(self.callerArgs.data)>0: # control only update acl data, no more other fields ent.properties = dict() ent['sharing'] = meta['sharing'] ent['owner'] = meta['owner'] ent['perms.read'] = [None] ent['perms.write'] = [None] # user should not POST non acl related fields, if so, it will throw errors anyway. for k, v in self.callerArgs.data.items(): ent[k] = v en.setEntity(ent, self.getSessionKey(), uri=ent.id+'/acl') ent = self.get() confItem = confInfo[self.callerArgs.id] acl = copy.deepcopy(meta) confItem.actions = self.requestedAction confItem.setMetadata(admin.EAI_ENTRY_ACL, acl) except splunk.ResourceNotFound as ex: logger.exception('handleACL Failed - arguments = %s, exception = %s' % (self.callerArgs, ex))
def commit(viewstate): ''' Persists a viewstate object. ''' if not isinstance(viewstate, Viewstate): raise ValueError, 'Cannot commit viewstate; Only viewstate objects supported' # check required properties for k in ['namespace', 'owner', 'view']: getattr(viewstate, k) # assert that the viewstate_id is not a hash if viewstate.id.find(':') > -1: raise ValueError, 'Cannot commit viewstate: viewstate_id contains a colon: %s' % viewstate.id entityWrapper = en.Entity(VIEWSTATE_ENTITY_CLASS, buildStanzaName(viewstate.view, viewstate.id), namespace=viewstate.namespace, owner=viewstate.owner) for module_name in sorted(viewstate.modules): for param_name in sorted(viewstate.modules[module_name]): entityWrapper[buildParamName( module_name, param_name)] = viewstate.modules[module_name][param_name] en.setEntity(entityWrapper) return True
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 addInput(sessionKey, source, namespace, owner, sourcetype, index): mon = en.getEntity('/data/inputs/monitor/','_new', sessionKey=sessionKey) mon["name"] = source if sourcetype != None: mon["sourcetype"] = sourcetype if index != None: mon["index"] = index mon.namespace = namespace mon.owner = owner en.setEntity(mon, sessionKey=sessionKey)
def addInput(sessionKey, source, namespace, owner, sourcetype, index): mon = en.getEntity('/data/inputs/monitor/', '_new', sessionKey=sessionKey) mon["name"] = source if sourcetype != None: mon["sourcetype"] = sourcetype if index != None: mon["index"] = index mon.namespace = namespace mon.owner = owner en.setEntity(mon, sessionKey=sessionKey)
def setKeyForDefaultInput(self, file_name, session_key): entity_entry = self.getDefaultGoogleDriveInputEntity(session_key) entity_entry['service_account_key_file'] = file_name entity_entry.namespace = ServiceAccountKeysRestHandler.DEFAULT_NAMESPACE entity_entry.owner = ServiceAccountKeysRestHandler.DEFAULT_OWNER entity.setEntity(entity_entry, sessionKey=session_key) self.setAppAsConfigured(session_key)
def update(self, **params): ent = en.getEntity( self._endpoint, self.callerArgs.id, namespace=self.appName, owner="nobody", sessionKey=self.getSessionKey() ) for arg in params.keys(): if arg in self._required_args + self._optional_args: ent[arg] = params[arg] en.setEntity(ent, sessionKey=self.getSessionKey())
def create(self, name, **params): user, app = self.user_app() new = entity.Entity(self.endpoint, "_new", namespace=app, owner=user) try: new["name"] = name for arg, val in list(params.items()): new[arg] = val entity.setEntity(new, sessionKey=self.getSessionKey()) except Exception as exc: RH_Err.ctl(-1, exc, logLevel=logging.INFO)
def handleEdit(self, confInfo): """ Handles edits to the configuration options """ logger.debug("In handleEdit") # Refresh self.handleReload() name = self.callerArgs.id args = self.callerArgs if name is not None: try: conf = entity.getEntity('configs/conf-log_review', name, sessionKey=self.getSessionKey()) except ResourceNotFound: raise admin.NotFoundException("A log_review setting with the given name '%s' could not be found" % (name)) else: # Stop if no name was provided raise admin.ArgValidationException("No name provided") # Create the resulting configuration that would be persisted if the settings provided are applied for key, val in conf.items(): if key in args.data: conf[key] = args[key][0] if key == admin.EAI_ENTRY_ACL: if val.has_key('app') and val['app'] is not None and len(val['app']) > 0: conf.namespace = val['app'] if val.has_key('owner') and val['owner'] is not None and len(val['owner']) > 0: conf.owner = val['owner'] if conf.namespace is None or len(conf.namespace) == 0: conf.namespace = LogReview.DEFAULT_NAMESPACE if conf.owner is None or len(conf.owner) == 0: conf.owner = LogReview.DEFAULT_OWNER # Check the configuration try: self.checkConf(conf, name) except InvalidConfigException as e: logger.error( "The configuration for '%s' is invalid and could not be edited: %s" % ( name, str(e)) ) raise admin.ArgValidationException( str(e) ) logger.debug("Updating configuration for " + str(name)) entity.setEntity(conf, sessionKey=self.getSessionKey()) ## Reload log_review self.handleReload()
def commitChanges(app, view, uglyXML, updateMetaData, fileNameForNewView=None): removeIdsFromAllModules(uglyXML) # plan A uglyXML = uglyXML.toxml() parser = et.XMLParser(remove_blank_text=True, strip_cdata=False) etXML = et.XML(uglyXML, parser) prettyXML = et.tostring(etXML, pretty_print=True) # plan B #prettyXML = uglyXML.toprettyxml(indent=" ") prettyXML = patchXMLForReadability(prettyXML) viewEntity = en.getEntity('data/ui/views', view, namespace=app) garbagePropertiesReturnedBySplunk6Beta = [ "isDashboard", "isVisible", "label" ] for p in garbagePropertiesReturnedBySplunk6Beta: if (viewEntity.properties.get(p)): logger.warn( "Sideview Editor - garbage property detected in the getEntity response (" + p + "). We are deleting it here or else it will correctly trigger an error from splunkd when we try to post the modified entity back via setEntity" ) del (viewEntity.properties[p]) # in the create new cases, view will be "_new" if (fileNameForNewView): viewEntity.properties["name"] = fileNameForNewView viewEntity[en.EAI_DATA_KEY] = prettyXML currentUser = auth.getCurrentUser()['name'] try: en.setEntity(viewEntity) ## remnants of some 4.X logging insanity where I never got a handle on root cause. try: logger.info("view updated by Sideview Editor. view=" + str(view) + " user="******" " + str(updateMetaData)) except Exception, e: logger.error("exception trying to log view update. " + str(view) + " user="******"exception trying to update view. view=" + str(view) + " user="******" message=" + str(e)) logger.error(traceback.print_exc(e)) return e
def update(self, **params): ent = en.getEntity(self._endpoint, self.callerArgs.id, namespace=self.appName, owner='nobody', sessionKey=self.getSessionKey()) for arg in params.keys(): if arg in self._required_args + self._optional_args: ent[arg] = params[arg] en.setEntity(ent, sessionKey=self.getSessionKey())
def create(self, **params): new = en.Entity(self._endpoint, self.callerArgs.id, namespace=self.appName, owner="nobody") for arg in self._required_args: new[arg] = params[arg] for arg in self._optional_args: try: new[arg] = params[arg] except: pass en.setEntity(new, sessionKey=self.getSessionKey())
def update(self, **params): app, user = self._namespace_and_owner() ent = en.getEntity(self._endpoint, self.callerArgs.id, namespace=app, owner=user, sessionKey=self.getSessionKey()) for arg in params.keys(): if arg in self._required_args + self._optional_args: ent[arg] = params[arg] en.setEntity(ent, sessionKey=self.getSessionKey())
def set_firewall_apikey(self, apikey): """Given a splunk self.session_key sets the firewall API key in the Splunk password store""" try: # The password cannot be modified, so it must be deleted before it can be added back. self.delete_firewall_apikey() apikey = {'name': 'firewall_api_key', 'password': apikey} apikey_entity = entity.Entity(['admin', 'passwords'], "firewall_api_key", namespace=self.APPNAME, owner='nobody', contents=apikey) entity.setEntity(apikey_entity, sessionKey=self.session_key, strictCreate=False) except Exception as e: stack = traceback.format_exc() self.logger.warn(stack) self.logger.warn("entity exception") self.exit_with_error("Could not set %s firewall apikey from splunk. Error: %s" % (self.APPNAME, str(e)))
def setIndexers(cls, indexers, sessionKey): # Validate the input cls.validateIndexers(indexers) # Get the default output group in tcpout defaultOutput = cls.getDefaultOutputGroup(sessionKey) # No group is defined, make it defaultGroupSet = True if defaultOutput is None: defaultGroupSet = False # See if the default group already exists #defaultOutput = Output.search('name=tcpout:indexCluster"', count_per_req=100, sessionKey=sessionKey) try: defaultOutput = en.getEntity('admin/conf-outputs', "tcpout:indexCluster", sessionKey=sessionKey) except splunk.ResourceNotFound: defaultOutput = None if defaultOutput is not None: pass # Otherwise, make the new group else: #defaultOutput = Output(ConfigCEFApp.DEFAULT_NAMESPACE, ConfigCEFApp.DEFAULT_OWNER, "tcpout:indexCluster") defaultOutput = en.getEntity('admin/conf-outputs', '_new', sessionKey=sessionKey) defaultOutput.namespace = ConfigCEFApp.DEFAULT_NAMESPACE defaultOutput.owner = ConfigCEFApp.DEFAULT_OWNER defaultOutput['name'] = "tcpout:indexCluster" # Update and save the entry #defaultOutput.server = indexers #defaultOutput.save() defaultOutput['server'] = indexers defaultOutput.namespace = ConfigCEFApp.DEFAULT_NAMESPACE defaultOutput.owner = ConfigCEFApp.DEFAULT_OWNER en.setEntity(defaultOutput, sessionKey=sessionKey) # Set this as the default group if not defaultGroupSet: cls.setDefaultTcpOutGroup(defaultOutput.name, sessionKey) # Disable local indexing cls.disableIndexAndForward(sessionKey)
def setDefaultTcpOutGroup(cls, groupName, sessionKey): groupName = cls.parseOutputName(groupName) tcpout_entity = en.getEntity('configs/conf-outputs', "tcpout", sessionKey=sessionKey) tcpout_entity['defaultGroup'] = groupName tcpout_entity['indexAndForward'] = 0 tcpout_entity.namespace = cls.DEFAULT_NAMESPACE tcpout_entity.owner = cls.DEFAULT_OWNER en.setEntity(tcpout_entity, sessionKey=sessionKey)
def create_new_scripted_inputs(self, data): inputdata = entity.getEntity('data/inputs/script', '_new', sessionKey=self.getSessionKey()) inputdata[ "name"] = '$SPLUNK_HOME\\etc\\apps\\TA-CMX\\bin\\Server.py' \ if platform.system().lower() == 'windows' else '$SPLUNK_HOME/etc/apps/TA-CMX/bin/Server.py' inputdata["interval"] = ["0"] inputdata["disabled"] = ["false"] inputdata["passAuth"] = ["splunk-system-user"] inputdata.namespace = "TA-CMX" entity.setEntity(inputdata, sessionKey=self.getSessionKey()) index = data["INDEX"][0] if data["INDEX"] else "main" inputdata = entity.getEntity('data/inputs/script', '_new', sessionKey=self.getSessionKey()) inputdata[ "name"] = '$SPLUNK_HOME\\etc\\apps\\TA-CMX\\bin\\CMXRestAPIMAP.py' \ if platform.system().lower() == 'windows' else '$SPLUNK_HOME/etc/apps/TA-CMX/bin/CMXRestAPIMAP.py' inputdata["interval"] = ["86400"] inputdata["disabled"] = ["false"] inputdata["index"] = [index] inputdata["sourcetype"] = ["cmxmap"] inputdata["passAuth"] = ["splunk-system-user"] inputdata.namespace = "TA-CMX" entity.setEntity(inputdata, sessionKey=self.getSessionKey()) inputdata = entity.getEntity('data/inputs/script', '_new', sessionKey=self.getSessionKey()) inputdata[ "name"] = '$SPLUNK_HOME\\etc\\apps\\TA-CMX\\bin\\CMXRestAPIAnalytics.py' \ if platform.system().lower() == 'windows' else '$SPLUNK_HOME/etc/apps/TA-CMX/bin/CMXRestAPIAnalytics.py' inputdata["interval"] = ["540"] inputdata["disabled"] = ["false"] inputdata["index"] = [index] inputdata["sourcetype"] = ["cmxanalytics"] inputdata["passAuth"] = ["splunk-system-user"] inputdata.namespace = "TA-CMX" entity.setEntity(inputdata, sessionKey=self.getSessionKey()) inputdata = entity.getEntity('data/inputs/script', '_new', sessionKey=self.getSessionKey()) inputdata[ "name"] = '$SPLUNK_HOME\\etc\\apps\\TA-CMX\\bin\\CMXRestAPIActive.py' \ if platform.system().lower() == 'windows' else '$SPLUNK_HOME/etc/apps/TA-CMX/bin/CMXRestAPIActive.py' inputdata["interval"] = ["960"] inputdata["disabled"] = ["false"] inputdata["index"] = [index] inputdata["sourcetype"] = ["cmxactive"] inputdata["passAuth"] = ["splunk-system-user"] inputdata.namespace = "TA-CMX" entity.setEntity(inputdata, sessionKey=self.getSessionKey())
def create(self, **params): app, user = self._namespace_and_owner() new = en.Entity(self._endpoint, self.callerArgs.id, namespace=app, owner=user) for arg in self._required_args: new[arg] = params[arg] for arg in self._optional_args: try: new[arg] = params[arg] except: pass en.setEntity(new, sessionKey=self.getSessionKey())
def set_suppression(id, enable, session_key=None): """ Enables/disable the given suppression. Returns true if the suppression was successfully disabled. """ # Try to get the session key if not provided session_key = NotableEventSuppression.__get_session_key__(session_key) # Get the appropriate entity entity = en.getEntity(NotableEventSuppression.EVENTTYPES_REST_URL, id, namespace=NotableEventSuppression.DEFAULT_NAMESPACE, owner=NotableEventSuppression.DEFAULT_OWNER, sessionKey=session_key) # Disable/enable the suppression entity['disabled'] = NotableEventSuppression.bool_to_int(not enable) en.setEntity(entity, sessionKey=session_key) return True
def update(self, name, **params): user, app = self.user_app() try: ent = entity.getEntity(self.endpoint, name, namespace=app, owner=user, sessionKey=self.getSessionKey()) for arg, val in params.items(): ent[arg] = val entity.setEntity(ent, sessionKey=self.getSessionKey()) except Exception as exc: RestHandlerError.ctl(-1, exc, logLevel=logging.INFO)
def updateStatus(self): if self.name != None and self.namespace != None and self.owner != None: try: # get entity first, so we get the canonical context base = entity.getEntity('admin/conf-export', self.name, namespace=self.namespace, owner=self.owner, sessionKey=self.sessionKey) en = entity.Entity('admin/conf-export', self.name, self.content, self.namespace, self.owner) entity.setEntity(en, self.sessionKey, uri=base.id) except: logger.exception('Failed to update status')
def create(self, **params): new = en.Entity(self._endpoint, self.callerArgs.id, namespace=self.appName, owner='nobody') for arg in self._required_args: new[arg] = params[arg] for arg in self._optional_args: try: new[arg] = params[arg] except: pass en.setEntity(new, sessionKey=self.getSessionKey())
def controlJob(self, sid, ctl, action, wait=True, ttl=None): ''' Executes control for a given job ''' resp = JsonResponse() # SDK does not have any functionality to change ACLs, so i have # had to add these custom actions for now. # TODO - if/when SDK has support for changing ACL's, rewrite this # code to not use the Entity class. if (action == "makeWorldReadable" or action == "undoWorldReadable"): jobPath = "search/jobs/" + sid entityName = "acl" aclEntity = en.getEntity( jobPath, entityName, namespace="system", owner=splunk.auth.getCurrentUser()['name']) if (action == "makeWorldReadable"): aclEntity.properties['perms.read'] = ["*"] else: aclEntity.properties['perms.read'] = [] try: result = en.setEntity(aclEntity, uri=jobPath + "/acl") except Exception, e: logger.exception(e) resp.addError( _("Splunk could not update permissions for this job")) return self.render_json(resp)
def controlJob(self, sid, ctl, action, ttl=None): """ Executes control for a given job """ resp = JsonResponse() # SDK does not have any functionality to change ACLs, so i have # had to add these custom actions for now. # TODO - if/when SDK has support for changing ACL's, rewrite this # code to not use the Entity class. if action == "makeWorldReadable" or action == "undoWorldReadable": jobPath = "search/jobs/" + sid entityName = "acl" aclEntity = en.getEntity( jobPath, entityName, namespace="system", owner=splunk.auth.getCurrentUser()["name"] ) if action == "makeWorldReadable": aclEntity.properties["perms.read"] = ["*"] else: aclEntity.properties["perms.read"] = [] try: result = en.setEntity(aclEntity, uri=jobPath + "/acl") except Exception, e: logger.exception(e) resp.addError(_("Splunk could not update permissions for this job")) return self.render_json(resp)
def handleCreate(self, confInfo): name = self.callerArgs.id new = en.Entity(ENDPOINT, name, namespace=self.appName, owner=self.userName) for arg in required_args: new[arg] = self.callerArgs[arg] for arg in optional_args: try: new[arg] = self.callerArgs[arg] except: pass en.setEntity(new, sessionKey = self.getSessionKey())
def update_state(self, entity, state): """ updates the state but this actually writes the entire content of the entity """ self._state[entity] = state contents = { 'STATE': json.dumps(self._state) } entity_path = ["configs", "conf-app-migration"] entity = en.Entity(entity_path, self.migration_id, contents=contents, namespace=NAMESPACE, owner=OWNER) # to bypass a funny check in getFullPath entity['eai:acl'] = {} en.setEntity(entity, sessionKey=self.session_key)
def handleACL(self, confInfo): ent = self.get(self.callerArgs.id) meta = ent[admin.EAI_ENTRY_ACL] if self.requestedAction != admin.ACTION_LIST: if ( self.requestedAction in [admin.ACTION_CREATE, admin.ACTION_EDIT] and len(self.callerArgs.data) > 0 ): ent.properties = dict() ent["sharing"] = meta["sharing"] ent["owner"] = meta["owner"] hasWritePerms = "perms.write" in self.callerArgs hasReadPerms = "perms.read" in self.callerArgs isPermsPost = hasWritePerms or hasReadPerms if ( "sharing" in self.callerArgs and "user" in self.callerArgs["sharing"] and isPermsPost ): msg = "ACL cannot be set for user-level sharing" stulog.logger.error(msg) raise Exception(msg) perms = meta.get("perms", {}) # for some reason, this can still return None if perms is None: perms = {} ent["perms.read"] = perms.get("read", []) ent["perms.write"] = perms.get("write", []) for k, v in list(self.callerArgs.data.items()): ent[k] = v entity.setEntity(ent, self.getSessionKey(), uri=ent.id + "/acl") confItem = confInfo[self.callerArgs.id] acl = copy.deepcopy(meta) confItem.actions = self.requestedAction confItem.setMetadata(admin.EAI_ENTRY_ACL, acl) self.handleList(confInfo)
def create(self, **params): app, user = self._namespace_and_owner() new = en.Entity(self._endpoint, self.callerArgs.id, namespace=app, owner=user) for arg in self._required_args: new[arg] = params[arg] for arg in self._optional_args: try: new[arg] = params[arg] except: pass en.setEntity(new, sessionKey=self.getSessionKey(), strictCreate=True)
def handleACL(self, confInfo): try: ent = self.get() meta = ent[admin.EAI_ENTRY_ACL] # for POST acl only. if self.requestedAction in [admin.ACTION_CREATE, admin.ACTION_EDIT] and len(self.callerArgs.data)>0: # control only update acl data, no more other fields ent.properties = dict() ent['sharing'] = meta['sharing'] ent['owner'] = meta['owner'] # SPL-69050 and SPL-68306 ent['perms.read'] = [None] ent['perms.write'] = [None] ''' if meta.has_key('perms'): perms = meta['perms'] # SPL-67185 if perms and isinstance(perms, dict): if perms.has_key('write'): ent['perms.write'] = perms['write'] if perms.has_key('read'): ent['perms.read'] = perms['read'] ''' # user should not POST non acl related fields, if so, it will throw errors anyway. for k, v in self.callerArgs.data.items(): ent[k] = v en.setEntity(ent, self.getSessionKey(), uri=ent.id+'/acl') ent = self.get() confItem = confInfo[self.callerArgs.id] acl = copy.deepcopy(meta) confItem.actions = self.requestedAction confItem.setMetadata(admin.EAI_ENTRY_ACL, acl) except splunk.ResourceNotFound as ex: logger.exception('handleACL Failed - arguments = %s, exception = %s' % (self.callerArgs, ex))
def handleCreate(self, confInfo): name = self.callerArgs.id new = en.Entity(ENDPOINT, name, namespace=self.appName, owner=self.userName) for arg in required_args: new[arg] = self.callerArgs[arg] for arg in optional_args: try: new[arg] = self.callerArgs[arg] except: pass en.setEntity(new, sessionKey=self.getSessionKey())
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)
def set_status(job_list, status, token): if job_list and (len(job_list) < 1 or not isinstance(job_list, list)): return try: status = int(status) except: logger.error('set_status will only accept status integers') sys.exit() if status < 0 or status > 2: logger.error('set_status will only accept status integers between 0 and 2') for job in job_list: en = entity.getEntity(ENTITY_PATH, job, namespace=APP_NAME, owner='nobody', sessionKey=token) en['status'] = status entity.setEntity(en, sessionKey=token)
def handleCreate(self, confInfo): name = self.callerArgs.id logger.info('DEBUG %s' % name) new = en.Entity(ENDPOINT, name, namespace=self.appName, owner=self.userName) for arg in required_args: new[arg] = self.callerArgs[arg] for arg in optional_args: if arg in ['disabled']: next try: new[arg] = self.callerArgs[arg] except: pass en.setEntity(new, sessionKey = self.getSessionKey())
def update(self, **params): app, user = self._namespace_and_owner() ent = en.getEntity( self._endpoint, self.callerArgs.id, namespace=app, owner=user, sessionKey=self.getSessionKey() ) for arg in self._optional_args: if arg in ["disabled"]: continue try: ent[arg] = params[arg] except: pass for arg in self._required_args: if arg in ["disabled"]: continue ent[arg] = params[arg] en.setEntity(ent, sessionKey=self.getSessionKey())
def handleCreate(self, confInfo): name = self.callerArgs.id new = en.Entity(ENDPOINT, name, namespace=self.appName, owner=self.userName) for arg in required_args: new[arg] = self.callerArgs[arg] for arg in self.callerArgs: if arg in ['disabled']: continue try: new[arg] = self.callerArgs[arg] except: pass en.setEntity(new, sessionKey=self.getSessionKey()) self.callerArgs.data = {"owner": "nobody", "sharing": "global"} self.handleACL(confInfo)
def update(self, **params): app, user = self._namespace_and_owner() ent = en.getEntity(self._endpoint, self.callerArgs.id, namespace=app, owner=user, sessionKey=self.getSessionKey()) for arg in params.keys(): if arg in self._required_args + self._optional_args: ent[arg] = params[arg] #check which args are allowed to be posted allowedArgs = [] if 'eai:attributes' in ent and 'requiredFields' in ent['eai:attributes'] and 'optionalFields' in ent['eai:attributes']: allowedArgs = ent['eai:attributes']['requiredFields'] + ent['eai:attributes']['optionalFields'] #filter out args that aren't allowed for arg in ent.keys(): if arg not in allowedArgs: del ent.properties[arg] en.setEntity(ent, sessionKey=self.getSessionKey())
def handleEdit(self, confInfo): # INIT Input fields to empty string instead of null if self.callerArgs.data['cisco_ips_sensor_ip'][0] == None: sensor_ip = '' else: sensor_ip = self.callerArgs.data['cisco_ips_sensor_ip'][0] if self.callerArgs.data['cisco_ips_sensor_username'][0] == None: sensor_username = '' else: sensor_username = self.callerArgs.data['cisco_ips_sensor_username'][0] if self.callerArgs.data['cisco_ips_sensor_password'][0] == None: sensor_password = '' else: sensor_password = self.callerArgs.data['cisco_ips_sensor_password'][0] if self.callerArgs.data['cisco_ips_sensor_interval'][0] == None: sensor_interval = '' else: sensor_interval = self.callerArgs.data['cisco_ips_sensor_interval'][0] # INPUT VALIDATION # Hostname or IP Address: make sure it is a valid IPv4 or IPv6 address or a hostname validHostnameRegex = re.compile("^(([a-zA-Z0-9\-\_]+)\.)*([A-Za-z0-9\-\_]+)$") validHostname = re.search(validHostnameRegex, sensor_ip) if not (is_valid_ip(sensor_ip) or validHostname): raise admin.ArgValidationException, "CISCO_IPS_SETUP-INPUT_ERROR-xxx: Invalid Hostname or IP address specified for IPS device. Must be valid IPv4 or IPv6 or hostname." # Username: make sure it is a string with no spaces containsSpaceRegex = re.compile("\s+") invalidUsername = re.search(containsSpaceRegex, sensor_username) if invalidUsername or len(sensor_username) < 1: raise admin.ArgValidationException, "CISCO_IPS_SETUP-INPUT_ERROR-xxx: Invalid username specified for IPS device. Must be a string without spaces." # Password: make sure it is a string with no spaces invalidPassword = re.search(containsSpaceRegex, sensor_password) if invalidPassword or len(sensor_password) < 1: raise admin.ArgValidationException, "CISCO_IPS_SETUP-INPUT_ERROR-xxx: Invalid password specified for IPS device. Must be a string without spaces." # Polling Interval: make sure it is a number between 0 and 3600 if not (sensor_interval.isdigit() and int(sensor_interval) >= 0 and int(sensor_interval) <= 3600): raise admin.ArgValidationException, "CISCO_IPS_SETUP-INPUT_ERROR-xxx: Invalid Poling Interval entered. Must be an number between 0 and 3600 seconds." # Get session key so we can talk to REST API sessionKey = self.getSessionKey() # Check to make sure Cisco IPS Sensor script does not already exist in inputs.conf via REST API try: entities = entity.getEntities('data/inputs/script', search="\" " + sensor_ip + " \"", sessionKey=sessionKey) except: raise admin.ArgValidationException, "Failed to search for existing Cisco IPS Sensor script in inputs.conf!" if len(entities.items()) != 0: raise admin.ArgValidationException, "Cisco IPS Sensor script for " + sensor_ip + " already exists in inputs.conf. Remove it, restart Splunk, and try again." # Check to make sure Cisco IPS Sensor cedential does not already exist in app.conf via REST API try: entities = entity.getEntities('storage/passwords', search="realm=\"" + sensor_ip + "\"", sessionKey=sessionKey) except: raise admin.ArgValidationException, "Failed to search for existing Cisco IPS Sensor credential in app.conf!" if len(entities.items()) != 0: raise admin.ArgValidationException, "Cisco IPS Sensor credential for " + sensor_ip + " already exists in app.conf. Remove it, restart Splunk, and try again." # Create Scripted Input in inputs.conf via REST API try: script = entity.getEntity('/data/inputs/script/','_new', sessionKey=sessionKey) script["interval"] = '1' script["name"] = os.path.join('$SPLUNK_HOME', 'etc', 'apps', 'Splunk_CiscoIPS','bin','get_ips_feed.py') + ' ' + sensor_ip + ' ' + sensor_interval script["passAuth"] = 'splunk-system-user' script["source"] = 'SDEE' script["sourcetype"] = 'cisco_ips_syslog' script.namespace = APPNAME entity.setEntity(script, sessionKey=sessionKey) except: raise admin.ArgValidationException, "Failed to create scripted input!" # Create Encrypted Credential in app.conf via REST API try: creds = entity.getEntity('/storage/passwords/','_new', sessionKey=sessionKey) creds["name"] = sensor_username creds["password"] = sensor_password creds["realm"] = sensor_ip creds.namespace = APPNAME entity.setEntity(creds, sessionKey=sessionKey) except: raise admin.ArgValidationException, "Failed to create credential!"