Reply
Highlighted
Accepted Solution

API How to "Dummy's Guide"

[ Edited ]
Authority
Posts: 36
30159     0

I am very much a newbie when it comes to scripting but I have a task in front of me that needs to be completed and so I am on a mission to figure it out.

 

I have been trying to figure out how to pull information from Infoblox (6.12.9) using API calls.  My goal is to have a simple html page that displays information once someone clicks on a link that will display the below information (possibly even give them the ability to export it to a csv file)

  • subnet address
  • subnet mask
  • Total IPs
  • Used IPs
  • Percent Used
  • EA-subnet name
  • EA-LocationID
  • EA-Street
  • EA-City
  • EA-State
  • EA-Zip
  • EA-Country

Any help anyone could offer on how to accomplish this I would be very appreciative.  I have been looking through the posts on here trying to figure this out but I'm running into a wall.  I've googled like crazy looking for an example of something similar and not much luck.

Re: API How to "Dummy's Guide"

Adviser
Posts: 131
30160     0

Actually I answered a question about "WAPI IPAM statistics" a while back that was similar to this. Since I already had a program that was somewhat close to what you wanted, I decided to modify it to make it closer. See the attached file.

 

To use the script, rename it to "ipam-stats.py" and modify it to change "gm.example.com" to the name of your grid master. In this script I just exported the values of the Country and State extensible attributes. It should be fairly obvious how to modify the script to export other EAs.

 

You will need to have the Python "requests" module installed if you don't already have it. Ask a local Python how to do this, or go to the requests module web site. (But, really, if you're totally new to scripting find someone who can help you get Python and the necessary modules up and running. If you don't know any such person ask here and I'll try to help.)

 

One major point noted in my original answer: This script assumes that all the addresses assigned to a DHCP range are "used", even if there are addresses in the range for which leases have not been granted. Fixing this would require writing some additional code to look at the leases themselves; I haven't tried to do this yet.

Re: API How to "Dummy's Guide"

Authority
Posts: 36
30160     0

Thank You for getting me started down a path.

 

I am missing something. I verified python and the python requests module was installed. I then ran the script (after changing the Grid Master URL and login user only) and it just hangs. I did a CTRL + C to break out since it felt obvious it wasn't working and I got the following errors.  My plan is to try and decphier the errors but figured I'd let you know in case it was really obvious.

 

