#!/usr/local/bin/python """ Export used IPv4 addresses in selected networks. This script finds all networks (in the default network view) with comments matching a specified string, and then exports all non-DHCP addresses within those networks for which there is IPAM information (i.e., the status field has the value "USED"). To use this script change the 'url' variable to contain the domain name or IP address of the grid master, and change the 'id' variable to contain a userid with WAPI access to the grid master. (The script will prompt for the corresponding password when run.) If your grid master uses a TLS/SSL certificate from a commercial CA then set the variable 'valid_cert' to True. If your grid contains more than 5,000 networks or more than 5,000 used addresses in a given network then set the variable 'max_results' to the (negative of the) number of networks or addresses to return. This script should work for NIOS 6.12 and later (WAPI 1.7 and later). """ # Import the required Python modules. import requests import json import csv import getpass import sys def ipv4addr_key(address_tuple): """ Return a character string to use for sorting IPv4 addresses. Args: address_tuple (tuple): A tuple with a string containing an IPv4 address as the first element. Returns: str: A 12-character string containing the zero-filled integer value for the 32-bit network address """ # Split dotted decimal address into octets, convert to binary. addr_str = address_tuple[0] addr_octets = [int(octet) for octet in addr_str.split('.')] addr_value = (256*256*256 * addr_octets[0] + 256*256 * addr_octets[1] + 256 * addr_octets[2] + addr_octets[3]) # Format address value to form sort key. key_str = '{:0>12d}'.format(addr_value) return key_str # Set parameters to access the NIOS WAPI. url = 'https://gm.example.com/wapi/v1.7/' id = 'api' # Userid with WAPI access valid_cert = False # True if GM uses certificate from commercial CA # Prompt for the API user password. pw = getpass.getpass('Password for user ' + id + ': ') # Avoid warnings due to a self-signed cert. if not valid_cert: requests.packages.urllib3.disable_warnings() # The string we want to match in comments. #string_to_match = 'ome' # Retrieve all network objects (up to a max of 5000) in the default # network view with comments matching a certain string. # # NOTE: We have to include all parameters as part of the url argument # to requests.get() because string matching uses '~=' instead of '='. network_view = 'default' max_results = -5000 r = requests.get(url + 'network' + '?network_view=' + network_view + '&_max_results=' + str(max_results) + '', # '&comment~=' + string_to_match, auth=(id, pw), verify=valid_cert) if r.status_code != requests.codes.ok: print r.text exit_msg = 'Error {} finding networks: {}' sys.exit(exit_msg.format(r.status_code, r.reason)) network_results = r.json() # Save the authentication cookie for use in the next request. ibapauth_cookie = r.cookies['ibapauth'] # Print networks found. print 'Matching networks:' for network_result in network_results: print network_result['network'], network_result['network_view'] # For each matching network retrieve all used addresses (up to a max # of 5000) and filter them to remove addresses dynamically assigned # via DHCP (DHCP fixed addresses are OK). print 'Finding used addresses...' used_addresses = [] for network_result in network_results: network = network_result['network'] network_view = network_result['network_view'] # Skip any network larger than a /24. addr_str, prefix_str = network.split('/') prefix = int(prefix_str) if prefix < 24: continue # Use the ibapauth cookie to authenticate instead of userid/password. request_cookies = {'ibapauth': ibapauth_cookie} max_results = -5000 req_params = {'network': network, 'network_view': network_view, 'status': 'USED', '_max_results': str(max_results)} r = requests.get(url + 'ipv4address', params=req_params, cookies=request_cookies, verify=valid_cert) if r.status_code != requests.codes.ok: print r.text exit_msg = 'Error {} finding network containers: {}' sys.exit(exit_msg.format(r.status_code, r.reason)) address_results = r.json() for address_result in address_results: address = address_result['ip_address'] names = ','.join(address_result['names']) type = '' if 'lease_state' in address_result: if address_result['lease_state'] == 'ACTIVE': type = 'dynamic' else: type = 'free' elif 'FA' in address_result['types']: type = 'fixed' else: type = 'static' used_addresses.append((address, names, type)) print '...done' # Sort the resulting used address list by address. used_addresses.sort(key=ipv4addr_key) # Export the results in CSV format. print 'Exporting used addresses...' with open('export-used-addresses.csv', 'wb') as out_file: out_csv = csv.writer(out_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) # Export these columns. header_row = ['Address', 'Names', 'Type'] out_csv.writerow(header_row) # Export one row for each used address. for used_address in used_addresses: out_csv.writerow(used_address) print '...done'