Search code examples
pythonjsonpython-requestsinfoblox

Infoblox WAPI: how to search for an IP


Our network team uses InfoBlox to store information about IP ranges (Location, Country, etc.) There is an API available but Infoblox's documentation and examples are not very practical.

I would like to search via the API for details about an IP. To start with - I would be happy to get anything back from the server. I modified the only example I found

import requests
import json

url = "https://10.6.75.98/wapi/v1.0/"
object_type = "network"    
search_string = {'network':'10.233.84.0/22'}

response = requests.get(url + object_type, verify=False,
  data=json.dumps(search_string), auth=('adminname', 'adminpass'))

print "status code: ", response.status_code
print response.text

which returns an error 400

status code:  400
{ "Error": "AdmConProtoError: Invalid input: '{\"network\": \"10.233.84.0/22\"}'",
  "code": "Client.Ibap.Proto",
  "text": "Invalid input: '{\"network\": \"10.233.84.0/22\"}'"
}

I would appreciate any pointers from someone who managed to get this API to work with Python.


UPDATE: Following up on the solution, below is a piece of code (it works but it is not nice, streamlined, does not perfectly checks for errors, etc.) if someone one day would have a need to do the same as I did.

def ip2site(myip): # argument is an IP we want to know the localization of (in extensible_attributes)
    baseurl = "https://the_infoblox_address/wapi/v1.0/"

    # first we get the network this IP is in
    r = requests.get(baseurl+"ipv4address?ip_address="+myip, auth=('youruser', 'yourpassword'), verify=False)
    j = simplejson.loads(r.content)
    # if the IP is not in any network an error message is dumped, including among others a key 'code'
    if 'code' not in j: 
        mynetwork = j[0]['network']
        # now we get the extended atributes for that network
        r = requests.get(baseurl+"network?network="+mynetwork+"&_return_fields=extensible_attributes", auth=('youruser', 'youpassword'), verify=False)
        j = simplejson.loads(r.content)
        location = j[0]['extensible_attributes']['Location']
        ipdict[myip] = location
        return location
    else:
        return "ERROR_IP_NOT_MAPPED_TO_SITE"

Solution

  • By using requests.get and json.dumps, aren't you sending a GET request while adding JSON to the query string? Essentially, doing a

    GET https://10.6.75.98/wapi/v1.0/network?{\"network\": \"10.233.84.0/22\"}
    

    I've been using the WebAPI with Perl, not Python, but if that is the way your code is trying to do things, it will probably not work very well. To send JSON to the server, do a POST and add a '_method' argument with 'GET' as the value:

    POST https://10.6.75.98/wapi/v1.0/network
    
    Content: {
       "_method": "GET",
       "network": "10.233.84.0/22"
    }
    
    Content-Type: application/json
    

    Or, don't send JSON to the server and send

    GET https://10.6.75.98/wapi/v1.0/network?network=10.233.84.0/22
    

    which I am guessing you will achieve by dropping the json.dumps from your code and handing search_string to requests.get directly.