My first action

Supported in:

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 in the upper left hand corner to Add New IDE Item. Select the Action radio button, name the Action "Get Domain Details" and select the integration. Then click Create.

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.

myfirstaction1

  1. To configure the parameters click in the right part of the IDE module.
    myfirstaction2
  2. 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.
    myfirstaction3
  3. 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.
    myfirstaction4

Edit the Get domain details action

  1. 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)

  2. 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) and siemplify.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)
      
  3. 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.

  1. In order to insert a JSON example copy the JSON from the Example in the WHOIS site as presented in the following JSON example.
  2. 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.
    myfirstaction5

Testing the action

Once we have finished creating the action we will test the action on a test case.

  1. Navigate to the "Testing" tab and choose the Scope, Test Case and Integration Instance.
  2. 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.
    myfirstaction6

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.

myfirstaction7

Creating an enrichment action

  1. 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.
  2. 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()
    
  3. 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.
  4. 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
    
  5. 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) 
    
  6. 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.