Pool Member Update By A Record

Problem this snippet solves:

This is a script will do an A record lookup for a hostname and populate the specified pool with all available A records. The script will not change the existing pool member(s) or modify their connections if the next A record matches. Only changes to the associated A record will result in changes to the pool members. The script will error out and print a help message if any of the following conditions are met: 6 arguments are not provided (BIG-IP address, BIG-IP user, BIG-IP password, A record query, pool name, pool member port), the port is an invalid integer (valid ports: 1-65535), BIG-IP connection cannot be made, the pool does not exist, or no A record returned.

How to use this snippet:

Requirements

  • Ruby
  • Ruby Gems
  • F5 iControl for Ruby library (https://devcentral.f5.com/Tutorials/TechTips/tabid/63/articleType/ArticleView/articleId/1086421/Getting-Started-With-Ruby-and-iControl.aspx)
  • other dependencies will be installed with the iControl gem

Installation Steps

  1. Install Ruby, Ruby's OpenSSL library, Ruby Gems, and the Ruby iControl libraries
  2. Copy this code to /usr/local/bin and chmod +x to make the script executable
  3. Run it!
    • change-pool-member-to-a-record-result <BIG-IP address> <BIG-IP user> <BIG-IP password> < A record query> < pool name> < pool member port>

Code :

#!/usr/bin/ruby

require 'rubygems'
require 'f5-icontrol'
require 'resolv'

def usage
  puts $0 + '      '
  exit
end

# make sure enough arguments have been provided
usage if $*.size < 6
$*[5] = $*[5].to_i

# create iControl interface
bigip = F5::IControl.new($*[0], $*[1], $*[2], ['LocalLB.Pool']).get_interfaces

# test iControl connectivity
begin
  bigip['LocalLB.Pool'].get_version
rescue
  puts "Error: could not establish a connection to the BIG-IP. Check the hostname, user, and password."
  exit 1
end

# ensure that the pool member port is an integer and in the valid range
unless $*[5].between?(1, 65535)
  puts "Error: please provide a valid integer for the pool member port."
  exit 1
end

# make sure that the provided pool exists
unless bigip['LocalLB.Pool'].get_list.include? $*[4]
  puts "Error: could not locate #{$*[4]} pool. If using version 11, make sure to prepend the folder, e.g. /Common/my_pool"
  exit 1
end

# attempt to resolve the hostname
resources = Resolv::DNS.new.getresources($*[3], Resolv::DNS::Resource::IN::A)

# check if we received a response, exit on empty responses
if resources.size == 0
  puts "Error: could not resolve #{$*[3]}. Please verify the name, ensure that it is fully qualified, and verify setting in /etc/resolv.conf"
  exit 1
end

# grab a list of current pool members
old_members = bigip['LocalLB.Pool'].get_member([ $*[4] ])[0].collect do |member|
  { 'address' => member.address, 'port' => member.port }
end

# create an array to hold new member records and 
new_members = []

# add each of the returned a records to the pool
resources.each do |record|
  new_member = { 'address' => record.address.to_s, 'port' => $*[5] }

  if old_members.include? new_member
    old_members.delete new_member
    puts "Info: preserving pool member: #{new_member['address']}:#{new_member['port']}"
  else
    new_members << new_member
  end
end

# delete old members that are no longer used
old_members.each do |member|
  puts "Info: removing pool member: #{member['address']}:#{member['port']}"
end

bigip['LocalLB.Pool'].remove_member([ $*[4] ], [ old_members ])

# add new members to pool
new_members.each do |member|
  puts "Info: adding new pool member: #{member['address']}:#{member['port']}"
end

bigip['LocalLB.Pool'].add_member([ $*[4] ], [ new_members ])
Published Mar 09, 2015
Version 1.0

Was this article helpful?

No CommentsBe the first to comment