Splunk Dev

How to do POST call / webhook from Splunk Dashboard on Click button

mayurr98
Super Champion

Suppose I have a test curl command which is working:

curl -k http://ip:port/get_config -d tgt=juniper -d tgt_type=glob

now I need to figure out how to issue a POST call from Splunk dashboard and what the call format needs to be.

so here is a thing :

1) I have 2 inputs say tgt and tgt_type (could be a dropdown/input box) and submit button :
For example:

<form script="test1.js">
  <label>test</label>
  <fieldset submitButton="true" autoRun="false">
    <input type="dropdown" token="tgt" searchWhenChanged="true">
      <label>tgt</label>
      <choice value="juniper">juniper</choice>
    </input>
    <input type="dropdown" token="tgt_type" searchWhenChanged="true">
      <label>tgt_type</label>
      <choice value="glob">glob</choice>
    </input>
  </fieldset>
</form>

2) Once I select the values and click on the submit button, I should make a POST request/webhook using any method ajax or js,etc.

consider a POST URL is http://ip:port/hook/get_config?tgt=$tgt$&tgt_type=$tgt_type$

Thanks in Advance.

0 Karma
1 Solution

harsmarvania57
Ultra Champion

Hi @mayurr98,

As per @dwaddle suggestion, here is sample script which fire POST request to HEC URL with custom search command.

$SPLUNK_HOME/etc/apps/myapp/bin/test.py (Please change mode of execution for this script For exa. chmod 750 test.py for linux)

import requests, splunk.Intersplunk, json

keywords, argvals = splunk.Intersplunk.getKeywordsAndOptions()
if 'tgt' in argvals:
    target = argvals.get("tgt", None)

if 'tgt_type' in argvals:
    target_type = argvals.get("tgt_type", None)


if not target:
    splunk.Intersplunk.parseError("'tgt' argument not provided")

if not target_type:
    splunk.Intersplunk.parseError("'tgt_type' argument not provided")

try:
    head={"Authorization":"Splunk <HEC Token>", "Content-Type": "application/json"}
    url="https://localhost:8088/services/collector/event"
    data={"sourcetype": "test", "event": {"tgt": target, "tgt_type": target_type}}
    r = requests.post(url, data=json.dumps(data), headers=head, verify=False)
except Exception, e:
    splunk.Intersplunk.parseError(e)

In above script I have disabled certificate verification in my lab but please remove verify=False in production environment if you have enabled HEC over SSL so that it will verify certificate.

$SPLUNK_HOME/etc/apps/myapp/default/commands.conf

[testcommand]
filename = test.py
local = true
generating = true
supports_rawargs = false

$SPLUNK_HOME/etc/apps/myapp/metadata/default.meta (Here I have restricted testcommand to admin only but you can adjust permission based on your requirement)

[commands]
access = read : [ * ], write : [ admin ]
export = system

[commands/testcommand]
access = read : [ admin ], write : [ admin ]
export = system

Search Window

| testcommand tgt=juniper tgt_type=glob

When you run above command it will ingest event in HEC with JSON format and event raw data will be {"tgt": "juniper", "tgt_type": "glob"}

View solution in original post

gjanders
SplunkTrust
SplunkTrust

You could also consider the Web Tools Add-on , this provides a curl command in Splunk

0 Karma

harsmarvania57
Ultra Champion

Hi @mayurr98,

As per @dwaddle suggestion, here is sample script which fire POST request to HEC URL with custom search command.

$SPLUNK_HOME/etc/apps/myapp/bin/test.py (Please change mode of execution for this script For exa. chmod 750 test.py for linux)

import requests, splunk.Intersplunk, json

keywords, argvals = splunk.Intersplunk.getKeywordsAndOptions()
if 'tgt' in argvals:
    target = argvals.get("tgt", None)

if 'tgt_type' in argvals:
    target_type = argvals.get("tgt_type", None)


if not target:
    splunk.Intersplunk.parseError("'tgt' argument not provided")

