Managing Objects Tutorial

Here we're going to show you have to manage a very useful object, a saved-search. Along the way you'll learn how to make any kind of new object, get back a list of those objects, edit, and delete them.

All management endpoints behave in a similar fashion, taking the same global parameters and return responses in the same format. Use a GET request to retrieve information from a resource and a POST to update an entity.

What are objects?

Let me answer that with another question: what is a namespace? A namespace is a specific context from which REST calls are made, made up of the app and user that is trying to interact with it. In short, a namespace = app+user specification. So, now, what is an object? Objects are things that come back from the splunk REST API that are dependent on a namespace. For example, a saved search is an object. Depending on the namespace (app+user) specification, one user might not be able to see a saved search that another user made or that was in another app, or in fact, they may get another object altogether.

As an aside, what isn't an object? Configuration. Configurations are not dependent on a namespace (app+user). Therefore, indexes, inputs, users and roles are the same whether Bob accesses them from app Foo, or Dan accesses them from app Bar.

In this tutorial we are covering Objects using the REST API. Configuration will be covered in a separate tutorial.

The URIs for object endpoints are served off of https://localhost:8089/servicesNS/<user>/<app>. Use your installation host name and management port -- by default, 8089. Note that Splunk's API is secure, so use HTTPS whenever you access any endpoints.

Note: Again, the examples here use curl, but you can use wget, libcurl or any other method to GET and POST in your preferred language. You will need some way to parse the XML responses, too. Your preferred coding language should include libraries to support making HTTP requests and parsing XML responses.

Listing and Searching

A savedsearch is a stored search that can be conveniently recalled to run a search again. It can be automatically scheduled to run at preset times, and can be used with Splunk's alerting mechanism. By default, Splunk ships with a few savedsearches. Let's use the saved/searches REST endpoint to list them:

curl --get -k -u admin:changeme https://localhost:8089/servicesNS/admin/search/saved/searches

Note: In this endpoint URL, we've specified that we are user "admin" and we are in the "search" app, which is the default searching app for Splunk. Also note that by default only 30 objects are returned.

All endpoints that return lists of objects adhere to a standard interface for paging and filtering of their list output. Any endpoint that returns a list of objects in an Atom feed format provides paging and filtering capabilities. We'll just cover a few here. There is a count argument, which defaults to 30, as well as an offset value, which is a zero-based argument useful for paging between objects. For example, to list the 2rd-5th savedsearches, inclusively, you would set count=4 and offset=1 (it's zero-based).

curl --get -k -u admin:changeme -d "count=4" -d "offset=1" https://localhost:8089/servicesNS/admin/search/saved/searches

To search for objects, use the search argument, which filters the returned objects by matching any eligible field value against the search expression. For example:search=foo would match any object that has the value 'Äòfoo'Äô as a substring of at least one of the eligible fields. The search can also be restricted to a single field as follows: search="field_name=field_value". For example, the following call will return any saved searches that have "in the last" in their text.

curl --get -k -u admin:changeme -d "count=99" -d 'search="in the last"' https://localhost:8089/servicesNS/admin/search/saved/searches

Given a fresh install of Splunk, which ships with a few savedsearches, you'll get two savedsearches returned, one entitled "Errors in the last 24 hours" and another "Errors in the last hour".

Making a new object

By appending on "/_new" to a endpoint that lists objects, you can get the sets of required and optional arguments for that endpoint. For example, the saved/searches/_new endpoint:

curl -k -u admin:changeme https://localhost:8089/servicesNS/admin/search/saved/searches/_new

will return XML that includes:

    ...
    <s:key name="eai:attributes">
        <s:dict>
            <s:key name="optionalFields"><s:list><s:item>action.email</s:item>...
            <s:key name="requiredFields"><s:list><s:item>name</s:item><s:item>search</s:item></s:list></s:key>
    ...

letting us know that savedsearches must have a name and a search attribute. This sort of programmatic access to the required attributes could be useful for automating required fields on forms, but clearly the REST API reference doc for any given endpoint will give you more and better information.

Now let's actually create a savedsearch, called "web_errors", which runs a search looking for web error codes: "source=*web.log status>400":

curl -k -u admin:changeme -d "name=web_errors" -d 'search="source%3D*web.log+status>400"' https://localhost:8089/servicesNS/admin/search/saved/searches

If everything went well, we get our savedsearch back:

    <?xml-stylesheet type="text/xml" href="/static/atom.xsl"?>
    <feed xmlns="http://www.w3.org/2005/Atom" xmlns:s="http://dev.splunk.com/ns/rest" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/">
    ...
    <entry>
        <title>web_errors</title>
        <id>https://localhost:8089/servicesNS/admin/search/saved/searches/web_errors</id>
        ...
        <author>
            <name>admin</name>
        </author>
        ...
        <content type="text/xml">
            <s:dict>
            ...
            <s:key name="search">source=*web.log status&gt;400</s:key>
            ...
            </s:dict>
        </content>
     </entry>
     </feed>

We can also use search to verify our object is really there:

curl --get -k -u admin:changeme -d 'search=web_errors' https://localhost:8089/servicesNS/admin/search/saved/searches

Editing

At this point, we've made a new savedsearch called web_errors. Let's edit it. Look back at the above XML. Note the id value:

    ...
    <id>https://localhost:8089/servicesNS/admin/search/saved/searches/web_errors</id>
    ...

This is essentially the object list endpoint with the name of the object appended on. This is the URL that we need to use to modify our object. Let's change the value of our savedsearch's search attribute to be "fail OR error":

curl -k -u admin:changeme -d 'search="fail+OR+error"' https://localhost:8089/servicesNS/admin/search/saved/searches/web_errors

If everything went well, we get our savedsearch back, with the new search value:

    ...
    <s:key name="search">fail OR error</s:key>
    ...

Disable/Enabling

The boolean attribute "disabled" is used to enable and disable objects. Disabled objects are not used by Splunk in processing, but they are still retrievable. (To hide objects from the Splunk UI, use is_visible). Let's disable our savedsearch, web_errors:

$ curl -k -u admin:changeme -d "disabled=1" -d 'search="fail+OR+error"' https://localhost:8089/servicesNS/admin/search/saved/searches/web_errors

Note: Required arguments are necessary when modifying an object, so even though we are changing the value of "disabled", we still need to pass in the value of "search" which is a required attribute.

Note: Boolean values can be specified with 0 (false) or 1 (true).

Deleting

To delete an object we need to use the DELETE request method. Up until this point we've used the GET method to retrieve objects, and the POST method to make changes. The following call will delete our web_errors savedsearch:

$ curl --request DELETE -k -u admin:changeme https://localhost:8089/servicesNS/admin/search/saved/searches/web_errors

Run it again and you'll get an error that the object no longer exists.