Project

General

Profile

Download (3.1 KB) Statistics
| Branch: | Tag: | Revision:
b3c7e27f Ohad Levy
require "proxy/dns"
5bea99b1 Paul Kelly
require 'resolv'
b3c7e27f Ohad Levy
module Proxy::DNS
7e72434b Dominic Cleal
class Nsupdate < Record
b3c7e27f Ohad Levy
0dd2f70c Jeremy Kitchen
include Proxy::Log
741d4f86 Ohad Levy
include Proxy::Util
b1b32f74 Paul Kelly
attr_reader :resolver
741d4f86 Ohad Levy
ba083eee Ohad Levy
def initialize options = {}
60072a4c Paul Kelly
raise "Unable to find Key file - check your dns_key settings" unless SETTINGS.dns_key == false or File.exists?(SETTINGS.dns_key)
b3c7e27f Ohad Levy
super(options)
end

# create({ :fqdn => "node01.lab", :value => "192.168.100.2"}
# create({ :fqdn => "node01.lab", :value => "3.100.168.192.in-addr.arpa",
# :type => "PTR"}
bb559b8b Ohad Levy
def create
b3c7e27f Ohad Levy
nsupdate "connect"
b1b32f74 Paul Kelly
@resolver = Resolv::DNS.new(:nameserver => @server)
b3c7e27f Ohad Levy
case @type
b1b32f74 Paul Kelly
when "A"
if ip = dns_find(@fqdn)
ce02a67a Paul Kelly
raise(Proxy::DNS::Collision, "#{@fqdn} is already used by #{ip}") unless ip == @value
b1b32f74 Paul Kelly
else
nsupdate "update add #{@fqdn}. #{@ttl} #{@type} #{@value}"
end
when "PTR"
if name = dns_find(@value)
ce02a67a Paul Kelly
raise(Proxy::DNS::Collision, "#{@value} is already used by #{name}") unless name == @fqdn
b1b32f74 Paul Kelly
else
nsupdate "update add #{@value}. #{@ttl} IN #{@type} #{@fqdn}"
end
b3c7e27f Ohad Levy
end
nsupdate "disconnect"
b1b32f74 Paul Kelly
ensure
0abb301b Paul Kelly
@om.close unless @om.nil? or @om.closed?
b3c7e27f Ohad Levy
end

# remove({ :fqdn => "node01.lab", :value => "192.168.100.2"}
bb559b8b Ohad Levy
def remove
b3c7e27f Ohad Levy
nsupdate "connect"
case @type
when "A"
nsupdate "update delete #{@fqdn} #{@type}"
when "PTR"
nsupdate "update delete #{@value} #{@type}"
end
nsupdate "disconnect"
end

7e72434b Dominic Cleal
protected
b3c7e27f Ohad Levy
7e72434b Dominic Cleal
def nsupdate_args
args = ""
args = "-k #{SETTINGS.dns_key} " if SETTINGS.dns_key
args
741d4f86 Ohad Levy
end

b3c7e27f Ohad Levy
def nsupdate cmd
status = nil
if cmd == "connect"
741d4f86 Ohad Levy
find_nsupdate if @nsupdate.nil?
7e72434b Dominic Cleal
nsupdate_cmd = "#{@nsupdate} #{nsupdate_args}"
logger.debug "running #{nsupdate_cmd}"
@om = IO.popen(nsupdate_cmd, "r+")
logger.debug "nsupdate: executed - server #{@server}"
b3c7e27f Ohad Levy
@om.puts "server #{@server}"
18a0cb41 Ohad Levy
elsif cmd == "disconnect"
b3c7e27f Ohad Levy
@om.puts "send"
@om.puts "answer"
@om.close_write
status = @om.readlines
@om.close
c6ea383c Paul kelly
@om = nil # we cannot serialize an IO object, even if closed.
b3c7e27f Ohad Levy
# TODO Parse output for errors!
ce02a67a Paul Kelly
if !status.empty? and status[1] !~ /status: NOERROR/
18a0cb41 Ohad Levy
logger.debug "nsupdate: errors\n" + status.join("\n")
46a733fb Ohad Levy
raise Proxy::DNS::Error.new("Update errors: #{status.join("\n")}")
18a0cb41 Ohad Levy
end
b3c7e27f Ohad Levy
else
logger.debug "nsupdate: executed - #{cmd}"
@om.puts cmd
end
end
7e72434b Dominic Cleal
b1b32f74 Paul Kelly
private
7e72434b Dominic Cleal
def find_nsupdate
7e3ca5c2 Michael Moll
@nsupdate = which("nsupdate")
7e72434b Dominic Cleal
unless File.exists?("#{@nsupdate}")
logger.warn "unable to find nsupdate binary, maybe missing bind-utils package?"
raise "unable to find nsupdate binary"
end
end

b1b32f74 Paul Kelly
def dns_find key
if match = key.match(/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/)
resolver.getname(match[1..4].reverse.join(".")).to_s
else
resolver.getaddress(key).to_s
end
rescue Resolv::ResolvError
false
end
b3c7e27f Ohad Levy
end
end