Infoblox Automate IPAM


#1

Hi,

Does anyone have any automate code they can provide that gets IP addresses from Infoblox IPAM. I understand there’s a POC domain which has a reserveDHCP infoblox method but I want to get and an address from IPAM.

What I want to achieve

  1. Get IP details from infoblox for all machine provisioning
  2. Update VMware custom spec with static IP information from Infoblox

Thanks


#2

There is a Ruby gem here that can make adding to your methods a little easier, or you can make API calls directly to Infoblox. Infoblox has a good list of examples of REST API calls on their community page.


#3

Hi,

You can also check the community depot -> https://depot.manageiq.org


#4

Take a look at this blog which should help you get started.

The code that is on the blog is 3 years old, You may want to try the one from the POC instead which should do what you need it can be found here

As for where to set it in the provisioning it has changed since that blog and is now as per my screenshot

Also don’t forget to also make use of the ReleaseIP feature for when you decommission boxes.


#5

Hi,

I’m using Infoblox IPAM too.
We use the ruby gem to interact with Infoblox.
You can also request the infoblox API directly using httpclient gem.

connection = Infoblox::Connection.new(
      :username => infoblox_config[:username],
      :password => infoblox_config[:password],
      :host     => infoblox_config[:server]
    )
network=Infoblox::Network.find(connection,{"network"=><YourSubnet>}).first
ip = network.next_available_ip.first
host = Infoblox::Host.new(:connection => connection)
    host.ipv4addrs = [{
        :ipv4addr => "#{ip}",
        :mac => mac.gsub('-', ':')
      }]
host.name = <YourHostname>
    host.post

Something like code above will do the trick of getting an available ip and register an host.


#6

Here is what we use. It’s adapted from the ramrexx/CloudFormsPOC code.
There’s probably a lot of room for improvement but it works.
You’ll obviously need to update with your VLAN info and have the right schema fields.

require 'rest_client'
require 'json'
require 'ipaddr'

def log(level, message)
  $evm.log(level, 'GetIP -> ' + message)
end

# Reserve next IP Address and return created host record
def reserveIP(hostname)
  function_string = 'func:nextavailableip:' + @network
  url = 'https://' + @connection + '/wapi/v2.2/record:host'
  headers = { content_type: :json, accept: :json }
  content = { ipv4addrs: [{ ipv4addr: function_string }], name: hostname }
  options = {
    url: url,
    method: :post,
    headers: headers,
    payload: content.to_json,
    verify_ssl: false }
  r = RestClient::Request.execute(options)
  host_ref = JSON.parse(r.body).to_s
rescue Exception => e
  log(:warn, "error: #{e.inspect}")
  log(:info, "Response: #{r}")
  false
end

# Get and return IP Address
def getIP(host)
  url = 'https://' + @connection + '/wapi/v2.2/' + host
  headers = { accept: :json }
  options = {
    url: url,
    method: :get,
    headers: headers,
    verify_ssl: false }
  r = RestClient::Request.execute(options)
  hash = JSON.parse(r)
  ip = hash['ipv4addrs'][0]['ipv4addr']
rescue Exception => e
  log(:warn, "error: #{e.inspect}")
  log(:info, "Response: #{r}")
  false
end

# Set netmask
def netmask(cdir)
  netblock = IPAddr.new(cdir)
  netins =  netblock.inspect
  netmask = netins.match(/(?<=\/)(.*?)(?=\>)/)
  log(:info, "Netmask = #{netmask}")
  netmask
end

# Set Options in prov
def set_prov(prov, hostname, ipaddr, netmask, gateway)
  log(:info, "Hostname = #{hostname}")
  log(:info, "IP Address = #{ipaddr}")
  log(:info, "Netmask = #{netmask}")
  log(:info, "Gateway = #{gateway}")
  prov.set_option(:sysprep_spec_override, [true, 1])
  prov.set_option(:addr_mode, ["static", "Static"])
  prov.set_option(:ip_addr, ipaddr.to_s)
  prov.set_option(:subnet_mask, netmask.to_s)
  prov.set_option(:gateway, gateway.to_s)
  prov.set_option(:vm_target_name, hostname.to_s)
  prov.set_option(:linux_host_name, hostname.to_s)
  prov.set_option(:vm_target_hostname, hostname.to_s)
  prov.set_option(:hostname, hostname.to_s)
  prov.set_option(:host_name, hostname.to_s)

# Set VLAN options
def find_vlan(vlan, prov)
  prov.set_vlan(vlan)
  prov.set_dvs(vlan)
  case vlan
  when 'VLAN_1'
    log(:info, 'Assigned to VLAN 1')
    @gateway = '0.0.0.0'
    @network = '0.0.0.0/27'
  when 'VLAN_2'
    log(:info, 'Assigned to VLAN 2')
    @gateway = '0.0.0.0'
    @network = '0.0.0.0/27'
  else
    log(:info, 'Invalid VLAN requested')
  end
end

# MAIN PROGRAM
begin
  log(:info, '********* InfoBlox - GetIP STARTED *********')
  username = $evm.object['user']
  password = $evm.object.decrypt('passwd')
  server = $evm.object['grid_server']
  @dnsdomain = $evm.object['dns_domain']
  @connection = "#{username}:#{password}@#{server}"
  prov = $evm.root['miq_provision'] || \
         $evm.root['miq_provision_request'] || \
         $evm.root['miq_provision_request_template']
  init_vlan = case prov.options[:vlan].class
              when String
                prov.options[:vlan]
              when Array
                prov.options[:vlan].first
              end
  vlans = $evm.object['vlan_array']

  # initialize vars for loop
  index = vlans.find_index(init_vlan)
  num_tried = 0

  until num_tried == vlans.length
    vlan_string = vlans[index]
    find_vlan(vlan_string, prov)
    host_ref = reserveIP("#{prov.options[:vm_target_name]}.#{@dnsdomain}")
    log(:info, 'INFOBLOX Response: ' + host_ref.try(:inspect)) # for debugging

    # if a host record is returned set options in prov, otherwise try the next VLAN
    if host_ref != false
      next_ip = getIP(host_ref)
      netmask = netmask(@network)
      set_prov(prov, prov.options[:vm_target_name], next_ip, netmask, @gateway)
      log(:info, "#{prov.options[:vm_target_name]}.#{@dnsdomain} with IP Address #{next_ip} created successfully")
      break # SUCCESS
    else
      log(:warn, "#{prov.options[:vm_target_name]}.#{@dnsdomain} IP Address FAILED")
    end

    num_tried += 1
    index == vlans.length - 1 ? (index = 0) : (index += 1)
  end

  log(:info, "Provision object updated: [ip_addr: #{prov.options[:ip_addr]} subnet_mask: #{prov.options[:subnet_mask]} gateway: #{prov.options[:gateway]}]")
  log(:info, '********* InfoBlox - GetIP COMPLETED *********')
  host_ref ? (exit MIQ_OK) : (exit MIQ_ABORT)
rescue => err
  log(:error, "[#{err}]\n#{err.backtrace.join("\n")}")
  exit MIQ_ABORT
end