My first action
In My first integration, we created a custom integration, defined the parameters related to the integration and created a Ping Action to test connection to the product. In this tutorial, we will create two Actions for the integration, one will get the Domain details and present a JSON result and the other is the Enrich Entities action. Knowledge of Python and object oriented programming is necessary for this tutorial. Additionally, exploring the SDK modules themselves is highly recommended.
Creating a custom action
Navigate to the IDE and click
The IDE will create a new template that has some very useful code comments and explanations. Make sure to give this template a look over when possible.
Action parameters
In order to configure the relevant parameters for this action, review the input parameters in the WHOIS XML API documentation. For the Get Domain Details we will need to configure 2 parameters for the action – Check Availability & Domain Name.
-
To configure the parameters click
in the right part of the IDE module. -
Create the first parameter and fill in the fields as presented in the screenshot for the "Check availability" parameter and click Save. This parameter indicates if the domain is available or not and the result will be used in the automation we create.
-
Create the second parameter and fill in the fields as presented in the screenshot for the "Domain Name" parameter and click Save. This field will be used to insert the domain name we would like the action to check its details.
Edit the Get domain details action
-
Copy the below code created for the Get Domain Details, paste it in the IDE and follow the explanation of the action.
from SiemplifyAction import SiemplifyAction from SiemplifyUtils import output_handler import requests # Example Consts: INTEGRATION_NAME = "My first Integration - Whois XML API" SCRIPT_NAME = "WHOIS XML API GetDomainDetails" @output_handler def main(): siemplify = SiemplifyAction() siemplify.script_name = SCRIPT_NAME siemplify.LOGGER.info("================= Main - Param Init =================") api_key = siemplify.extract_configuration_param(provider_name=INTEGRATION_NAME, param_name="API Key") url = f"https://www.whoisxmlapi.com/whoisserver/WhoisService?apiKey={api_key}&outputFormat=json" domain = siemplify.extract_action_param(param_name="Domain Name", print_value=True) availability_check = siemplify.extract_action_param(param_name="Check availability", is_mandatory=False, print_value=True) # Add domain to scan url = f"{url}&domainName={domain}" # Determine availability check if availability_check.lower() == 'true': availability_check_qs = 1 else: availability_check_qs = 0 url = f"{url}&da={availability_check_qs}" response = requests.get(url) response.raise_for_status() # Add a Json result that can be used in the next steps of the playbook. siemplify.result.add_result_json(response.json()) # Add the Json to the action result presented in the context details. siemplify.result.add_json("WhoisDetails", response.json()) msg = f"Fetched data for {domain}" siemplify.end(msg, None) if __name__ == "__main__": main()
There are two things that must happen in an Action. Firstly, an object must be instantiated from the
SiemplifyAction
class that extracts the Google Security Operations SDK.from SiemplifyAction import SiemplifyAction from SiemplifyUtils import output_handler import requests
The second is that the object must utilize the class's
end
method to return an output message and a result value.siemplify.end(msg, None)
-
Extract integration & action params – as you can see in the code copied into the action, from line 17 to 24 we use the
siemplify.extract_configuration_param
function which extracts the parameters configured for the integration (API Key) andsiemplify.extract_action_param
function which extracts each of the parameters we configured for the action (Domain Name & Check availability).api_key = siemplify.extract_configuration_param(provider_name=INTEGRATION_NAME, param_name="API Key") url = f"https://www.whoisxmlapi.com/whoisserver/WhoisService?apiKey={api_key}&outputFormat=json" domain = siemplify.extract_action_param(param_name="Domain Name", print_value=True) availability_check = siemplify.extract_action_param(param_name="Check availability", is_mandatory=False, print_value=True)
-
Once we have extracted the parameters configured for the integration and Action, we will then build the URL according to the Boolean
availability_check
. Once the URL is ready, we will create a request to the WHOIS site, parse the answer and will add it to the result of the action. We then add the JSON result and define the output message that will be presented in the action result.
# Add domain to scan
url = f"{url}&domainName={domain}"
# Determine availability check
if availability_check.lower() == 'true':
availability_check_qs = 1
else:
availability_check_qs = 0
url = f"{url}&da={availability_check_qs}"
response = requests.get(url)
response.raise_for_status()
# Add a Json result that can be used in the next steps of the playbook.
siemplify.result.add_result_json(response.json())
# Add the Json to the action result presented in the context details.
siemplify.result.add_json("WhoisDetails", response.json())
msg = f"Fetched data for {domain}"
siemplify.end(msg, None)
if __name__ == "__main__":
main()
Adding a JSON result to the action
As part of the Get Domain Details action we will also add a JSON example to the action using the "Include JSON Result" toggle. We will be utilizing the JSON example in the playbook designer in the "My first automation" tutorial to extract a specific field in the JSON.
- In order to insert a JSON example copy the JSON from the Example in the WHOIS site as presented in the following JSON example.
-
Enable the toggle in the "Details" tab in the IDE that will enable the JSON icon in the top part of the IDE. Click on the JSON icon and import the JSON from the example in the previous link.
Testing the action
Once we have finished creating the action we will test the action on a test case.
- Navigate to the "Testing" tab and choose the Scope, Test Case and Integration Instance.
-
Once all the fields are filled click on the play icon in the top part of the IDE and view the result of the action in the Testing tab. You can also view
the Debug Output once that test has been completed by navigating to the "Debug Output" tab. Please note that the debug shows prints and logs.
If you don't have any Test Cases in your environment, navigate to the Cases screen and click on Ingest alert as test case in one of your cases. This action will create a test case that will be presented with a "Test" label in your case queue. Once you have finished creating the test case navigate back to the IDE and choose the test case from the list.
Creating an enrichment action
- Part of the automation we will create in "My first automation" will include an enrichment action that will enrich the entities and add the enrichment data to the different entities which can be viewed in the Entity Explorer.
-
Start off by creating a new action in the IDE and provide it the name "Enrich Entities". Copy the below code:
from SiemplifyAction import SiemplifyAction from SiemplifyUtils import output_handler from SiemplifyDataModel import EntityTypes import requests # Example Consts: INTEGRATION_NAME = "My first Integration - Whois XML API" SCRIPT_NAME = "WHOIS XML API EnrichEntities" @output_handler def main(): siemplify = SiemplifyAction() siemplify.script_name = SCRIPT_NAME siemplify.LOGGER.info("================= Main - Param Init =================") api_key = siemplify.extract_configuration_param(provider_name=INTEGRATION_NAME, param_name="API Key") url = f"https://www.whoisxmlapi.com/whoisserver/WhoisService?apiKey={api_key}&outputFormat=json" siemplify.LOGGER.info("----------------- Main - Started -----------------") output_message = "output message :" # human readable message, showed in UI as the action result successful_entities = [] # In case this actions contains entity based logic, collect successful entity.identifiers for entity in siemplify.target_entities: siemplify.LOGGER.info(f"processing entity {entity.identifier}") if (entity.entity_type == EntityTypes.HOSTNAME and not entity.is_internal) or entity.entity_type == EntityTypes.URL: entity_to_scan = entity.identifier scan_url = f"{url}&domainName={entity_to_scan}" response = requests.get(scan_url) response.raise_for_status() register_details = response.json().get("WhoisRecord", {}).get("registrant", {}) if register_details: entity.additional_properties.update(register_details) successful_entities.append(entity) if successful_entities: output_message += "\n Successfully processed entities:\n {}".format("\n ".join([x.identifier for x in successful_entities])) siemplify.update_entities(successful_entities) # This is the actual enrichment (this function sends the data back to the server) else: output_message += "\n No entities where processed." result_value = len(successful_entities) siemplify.LOGGER.info("----------------- Main - Finished -----------------") siemplify.end(output_message, result_value) if __name__ == "__main__": main()
- As seen in the code and done previously in the "Get Domain Details" action, we extract the parameters of the integration – the WHOIS XML API Key.
-
We are using
siemplify.target_entities
in the action which returns a list of all the target entities. We then define the Entity type we would like the action to run on, in this case a non internal Hostname or URLs.for entity in siemplify.target_entities: siemplify.LOGGER.info(f"processing entity {entity.identifier}") if (entity.entity_type == EntityTypes.HOSTNAME and not entity.is_internal) or entity.entity_type == EntityTypes.URL: entity_to_scan = entity.identifier
-
We then scan the domain, define the enrichment step of the action and the output message. This action runs on an Entity scope and therefore does not
require to configure specific parameters, this is already embedded in the code.
scan_url = f"{url}&domainName={entity_to_scan}" response = requests.get(scan_url) response.raise_for_status() register_details = response.json().get("WhoisRecord", {}).get("registrant", {}) if register_details: entity.additional_properties.update(register_details) successful_entities.append(entity) if successful_entities: output_message += "\n Successfully processed entities:\n {}".format("\n ".join([x.identifier for x in successful_entities])) siemplify.update_entities(successful_entities) # This is the actual enrichment (this function sends the data back to the server) else: output_message += "\n No entities where processed." result_value = len(successful_entities)
- Enable the action and save it. You now have a custom Integration that you created that has 3 custom actions – a ping action that enabled us to test the connection to the WHOIS XML API product, a Get Domain Details action that extracts data regarding the domain presenting a JSON result and a final action that enriches the entities and adds additional data to the target entities that are presented in the Entity Explorer module. Everything is now ready for you to create your first automation using the actions you customized.