Introducing SOC Insights for BloxOne Threat Defense: Boost your SOC efficiency with AI-driven insights to eliminate manual work and accelerate investigation and response times. Read the blog announcement here.

How-to Articles

470779813-660x454.jpg

5 Python Scripts to get you started in NetMRI

If you are like me at some point you got psyched that Python was coming to NetMRI.  This article will get you started with Python in NetMRI from the basics “run this command” on my devices to advance “grab some data via an API call” and trigger an action within NetMRI. 

 

Before you get started…Need to Know about Python Scripts


Note: Well-known variables for Python scripting are listed in the topic Scripting Well-Known Variables (Perl, Python, and CCS).


 

Python scripts use a script header similar to a CCS script, contained within a well-known comment block.

The script header block influences a number of runtime behaviors, including:

 

Script-Timeout

Specifies the per-command timeout for the entire script in seconds.

  • Type: Integer
  • Required: No
  • Default if not specified: 60

 

Script-Login

Specifies whether the job engine should automatically establish a connection with the target device.

  • Type: Boolean
  • Required: No
  • Default if not specified: true

 

Script-Variables

  • Specifies inputs needed by the script.
  • Type: Tuple (ordered list of elements)
  • Required: No
  • Default if not specified: None

 

Script-Filter

Specifies the device types processed by the script.

  • Type: String
  • Required: Yes

