Infoblox dns management – using the REST api with Python

Infoblox provides a product to manage your DNS, DHCP and IPAM through a single management interface. In this short article, I will walk you through automating some of the day to day operations work in managing DNS using Infoblox REST API. The REST based api tool can be also used to manage DHCP and IPAM.

The Infoblox WAPI is the REST interface we will interact with. In a highly available DNS setup, the WAPI requests go to the HA Grid Master IP or hostname. The requests typically have arguments and body. A great resource that helped me get started is a github repo of Infoblox Api python modules.

Clone the Infoblox Python modules repo to get started –

cd /tmp
git clone https://github.com/Infoblox-Development/Infoblox-API-Python.git

The class initialization of infoblox api (infoblox.py ) holds certain parameters, including ones used for authentication. Set this values according to your environment.

        """ Class initialization method
        :param iba_ipaddr: IBA IP address of management interface
        :param iba_user: IBA user name
        :param iba_password: IBA user password
        :param iba_wapi_version: IBA WAPI version (example: 1.0)
        :param iba_dns_view: IBA default view
        :param iba_network_view: IBA default network view
        :param iba_verify_ssl: IBA SSL certificate validation (example: False)
        """

Once you have the right parameters, you can write scripts which utilize the infoblox.py module. Here is a simple python script to get A record record details, given an IP address and domain.

Make sure you work under the directory where you cloned the infoblox github repo –

Script path: /tmp/get_a_record.py
Usage example: python /tmp/get_a_record.py 192.168.100.2  mail-gateway.example.net

Script to pull A record details of a DNS zone –

#!/usr/bin/env python

import infoblox
import sys
import requests
import json
import socket

def Usage():
    print "{0} {1} {2}".format(sys.argv[0], 'IP-ADDRESS','FQDN')
    sys.exit(1)

if len(sys.argv)<3:
    Usage()

myip=sys.argv[1]
myfqdn=sys.argv[2].lower()
try:
    socket.inet_aton(myip)
except:
    print "Not valid IP."
    sys.exit(1)

# Create a session
ibx_server='grid-master.example.net'
ibx_username='dns-admin'
ibx_password='admin-secret'
ibx_version='1.6'
ibx_dns_view='default'
ibx_net_view='default'

ibx=infoblox.Infoblox(ibx_server, ibx_username, ibx_password, ibx_version, ibx_dns_view, ibx_net_view, iba_verify_ssl=False)

# Get address details
payload='{"ipv4addr": '  + json.JSONEncoder().encode(myip) + ',' + '"name": ' + json.JSONEncoder().encode(myfqdn) + '}'
my_url='https://' + ibx.iba_host + '/wapi/v' + ibx.iba_wapi_version + '/record:a'
r = requests.get(url=my_url, auth=(ibx.iba_user, ibx.iba_password), verify=ibx.iba_verify_ssl, data=payload)
data = r.json()
print data

You can also use the existing class methods defined in the infoblox module. In the below example, I am using the ‘create_cname_record’ method to create an Alias.

ibx=infoblox.Infoblox(ibx_server, ibx_username, ibx_password, ibx_version, ibx_dns_view, ibx_net_view, iba_verify_ssl=False)
canonical='www.example.net'
name='web-server1.example.net'
ibx.create_cname_record(canonical, name)

If you can’t find the particular method in the infoblox module, it should’t be difficult to write one. Follow the api reference documentation on the structure of the WAPI Api calls.

Note – in some cases, you have to make multiple api calls to perform certain tasks. One example is updating the TTL for a DNS entry. On the first call, you need to get the host reference id and on second call update the TTL. The below example shows a simple python script to update the TTL (in seconds) for an existing FQDN entry.

Usage example - python update_ttl.py mail-gateway.example.net 600

update_ttl.py script –

#!/usr/bin/env python

import infoblox
import sys
import json
import requests

def Usage():
    print "{0} {1} {2}".format(sys.argv[0], 'ExistingFQDN', 'TTL')
    sys.exit(1)

if len(sys.argv)<3:
    Usage()

oldname=sys.argv[1].lower()
newttl=int(sys.argv[2])

# Create a session
ibx_server='grid-master.example.net'
ibx_username='dns-admin'
ibx_password='admin-secret'
ibx_version='1.6'
ibx_dns_view='default'
ibx_net_view='default'
ibx=infoblox.Infoblox(ibx_server, ibx_username, ibx_password, ibx_version, ibx_dns_view, ibx_net_view, iba_verify_ssl=False)
# Validate oldname exists
ibxhost=ibx.get_host(oldname)
if ibxhost['name'] != oldname:
    print oldname + " does not exist."
    sys.exit(1)
# update data
host_ref=ibxhost['_ref']
payload=json.dumps({'ttl':newttl})
my_url = 'https://' + ibx.iba_host + '/wapi/v' + ibx.iba_wapi_version + '/' + host_ref
r = requests.put(url=my_url, auth=(ibx.iba_user, ibx.iba_password), verify=ibx.iba_verify_ssl, data=payload)
if r.ok:
    print("TTL updated successfully.")
else:
    print("Error - {}".format(r.content))

References –

Products page – https://www.infoblox.com/products/dns/

Rest API documentation – https://www.infoblox.com/wp-content/uploads/infoblox-deployment-infoblox-rest-api.pdf

HA GRID MASTER – https://docs.infoblox.com/display/NAG8/Chapter+5+Deploying+a+Grid#Chapter5DeployingaGrid-bookmark587