
Building an app and making sure that it is environment agnostic can be a bit challenging. One challenge that I come across over and over is how to make it work cross-platform… whether Splunk is installed on Windows, MacOS or *nix environments.
A good illustration of that challenge is when you use a “Scripted Input” in your app. Scripted Inputs are one of the many ways you can use Splunk to run scripts to collect data from 3rd party interfaces such as REST. Referencing that script in a Windows environment is different than the way you would do it in a MacOS environment.
Let’s take the example of the following scripted input stanza:
[script://./bin/scripts/snow.py incident]
disabled = 1
index = snowincident
interval = 300
source = SNow_Incident
sourcetype = SNow_Incident
‘./bin/scripts/snow.py incident’ is the actual scripted command that Splunk would need to run to pull data from 3rd party REST API. This command is well suited for MacOS or *nix environments but does not work in a Windows environment due to the simple fact that Windows requires backslashes ‘\’ instead of forward slashes ‘/’ to reference directory structures. So how can this be done?
A good approach to solving the problem is to have Splunk check the environment at the app setup time and build the right scripted input based on the environment. Setup.xml is a good method that I usually use to build the app setup screen.
In order to handle the setup configuration of the setup.xml file, you can write python script that initializes your setup screen and handles the user-entered values.For more details, refer to the product documentation:
Now we need to use the python handler script to check the environment and dynamically build the inputs.conf stanza based on the platform detected. To do so, you can add the following code in the “handleEdit()” method of your handler. This method handles actions taken when user hits “Save” on the Setup screen window. The code that needs to be added is described in the following 3 steps.
Step1: Set a variable that contains the stanza’s name-value pairs parameters. In the above example, this would correspond to the following name-value pairs:
disabled = 1
index = snowincident
interval = 300
source = SNow_Incident
sourcetype = SNow_Incident
The code would look like:
input_1 = {‘disabled’: ‘1’, ‘index’: ‘snowincident’, ‘interval’: ‘300’, ‘source’ : ‘SNow_Incident’ , ‘sourcetype’ : ‘SNow_Incident’}
Step2: Build the path to the Script location using the python OS module to generate the right path based on the platform.
For the above scripted input stanza, this would correspond to either
script://./bin/scripts/snow.py incident – for MacOS or Unix
or
script://.\bin\scripts\snow.py incident – for Windows
The code would like:
SNOW_FILE = os.path.join( ‘.’, ‘bin’, ‘scripts’, ‘snow.py incident’)
SNOW_FILE = ‘script://’ + SNOW_FILE
Step3 – Use the writeConf() method to add a new entry to inputs.conf through the rest API. WriteConf() takes the variables defined in Step 1 and 2 as arguments:
self.writeConf(‘inputs’, SNOW_FILE, input_1)
Hope this helps someone else with the same problem…