#!/usr/local/bin/python """ Export network containers and networks and their EAs in CSV format. This script will produce a CSV file containing information for each network and network container in the default network view. For each network or network container the corresponding row in the CSV output includes the network address in CIDR format, the comment associated with the network or network container, and then multiple columns for the extensible attribute values for the network or network container. The CSV output will contain a column for each of the extensible attributes for which at least one network or network container has a value, listed in alphabetical order of the EA names. If a given network or network container does not have a particular EA defined then the column for that EA will be blank. If a given network or network container has an EA with multiple values then the column for that EA will contain a quoted comma-separated list of the values. 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 network containers) then set the variable 'max_results' to the (negative of the) number of networks (or network containers) to return. This script should work for NIOS 6.8 and later (WAPI 1.2 and later). """ # Import the required Python modules. import requests import json import csv import getpass import sys def ea_values(ea_names, result): """ Given a list of EA names, return the list of corresponding values. Args: ea_names (list): a list of strings representing EA names. result (dict): the fields of a WAPI object. Returns: list: A list of strings representing the EA values corresponding to the EA names. For a multi-valued EA the string corresponding to that EA name will contain the values separated by commas, e.g., '192.168.0.1,192.168.0.2'. """ ea_values = [] # Verify that the object actually contains an EA field. if 'extattrs' in result: extattrs = result['extattrs'] # For each EA of interest, retrieve the value of that EA for # this object, if it has one defined. for ea_name in ea_names: ea_value = '' if ea_name in extattrs: ea_value = extattrs[ea_name]['value'] # If the EA contains multiple values then create a string # containing the comma-separate values. if isinstance(ea_value, list): ea_value = ','.join(ea_value) ea_values.append(ea_value) return(ea_values) def ipv4addr_key(network_info): """ Return a character string to use for sorting networks by address. Args: network_info (list): Information about the network, with a string containing an IPv4 network address in CIDR format as the first element. Returns: str: A 14-character string, with the first 12 characters containing the zero-filled integer value for the 32-bit network address, and the last 2 characters containing the zero-filled integer value for the CIDR prefix. """ # Split CIDR string into network address string and prefix string. cidr = network_info[0] addr_str, prefix_str = cidr.split('/') # Split dotted decimal address into octets, convert to binary. 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]) # Concatenate address value and prefix value to form sort key. prefix_value = int(prefix_str) key_str = '{:0>12d}/{:0>2d}'.format(addr_value, prefix_value) return key_str # Set parameters to access the NIOS WAPI. url = 'https://gm.example.com/wapi/v1.2/' 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 + ': ') # If running on Windows avoid error due to a self-signed cert. if sys.platform.startswith('win') and not valid_cert: requests.packages.urllib3.disable_warnings() # Retrieve all network objects (up to a max of 5000). network_view = 'default' max_results = -5000 req_params = {'network_view': network_view, '_return_fields+': 'extattrs', '_max_results': str(max_results)} r = requests.get(url + 'network', params=req_params, 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)) results = r.json() # Save the authentication cookie for use in the next request. ibapauth_cookie = r.cookies['ibapauth'] # Retrieve all network container objects (up to a max of 5000). # Use the ibapauth cookie to authenticate instead of userid/password. request_cookies = {'ibapauth': ibapauth_cookie} network_view = 'default' max_results = -5000 req_params = {'network_view': network_view, '_return_fields+': 'extattrs', '_max_results': str(max_results)} r = requests.get(url + 'networkcontainer', 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)) results.extend(r.json()) # Determine the full set of extensible attributes returned. ea_names = set() for result in results: if 'extattrs' in result: ea_names.update(result['extattrs'].keys()) # Create a sorted list of the EA names found. ea_names = sorted(ea_names) # For each network or container keep track of the network address, any # comment, and any extensible attribute values, and add the resulting # information for that network/container to the list of networks. networks = [] for result in results: # Use a blank comment if no comment was defined. network = [result['network'], result.get('comment', '')] # Check to see if the network has values for the EAs found above # and if so add the EA values to the network information. network.extend(ea_values(ea_names, result)) networks.append(network) # Sort the resulting list by network address and prefix. networks.sort(key=ipv4addr_key) # Export the results in CSV format. with open('export-network-hierarchy-with-ea-values.csv', 'wb') as out_file: out_csv = csv.writer(out_file, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL) # Always export these columns. header_row = ['Network', 'Comment'] # Export additional columns for any EAs found. header_row.extend(ea_names) out_csv.writerow(header_row) # Export one row for each network or network container. for network in networks: out_csv.writerow(network)