Splunk Dev

How to make rest calls from python to modify saved search properties?

snipedown21
Path Finder

Let me start off with what I already have:
an XML dashboard
a JS script
a python handler
a restmap.conf
a web.conf

XML Dashboard

Saved-Search Email Change Dashboard

<panel>
  <html>
    <form id="userPOSTForm">
      <div>
        <label for="Search">Search</label>
        <input type="text" name="Search"/>
      </div>
      <div>
        <label for="Email">Email</label>
        <input type="text" name="Email"/>
      </div>
      <div>
        <button id="postButton">Submit</button>
      </div>
    </form>
    <div id="postResponseBox"/>
  </html>
</panel>
<panel>
  <title>GET Form</title>
  <html>
    <form id="userGETForm">
      <div>
        <label for="Search">Search</label>
        <input type="text" name="Search"/>
      </div>
      <div>
        <button id="getButton">Get Data!</button>
      </div>
    </form>
    <div id="getResponseBox"/>
  </html>
</panel>  

email_change.js

require([
    'underscore',
    'jquery',
    'splunkjs/mvc',
    'splunkjs/mvc/simplexml/ready!'
], function(_, $, mvc) {

    $(document.body).on('click', '#postButton', function(e) {

        e.preventDefault();
        var service = mvc.createService();
        var data = $('#userPOSTForm').serializeArray();
        var data_obj = {};

        _.each(data, function(field) {
            var key = field['name'];
            var value = field['value'];

            if(key == 'Email') {
                data_obj[key] = value.split(',');
            } else {
                data_obj[key] = value;
            }

        });
        alert(data_obj['Search']);
        service.post('/servicesNS/nobody/app_name/saved/searches/send', data_obj, function(err, response) {

            if(err) {
                console.log('error: ', err);
            }
            else if(response.status === 200) {
                console.log('response: ', response);
                $('#postResponseBox').empty();
                $('#postResponseBox').append('<p class=\"successBox\">Email(s) Updated Successfully</p>');
                $('#userPOSTForm')[0].reset();
                setTimeout(function() { $('#postResponseBox').empty(); }, 4000);
            }
        });
    });

    $(document.body).on('click', '#getButton', function(e) {

        e.preventDefault();

        var service = mvc.createService();
        var get_data = $('#userGETForm').serializeArray();
        var cleaned_data = {};

            cleanData = function(data) {
            _.each(data, function(field) {
                var key = field['name'];
                var value = field['value'];

                cleaned_data[key] = value;
            });
        }

        cleanData(get_data);

        service.get('/servicesNS/nobody/app_name/saved/searches/receive', cleaned_data, function(err, response) {

            if(err) {
                console.log('error: ', err);
            }
            else if(response.status === 200) {
                console.log('Response: ', response.data);
                var response_data = JSON.parse(response.data);
                $('#getResponseBox').empty();
                $('#getResponseBox').append('Emails configured: ' + response_data.entry[0].content.email);
                $('#userGETForm')[0].reset();
            }
        });
    });
});

Python handler

import splunk

class Send(splunk.rest.BaseRestHandler):

    def handle_POST(self):
        sessionKey = self.sessionKey
        search = ''
        email = []

        try:
            payload = self.request['payload']

            for el in payload.split('&'):
                key, value = el.split('=')
                if 'Search' in key:
                    search = value
                if 'Email' in key:
                    email.append(value)

            if search is '':
                self.response.setStatus(400);
                self.response.write('A search must be provided')
            else:
                post_path = '/servicesNS/nobody/app_name/saved/searches/' + search
                new_emails = { 'action.email.to' : email }
                serverContent = splunk.rest.simpleRequest(post_path, sessionKey=sessionKey, postargs=new_emails, method='POST', raiseAllErrors=True)    

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

    handle_GET=handle_POST

class Receive(splunk.rest.BaseRestHandler):

    def handle_GET(self):
        sessionKey = self.sessionKey

        try:
            queried_search = self.request['query']['Search']

            get_path = '/servicesNS/nobody/app_name/saved/searches/' + queried_search + "?output_mode=json"

            serverResponse, serverContent = splunk.rest.simpleRequest(get_path, sessionKey=sessionKey, method='GET', raiseAllErrors=True)
            self.response.write(serverContent)

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

restmap.conf

[script:email_change_send]
match=/send
handler=email_change.Send

[script:email_change_receive]
match=/receive
handler=email_change.Receive

web.conf

[expose:email_change_send]
pattern=send
methods=POST

[expose:email_change_receive]
pattern=receive
methods=GET

I am trying to create a dashboard that can update the email addresses associated with a saved search using POST calls. Also, I want to retrieve the email attached to the saved search via a GET request.
What am I doing wrong here?

0 Karma

Dev999
Communicator

Nice post!

I am trying to set up my custom endpoint, pretty sure went through restmap.conf and web.xml, python file properly. I can view the endpoint on port 8089 at https://mysplunk:8089/services/testendpoint and can get the print out from the python file. However, when I tried to call service in dashboard javascript with:
service.post('/services/testendpoint', ...)
I got 404 error. I am using Splunk 7.2.0.
I noticed that you used '/servicesNS/nobody/app_name/saved/searches/receive', Why is it "saved/searches'? I tried the same path and got "Bad Request" error even I don't do anything with the form data. Curious what is your URL on your 8089 port web? I appreciate your response.

Thanks,
Tony

0 Karma

fk319
Builder

This looks very close to what Hurricane Labs posted
(I have a slightly different issue, and I ran across this in my research.)

Splunk Custom Endpoints

0 Karma
Get Updates on the Splunk Community!

Routing logs with Splunk OTel Collector for Kubernetes

The Splunk Distribution of the OpenTelemetry (OTel) Collector is a product that provides a way to ingest ...

Welcome to the Splunk Community!

(view in My Videos) We're so glad you're here! The Splunk Community is place to connect, learn, give back, and ...

Tech Talk | Elevating Digital Service Excellence: The Synergy of Splunk RUM & APM

Elevating Digital Service Excellence: The Synergy of Real User Monitoring and Application Performance ...