Matching of IP-entities against a list of CIDR address

Hi Community,
I just tried importing a subnet list (Settings -> Environments -> Networks) with ~1450 lines, but was stopped by Siemplify informing me there's a maximum of 1000 lines allowed.
While my FR to raise this limit is ongoing: Does anybody know of a way to do a matching of IP-entities against a list of CIDR address ranges, and the smallest matching range would be returned in the result?

0 12 249
12 REPLIES 12

Welp, I realized I've been wanting the same action and noticed it was missing. So I wrote a custom action

Step 1: Make a custom Integration. I already had one named SiemplifyNPS (not pro services ) and make sure to include the ipaddress library.

Step 2: Make a new action in that integration. I named mine NPS_IP in Subnet

Step 3: Insert code, and params and test.
from SiemplifyAction import SiemplifyAction
from SiemplifyUtils import unix_now, convert_unixtime_to_datetime, output_handler
from ScriptResult import EXECUTION_STATE_COMPLETED, EXECUTION_STATE_FAILED,EXECUTION_STATE_TIMEDOUT
from ipaddress import ip_network, ip_address


@output_handler
def main():
siemplify = SiemplifyAction()

# parameters
ip = siemplify.extract_action_param("IP", print_value=True)
subnet = siemplify.extract_action_param("SUBNET", print_value=True)

try:
# logic to check if IP in SUBNET
net = ip_network(subnet)
# returns True or False
in_net = ip_address(ip) in net

#print("********** ", in_net)


result_value = in_net # True or False from above comparison
output_message = "Comparison Completed. IP {} in Subnet {} : {}".format(ip, subnet, in_net)
status = EXECUTION_STATE_COMPLETED


except Exception as e:
result_value = 'Error'
status = EXECUTION_STATE_FAILED
output_message = "Failed. Error is : {}".format(e)


siemplify.LOGGER.info("----------------- Main - Finished -----------------")
siemplify.LOGGER.info("Output Message: {}".format(output_message))

siemplify.end(output_message, result_value, status)


if __name__ == "__main__":
main()

View files in slack

Note that the code's formatting is all screwed up

So... to do it against a list, You could change the SUBNET param to a list of strings and then make a for loop to iterate over the list

But you'd want to create a dict and populate it with subnet:result like {0.0.0.0:True, 1.1.1.1:False}

If I get a free moment tomorrow I can try to stub that out as well I suppose

Hey @John DePalma thanks a lot for posting all this!
In my personal case, thanks to Siemplifys awesome support, my issue was solved within 1 hour after opening the FR. I was provided with code for a custom job that imports network ranges from a csv stored in the filesystem, which did the job it was expected to do AND some more that I wasn't even expecting

that sounds excellent! I wonder if that'll be made available elsewhere

Hi @ShakedTal can you please look into Zendesk support ticket 9074 and check if Ciprians helpful workaround can be made available to the community members?

Sure @Marek Kreul ! Ciprian will share it here.

This comment was originally sent by Ciprian Monoran
hi @Marek Kreul @John DePalma I'm adding below some steps and the code from the JOB created by our colleague @surajd

2. Copy the following code and replace all the codes seen on the screen.
from SiemplifyJob import SiemplifyJob
import requests
import json
import uuid
import csv


SCRIPT_NAME = "Import Network list from CSV"
HEADERS = {"Content-Type": "application/json", "Accept": "application/json"}



def main():
    siemplify = SiemplifyJob()
    siemplify.script_name = SCRIPT_NAME

    server_ip = siemplify.parameters.get("API Root")
    full_path = siemplify.parameters.get("File Path")

    siemplify.LOGGER.info("Job started")
    api_root = server_ip

    session = requests.Session()
    session.verify = False
    session.headers = HEADERS
    session.headers['AppKey'] = siemplify.api_key
    row={}
    with open(full_path, "r") as f:
        dreader = csv.DictReader(f)
        for row in dreader:
            address = row["Addresses Range (cidr)"]
            priority = row["Priority (number 1-highest ... 5-lowest)"]
            environment = row["Environment"]
            #siemplify.LOGGER.info(environment)
            name = row["Network Name (free text)"]
            new_dict = {"name":name,"address":address,"priority":priority,"environments":[environment]}
            add_line = session.post('{}/api/external/v1/settings/AddOrUpdateNetworkDetailsRecords'.format(api_root),json=new_dict)
            siemplify.LOGGER.info(new_dict)
            add_line.raise_for_status()

    siemplify.LOGGER.info("Job ended")
    siemplify.end_script()
# params, json, data, verify, headers, auth,

if __name__ == "__main__":
    main() 3. Go to the Details tab on the right, and click on + icon to add parameters. You will need to add two parameters, API Root and File Path. API Root is  https://localhost  and File Path needs to be in /opt/siemplify/siemplify_server/Scripting/Networks.csv (Networks.csv can be different name for the CSV - /opt/siemplify/siemplify_server/Scripting/Networks.csv file needs to have the  siemplifyadmin:siemplifyadmin  ownership).

4. Save the integration, go to Testing tab, and run "play" button.

NOTES:
Network Name (free text),Addresses Range (cidr),Priority (number 1-highest ... 5-lowest),Environment
Test,10.10.10.0/24,3,Default Environment
Test1,10.10.10.0/25,4,Default Environment
Test2,10.10.10.0/26,3,Default Environment

This comment was originally sent by Ciprian Monoran


View files in slack

very cool and seems simple enough. Thanks!!

also thanks to @surajd !