splunk-sdk
Version:
SDK for usage with the Splunk REST API
1,144 lines (1,065 loc) • 242 kB
JavaScript
/*!*/
// 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);