Splunk® SOAR (On-premises)

Build Playbooks with the Playbook Editor

The classic playbook editor will be deprecated in early 2025. Convert your classic playbooks to modern mode.
After the future removal of the classic playbook editor, your existing classic playbooks will continue to run, However, you will no longer be able to visualize or modify existing classic playbooks.
For details, see:

Add custom code to your Playbook with the legacy custom function block using the classic playbook editor

Legacy custom function blocks are the custom functions that were introduced in Splunk Phantom version 4.2 and are supported for playbooks which use those blocks. A newer implementation was released in Splunk Phantom version 4.9 and should be used instead. For information on converting legacy custom functions to the current custom function implementation, see Convert legacy custom functions to new custom functions.

Add custom Python code to a Custom Function block. Custom functions enable you to expand the kinds of processing performed in a playbook, such as adding custom input parameters and output variables. To use a legacy custom function block, you must have Edit Code permissions, which can be configured in Administration > User Management > Roles and Permissions. For more information on the Edit Code permission, see Add a role to in the Administer manual.

Functions, parameters, and output variables can all have custom names using the following characters:

  • A-Z
  • a-z
  • 0-9
  • Underscores

Setting or changing a custom name changes that custom name in all data paths that use it, including generated and custom code.

Set the name, tooltip, comments and other options for the block in the Advanced Settings > General Settings.

Click the </> icon to open the Python Playbook Editor to add your custom code:

This screen image shows a custom block on the classic playbook editor. The main elements are Input and Output parameters, which are described in the sections immediately following this image.

Input parameters

Input parameters represent a data path. You can set a data path from any valid blocks upstream, artifact data, and container data.

To create or remove an input parameter, perform the following steps:

  1. Click the + icon to add an input parameter. The index of parameters starts at zero.
  2. Type a name to set the name for or rename the input parameter.
  3. Click the > icon to set the properties for the input parameter.

You can delete the input parameter by clicking the x icon.

Output variables

Output variables are usable as inputs in other downstream blocks, such as Action, API, Filter, Decision, Format, Prompt, or other Custom Function blocks. The name of an output variable becomes <block_name>__<variable_name> in the auto-generated section of the playbook code. Give your output variables clear and meaningful names in your custom code.

Follow these steps to create or remove an output variable:

  1. Click the + icon to add an output variable.
  2. Type a name to set the name for, or rename the output variable.
  3. Click the x icon to delete an output variable.

See the following example of a custom function:

def format_login(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None):
phantom.debug('format_login() called')
results_data_1 = phantom.collect2(container=container, datapath=['get_login_history:action_result.data.*.output'], action_results=results)
results_item_1_0 = [item[0] for item in results_data_1]
    
format_login__login_table = None
    
################################################################################
## Custom Code Start
################################################################################
    
# format the output into Jira's markup language for rendering a table
format_login__login_table = "|| output of '/usr/bin/last -a' ||\n"
last_lines = results_item_1_0[0].split('\n')
for line in last_lines:
    format_login__login_table += "| {} |\n".format(line)
        
phantom.debug("table of logins for jira:")
phantom.debug(format_login__login_table)
    
################################################################################
## Custom Code End
################################################################################
    
phantom.save_run_data(key='format_login:login_table', value=json.dumps(format_login__login_table))
enrich_ticket_1(container=container)
    
return    

Custom function example for processing multiple artifacts to build a parameter list

def DBSearch(action=None, success=None, container=None, results=None, handle=None, filtered_artifacts=None, filtered_results=None):
    phantom.debug('SearchDB() called')
    name_value = container.get('name', None)
    container_data = phantom.collect2(container=container, datapath=['artifact:*.cef.message', 'artifact:*.cef.startTime', 'artifact:*.id'])
    container_item_0 = [item[0] for item in container_data]
    container_item_1 = [item[1] for item in container_data]

    ################################################################################
    ## Custom Code Start
    ################################################################################

    # Write your custom code here...
    customernamestr = name_value
    parameters = []

    # Loop over the container data structure (a list of lists, with each inner list of length three)
    for messagestr, start_time, artifact_id in container_data:
        startdatestr = start_time.split(' ')[0]
        starttimestr = start_time.split(' ')[1]

        # Build the SQL
        if 'groupName:' in messagestr:
            hostgroupstr = messagestr.split('/')[0].replace('groupName:', '')
            hoststr = messagestr.split('/')[1].split(':')[1]
            sqlstr = "select COUNT(*) as cnt from schedule where customer = '"+ customernamestr +"' and startdate <= '"+ startdatetimestr +"' and enddate >= '"+ startdatetimestr +"' and ("
            for group in hostgroupstr.split('/'):
                sqlstr = sqlstr + "kyoten like '%"+ group +"%' or reason like '%"+ group +"%' or "
            sqlstr = sqlstr + "kyoten like '%"+ hoststr +"%' or reason like '%"+ hoststr +"%')"
            
        else:
            hoststr = messagestr.split(':')[0]
            sqlstr = "select COUNT(*) as cnt from schedule where customer = '"+ customernamestr +"' and  (kyoten like '%"+ hoststr +"%' or reason like '%"+ hoststr +"%') and startdate <= '"+ startdatetimestr +"' and enddate >= '"+ startdatetimestr +"'"

        # Update the parameter list
        # There should be one parameter per item in the container_data variable
        # There should be one item in the container_data variable per artifact
        # Thus, there should be one parameter per artifact
        parameters.append({
            'query': sqlstr,
            'format_vars': "",
            'no_commit': False,
        })

    phantom.act("run query", parameters=parameters, assets=['mysql'], callback=filter_2, name="SearchDB")

    ################################################################################
    ## Custom Code End
    ################################################################################
    filter_2(container=container)

    return

Last modified on 02 April, 2024
Add custom code to your playbook with the custom function block using the classic playbook editor   Determine your playbook flow using the classic playbook editor

This documentation applies to the following versions of Splunk® SOAR (On-premises): 5.1.0, 5.2.1, 5.3.1, 5.3.2, 5.3.3, 5.3.4, 5.3.5, 5.3.6, 5.4.0, 5.5.0, 6.0.0, 6.0.1, 6.0.2, 6.1.0, 6.1.1, 6.2.0, 6.2.1, 6.2.2, 6.3.0, 6.3.1


Was this topic useful?







You must be logged into splunk.com in order to post comments. Log in now.

Please try to keep this discussion focused on the content covered in this documentation topic. If you have a more general question about Splunk functionality or are experiencing a difficulty with Splunk, consider posting a question to Splunkbase Answers.

0 out of 1000 Characters