Splunk Custom Endpoints Part 1: The Basics

Custom Endpoints in Splunk – it’s something you may have heard about, but I find that most people who work in Splunk have a hard time figuring out what to use it for or really HOW to use them.



Custom Endpoints in Splunk – it’s something you may have heard about, but I find that most people who work in Splunk have a hard time figuring out what to use it for or really HOW to use them. There’s some documentation about setting up custom endpoints in Splunk, specifically in regards to building setup pages in Splunk. Regardless, there seems to be a sense of mystery that surrounds custom endpoints.

In this screencast / blog post series I hope to break through that mystery by providing some concrete examples on how we can best utilize custom endpoints in Splunk.

What will we build?

We will start with something simple. GET and POST requests utilizing custom endpoints is about as simple as it gets.

We will build a dashboard from which we can POST and GET to our custom endpoints. We will be modifying roles around users. This isn’t something that should be done on a production machine. The purpose of this is to provide a concrete example of GETting and POSTting data to and from a custom endpoint. By the end you should have a firm grasp on how custom endpoints work in Splunk which will allow you to do some pretty awesome stuff.

Custom Endpoint
Screenshot of the Custom Endpoint dashboard.

The files we will be creating:

  • custom_endpoint.xml – our dashboards that will communicate with our custom endpoints

  • custom_endpoint.py – Python script to handle our GET and POST requests

  • restmap.conf – maps Python classes to uri paths

  • web.conf – allows verbs (GET, POST etc.) to specific endpoints

  • custom_endpoint.js – handles GET, POST requests on dashboards; communicates with custom endpoints

The following is not meant to be a real world example, but hopefully this provides some insight into how custom endpoints in Splunk work. So, this begs the question - what are some real-world examples of how custom endpoints can be utilized?

  1. Let’s say you need to pull data in from an external API or service - that may be a time to use a custom endpoint.

  2. Another example would be if you wanted a third-party service to pull data from Splunk. Setting up a custom endpoint and then allowing the service to GET data from the endpoint. These may be some examples I will cover in future screencasts and blog posts.


Getting Started

Because we will be dealing with user data, let’s create a sample user that we can work with. This user will simply be given the role of ‘user’.

Go to Settings < Access Controls and click ‘Add New’ next to Users and then fill out the form. I’m going to call my user ‘batman’:

Splunkd

In order to interact with our user data we will need to interact with splunkd, which usually resides on port 8089 unless you’ve specified it to exist on a different port.

In order to view our new users permission information go to https://<hostname>:<splunkd_port>/services/admin/users/<user_name> – you should see something like this (plus a bunch of other items)

We are going to hook into this endpoint from our custom endpoint to add additional role capabilities to this user.

Setting up Python

Inside of the Search and Reporting app look for the bin folder. In the bin folder we will be adding our Python script, name it custom_endpoint.py. Let’s start by building out one class call Send. Our Send class will inherit from splunk.rest.BaseRestHandler. From the BaseRestHandler we will inherit all of the handle methods such as handle_POST, handle_GET etc. In this class we will write a handle for POSTing.

import splunk

class Send(splunk.rest.BaseRestHandler):

    def handle_POST(self):
        sessionKey = self.sessionKey

        try:
            post_path = '/services/admin/users/batman'
            new_roles = { "roles" : ["user","admin"] }
            serverContent = splunk.rest.simpleRequest(post_path, sessionKey=sessionKey, postargs=new_roles, method='POST', raiseAllErrors=True)

        except Exception, e:
            self.response.write(e)

        try:
            self.response.setHeader(“content-type', 'text/html”)
            self.response.write(“<p>Success!</p>”)

        except:
            self.response.setHeader(“content-type', 'text/html”)
            self.response.write(“<p>Uh oh! Something's wrong!</p>”)

    #handle verbs, otherwise Splunk will throw an error
    handle_GET = handle_POST

Here is what we are doing:

  1. First set up our POST handle with the function handle_POST().

  2. Inside of the handle_POST() function we pull out the sessionKey as we will need this later when we make our POST request.

  3. We try to make our request and if it fails then we throw an exception.

  4. Output a successful message in the browser making sure to set the header as ‘text/html’ so it renders appropriately. If this fails we instead pass back an error message into the browser.

  5. Finally, we handle our verbs by setting handle_GET to handle_POST. If we do not do this Splunk will throw an error.

Configuration Files

Now we need to set up our endpoint so that when we hit https://<hostname>:<splunkd_port>/services/send it will trigger our handle_POST method. To do this we need to set up our restmap.conf and web.conf files.

restmap.conf

Let’s look at restmap.conf first. Look in the Search and Reporting app’s local folder and if a restmap.conf doesn’t already exist then create one.

In restmap.conf file add the following:

[script:custom_endpoint_send]
#matches https://$SERVER:$PORT/services/send
match=/send
#splunk automatically looks for the script in the app's bin folder
#handler=<script_name>.<className>
handler=custom_endpoint.Send

Here is what we are doing:

  1. First we provide a script stanza. I am calling it custom_endpoint_send.

  2. Then we need to match the path of /send, which will map to https://$SERVER:$PORT/services/send.

  3. Finally, we add a handler which connects to our custom_endpoint.py and looks for the Send class in the form of custom_endpoint.Send.

web.conf

In order for us to allow POSTing to our /send endpoint from our soon-to-be-created dashboard we also need to set up a web.conf in our app’s local folder (same place as restmap.conf).

In web.conf file add the following:

[expose:custom_endpoint_send]
pattern=send
methods=POST

Here is what we are doing:

  1. Setting up a new stanza called [expose:custom_endpoint_send]

  2. Setting our pattern to send (make sure to omit the / here)

  3. Specify which methods are allowed. Here we are allowing POST.

You may notice that I’ve named the stanzas in both the web.conf and restmap.conf the same e.g [script:custom_endpoint_send] in restmap.conf and [expose:custom_endpoint_send] in web.conf. I am doing this for consistency purposes but they don’t have to be named the same. The only format these must follow is using expose: in web.conf and script: in restmap.conf.

Now that both your restmap.conf and custom_endpoint.py file are set up go ahead and restart Splunk.




Close off Canvas Menu