Hello All! I'm just starting with Phantom and having a hard time creating "reusable code". To give an example, I have a sequence of 3 actions which will be commonly seen in my playbooks:
1. Format a splunk query 2. Run the splunk query 3. Format the output to fit my needs based on an input parameter
Since these same 3 steps are commonly seen in playbooks, it would make sense to put them into some reusable format. My first thought was to take the code for these 3 actions and put it in a custom function, but they don't allow calls to phantom.act, so that doesn't work. My second thought was a playbook, which could be used as a sub-playbook. However, sub-playbooks don't have inputs/outputs, so that's not a good option. If I did go the sub-playbook route, I could use something like "save_object", but that still requires me to do almost as much work within my playbook to give input to and get output of my "sub-playbook", which defeats the purpose. Did anyone else struggle with this? Is there something I'm missing that could help me with this use case?
@stauff This is the ideal use of a Modular Playbook in Phantom!
It depends on what you need to do with the data you get from the SPL Queries as you can persist in a few ways. save_object is great for persisting data to be re-used downstream in other playbooks as it doesn't worry about scope and is only accessible to the container being processed when it was saved in the playbook, stopping issues with other containers updating the same field (Race Conditions).
The save_object piece is not a lot of work but you could also consider custom_lists, new artifacts, or custom_fields to persist the data you need further on but I would state that save_object is likely your best option.
I would also re-itertate it depends on what data you are looking to persist as an output to the SPL.
@phanTom It sounds like, given the options, save_object() would be the best option. How do you handle your calls to get_object in the parent playbook? Let's say I have 4 actions that use the result from get_object(). It seems like I would have to edit the code block for each of the 4 actions, to call get_object() and then use that object for the action call, which forces me to maintain callbacks for those 4 actions if I choose to make any changes to the playbook in the future. You can't use get_object() in the new custom functions, and legacy custom functions will be going away, so I don't know what other options I have.