diff options
author | Hugo Hörnquist <hugo@lysator.liu.se> | 2023-05-05 01:46:46 +0200 |
---|---|---|
committer | Hugo Hörnquist <hugo@lysator.liu.se> | 2023-06-06 18:31:17 +0200 |
commit | 812c3f4d6162cf7af8f8cbedb6abb6d72bd537e9 (patch) | |
tree | 109619457ac9b9028eae7297c4f72deadad68c52 /lib/puppet/provider | |
parent | tmp disable creation. (diff) | |
download | dns-812c3f4d6162cf7af8f8cbedb6abb6d72bd537e9.tar.gz dns-812c3f4d6162cf7af8f8cbedb6abb6d72bd537e9.tar.xz |
"Working" product.
Diffstat (limited to 'lib/puppet/provider')
-rw-r--r-- | lib/puppet/provider/dns_record2/named.rb | 137 | ||||
-rw-r--r-- | lib/puppet/provider/dns_zone2/named.rb | 96 |
2 files changed, 233 insertions, 0 deletions
diff --git a/lib/puppet/provider/dns_record2/named.rb b/lib/puppet/provider/dns_record2/named.rb new file mode 100644 index 0000000..61f4a96 --- /dev/null +++ b/lib/puppet/provider/dns_record2/named.rb @@ -0,0 +1,137 @@ +# require 'resolv' + +Puppet::Type.type(:dns_record2).provide(:named) do + def self.instances + objects = [] + # `named-checkconf -l`.split("\n").each do |zone| + # zonename, cls, view, _ = zone.split(' ') + # path = `rndc zonestatus #{zonename} #{cls} #{view} 2>/dev/null | awk -F' ' '/^files:/ { print $2 }'`.strip; + # `named-checkzone -q -D #{zonename} /var/named/#{path} | sed 's/[[:space:]]\+/ /g'`.split("\n").each do |record| + # key, ttl, cls, type, *value = record.split(' ') + # value = value.join(' ') + + # name = "#{zonename} #{cls} #{view} #{key} #{type} #{value}" + + # objects << new(:name => name, + # :key => key, + # :ttl => ttl, + # :class => cls, + # :type => type, + # :value => value) + # end + # end + objects + end + + def create + # print("Create\n") + end + + def destroy + # print("Destroy\n") + end + + def exists? + # print("record = [#{record().inspect}]\n") + record() != nil + end + + def type + resource[:type] + end + + def value + # print("Get old value (#{resource[:value]}, #{get(:value)})\n") + t = record() + case t + when NilClass + :absent + when String + t + else + "INVALID VALUE (#{t.class}, #{t})" + end + end + + def value=(v) + # print("Set new value (#{v})\n") + # resource[:value] = v + end + + def key + resource[:key] + end + + # def key=(v) + # resource[:key] = v + # end + + def zone + resource[:zone] + end + + def full_key + if resource[:key] == '@' + resource[:zone] + elsif resource[:key][-1] == '.' + resource[:key] + else + "#{resource[:key]}.#{resource[:zone]}" + end + end + + # def zone=(v) + # # set(:zone, v) + # resource[:zone] = v + # end + + def record + # dns = Resolv::DNS.new(nameserver: ['localhost']) + # type = { + # A: Resolv::DNS::Resource::IN::A, + # AAAA: Resolv::DNS::Resource::IN::AAAA, + # CNAME: Resolv::DNS::Resource::IN::CNAME, + # HINFO: Resolv::DNS::Resource::IN::HINFO, + # MINFO: Resolv::DNS::Resource::IN::MINFO, + # MX: Resolv::DNS::Resource::IN::MX, + # NS: Resolv::DNS::Resource::IN::NS, + # PTR: Resolv::DNS::Resource::IN::PTR, + # SOA: Resolv::DNS::Resource::IN::SOA, + # TXT: Resolv::DNS::Resource::IN::TXT, + # WKS: Resolv::DNS::Resource::IN::WKS, + # }[resource[:type]] + + # if type == nil + # nil + # else + # rs = dns.getresources(full_key, type) + # if rs.length == 0 + # nil + # else + # rs[0] + # end + # end + lines = `named-checkzone -j -q -D #{zone} /var/named/zones/#{zone}db` + .split("\n") + .map {|line| line.gsub(/[[:space:]]+/, ' ').split(' ') } + + matches = lines + .filter {|line| + line[0] == full_key and line[3].to_sym == resource[:type] + } + .map {|line| line[(4..)].join(' ') } + + + if matches.length == 0 + nil + elsif matches.length == 1 + matches[0] + else + matches + end + end + + def cls + 'IN' + end +end diff --git a/lib/puppet/provider/dns_zone2/named.rb b/lib/puppet/provider/dns_zone2/named.rb new file mode 100644 index 0000000..e249be6 --- /dev/null +++ b/lib/puppet/provider/dns_zone2/named.rb @@ -0,0 +1,96 @@ +Puppet::Type.type(:dns_zone2).provide(:named) do + def self.instances + `named-checkconf -l`.split("\n").map do |record| + name, cls, view, type = record.split(' '); + new(:name => name, :cls => cls, :view => view, :type => type) + end + end + + def create(records) + print("Create #{resource[:name]}\n") + write_zone records + end + + def destroy + print("Remove #{resource[:name]}\n") + end + + def refresh(records) + print("Refresh #{resource[:name]}\n") + write_zone records + end + + def exists? + # instances.find { |r| r.name == resource[:name] } + # resource[:ensure] == :present + `named-checkconf -l` + .split("\n") + .grep(/#{resource[:origin]} /) + .length > 0 + end + + def filename + "/var/named/zones/#{resource[:name]}db" + end + + def zone_content(records) + content = <<~EOF + ; File managed by Puppet. + ; Local changes WILL be overwritten + ; File last generated #{Time.now} + + $ORIGIN #{resource[:origin]} + $TTL #{resource[:default_ttl]} + + @ #{resource[:soa_ttl]} IN SOA #{resource[:mname]} #{resource[:rname]} ( + #{serial+1} ; serial + #{resource[:refresh]} ; refresh + #{resource[:retry]} ; retry + #{resource[:expire]} ; expire + #{resource[:negative_ttl]} ; Negative TTL + ) + EOF + + records + .filter {|r| r[:zone] == resource[:name] } + .group_by {|r| r[:type]} + .sort_by {|(type, _)| + # Bit of a hack, but ensures that SOA is always first, + # NS is after + # And the rest have stable order + { + SOA: 0, + NS: 1, + A: 2, + AAAA: 3, + CNAME: 4, + HINFO: 5, + MINFO: 6, + MX: 7, + PTR: 8, + TXT: 9, + WKS: 10, + }[type] + }.each{|(type, values)| + content += <<~EOF + ; #{type} Records + EOF + values.each {|val| + content += <<~EOF + #{val[:key]} #{val[:ttl]} IN #{val[:type]} #{val[:value]} + EOF + } + } + content + end + + def write_zone(content) + File.open(filename, 'w') do |file| + file.write content + end + end + + def serial + `rndc zonestatus #{name} | awk -F' ' '/^serial:/ { print $2 }'`.to_i + end +end |