dennis@ubuntu:~$ python ipam-stats.py
Password for user admin:
^CTraceback (most recent call last):
  File "ipam-stats.py", line 58, in <module>
    verify=valid_cert)
  File "/usr/lib/python2.7/dist-packages/requests/api.py", line 60, in get
    return request('get', url, **kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/api.py", line 49, in request
    return session.request(method=method, url=url, **kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 457, in request
    resp = self.send(prep, **send_kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 569, in send
    r = adapter.send(request, **kwargs)
  File "/usr/lib/python2.7/dist-packages/requests/adapters.py", line 362, in send
    timeout=timeout
  File "/usr/lib/python2.7/dist-packages/urllib3/connectionpool.py", line 511, in urlopen
    conn = self._get_conn(timeout=pool_timeout)
  File "/usr/lib/python2.7/dist-packages/urllib3/connectionpool.py", line 231, in _get_conn
    return conn or self._new_conn()
  File "/usr/lib/python2.7/dist-packages/urllib3/connectionpool.py", line 714, in _new_conn
    return self._prepare_conn(conn)
  File "/usr/lib/python2.7/dist-packages/urllib3/connectionpool.py", line 687, in _prepare_conn
    conn.connect()
  File "/usr/lib/python2.7/dist-packages/urllib3/connection.py", line 237, in connect
    ssl_version=resolved_ssl_version)
  File "/usr/lib/python2.7/dist-packages/urllib3/contrib/pyopenssl.py", line 281, in ssl_wrap_socket
    cnx.do_handshake()
KeyboardInterrupt

 

I am curious as to how code could be written to show actual (not Free) IP utilization.  That would be the optimum report.

Re: API How to "Dummy's Guide"

Adviser
Posts: 131
30160     0

This error may have to do with an extra step you need on Windows that I forgot (because I use a Mac). I was writing up a separate reply on starting from scratch, and I'll go ahead and post that. It includes a small test program.

 

Frank

 

Re: API How to "Dummy's Guide"

Adviser
Posts: 131
30160     0

Since the subject of this thread is "API 'How to Dummy's Guide'" I thought it would also be good to include a (relatively) brief introduction for people who are new to both scripting and to the Infoblox APIs. This is oriented to the newer Web API (WAPI), also known as the RESTful API. There is another API, the Perl API or PAPI. I don't use that so I'm not that familar with it; I'll leave it to somone else to give an example Perl/PAPI script for this problem. Also, I use Python to do WAPI scripting, because Python is both powerful and relatively easy to learn; again, if you want to do WAPI scripting in PowerShell, Perl, etc., other people can address that.

 

First you need to install Python; I'll presume you're using Microsoft Windows. (Python comes pre-installed on Mac and Linux systems.) Windows installers for Python 2 and Python 3 are available from the Python Software Foundation at https://www.python.org/downloads/windows. I recommend using the latest Python 2.7 release (2.7.10 at the time of writing). You can install Python for all users on the system (default) or just for yourself. By default Python is installed into the directory C:\Python27, and I recommend you leave it there. Finally, you should add C:\Python27 and C:\Python27\Scripts to the system PATH variable. (This is not done by default.)

 

Python scripts are run from the Windows command prompt; once Python is installed and your PATH variable is set correctly you should be able to enter the following commands to verify that both Python itself and the pip utility are installed:

 

python --version
pip --version

You should then install the Python requests module:

 

pip install requests

Finally, you can test whether you can do WAPI calls as follows: First, create a file called wapitest.py with the following contents, replacing 'gm.example.com' with the name or IP address of your grid master, 'admin' with a suitable Infoblox userid, and 'infoblox' by the corresponding password:

 

import requests

url = 'https://gm.example.com/wapi/v1.0/'
id = 'admin'
pw = 'infoblox'

# The following line is needed only for Windows; omit it otherwise.
requests.packages.urllib3.disable_warnings()

r = requests.get(url + 'network', auth=(id, pw), verify=False)

print r.text

Then run the following command from the Windows command prompt:

 

python wapitest.py

The script should print out a list that looks something like the following, where each set of curly braces { and } enclose a WAPI object for a particular network:

 

[
    {
        "_ref": "network/ZG5zLm5ldHdvcmskMTkyLjE2OC4wLjAvMjMvMA:192.168.0.0/23/default", 
        "comment": "Main home network", 
        "network": "192.168.0.0/23", 
        "network_view": "default"
    }
 ...
]

If the above program works then you are ready to create more complicated scripts, and to run the script I attached earlier. (You just need to include the code line above that disables warning; I forgot about that because I write my scripts on a Mac.) If you're interested in learning more about how to code in Python there are lots of free resources on the Internet, including the Python tutorial (https://docs.python.org/2/tutorial/) and the Hitchhiker's Guide to Python (http://docs.python-guide.org/en/latest/).

Re: API How to "Dummy's Guide"

Adviser
Posts: 131
30160     0

Here's an even simpler way to test to see if you can access the Web API: If you're using Windows, bring up Internet Explorer and enter the following URL (again replacing 'gm.example.com' with the name or IP address of your grid master):

 

https://gm.example.com/wapi/v1.0/network?_return_type=xml-pretty

 

 This should first give you a certificate error page you'll have to click through, and then it should display a page of XML output listing the network objects.

 

If the above test fails, and if you can access your normal grid master interface via the same browser and site, post a reply and we can try further debugging.

Re: API How to "Dummy's Guide"

[ Edited ]
Authority
Posts: 36
30160     0

Is that example trying to display all objects or can it be limited to just IPv4 subnets/networks?  Reason I ask is most sample scripts I have been trying I keep getting too large so I am assuming its grabbing more than just the networks.

 

{ "Error": "AdmConProtoError: Result set too large (> 1000)", 
  "code": "Client.Ibap.Proto", 
  "text": "Result set too large (> 1000)"
}

 I'm assuming the scripts hanging is because I have a very large network.  Can't tell if the python script is not working or if its just trying to export a huge amount of data.

Re: API How to "Dummy's Guide"

Adviser
Posts: 131
30160     0

@DHosang_1 wrote:

Is that example trying to display all objects or can it be limited to just IPv4 subnets/networks?

The simple WAPI examples I've been giving (wapitest.py and the URL for use in MSIE) are retrieving only IPv4 network objects. If you're getting a "Result set too large" error then you should add the _max_results parameter, for example using a URL like the following:

 

https://gm.fhecker.com/wapi/v1.0/network?_return_type=xml-pretty&_max_results=-5000

This will return all results if the number if less than or equal to 5,000. If the number of results is greater than 5,000 then it will return an error (like the one you saw). If you use a positive 5,000 instead then you'll get the first 5,000 results, with any further results not returned:

 

https://gm.fhecker.com/wapi/v1.0/network?_return_type=xml-pretty&_max_results=5000

Re: API How to "Dummy's Guide"

Authority
Posts: 36
30160     0

I really want to thank you for your help.  In the spirit of API How to "Dummy's Guide" can you help me understand some of the basics to the scripts so I(we) can branch out experiementing more.

 

For example, you provided this python script to find all ranges with a certain DHCP Scope Option.  I have been trying to figure out how to include in the csv the EA LocationID so we can tell where each range is.  Your very helpful code is:

# Import the required Python modules.
import requests
import json
import csv

# Set parameters to access the Infoblox API for your own grid master.
url = 'https://gm.example.com/wapi/v1.0/'
id = 'admin'
pw = 'infoblox'
valid_cert = True  # False if self-signed certificate
desired_option = 7  # DHCP option to look for

# Retrieve DHCP ranges (up to first 2000, increase this if needed).
r = requests.get(url + 'range',
                 params={'_max_results': str(2000)},
                 auth=(id, pw),
                 verify=valid_cert)
ranges = r.json()

# Retrieve the options for each range, look for the option we're
# interested in.
discovered_options = []
for range in ranges:
    r = requests.get(url + range['_ref'],
                     params={'_return_fields': 'options'},
                     auth=(id, pw),
                     verify=valid_cert)
    options = r.json()['options']
    for option in options:
        if (option['vendor_class'] == 'DHCP' and
            option['num'] == desired_option):
            option_info = [range['network'],
                           range['start_addr'],
                           range['end_addr'],
                           option['num'],
                           option['value']]
            discovered_options.append(option_info)

# Print information about the ranges containing the option and the
# option's value in each range.
with open('ranges-with-option.csv', 'wb') as out_file:
    out_csv = csv.writer(out_file,
                         delimiter=',',
                         quotechar='"',
                         quoting=csv.QUOTE_MINIMAL)
    out_csv.writerow(['network', 'start_addr', 'end_addr', 'option', 'value'])
    for info in discovered_options:
        out_csv.writerow(info)

 

I believe all i have to do is concentrate on the
option_info = [range['network'],
range['start_addr'],
range['end_addr'],
option['num'],
option['value']]

It appears that start_addr is an attribute under the range object?  Is that the right though process? If so, how do I understand what other objects are available (like extensivle attributes object), etc..?

 

 

Re: API How to "Dummy's Guide"

Adviser
Posts: 131
30160     0

@DHosang_1 wrote:

It appears that start_addr is an attribute under the range object?  Is that the right though process? If so, how do I understand what other objects are available (like extensivle attributes object), etc..?


Yes, start_addr is a field within the range object. The basic idea is that every WAPI object has a set of fields associated with it. So, for example, in NIOS 6.12 (WAPI 1.7) the range object has 78 different possible fields (if I've counted correctly), including start_addr, end_addr, network (the subnet containing the range), and so on. The fields for each object are documented in the WAPI reference manual; for the range object see Section 3.32, Table 3.13, on pages 395-396 in the WAPI 1.7 manual.

 

When the WAPI results are returned in JSON format (the normal case) the fields of an object are represented as key/value pairs, where the key is the field name and the value is the field value, for example:

 

{'field_1': 'value_1', 'field_2': 'value_2', ..., 'field_n': 'value_n'}

 

Note that field names are always character strings, but (unlike the example above) in general field values may be strings, numbers, or more complex objects (e.g., lists of strings).

 

In Python a WAPI object and its fields are represented using the Python dictionary type, with syntax like that shown above. If range1 is a range object then the start_addr field of that object would be retrieved as either range1['start_addr'] or range1.get('start_addr'). The difference between these is relevant when a particular field does not have a value for a particular object. For example, some range objects may have an associated comment and some may not. If the range object range1 does not have an associated comment then referencing range1['comment'] will cause a fatal error, but using range1.get('comment') will just return an empty string.

 

This is relevant when retrieving the names and values of extensible attributes for an object. In WAPI 1.2 and later an object's extensible attributes are returned in a special field extattrs; for example, if range1 is a range object then its associated collection of extensible attributes would be accessible as range1['extattrs']. The value of the extattrs field is a set of key/value pairs representing the various extensible attributes; in other words, in Python the value of the extattrs field is itself a dictionary. For example, if the range object range1 has two extensible attributes Country and State, then range1['extattrs'] would have a value like the following:

 

{'Country': {'value': 'US'}, 'State': {'value': 'Maryland'}}

 

Note that the values of each of the extensible attributes Country and State are not simple strings, but are sets of key/value pairs, one of which (with the key 'value') stores the actual extensible attribute value.

 

Retrieving extensible attribute values is therefore a bit tricky: First you have to check if the extensible attribute is actually present in the extattrs field, and then (and only then) you can retrieve its values. If range1 is a range object then you can do this using Python code as follows:

 

country = ''
if 'Country' in range1['extattrs']:
    country = range1['extattrs']['Country']['value']

 

or as follows:

 

if 'Country' not in range1['extattrs']:
    country = ''
else:
    country = range1['extattrs']['Country']['value']

 

(There are likely more terse ways to do this in Python, but these is the most understandable ways I think.) The way to interpret the code above is as follows: 1. range1 is a Python dictionary, we index into it using the field name 'extattrs' to retrieve the extattrs field. 2. range1['extattrs'] is also a Python dictionary, we index into it using the extensible attribute name 'Country' to retrieve the Country extensible attribute. 3. range1['extattrs']['Country'] is also a Python dictionary, we index into it using the string 'value' to retrieve the actual value of the Country extensible attribute.

 

In this example the value of the Country extensible attribute was a text string ('US'), but in general extensible attributes can also be lists, numbers, etc. But that's enough complications for one post!

 

Frank

Re: API How to "Dummy's Guide"

wordprax
Techie
Posts: 2
30160     0

To fetch the items, we're going to use the aptly named Fetch API. Fetch makes making requests much easier than the classic XMLHttpRequest and returns a promise of the resolved response (which is important to Thunk).

 

 

 

 

HTML to Wordpress

Showing results for 
Search instead for 
Do you mean 

Recommended for You

Demo: Infoblox IPAM plug-in integration with OpenStack Newton