Merge pull request #9 from inkblot/resource-record-type
Create resource_record type
This commit is contained in:
commit
7bb07a4d10
@ -1,6 +1,9 @@
|
|||||||
require 'tempfile'
|
require 'puppet_bind/provider/nsupdate'
|
||||||
|
|
||||||
Puppet::Type.type(:dns_rr).provide(:nsupdate) do
|
Puppet::Type.type(:dns_rr).provide(:nsupdate) do
|
||||||
|
|
||||||
|
include PuppetBind::Provider::NsUpdate
|
||||||
|
|
||||||
commands :dig => 'dig', :nsupdate => 'nsupdate'
|
commands :dig => 'dig', :nsupdate => 'nsupdate'
|
||||||
|
|
||||||
def initialize(value={})
|
def initialize(value={})
|
||||||
@ -8,38 +11,6 @@ Puppet::Type.type(:dns_rr).provide(:nsupdate) do
|
|||||||
@properties = {}
|
@properties = {}
|
||||||
end
|
end
|
||||||
|
|
||||||
def exists?
|
|
||||||
!(query.empty?)
|
|
||||||
end
|
|
||||||
|
|
||||||
def create
|
|
||||||
update do |file|
|
|
||||||
accio(file)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
update do |file|
|
|
||||||
destructo(file)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def flush
|
|
||||||
return if @properties.empty?
|
|
||||||
update do |file|
|
|
||||||
destructo(file)
|
|
||||||
accio(file)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def ttl
|
|
||||||
query.first[:ttl]
|
|
||||||
end
|
|
||||||
|
|
||||||
def ttl=(ttl)
|
|
||||||
@properties[:ttl] = ttl
|
|
||||||
end
|
|
||||||
|
|
||||||
def rrdata
|
def rrdata
|
||||||
query.map { |record| record[:rrdata] }.sort
|
query.map { |record| record[:rrdata] }.sort
|
||||||
end
|
end
|
||||||
@ -50,43 +21,8 @@ Puppet::Type.type(:dns_rr).provide(:nsupdate) do
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def update(&block)
|
def newdata
|
||||||
file = Tempfile.new('dns_rr-nsupdate-')
|
resource[:rrdata]
|
||||||
file.write "server #{server}\n"
|
|
||||||
file.write "zone #{resource[:zone]}\n" unless resource[:zone].nil?
|
|
||||||
yield file
|
|
||||||
file.write "send\n"
|
|
||||||
file.close
|
|
||||||
if keyed?
|
|
||||||
nsupdate('-y', tsig_param, file.path)
|
|
||||||
else
|
|
||||||
nsupdate(file.path)
|
|
||||||
end
|
|
||||||
file.unlink
|
|
||||||
end
|
|
||||||
|
|
||||||
def accio(file)
|
|
||||||
resource[:rrdata].each do |datum|
|
|
||||||
file.write "update add #{name}. #{resource[:ttl]} #{rrclass} #{type} #{datum}\n"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def destructo(file)
|
|
||||||
rrdata.each do |datum|
|
|
||||||
file.write "update delete #{name}. #{ttl} #{rrclass} #{type} #{datum}\n"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def keyed?
|
|
||||||
!(resource[:secret].nil?)
|
|
||||||
end
|
|
||||||
|
|
||||||
def tsig_param
|
|
||||||
"#{resource[:hmac]}:#{resource[:keyname]}:#{resource[:secret]}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def server
|
|
||||||
resource[:server]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def specarray
|
def specarray
|
||||||
@ -105,27 +41,4 @@ private
|
|||||||
specarray[2]
|
specarray[2]
|
||||||
end
|
end
|
||||||
|
|
||||||
def query
|
|
||||||
unless @query
|
|
||||||
if keyed?
|
|
||||||
dig_text = dig("@#{server}", '+noall', '+answer', name, type, '-c', rrclass, '-y', tsig_param)
|
|
||||||
else
|
|
||||||
dig_text = dig("@#{server}", '+noall', '+answer', name, type, '-c', rrclass)
|
|
||||||
end
|
|
||||||
@query = dig_text.lines.map do |line|
|
|
||||||
linearray = line.chomp.split(/\s+/, 5)
|
|
||||||
{
|
|
||||||
:name => linearray[0],
|
|
||||||
:ttl => linearray[1],
|
|
||||||
:rrclass => linearray[2],
|
|
||||||
:type => linearray[3],
|
|
||||||
:rrdata => linearray[4]
|
|
||||||
}
|
|
||||||
end.select do |record|
|
|
||||||
record[:name] == "#{name}."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@query
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
44
lib/puppet/provider/resource_record/nsupdate.rb
Normal file
44
lib/puppet/provider/resource_record/nsupdate.rb
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
require 'puppet_bind/provider/nsupdate'
|
||||||
|
|
||||||
|
Puppet::Type.type(:resource_record).provide(:nsupdate) do
|
||||||
|
|
||||||
|
include PuppetBind::Provider::NsUpdate
|
||||||
|
|
||||||
|
commands :dig => 'dig', :nsupdate => 'nsupdate'
|
||||||
|
|
||||||
|
def initialize(value={})
|
||||||
|
super(value)
|
||||||
|
@properties = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
def data
|
||||||
|
query.map { |record| record[:rrdata] }.sort
|
||||||
|
end
|
||||||
|
|
||||||
|
def data=(data)
|
||||||
|
@properties[:rrdata] = data
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def rrdata
|
||||||
|
data
|
||||||
|
end
|
||||||
|
|
||||||
|
def newdata
|
||||||
|
resource[:data]
|
||||||
|
end
|
||||||
|
|
||||||
|
def rrclass
|
||||||
|
resource[:rrclass]
|
||||||
|
end
|
||||||
|
|
||||||
|
def type
|
||||||
|
resource[:type]
|
||||||
|
end
|
||||||
|
|
||||||
|
def name
|
||||||
|
resource[:record]
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
@ -10,14 +10,14 @@ Puppet::Type.newtype(:dns_rr) do
|
|||||||
if (value =~ /^([A-Z]+)\/([A-Z]+)\/[a-zA-Z0-9._-]+$/)
|
if (value =~ /^([A-Z]+)\/([A-Z]+)\/[a-zA-Z0-9._-]+$/)
|
||||||
rrclass = $1
|
rrclass = $1
|
||||||
if ( !%w(IN CH HS).include? rrclass )
|
if ( !%w(IN CH HS).include? rrclass )
|
||||||
raise ArgumentError, "Invalid resource record class: %s" % rrdata
|
Util::Errors.fail "Invalid resource record class: %s" % rrdata
|
||||||
end
|
end
|
||||||
type = $2
|
type = $2
|
||||||
if ( !%w(A AAAA CNAME NS MX SRV NAPTR PTR).include? type)
|
if ( !%w(A AAAA CNAME NS MX SPF SRV NAPTR PTR TXT).include? type)
|
||||||
raise ArgumentError, "Invalid resource record type: %s" % type
|
Util::Errors.fail "Invalid resource record type: %s" % type
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
raise ArgumentError, "%s must be of the form Class/Type/Name" % value
|
Util::Errors.fail "%s must be of the form Class/Type/Name" % value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -33,6 +33,7 @@ Puppet::Type.newtype(:dns_rr) do
|
|||||||
|
|
||||||
newproperty(:rrdata, :array_matching => :all) do
|
newproperty(:rrdata, :array_matching => :all) do
|
||||||
desc 'The resource record\'s data'
|
desc 'The resource record\'s data'
|
||||||
|
isrequired
|
||||||
|
|
||||||
def insync?(is)
|
def insync?(is)
|
||||||
Array(is).sort == Array(@should).sort
|
Array(is).sort == Array(@should).sort
|
||||||
|
|||||||
72
lib/puppet/type/resource_record.rb
Normal file
72
lib/puppet/type/resource_record.rb
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
Puppet::Type.newtype(:resource_record) do
|
||||||
|
@doc = 'A Resource Record in the Domain Name System'
|
||||||
|
|
||||||
|
ensurable
|
||||||
|
|
||||||
|
newparam(:title, :namevar => true) do
|
||||||
|
desc 'A unique name for the puppet resource'
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:rrclass) do
|
||||||
|
desc 'The record class'
|
||||||
|
defaultto 'IN'
|
||||||
|
newvalues 'IN', 'CH', 'HS'
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:type) do
|
||||||
|
desc 'The record type'
|
||||||
|
isrequired
|
||||||
|
newvalues 'A', 'AAAA', 'CNAME', 'NS', 'MX', 'SPF', 'SRV', 'NAPTR', 'PTR', 'TXT'
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:record) do
|
||||||
|
desc 'The fully-qualified record name'
|
||||||
|
isrequired
|
||||||
|
|
||||||
|
validate do |value|
|
||||||
|
Util::Errors.fail "Invalid value for record: #{value}" unless value =~ /^([a-zA-Z0-9_-]+\.)*[a-zA-Z0-9_-]+$/
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:zone) do
|
||||||
|
desc 'The zone to update'
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:server) do
|
||||||
|
desc 'The master server for the resource record'
|
||||||
|
defaultto 'localhost'
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:keyname) do
|
||||||
|
desc 'Keyname for the TSIG key used to update the record'
|
||||||
|
defaultto 'update'
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:hmac) do
|
||||||
|
desc 'The HMAC type of the update key'
|
||||||
|
defaultto 'HMAC-SHA1'
|
||||||
|
end
|
||||||
|
|
||||||
|
newparam(:secret) do
|
||||||
|
desc 'The secret of the update key'
|
||||||
|
end
|
||||||
|
|
||||||
|
newproperty(:ttl) do
|
||||||
|
desc 'Time to live of the resource record'
|
||||||
|
defaultto 43200
|
||||||
|
|
||||||
|
munge do |value|
|
||||||
|
Integer(value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
newproperty(:data, :array_matching => :all) do
|
||||||
|
desc 'The resource record\'s data'
|
||||||
|
isrequired
|
||||||
|
|
||||||
|
def insync?(is)
|
||||||
|
Array(is).sort == Array(@should).sort
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
125
lib/puppet_bind/provider/nsupdate.rb
Normal file
125
lib/puppet_bind/provider/nsupdate.rb
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
require 'tempfile'
|
||||||
|
|
||||||
|
module PuppetBind
|
||||||
|
module Provider
|
||||||
|
|
||||||
|
def self.nsupdate_provider(type)
|
||||||
|
end
|
||||||
|
|
||||||
|
module NsUpdate
|
||||||
|
|
||||||
|
def exists?
|
||||||
|
!(query.empty?)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
update do |file|
|
||||||
|
accio(file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
update do |file|
|
||||||
|
destructo(file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def flush
|
||||||
|
return if @properties.empty?
|
||||||
|
update do |file|
|
||||||
|
destructo(file)
|
||||||
|
accio(file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def ttl
|
||||||
|
query.first[:ttl]
|
||||||
|
end
|
||||||
|
|
||||||
|
def ttl=(ttl)
|
||||||
|
@properties[:ttl] = ttl
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def update(&block)
|
||||||
|
file = Tempfile.new('dns_rr-nsupdate-')
|
||||||
|
file.write "server #{server}\n"
|
||||||
|
file.write "zone #{zone}\n" unless zone.nil?
|
||||||
|
yield file
|
||||||
|
file.write "send\n"
|
||||||
|
file.close
|
||||||
|
if keyed?
|
||||||
|
nsupdate('-y', tsig_param, file.path)
|
||||||
|
else
|
||||||
|
nsupdate(file.path)
|
||||||
|
end
|
||||||
|
file.unlink
|
||||||
|
end
|
||||||
|
|
||||||
|
def accio(file)
|
||||||
|
newdata.each do |datum|
|
||||||
|
file.write "update add #{name}. #{resource[:ttl]} #{rrclass} #{type} #{datum}\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destructo(file)
|
||||||
|
rrdata.each do |datum|
|
||||||
|
file.write "update delete #{name}. #{ttl} #{rrclass} #{type} #{datum}\n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def server
|
||||||
|
resource[:server]
|
||||||
|
end
|
||||||
|
|
||||||
|
def zone
|
||||||
|
resource[:zone]
|
||||||
|
end
|
||||||
|
|
||||||
|
def keyname
|
||||||
|
resource[:keyname]
|
||||||
|
end
|
||||||
|
|
||||||
|
def hmac
|
||||||
|
resource[:hmac]
|
||||||
|
end
|
||||||
|
|
||||||
|
def secret
|
||||||
|
resource[:secret]
|
||||||
|
end
|
||||||
|
|
||||||
|
def keyed?
|
||||||
|
!secret.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
def tsig_param
|
||||||
|
"#{hmac}:#{keyname}:#{secret}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def query
|
||||||
|
unless @query
|
||||||
|
if keyed?
|
||||||
|
dig_text = dig("@#{server}", '+noall', '+answer', name, type, '-c', rrclass, '-y', tsig_param)
|
||||||
|
else
|
||||||
|
dig_text = dig("@#{server}", '+noall', '+answer', name, type, '-c', rrclass)
|
||||||
|
end
|
||||||
|
@query = dig_text.lines.map do |line|
|
||||||
|
linearray = line.chomp.split(/\s+/, 5)
|
||||||
|
{
|
||||||
|
:name => linearray[0],
|
||||||
|
:ttl => linearray[1],
|
||||||
|
:rrclass => linearray[2],
|
||||||
|
:type => linearray[3],
|
||||||
|
:rrdata => linearray[4]
|
||||||
|
}
|
||||||
|
end.select do |record|
|
||||||
|
record[:name] == "#{name}."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@query
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in New Issue
Block a user