A Python Script header block must be defined inside of comments within a "well known" comment section (between # BEGIN-SCRIPT-BLOCK and a # END-SCRIPT-BLOCK). The following example demonstrates the difference between a CCS and Python Script header block that specifies a Script-Filter that applies to all Cisco IOS devices.

As a comparison, a CCS implementation is straightforward:

          Script-Filter: $Vendor == "Cisco" and $sysDesc like /IOS/

          You can filter by the network view:

          Script-Filter: $network == "blue"

         A comparable Python implementation is as follows:

         # BEGIN-SCRIPT-BLOCK

         # Script-Filter: $Vendor == "Cisco" and $sysDesc like /IOS/

         # END-SCRIPT-BLOCK

 

 

Working Environment

  • NetMRI System version 7.2(Python was added as a scripting option in NetMRI)
  • Sandbox System
  • Python scripts run inside the sandbox, using the Python API to communicate with the Device Interaction Server (DIS) on NetMRI. The DIS proxies CLI requests/responses to/from network devices on behalf of the Python scripts.

Before commands can be sent to a network device, a Python script must first establish a DIS session (see v2 API object DisSession). After a session has been established, a CLI connection with the target device must be established for the given session (see v2 API object CliConnection).

 

The majority of the time, a Python script will follow this same initialization sequence. First, establish the API session, establish the DIS session, then establish a CLI connection with the target device. For this reason, netmri_easy.py, a pre-installed Python library, is provided in the appliance (see Configuration Management –> Job Management –> Library –> netmri_easy).

 

python1.png

 

Practical Examples

 

Script 1 - Sending a basic command

 

Goal: Run a simple command via scripting. Understand and see the impact of DEBUG option.

This will show you the example of sending “show version” on a device.  The second command is to show you that we can use the CCS DEBUG option which will not run “show version” on the device but show you that we would have if you remove the DEBUG. 

 


# BEGIN-SCRIPT-BLOCK

#

# Script-Filter:

#     true

#

# END-SCRIPT-BLOCK

 

from infoblox_netmri.easy import NetMRIEasy

 

# This values will be provided by NetMRI before execution

defaults = {

   "api_url": api_url,

   "http_username": http_username,

   "http_password": http_password,

   "job_id": job_id,

   "device_id": device_id,

   "batch_id": batch_id

}

 

# Create NetMRI context manager. It will close session after execution

with NetMRIEasy(**defaults) as easy:

   easy.send_command('show version')

   easy.send_command('DEBUG:show version')


 

Script 2 - Using Script Variables

 

Goal: Use Scripting to change the password on a device.

 

Just like using Script Variables in CCS and PERL we can do the same in Python, the only difference is that we can NOT use “Well Known Variables.”  

 

This example script will first prompt for a new password ($new_password), and then NetMRI uses that variable to change the password on our target devices.

 


# BEGIN-SCRIPT-BLOCK

#

# Script-Filter: true

#

# Script-Variables:

#     $new_password password "password"

#

# END-SCRIPT-BLOCK

 

from infoblox_netmri.easy import NetMRIEasy

 

# This values will be provided by NetMRI before execution

defaults = {

   "api_url": api_url,

   "http_username": http_username,

   "http_password": http_password,

   "job_id": job_id,

   "device_id": device_id,

   "batch_id": batch_id

}

 

# Create NetMRI context manager. It will close session after execution

with NetMRIEasy(**defaults) as easy:

   easy.send_command('config t')

   easy.send_command("username name secret 0 {}".format(new_password))

   easy.send_command('end')

   easy.send_command('wr mem')

 


 

Script 3 - Generate a Custom Issue

 

Goal: Create a custom issue to drive additional responses from NetMRI, based on the script output.

 

This will run “show vtp status” on a switch, parse each line of the output looking for “VTP Operating Mode” where, if the devices we select are configured as Server, we will generate an issue. 


# BEGIN-SCRIPT-BLOCK

#

# Script-Filter:

#     true

#

# END-SCRIPT-BLOCK

 

import requests, json, re

from infoblox_netmri.easy import NetMRIEasy

 

# This values will be provided by NetMRI before execution

defaults = {

   "api_url": api_url,

   "http_username": http_username,

   "http_password": http_password,

   "job_id": job_id,

   "device_id": device_id,

   "batch_id": batch_id

}

 

# Create NetMRI context manager. It will close session after execution

with NetMRIEasy(**defaults) as easy:

   vtpstatus = easy.send_command('show vtp status')

   regexp = re.compile(r"VTP Operating Mode\s*: (.*)")

   if regexp.search(vtpstatus):

       #print ('matched')

       status = re.search('(?<=VTP Operating Mode\s.)(.*)', vtpstatus, re.MULTILINE).group()

       if re.search(r'Server', status):

           issue_id = easy.generate_issue("info", "siftest",**{

                "Host":device_devicename,

                "IPAddress":device_deviceipdotted,

                "noclue1":'test1',

                "noclue2":'test2',

                "device_id": device_id,

                "batch_id": batch_id

           })

       else:

           print ('no match')


 

Script 4 - Adding data to Custom Fields

 

Goal: Parse needed information out of a show command, and then populate into a custom field.

 

Wrote this one for a customer because SNMP did not have the correct Serial number for Cisco ASAs, We will run “show inventory” and parse the output looking for the System Serial number and update our Custom field named “Sif Test2.”

 


# BEGIN-SCRIPT-BLOCK

#

# Script-Filter:

#     $vendor eq "Cisco" and $type eq “Firewall”

#

# END-SCRIPT-BLOCK

 

from infoblox_netmri.easy import NetMRIEasy

import re

 

# This values will be provided by NetMRI before execution

defaults = {

   "api_url": api_url,

   "http_username": http_username,

   "http_password": http_password,

   "job_id": job_id,

   "device_id": device_id,

   "batch_id": batch_id

}

 

# Create NetMRI context manager. It will close the session after execution

with NetMRIEasy(**defaults) as easy:

   # Everything has to be indented under the context manager if we are sending commands to NetMRI

   #

   # This is how you will create a custom field name, we are using "Sif Test2"

   #

   broker = easy.client.get_broker('CustomFields')

   broker.create_field(

       model='Device',

       name='Sif Test2',

       type='string'

   )

 

   # get device

   device = easy.get_device()

   #

   # The method for retrieving the serial number via the

   # CLI depends on the type of device.

   #

   # This portion of the code will run if the Device is a Router

   # For the gather the serial number we are using RegEx - check out FB/ArtOfRegex

   #

   if device.DeviceType == 'Router':

       inventory = easy.send_command('show inventory')

       serial = re.search('(?<=SN: ).*$', inventory).group()

   #

   # This portion of the code will run if the Device is anything but a Router

   # For the gather the serial number we are using RegEx - check out FB/ArtOfRegex

   #

   else:

       info = easy.send_command('show version | inc System serial')

       serial = re.search('(?<=System serial number: ).*$', info).group()



   # Custom field "sif_test" update

   # all custom fields should start with 'custom_'

   device_broker = easy.client.get_broker('Device')

   field_name = "custom_{}".format('sif_test2')

   params = {

       'DeviceID': device.DeviceID,

       field_name: serial

   }

   result = device_broker.update(**params)

   print(result)


 

Script 5 - Grab Networks from DDI

 

Goal: Automate the addition of a new network in DDI into the NetMRI scanners.

Automation does not have to be complex in order to be useful. In a use case where you want to automatically keep the NetMRI scanning system in sync with the Infoblox grid, this simple check can accomplish it with minimal hassle.


In order to enable this functionality, we will first create an Extensible Attribute (EA) associated with network objects in the NIOS IPAM system.

This script will grab data from NIOS where EA:NetMRI equal to “Add”, we will take the networks from NIOS and add it to NetMRI discovery then update the EA:NetMRI to “Done”

 


# BEGIN-SCRIPT-BLOCK

#

# Script-Filter:

#     true

#

# Script-Variables:

#     $gmuser string "Grid Master Username"

#     $gmpassword password "Grid Master Password"

#     $gmipaddress string "192.168.1.2"

#

# END-SCRIPT-BLOCK

 

import requests

import json, re

# This will not error when you are not verifying Certs for https

#

requests.packages.urllib3.disable_warnings()

#

# gmip is a variable we asked for the Grid Master IP/FQDN

gmip = "https://{}/wapi/".format(gmipaddress)

#

# The version of WAPI you are using

wapi = "v2.5"

#

# The WPI call that we are going to use

call = "/network?*NetMRI%3A=Yes&_return_fields%2B=extattrs"

#

# Now we combine all the above to equal "url"

# https://192.168.1.2/wapi/v2.5/network?network=10.10.10.0/24

url = gmip + wapi + call

 

r = requests.get(url, auth=(gmuser, gmpassword), verify=False)

 

json_input = r.text

 

decoded = json.loads(json_input)

#print (decoded['network'])

 

for j in decoded:

   print (j['network'], j['network_view'],j['_ref'])

   url1 = "{}/api/3.2/discovery_settings/create?range_value=".format(api_url)

   url2 = j['network']

   url3 = "&range_type=CIDR&discovery_status=INCLUDE"

   url4 = url1 + url2 + url3

   add_net = requests.get(url4, auth=(gmuser, gmpassword), verify=False)

   print ("Added")

   call2 = j['_ref']

   url_update = gmip + wapi + "/" + call2

   payload = "{\n\t\"extattrs\": {\n\t\t\"NetMRI\": {\n\t\t\t\"value\": \"Done\"\n\t\t}\n\t}\n}"

   response = requests.request("PUT", url_update,auth=(gmuser, gmpassword), data=payload, verify=False)

   print("Updated NIOS EA")


Conclusion

NetMRI gives you a framework to focus your automation tasks around. By providing a common interface to numerous APIs and CLIs, you are already embracing the paradigm shift towards automate/virtualize/cloud/software defined everything that has become the latest solution to deal with scaling up into large network infrastructures.

Showing results for 
Search instead for 
Did you mean: