#! /usr/bin/env python3 # # Uses GET, PUT, and POST requests in the Infoblox RESTful Web API (WAPI) to # either create a new Host record or add an IP to an existing Host record. # # Requires ipam.py # # Author: dmrz import argparse import ipaddress import sys argparser = argparse.ArgumentParser( formatter_class=argparse.RawDescriptionHelpFormatter, description=""" Creates a new Host record with the specified primary fqdn and IP. If a Host record already exists with the specified fqdn, adds IP to that Host record instead. If IP is already registered to another Host, aborts with a warning. """, epilog=""" Examples: %(prog)s foo.sandbox.illinois.edu 192.168.0.5 %(prog)s foo.sandbox.illinois.edu 2001:db8::5 """) argparser.add_argument('fqdn', help='a fully-qualified domain name') argparser.add_argument('ip', help='an IPv4 or IPv6 address') args = argparser.parse_args() ### interesting work starts here import ipam s = ipam.Session( # Comment this out if you don't want to see debugging debug_enable=1 ) WAPI = s.WAPI # used in request URLs below def add_host_ip(fqdn, ipaddr): ip = ipaddress.ip_address(ipaddr) # check if IP already has a Host if ip.version == 4: response = s.get(WAPI+'/record:host', params={ 'ipv4addr': ipaddr, '_return_fields': ['name'] }) else: response = s.get(WAPI+'/record:host', params={ # search is picky about IPv6 spelling 'ipv6addr': ip.compressed, '_return_fields': ['name'] }) existing_hosts_for_ip = response.json() for host in existing_hosts_for_ip: name = host['name'] sys.exit("Abort: IP '{}' already in use by Host '{}', " "creating another Host would result in duplicate PTRs" .format(ipaddr, name)) # check if Host already exists (note ':' for case-insensitive search) existing_hosts_for_fqdn = s.get(WAPI+'/record:host', params={ 'name:': fqdn }).json() if existing_hosts_for_fqdn: # use PUT to modify the existing Host record (note special '+' behavior # supported by these fields to add a new IP without altering others) host = existing_hosts_for_fqdn[0] hostref = host['_ref'] if ip.version == 4: s.put(WAPI+'/'+hostref, json={ "ipv4addrs+": [{"ipv4addr": ipaddr}] }) else: s.put(WAPI+'/'+hostref, json={ "ipv6addrs+": [{"ipv6addr": ipaddr}] }) print("Added IP '{}' to Host '{}'".format(ipaddr, fqdn)) else: # use POST to create a new Host record if ip.version == 4: s.post(WAPI+'/record:host', json={ "name": fqdn, "ipv4addrs": [{"ipv4addr": ipaddr}] }) else: s.post(WAPI+'/record:host', json={ "name": fqdn, "ipv6addrs": [{"ipv6addr": ipaddr}] }) print("Created new Host '{}'".format(fqdn)) add_host_ip(args.fqdn, args.ip)