Default Route Ping and Failover Script [Solaris/Ruby]

Wrote this for my squid boxes. They’re built with lots of redundancy – I can fail over to a different NIC/IP address in the event of a connectivity failure.

Written and tested on Solaris, runs as a Ruby daemon.

#!/usr/local/bin/ruby
 
require 'net/smtp'
require 'daemons'
 
#
# defaultroute_failover.rb runs as a daemon.
#
#  $ ruby myproc_control.rb start
#      (myproc.rb is now running in the background)
#  $ ruby myproc_control.rb restart
#      (...)
#  $ ruby myproc_control.rb stop
#
# For testing purposes you can even run myproc.rb without forking in the background:
#
#  $ ruby myproc_control.rb run
#
 
###########################
# LOCAL CONFIGS
#
router_a = "161.201.128.1"
router_b = "62.50.202.65"
 
admin_email="noc@foo.com"
sleep_interval=60
debug=false
mail_enabled=true
#
###########################
 
hostname = `hostname`.chomp
 
active_defaultrouter = ""
backup_defaultrouter = ""
 
def get_defaultrouter
  return `netstat -rn | grep '^default' | awk '{ print $2 }'`.chomp
end
 
def ping(host)
  system "/usr/local/sbin/fping -r 5 -t 1000 -p 3000 -q #{host} >/dev/null 2>&1"
 
  if ($?.exitstatus == 0)
    return true
  else 
    return false
  end
end
 
def mail_admin(msg)
  if mail_enabled
    from = "root@#{hostname}.foo.com"
    to = admin_email
    Net::SMTP.start('localhost') do |smtp|
      smtp.send_message msg, from, to
    end
  end
end
 
def switch_defaultrouter
  `route delete default #{active_defaultrouter}`
  `route add default #{backup_defaultrouter}`
end
 
#############################################################################################################################
 
Daemons.run_proc('defaultroute_failover.rb') do
  loop do
 
    active_defaultrouter = get_defaultrouter()
 
    if active_defaultrouter == router_a
      backup_defaultrouter = router_b
    elsif active_defaultrouter == router_b
      backup_defaultrouter = router_a
    else
      msg = "Active default router is an unrecognized IP address: #{active_defaultrouter}. Exiting with no actions."
      puts msg if debug
      mail_admin msg
      exit 1
    end
 
    if debug
      puts "router_a = #{router_a}"
      puts "router_b = #{router_b}"
      puts "active_defaultrouter = #{active_defaultrouter}"
      puts "backup_defaultrouter = #{backup_defaultrouter}"
    end
 
    if ! ping(active_defaultrouter)
      puts "I canont ping the active default router at #{active_defaultrouter}!!!" if debug
      if ping(backup_defaultrouter)
        puts "I can ping the backup default router at #{backup_defaultrouter}." if debug
        switch_defaultrouter if !debug
        msg = "#{hostname} proxy defaultrouter unpingable. switched defaultrouter from #{active_defaultrouter} to #{backup_defaultrouter}."
        puts msg if debug
        mail_admin msg
      else
        puts "I can NOT ping the backup default router at #{backup_defaultrouter}!!!" if debug
        msg = "#{hostname} proxy defaultrouter and backup defaultrouter unpingable."
        puts msg if debug
        mail_admin msg
      end
    else
      puts "I can ping the active default router at #{active_defaultrouter} with no issues." if debug
    end
    sleep sleep_interval
  end
end
This entry was posted in Uncategorized and tagged , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">