if not target_type:
    splunk.Intersplunk.parseError("'tgt_type' argument not provided")

try:
    head={"Authorization":"Splunk <HEC Token>", "Content-Type": "application/json"}
    url="https://localhost:8088/services/collector/event"
    data={"sourcetype": "test", "event": {"tgt": target, "tgt_type": target_type}}
    r = requests.post(url, data=json.dumps(data), headers=head, verify=False)
except Exception, e:
    splunk.Intersplunk.parseError(e)

In above script I have disabled certificate verification in my lab but please remove verify=False in production environment if you have enabled HEC over SSL so that it will verify certificate.

$SPLUNK_HOME/etc/apps/myapp/default/commands.conf

[testcommand]
filename = test.py
local = true
generating = true
supports_rawargs = false

$SPLUNK_HOME/etc/apps/myapp/metadata/default.meta (Here I have restricted testcommand to admin only but you can adjust permission based on your requirement)

[commands]
access = read : [ * ], write : [ admin ]
export = system

[commands/testcommand]
access = read : [ admin ], write : [ admin ]
export = system

Search Window

| testcommand tgt=juniper tgt_type=glob

When you run above command it will ingest event in HEC with JSON format and event raw data will be {"tgt": "juniper", "tgt_type": "glob"}

mayurr98
Super Champion

Thanks with few modifications it worked:

import requests, splunk.Intersplunk, json

keywords, argvals = splunk.Intersplunk.getKeywordsAndOptions()
if 'tgt' in argvals:
     target = argvals.get("tgt", None)

if 'tgt_type' in argvals:
     target_type = argvals.get("tgt_type", None)


if not target:
     splunk.Intersplunk.parseError("'tgt' argument not provided")

if not target_type:
     splunk.Intersplunk.parseError("'tgt_type' argument not provided")

results = []
result = {}

try:
     head = {'Content-Type': "application/x-www-form-urlencoded"}
     url="api"
     data={"tgt": target, "tgt_type": target_type}
     r = requests.post(url, data=json.dumps(data), headers=head)
     if r.status_code == 200:
        result['response'] = r.content
        results.append(result)
        splunk.Intersplunk.outputResults(results)
     else:
        result['response'] = "Failed"
        results.append(result)
        splunk.Intersplunk.outputResults(results)
except Exception, e:
     splunk.Intersplunk.parseError(e)
0 Karma

dwaddle
SplunkTrust
SplunkTrust

I don't know about overriding a dashboard's submit button. That sounds like a bad idea. But beyond that, you can put an html simple XML element on the page and stuff arbitrary HTML and buttons and javascript to fire on them right there on the page.

My bigger concern would be things like the browser's CORS. I would not personally want to have to change the CORS of splunk itself to enable javascript running in my dashboard to make calls to a remote origin.

Also, you'd have to provide credentials to the javascript in the browser to be able to interact with the external service (unless it lacks authentication)

What I would suggest is that you put your "webhook call" in a custom search command on the search head. Then your dashboard can call your " | mycommand arg1 arg2 arg3 " -- and the webhook call occurs on the server. Your custom command can then consult Splunk's credential store to get the authentication data it needs, make the call, and return any data to the dashboard.

Just my two cents

mayurr98
Super Champion

sorry i am new to dev,how can I make the custom command to call the API which can pass args.

0 Karma
Get Updates on the Splunk Community!

What's New in Splunk Enterprise 9.4: Features to Power Your Digital Resilience

Hey Splunky People! We are excited to share the latest updates in Splunk Enterprise 9.4. In this release we ...

Take Your Breath Away with Splunk Risk-Based Alerting (RBA)

WATCH NOW!The Splunk Guide to Risk-Based Alerting is here to empower your SOC like never before. Join Haylee ...

SignalFlow: What? Why? How?

What is SignalFlow? Splunk Observability Cloud’s analytics engine, SignalFlow, opens up a world of in-depth ...