UNPKG

splunk-sdk

Version:

SDK for usage with the Splunk REST API

1,144 lines (1,065 loc) 242 kB
/*!*/ // Copyright 2014 Splunk, Inc. // // Licensed under the Apache License, Version 2.0 (the "License"): you may // not use this file except in compliance with the License. You may obtain // a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the // License for the specific language governing permissions and limitations // under the License. (function() { "use strict"; var Context = require('./context'); var Http = require('./http'); var Paths = require('./paths').Paths; var Class = require('./jquery.class').Class; var utils = require('./utils'); var root = exports || this; var Service = null; /** * Contains functionality common to Splunk Enterprise and Splunk Storm. * * This class is an implementation detail and is therefore SDK-private. * * @class splunkjs.private.BaseService * @extends splunkjs.Context */ var BaseService = Context.extend({ init: function() { this._super.apply(this, arguments); } }); /** * Provides a root access point to Splunk functionality with typed access to * Splunk resources such as searches, indexes, inputs, and more. Provides * methods to authenticate and create specialized instances of the service. * * @class splunkjs.Service * @extends splunkjs.private.BaseService */ module.exports = root = Service = BaseService.extend({ /** * Constructor for `splunkjs.Service`. * * @constructor * @param {splunkjs.Http} http An instance of a `splunkjs.Http` class. * @param {Object} params A dictionary of optional parameters: * - `scheme` (_string_): The scheme ("http" or "https") for accessing Splunk. * - `host` (_string_): The host name (the default is "localhost"). * - `port` (_integer_): The port number (the default is 8089). * - `username` (_string_): The Splunk account username, which is used to authenticate the Splunk instance. * - `password` (_string_): The password, which is used to authenticate the Splunk instance. * - `owner` (_string_): The owner (username) component of the namespace. * - `app` (_string_): The app component of the namespace. * - `sessionKey` (_string_): The current session token. * - `autologin` (_boolean_): `true` to automatically try to log in again if the session terminates, `false` if not (`true` by default). * - `version` (_string_): The version string for Splunk, for example "4.3.2" (the default is "5.0"). * @return {splunkjs.Service} A new `splunkjs.Service` instance. * * @method splunkjs.Service */ init: function() { this._super.apply(this, arguments); // We perform the bindings so that every function works properly this.specialize = utils.bind(this, this.specialize); this.apps = utils.bind(this, this.apps); this.configurations = utils.bind(this, this.configurations); this.indexes = utils.bind(this, this.indexes); this.savedSearches = utils.bind(this, this.savedSearches); this.jobs = utils.bind(this, this.jobs); this.users = utils.bind(this, this.users); this.currentUser = utils.bind(this, this.currentUser); this.views = utils.bind(this, this.views); this.firedAlertGroups = utils.bind(this, this.firedAlertGroups); this.dataModels = utils.bind(this, this.dataModels); }, /** * Creates a specialized version of the current `Service` instance for * a specific namespace context. * * @example * * let svc = ...; * let newService = svc.specialize("myuser", "unix"); * * @param {String} owner The Splunk username, such as "admin". A value of "nobody" means no specific user. The "-" wildcard means all users. * @param {String} app The app context for this resource (such as "search"). The "-" wildcard means all apps. * @return {splunkjs.Service} The specialized `Service` instance. * * @method splunkjs.Service */ specialize: function(owner, app) { return new Service(this.http, { scheme: this.scheme, host: this.host, port: this.port, username: this.username, password: this.password, owner: owner, app: app, sessionKey: this.sessionKey, version: this.version }); }, /** * Gets the `Applications` collection, which allows you to * list installed apps and retrieve information about them. * * @example * * // List installed apps * let apps = svc.apps(); * let res = await apps.fetch(); * console.log(res.list()); * * @return {splunkjs.Service.Collection} The `Applications` collection. * * @endpoint apps/local * @method splunkjs.Service * @see splunkjs.Service.Applications */ apps: function() { return new root.Applications(this); }, /** * Gets the `Configurations` collection, which lets you * create, list, and retrieve configuration (.conf) files. * * @example * * // List all properties in the 'props.conf' file * let files = svc.configurations(); * let propsFile = await files.item("props"); * let props = await propsFile.fetch(); * console.log(props.properties()); * * @param {Object} namespace Namespace information: * - `owner` (_string_): The Splunk username, such as "admin". A value of "nobody" means no specific user. The "-" wildcard means all users. * - `app` (_string_): The app context for this resource (such as "search"). The "-" wildcard means all apps. * - `sharing` (_string_): A mode that indicates how the resource is shared. The sharing mode can be "user", "app", "global", or "system". * @return {splunkjs.Service.Configurations} The `Configurations` collection. * * @endpoint configs * @method splunkjs.Service * @see splunkjs.Service.Configurations */ configurations: function(namespace) { return new root.Configurations(this, namespace); }, /** * Gets the `Indexes` collection, which lets you create, * list, and update indexes. * * @example * * // Check if we have an _internal index * let indexes = svc.indexes(); * let res = await indexes.fetch(); * let index = res.item("_internal"); * console.log("Was index found: " + !!index); * // `index` is an Index object. * * @param {Object} namespace Namespace information: * - `owner` (_string_): The Splunk username, such as "admin". A value of "nobody" means no specific user. The "-" wildcard means all users. * - `app` (_string_): The app context for this resource (such as "search"). The "-" wildcard means all apps. * - `sharing` (_string_): A mode that indicates how the resource is shared. The sharing mode can be "user", "app", "global", or "system". * @return {splunkjs.Service.Indexes} The `Indexes` collection. * * @endpoint data/indexes * @method splunkjs.Service * @see splunkjs.Service.Indexes */ indexes: function(namespace) { return new root.Indexes(this, namespace); }, /** * Gets the `SavedSearches` collection, which lets you * create, list, and update saved searches. * * @example * * // List all # of saved searches * let savedSearches = svc.savedSearches(); * let res = await savedSearches.fetch(); * console.log("# Of Saved Searches: " + res.list().length); * * @param {Object} namespace Namespace information: * - `owner` (_string_): The Splunk username, such as "admin". A value of "nobody" means no specific user. The "-" wildcard means all users. * - `app` (_string_): The app context for this resource (such as "search"). The "-" wildcard means all apps. * - `sharing` (_string_): A mode that indicates how the resource is shared. The sharing mode can be "user", "app", "global", or "system". * @return {splunkjs.Service.SavedSearches} The `SavedSearches` collection. * * @endpoint saved/searches * @method splunkjs.Service * @see splunkjs.Service.SavedSearches */ savedSearches: function(namespace) { return new root.SavedSearches(this, namespace); }, /** * Gets the `StoragePasswords` collection, which lets you * create, list, and update storage passwords. * * @example * * // List all # of storage passwords * let storagePasswords = svc.storagePasswords(); * let res = await storagePasswords.fetch(); * console.log("# of Storage Passwords: " + res.list().length); * * @param {Object} namespace Namespace information: * - `owner` (_string_): The Splunk username, such as "admin". A value of "nobody" means no specific user. The "-" wildcard means all users. * - `app` (_string_): The app context for this resource (such as "search"). The "-" wildcard means all apps. * - `sharing` (_string_): A mode that indicates how the resource is shared. The sharing mode can be "user", "app", "global", or "system". * @return {splunkjs.Service.StoragePasswords} The `StoragePasswords` collection. * * @endpoint storage/passwords * @method splunkjs.Service * @see splunkjs.Service.StoragePasswords */ storagePasswords: function(namespace) { return new root.StoragePasswords(this, namespace); }, /** * Gets the `FiredAlertGroupCollection` collection, which lets you * list alert groups. * * @example * * // List all # of fired alert groups * let firedAlertGroups = svc.firedAlertGroups(); * let res = await firedAlertGroups.fetch(); * console.log("# of alert groups: " + res.list().length); * * @param {Object} namespace Namespace information: * - `owner` (_string_): The Splunk username, such as "admin". A value of "nobody" means no specific user. The "-" wildcard means all users. * - `app` (_string_): The app context for this resource (such as "search"). The "-" wildcard means all apps. * - `sharing` (_string_): A mode that indicates how the resource is shared. The sharing mode can be "user", "app", "global", or "system". * @return {splunkjs.Service.FiredAlertGroupCollection} The `FiredAlertGroupCollection` collection. * * @endpoint saved/searches * @method splunkjs.Service * @see splunkjs.Service.FiredAlertGroupCollection */ firedAlertGroups: function(namespace) { return new root.FiredAlertGroupCollection(this, namespace); }, /** * Gets the `Jobs` collection, which lets you create, list, * and retrieve search jobs. * * @example * * // List all job IDs * let jobs = svc.jobs(); * let res = await jobs.fetch(); * let list = res.list(); * for(let i = 0; i < list.length; i++) { * console.log("Job " + (i+1) + ": " + list[i].sid); * } * * @param {Object} namespace Namespace information: * - `owner` (_string_): The Splunk username, such as "admin". A value of "nobody" means no specific user. The "-" wildcard means all users. * - `app` (_string_): The app context for this resource (such as "search"). The "-" wildcard means all apps. * - `sharing` (_string_): A mode that indicates how the resource is shared. The sharing mode can be "user", "app", "global", or "system". * @return {splunkjs.Service.Jobs} The `Jobs` collection. * * @endpoint search/jobs * @method splunkjs.Service * @see splunkjs.Service.Jobs */ jobs: function (namespace) { return new root.Jobs(this, namespace); }, /** * Gets the `DataModels` collection, which lets you create, list, * and retrieve data models. * * @endpoint datamodel/model * @method splunkjs.Service * @see splunkjs.Service.DataModels */ dataModels: function(namespace) { return new root.DataModels(this, namespace); }, /** * Gets the `Users` collection, which lets you create, * list, and retrieve users. * * @example * * // List all usernames * let users = svc.users(); * let res = await users.fetch(); * let list = res.list(); * for(let i = 0; i < list.length; i++) { * console.log("User " + (i+1) + ": " + list[i].properties().name); * } * * @return {splunkjs.Service.Users} The `Users` collection. * * @endpoint authorization/users * @method splunkjs.Service * @see splunkjs.Service.Users */ users: function() { return new root.Users(this); }, /** * Gets the `Views` collection, which lets you create, * list, and retrieve views (custom UIs built in Splunk's app framework). * * @example * * // List all views * let views = svc.views(); * let res = await views.fetch(); * let list = res.list(); * for(let i = 0; i < list.length; i++) { * console.log("View " + (i+1) + ": " + list[i].properties().name); * } * * @param {Object} namespace Namespace information: * - `owner` (_string_): The Splunk username, such as "admin". A value of "nobody" means no specific user. The "-" wildcard means all users. * - `app` (_string_): The app context for this resource (such as "search"). The "-" wildcard means all apps. * - `sharing` (_string_): A mode that indicates how the resource is shared. The sharing mode can be "user", "app", "global", or "system". * @return {splunkjs.Service.Views} The `Views` collection. * * @endpoint data/ui/views * @method splunkjs.Service * @see splunkjs.Service.Views */ views: function(namespace) { return new root.Views(this, namespace); }, /** * Creates a search job with a given search query and optional parameters, including `exec_mode` to specify the type of search: * * - Use `exec_mode=normal` to return a search job ID immediately (default). * Poll for completion to find out when you can retrieve search results. * * - Use `exec_mode=blocking` to return the search job ID when the search has finished. * * To run a oneshot search, which does not create a job but rather returns the search results, use `Service.oneshotSearch`. * * @example * * let newJob = await service.search("search ERROR", {id: "myjob_123"}); * console.log("CREATED: ", newJob.sid); * * @param {String} query The search query. * @param {Object} params A dictionary of properties for the job. For a list of available parameters, see <a href=" http://dev.splunk.com/view/SP-CAAAEFA#searchjobparams" target="_blank">Search job parameters</a> on Splunk Developer Portal. * @param {Object} namespace Namespace information: * - `owner` (_string_): The Splunk username, such as "admin". A value of "nobody" means no specific user. The "-" wildcard means all users. * - `app` (_string_): The app context for this resource (such as "search"). The "-" wildcard means all apps. * - `sharing` (_string_): A mode that indicates how the resource is shared. The sharing mode can be "user", "app", "global", or "system". * @param {Number} response_timeout A timeout period for aborting a request in milisecs (0 means no timeout). * * @endpoint search/jobs * @method splunkjs.Service */ search: function(query, params,namespace, response_timeout) { if (!response_timeout && utils.isNumber(namespace)) { response_timeout = namespace; namespace = null; } let jobs = new root.Jobs(this, namespace); return jobs.search(query, params,response_timeout); }, /** * A convenience method to get a `Job` by its sid. * * @param {String} sid The search ID for a search job. * @param {Object} namespace Namespace information: * - `owner` (_string_): The Splunk username, such as "admin". A value of "nobody" means no specific user. The "-" wildcard means all users. * - `app` (_string_): The app context for this resource (such as "search"). The "-" wildcard means all apps. * - `sharing` (_string_): A mode that indicates how the resource is shared. The sharing mode can be "user", "app", "global", or "system". * @param {Number} response_timeout A timeout period for aborting a request in milisecs (0 means no timeout). * * @endpoint search/jobs * @method splunkjs.Service */ getJob: function(sid, namespace,response_timeout) { if (!response_timeout && utils.isNumber(response_timeout)) { response_timeout = namespace; namespace = null; } let job = new root.Job(this, sid, namespace); return job.fetch({}, response_timeout); }, /** * Creates a oneshot search from a given search query and optional parameters. * * @example * * let results = await service.oneshotSearch("search ERROR", {id: "myjob_123"}); * console.log("RESULT FIELDS: ", results.fields); * * @param {String} query The search query. * @param {Object} params A dictionary of properties for the search: * - `output_mode` (_string_): Specifies the output format of the results (XML, JSON, or CSV). * - `earliest_time` (_string_): Specifies the earliest time in the time range to search. The time string can be a UTC time (with fractional seconds), a relative time specifier (to now), or a formatted time string. * - `latest_time` (_string_): Specifies the latest time in the time range to search. The time string can be a UTC time (with fractional seconds), a relative time specifier (to now), or a formatted time string. * - `rf` (_string_): Specifies one or more fields to add to the search. * @param {Object} namespace Namespace information: * - `owner` (_string_): The Splunk username, such as "admin". A value of "nobody" means no specific user. The "-" wildcard means all users. * - `app` (_string_): The app context for this resource (such as "search"). The "-" wildcard means all apps. * - `sharing` (_string_): A mode that indicates how the resource is shared. The sharing mode can be "user", "app", "global", or "system". * @param {Number} response_timeout A timeout period for aborting a request in milisecs (0 means no timeout). * * @endpoint search/jobs * @method splunkjs.Service */ oneshotSearch: function(query, params, namespace,response_timeout) { if (!response_timeout && utils.isNumber(response_timeout)) { response_timeout = namespace; namespace = null; } let jobs = new root.Jobs(this, namespace); return jobs.oneshotSearch(query, params, response_timeout); }, /** * Gets the user that is currently logged in. * * @example * * let user = await service.currentUser(); * console.log("Real name: ", user.properties().realname); * * @param {Number} response_timeout A timeout period for aborting a request in milisecs (0 means no timeout). * @return {splunkjs.Service.currentUser} The `User`. * * @endpoint authorization/current-context * @method splunkjs.Service */ currentUser: function(response_timeout) { var that = this; let req = this.get(Paths.currentUser, {}, response_timeout).then((response)=>{ let username = response.data.entry[0].content.username; let user = new root.User(that, username); return user.fetch({}, response_timeout) }); return req; }, /** * Gets configuration information about the server. * * @example * * let info = await service.serverInfo(); * console.log("Splunk Version: ", info.properties().version); * * @param {Number} response_timeout A timeout period for aborting a request in milisecs (0 means no timeout). * * @endpoint server/info * @method splunkjs.Service */ serverInfo: function(response_timeout) { let serverInfo = new root.ServerInfo(this); return serverInfo.fetch({}, response_timeout); }, /** * Parses a search query. * * @example * * let parse = await service.parse("search index=_internal | head 1"); * console.log("Commands: ", parse.commands); * * @param {String} query The search query to parse. * @param {Object} params An object of options for the parser: * - `enable_lookups` (_boolean_): If `true`, performs reverse lookups to expand the search expression. * - `output_mode` (_string_): The output format (XML or JSON). * - `parse_only` (_boolean_): If `true`, disables the expansion of search due to evaluation of subsearches, time term expansion, lookups, tags, eventtypes, and sourcetype alias. * - `reload_macros` (_boolean_): If `true`, reloads macro definitions from macros.conf. * @param {Number} response_timeout A timeout period for aborting a request in milisecs (0 means no timeout). * * @endpoint search/parser * @method splunkjs.Service */ parse: function(query, params,response_timeout) { if (!response_timeout && utils.isNumber(params)) { response_timeout = params; params = {}; } params = params || {}; params.q = query; // Pre-9.0 uses GET and v1 endpoint if (this.disableV2SearchApi()) { return this.get(Paths.parser, params, response_timeout).then((response) => { return response.data; }); } // Post-9.0 uses POST and v2 endpoint return this.post(Paths.parserV2, params, response_timeout).then((response) => { return response.data; }); }, /** * Provides auto-complete suggestions for search queries. * * @example * * let options = await service.typeahead("index=", 10); * console.log("Autocompletion options: ", options); * * @param {String} prefix The query fragment to autocomplete. * @param {Number} count The number of options to return (optional). * @param {Number} response_timeout A timeout period for aborting a request in milisecs (0 means no timeout). * * @endpoint search/typeahead * @method splunkjs.Service */ typeahead: function(prefix, count, response_timeout) { let params = { count: count || 10, prefix: prefix }; return this.get(Paths.typeahead, params,response_timeout).then((response) => { let results = (response.data || {}).results; return (results || []); }); }, /** * Logs an event to Splunk. * * @example * * let result = await service.log("A new event", {index: "_internal", sourcetype: "mysourcetype"}); * console.log("Submitted event: ", result); * * @param {String|Object} event The text for this event, or a JSON object. * @param {Object} params A dictionary of parameters for indexing: * - `index` (_string_): The index to send events from this input to. * - `host` (_string_): The value to populate in the Host field for events from this data input. * - `host_regex` (_string_): A regular expression used to extract the host value from each event. * - `source` (_string_): The value to populate in the Source field for events from this data input. * - `sourcetype` (_string_): The value to populate in the Sourcetype field for events from this data input. * @param {Number} response_timeout A timeout period for aborting a request in milisecs (0 means no timeout). * * @endpoint receivers/simple * @method splunkjs.Service */ log: function(event, params,response_timeout) { if (!response_timeout && utils.isNumber(params)) { response_timeout = params; params = {}; } params = params || {}; // If the event is a JSON object, convert it to a string. if (utils.isObject(event)) { event = JSON.stringify(event); } let path = this.paths.submitEvent; let method = "POST"; let headers = {"Content-Type": "text/plain"}; let body = event; let get = params; let post = {}; let req = this.request( path, method, get, post, body, headers, response_timeout ).then((response) => { return response.data; }); return req; } }); /** * Provides a base definition for a Splunk endpoint, which is a combination of * a specific service and path. Provides convenience methods for GET, POST, and * DELETE operations used in splunkjs, automatically preparing the path correctly * and allowing for relative calls. * * @class splunkjs.Service.Endpoint */ root.Endpoint = Class.extend({ /** * Constructor for `splunkjs.Service.Endpoint`. * * @constructor * @param {splunkjs.Service} service A `Service` instance. * @param {String} qualifiedPath A fully-qualified relative endpoint path (for example, "/services/search/jobs"). * @return {splunkjs.Service.Endpoint} A new `splunkjs.Service.Endpoint` instance. * * @method splunkjs.Service.Endpoint */ init: function(service, qualifiedPath) { if (!service) { throw new Error("Passed in a null Service."); } if (!qualifiedPath) { throw new Error("Passed in an empty path."); } this.service = service; this.qualifiedPath = qualifiedPath; // We perform the bindings so that every function works properly this.get = utils.bind(this, this.get); this.post = utils.bind(this, this.post); this.del = utils.bind(this, this.del); }, /** * Create the URL for the get and post methods * This is to allow v1 fallback if the service was instantiated with v2+ and a relpath v1 was provided * * @example * // Parameters * v2 example: * qualifiedPath = "/servicesNS/admin/foo/search/v2/jobs/id5_1649796951725" * qualifiedPath = "/services/search/v2/jobs/id5_1649796951725" * relpath = "search/v2/jobs/id5_1649796951725/events" * relpath = "events" * * // Step 1: * Specifically for splunkjs.Service.Job method, the service endpoint may be provided * Retrieve the service prefix and suffix * servicesNS: * - servicePrefix = "/servicesNS/admin/foo" * - serviceSuffix = "foo/v2/jobs/id5_1649796951725" * services: * - servicePrefix = "/services" * - serviceSuffix = "search/v2/jobs/id5_1649796951725" * * // Step 2: * Retrieve Service API version * If version can't be detected, default to 1 (v1) * qualifiedPathVersion = 2 * * // Step 3: * Retrieve relpath version * If version can't be detected, default to 1 (v1) * relpath = "search/v2/jobs/id5_1649796951725/events" * => relPathVersion = 2 * * Check if relpath is a one segment relative path, if so, set to -1 * relpath = "events" * => relPathVersion = -1 * * // Step 4: * Create the URL based on set criteria * url = "/servicesNS/admin/foo/search/v2/jobs/id5_1649796951725/events" * url = "/services/search/v2/jobs/id5_1649796951725/events" * * @param {String} qualifiedPath A fully-qualified relative endpoint path (for example, "/services/search/jobs"). * @param {String} relpath A relative path to append to the endpoint path. * * @method splunkjs.Service.Endpoint */ createUrl: function (qualifiedPath, relpath) { var url = qualifiedPath, servicePrefix = qualifiedPath.replace(/(\/services|\/servicesNS\/[^/]+\/[^/]+)\/(.*)/, "$1"), serviceSuffix = qualifiedPath.replace(/(\/services|\/servicesNS\/[^/]+\/[^/]+)\/(.*)/, "$2"), qualifiedPathVersionMatch = qualifiedPath.match(/\/(?:servicesNS\/[^/]+\/[^/]+|services)\/[^/]+\/v(\d+)\//), qualifiedPathVersionMatch = qualifiedPathVersionMatch ? qualifiedPathVersionMatch.length : 0, qualifiedPathVersion = qualifiedPathVersionMatch || 1, relPathVersionMatch = relpath.match(/^[^/]+\/v(\d+)\//), relPathVersionMatch = relPathVersionMatch ? relPathVersionMatch.length : 0, relPathVersion = relPathVersionMatch || 1; if (relpath.indexOf('/') == -1) { relPathVersion = -1; } /** * Use service v1 and relpath v1 endpoints * Use service v2+ and relpath v1 endpoints * Use service v2+ and relpath v2+ endpoints */ if (relPathVersion >= 1) { url = servicePrefix + "/" + relpath; /** * Use service v1 and one segment relative path * Use service v2+ and one segment relative path */ } else if (qualifiedPathVersion >= 1 && relPathVersion == -1) { url = qualifiedPath + "/" + relpath; /** * Catchall: use as instantiated by the service. */ } else { url = qualifiedPath + "/" + relpath; } return url; }, /** * Performs a relative GET request on an endpoint's path, * combined with the parameters and a relative path if specified. * * @example * * // Will make a request to {service.prefix}/search/jobs/123456/results?offset=1 * let endpoint = new splunkjs.Service.Endpoint(service, "search/jobs/12345"); * let res = await endpoint.get("results", {offset: 1}); * console.log("DONE"); * * @param {String} relpath A relative path to append to the endpoint path. * @param {Object} params A dictionary of entity-specific parameters to add to the query string. * @param {Number} response_timeout A timeout period for aborting a request in milisecs (0 means no timeout). * * @method splunkjs.Service.Endpoint */ get: function(relpath, params, response_timeout, isAsync) { let url = this.createUrl(this.qualifiedPath, relpath); return this.service.get( url, params, response_timeout, isAsync ); }, /** * Performs a relative POST request on an endpoint's path, * combined with the parameters and a relative path if specified. * * @example * * // Will make a request to {service.prefix}/search/jobs/123456/control * let endpoint = new splunkjs.Service.Endpoint(service, "search/jobs/12345"); * let res = await endpoint.post("control", {action: "cancel"}); * console.log("CANCELLED"); * * @param {String} relpath A relative path to append to the endpoint path. * @param {Object} params A dictionary of entity-specific parameters to add to the body. * @param {Number} response_timeout A timeout period for aborting a request in milisecs (0 means no timeout). * * @method splunkjs.Service.Endpoint */ post: function(relpath, params, response_timeout) { let url = this.createUrl(this.qualifiedPath, relpath); return this.service.post( url, params, response_timeout ); }, /** * Performs a relative DELETE request on an endpoint's path, * combined with the parameters and a relative path if specified. * * @example * * // Will make a request to {service.prefix}/search/jobs/123456 * let endpoint = new splunkjs.Service.Endpoint(service, "search/jobs/12345"); * let res = await endpoint.delete("", {}); * console.log("DELETED"); * * @param {String} relpath A relative path to append to the endpoint path. * @param {Object} params A dictionary of entity-specific parameters to add to the query string. * @param {Number} response_timeout A timeout period for aborting a request in milisecs (0 means no timeout). * * @method splunkjs.Service.Endpoint */ del: function(relpath, params, response_timeout) { let url = this.qualifiedPath; // If we have a relative path, we will append it with a preceding // slash. if (relpath) { url = url + "/" + relpath; } return this.service.del( url, params, response_timeout ); } }); /** * Provides a base definition for a Splunk resource (for example, an entity * such as an index or search job, or a collection of entities). Provides * basic methods for handling Splunk resources, such as validation and * accessing properties. * * This class should not be used directly because most methods are meant to be overridden. * * @class splunkjs.Service.Resource * @extends splunkjs.Service.Endpoint */ root.Resource = root.Endpoint.extend({ /** * Constructor for `splunkjs.Service.Resource`. * * @constructor * @param {splunkjs.Service} service A `Service` instance. * @param {String} path A relative endpoint path (for example, "search/jobs"). * @param {Object} namespace Namespace information: * - `owner` (_string_): The Splunk username, such as "admin". A value of "nobody" means no specific user. The "-" wildcard means all users. * - `app` (_string_): The app context for this resource (such as "search"). The "-" wildcard means all apps. * - `sharing` (_string_): A mode that indicates how the resource is shared. The sharing mode can be "user", "app", "global", or "system". * @return {splunkjs.Service.Resource} A new `splunkjs.Service.Resource` instance. * * @method splunkjs.Service.Resource */ init: function (service, path, namespace) { let fullpath = service.fullpath(path, namespace); this._super(service, fullpath); this.namespace = namespace; this._properties = {}; this._state = {}; // We perform the bindings so that every function works properly this._load = utils.bind(this, this._load); this.fetch = utils.bind(this, this.fetch); this.properties = utils.bind(this, this.properties); this.state = utils.bind(this, this.state); this.path = utils.bind(this, this.path); }, /** * Retrieves the REST endpoint path for this resource (with no namespace). * * @method splunkjs.Service.Resource */ path: function() { throw new Error("MUST BE OVERRIDDEN"); }, /** * Loads the resource and stores the properties. * * @param {Object} properties The properties for this resource. * * @method splunkjs.Service.Resource * @protected */ _load: function(properties) { this._properties = properties || {}; this._state = properties || {}; }, /** * Refreshes the resource by fetching the object from the server * and loading it. * * * * @method splunkjs.Service.Resource * @protected */ fetch: function() { throw new Error("MUST BE OVERRIDDEN"); }, /** * Retrieves the current properties for this resource. * * @return {Object} The properties. * * @method splunkjs.Service.Resource */ properties: function() { return this._properties; }, /** * Retrieves the current full state (properties and metadata) of this resource. * * @return {Object} The current full state of this resource. * * @method splunkjs.Service.Resource */ state: function() { return this._state; } }); /** * Defines a base class for a Splunk entity, which is a well-defined construct * with certain operations (such as "properties", "update", and "delete"). * Entities include search jobs, indexes, inputs, apps, and more. * * Provides basic methods for working with Splunk entities, such as fetching and * updating them. * * @class splunkjs.Service.Entity * @extends splunkjs.Service.Resource */ root.Entity = root.Resource.extend({ /** * A static property that indicates whether to call `fetch` after an * update to get the updated entity. By default, the entity is not * fetched because the endpoint returns (echoes) the updated entity. * * @method splunkjs.Service.Entity */ fetchOnUpdate: false, /** * Constructor for `splunkjs.Service.Entity`. * * @constructor * @param {splunkjs.Service} service A `Service` instance. * @param {String} path A relative endpoint path (for example, "search/jobs"). * @param {Object} namespace Namespace information: * - `owner` (_string_): The Splunk username, such as "admin". A value of "nobody" means no specific user. The "-" wildcard means all users. * - `app` (_string_): The app context for this resource (such as "search"). The "-" wildcard means all apps. * - `sharing` (_string_): A mode that indicates how the resource is shared. The sharing mode can be "user", "app", "global", or "system". * @return {splunkjs.Service.Entity} A new `splunkjs.Service.Entity` instance. * * @method splunkjs.Service.Entity */ init: function(service, path, namespace) { this._super(service, path, namespace); // We perform the bindings so that every function works properly this._load = utils.bind(this, this._load); this.fetch = utils.bind(this, this.fetch); this.remove = utils.bind(this, this.remove); this.update = utils.bind(this, this.update); this.fields = utils.bind(this, this.fields); this.links = utils.bind(this, this.links); this.acl = utils.bind(this, this.acl); this.acl_update = utils.bind(this, this.acl_update); this.author = utils.bind(this, this.author); this.updated = utils.bind(this, this.updated); this.published = utils.bind(this, this.published); this.enable = utils.bind(this, this.enable); this.disable = utils.bind(this, this.disable); this.reload = utils.bind(this, this.reload); // Initial values this._properties = {}; this._fields = {}; this._acl = {}; this._links = {}; }, /** * Loads the entity and stores the properties. * * @param {Object} properties The properties for this entity. * * @method splunkjs.Service.Entity * @protected */ _load: function(properties) { properties = utils.isArray(properties) ? properties[0] : properties; // Initialize the properties to // empty values properties = properties || { content: {}, fields: {}, acl: {}, links: {} }; this._super(properties); // Take out the entity-specific content this._properties = properties.content || {}; this._fields = properties.fields || this._fields || {}; this._acl = properties.acl || {}; this._links = properties.links || {}; this._author = properties.author || null; this._updated = properties.updated || null; this._published = properties.published || null; }, /** * Retrieves the fields information for this entity, indicating which * fields are wildcards, required, and optional. * * @return {Object} The fields information. * * @method splunkjs.Service.Entity */ fields: function() { return this._fields; }, /** * Retrieves the access control list (ACL) information for this entity, * which contains the permissions for accessing the entity. * * @return {Object} The ACL. * * @method splunkjs.Service.Entity */ acl: function() { return this._acl; }, /** * Update the access control list (ACL) information for this entity, * which contains the permissions for accessing the entity. * * @example * * let savedSearches = svc.savedSearches({ owner: "owner-name", app: "app-name"}); * let search = await searches.create({ search: "search * | head 1", name: "acl_test" }); * search = await search.acl_update({sharing:"app",owner:"admin","perms.read":"admin"}); * * @param {Object} options Additional entity-specific arguments (required): * - `owner` (_string_): The Splunk username, such as "admin". A value of "nobody" means no specific user (required). * - `sharing` (_string_): A mode that indicates how the resource is shared. The sharing mode can be "user", "app", "global", or "system" (required). * @param {Number} response_timeout A timeout period for aborting a request in milisecs (0 means no timeout). * * @method splunkjs.Service.Entity */ acl_update: function(options, response_timeout) { if(!options.hasOwnProperty("sharing")) { throw new Error("Required argument 'sharing' is missing."); } if(!options.hasOwnProperty("owner")) { throw new Error("Required argument 'owner' is missing."); } return this.post("acl", options, response_timeout).then((res)=>{ return this.fetch({}); }); }, /** * Retrieves the links information for this entity, which is the URI of * the entity relative to the management port of a Splunk instance. * * @return {Object} The links information. * * @method splunkjs.Service.Entity */ links: function() { return this._links; }, /** * Retrieves the author information for this entity. * * @return {String} The author. * * @method splunkjs.Service.Entity */ author: function() { return this._author; }, /** * Retrieves the updated time for this entity. * * @return {String} The updated time. * * @method splunkjs.Service.Entity */ updated: function() { return this._updated; }, /** * Retrieves the published time for this entity. * * @return {String} The published time. * * @method splunkjs.Service.Entity */ published: function() { return this._published; }, /** * Refreshes the entity by fetching the object from the server and * loading it. * * @param {Object} options An optional dictionary of collection filtering and pagination options: * - `count` (_integer_): The maximum number of items to return. * - `offset` (_integer_): The offset of the first item to return. * - `search` (_string_): The search query to filter responses. * - `sort_dir` (_string_): The direction to sort returned items: “asc” or “desc”. * - `sort_key` (_string_): The field to use for sorting (optional). * - `sort_mode` (_string_): The collating sequence for sorting returned items: “auto”, “alpha”, “alpha_case”, or “num”. * @param {Number} response_timeout A timeout period for aborting a request in milisecs (0 means no timeout). * * @method splunkjs.Service.Entity */ fetch: function(options, response_timeout) { if (utils.isNumber(options) && !response_timeout) { response_timeout = options; options = {}; } options = options || {}; var that = this; return this.get("", options, response_timeout).then((res) => { that._load(res.data ? res.data.entry : null);