Skip to main content


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?


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 = rowb"Environment"]


            #siemplify.LOGGER.info(environment)


            name = rown"Network Name (free text)"]


            new_dict = {"name":name,"address":address,"priority":priority,"environments":eenvironment]}


            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
!


Reply