Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
1b013e0
shuffle update_policy conditionals to prevent duplicate directives
griggi-clarkson Oct 18, 2021
24cccfa
Revert "shuffle update_policy conditionals to prevent duplicate direc…
griggi-clarkson Oct 18, 2021
ee0d710
RR creation via local nsupdate
griggi-clarkson Oct 18, 2021
b5cdadb
RR creation via local nsupdate
griggi-clarkson Oct 18, 2021
50ef264
RR deletion via local nsupdate, some ramblings on create
griggi-clarkson Oct 18, 2021
d1d5ae8
add resource record management to provider
griggi-clarkson Oct 25, 2021
0d24911
add resource record management to provider
griggi-clarkson Oct 25, 2021
58c840b
add resource record management to provider
griggi-clarkson Oct 25, 2021
6c8d17d
resource record parsing: trim newline
griggi-clarkson Oct 25, 2021
0cd794f
resource record parsing: debug prints
griggi-clarkson Oct 25, 2021
d0f57b4
resource record parsing: debug prints
griggi-clarkson Oct 25, 2021
2ee2a44
resource record parsing: incorrect attribute name
griggi-clarkson Oct 25, 2021
71b2fce
readd preemptive deletion to nsupdate in RR provider create method
griggi-clarkson Oct 25, 2021
16a5ee9
RR canonicalize debug
griggi-clarkson Oct 26, 2021
3a6eff0
RR additional debug prints
griggi-clarkson Oct 26, 2021
05ef4ba
zone scope mishap
griggi-clarkson Oct 26, 2021
9cbc1ef
trailing dot for zone getter as given by manifest
griggi-clarkson Oct 26, 2021
5b1c212
trailing dot for zone getter as given by manifest
griggi-clarkson Oct 26, 2021
199d3e4
trailing dot for zone getter as given by manifest
griggi-clarkson Oct 26, 2021
69f725a
local nsupdate explicit IPv4 to avoid requiring additional config
griggi-clarkson Oct 26, 2021
c4acb59
add explicit title in provider getter
griggi-clarkson Oct 26, 2021
695672b
more explicit composite namevars
griggi-clarkson Oct 26, 2021
d51176f
update canonicalize for parsed TXT records and trailing newlines from…
griggi-clarkson Oct 27, 2021
a4ba0e0
update canonicalize for parsed TXT records and trailing newlines from…
griggi-clarkson Oct 27, 2021
4482d63
RR canonicalize debug print
griggi-clarkson Oct 27, 2021
8c0f35b
update canonicalize for parsed TXT records and trailing newlines from…
griggi-clarkson Oct 27, 2021
bf555fe
update canonicalize for parsed TXT records and trailing newlines from…
griggi-clarkson Oct 27, 2021
2d7dd5b
update canonicalize for parsed TXT records and trailing newlines from…
griggi-clarkson Oct 27, 2021
7d0359f
delete method tweaks
griggi-clarkson Oct 27, 2021
efff8d9
delete method tweaks
griggi-clarkson Oct 27, 2021
3c9b7ec
per-zone RR purging
griggi-clarkson Oct 28, 2021
ba4042c
Revert "per-zone RR purging"
griggi-clarkson Oct 28, 2021
a7ec58c
some conditionals to prevent avoidable errors
griggi-clarkson Oct 28, 2021
2e99d00
canonicalize debug print
griggi-clarkson Oct 28, 2021
b99d1b8
canonicalize debug print
griggi-clarkson Oct 28, 2021
41af07a
PTR generation
griggi-clarkson Oct 28, 2021
3c958b1
PTR generation debug prints
griggi-clarkson Oct 28, 2021
7bb8d60
PTR generation debug prints
griggi-clarkson Oct 28, 2021
6e7a1d2
PTR generation debug prints
griggi-clarkson Oct 28, 2021
4b2c083
PTR generation debug prints
griggi-clarkson Oct 28, 2021
ed0d71c
PTR generation debug prints
griggi-clarkson Oct 28, 2021
15ecc54
PTR generation debug prints
griggi-clarkson Oct 28, 2021
c05c27a
PTR generation debug prints
griggi-clarkson Oct 28, 2021
0e79356
PTR generation debug prints
griggi-clarkson Oct 28, 2021
43118ea
PTR generation debug prints
griggi-clarkson Oct 28, 2021
fff8bb4
stop trying to access data we don't have
griggi-clarkson Oct 28, 2021
760bd08
Fix missing TTL on PTR nsupdate
griggi-clarkson Oct 28, 2021
4550e13
implement resource record management
griggi-clarkson Oct 18, 2021
5540d9b
Include data in namevar for safe deletion of differing records with s…
griggi-clarkson Nov 10, 2021
e7ef4ef
Include data in namevar for safe deletion of differing records with s…
griggi-clarkson Nov 10, 2021
05d7901
Include data in namevar for safe deletion of differing records with s…
griggi-clarkson Nov 10, 2021
1777e55
Add allow-query to zone definitions
griggi-clarkson Nov 11, 2021
c259872
primaries -> masters zone conf
griggi-clarkson Nov 11, 2021
53ef175
fix some canonicalization consistency
griggi-clarkson Nov 11, 2021
11088da
Revert "fix some canonicalization consistency"
griggi-clarkson Nov 11, 2021
8dd6a22
fix some canonicalization consistency
griggi-clarkson Nov 11, 2021
df43d50
fix some canonicalization consistency
griggi-clarkson Nov 11, 2021
dfd05e8
Define resource record title to always match that generated by provid…
griggi-clarkson Nov 15, 2021
5a418fe
Define resource record title to always match that generated by provid…
griggi-clarkson Nov 15, 2021
18aca36
Correct RR title regex
griggi-clarkson Nov 15, 2021
6b6a274
add allow-recursion to bind options
griggi-clarkson Dec 31, 2021
7fb4ed2
add allow-recursion to bind options
griggi-clarkson Dec 31, 2021
f56d32e
add forward/forwarders to bind options
griggi-clarkson Dec 31, 2021
972efb8
add forward/forwarders to bind options
griggi-clarkson Dec 31, 2021
af1e41f
stop trimming quotes from record data
griggi-clarkson Jan 12, 2022
316dbf0
fixup for quoting TXT records
griggi-clarkson Jan 12, 2022
6148461
use instance variable for get akin to prefetch in legacy providers
griggi-clarkson Jan 19, 2022
20fba41
use instance variable for get akin to prefetch in legacy providers
griggi-clarkson Jan 19, 2022
c3595aa
Merge pull request #1 from griggi-clarkson/rr_rsapi_cached
griggi-clarkson Jan 19, 2022
d5fe3e5
make rubocop happy
griggi-clarkson Jan 20, 2022
b526c97
make rubocop happy
griggi-clarkson Feb 28, 2022
8e72186
add provisions for a flag that prevents automatic PTR overwrites
griggi-clarkson Feb 28, 2022
330bbc8
add provisions for a flag that prevents automatic PTR overwrites
griggi-clarkson Feb 28, 2022
6d38074
add provisions for a flag that prevents automatic PTR overwrites
griggi-clarkson Mar 1, 2022
100461f
add provisions for a flag that prevents automatic PTR overwrites
griggi-clarkson Mar 4, 2022
5cc23ea
Revert "add provisions for a flag that prevents automatic PTR overwri…
griggi-clarkson Mar 4, 2022
4ab0ee1
force an initialize call if get has no results
griggi-clarkson Mar 8, 2022
85fb4c7
add some debug prints
griggi-clarkson Mar 8, 2022
eb7f1f1
Merge pull request #2 from griggi-clarkson/ptrhold
griggi-clarkson Apr 6, 2022
22e9a05
Revert "Add 'ptrhold' parameter for finer control over automatic PTR …
griggi-clarkson Apr 6, 2022
4103449
Merge pull request #3 from griggi-clarkson/revert-2-ptrhold
griggi-clarkson Apr 6, 2022
2b07645
resolve merge conflicts
griggi-clarkson Jun 2, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
196 changes: 179 additions & 17 deletions lib/puppet/provider/resource_record/resource_record.rb
Original file line number Diff line number Diff line change
@@ -1,40 +1,202 @@
# frozen_string_literal: true

require 'puppet/resource_api/simple_provider'

require 'ipaddr'
# Implementation for the resource_record type using the Resource API.
class Puppet::Provider::ResourceRecord::ResourceRecord < Puppet::ResourceApi::SimpleProvider
def initialize
super()
system('rndc', 'dumpdb', '-zones')
# Have to wait to ensure file is actually populated...embarrassingly this was the source of much wheel spinning.
sleep(2)
Puppet.debug('Parsing dump for existing resource records...')
@records = []
@heldptr = {}
currentzone = ''
# FIXME: location varies based on config/OS
unless File.exist?('/var/cache/bind/named_dump.db')
raise Puppet::Error, 'The named dump file does not exist in the expected location, cannot continue.'
end
File.readlines('/var/cache/bind/named_dump.db').each do |line|
if line[0] == ';' && line.length > 18
currentzone = line[%r{(?:.*?')(.*?)\/}, 1]
if currentzone.respond_to?(:to_str); currentzone = currentzone.downcase end
Puppet.debug("current zone updated: #{currentzone}")
elsif line[0] != ';'
line = line.strip.split(' ', 5)
rr = {}
rr[:label] = line[0]
if rr[:label].respond_to?(:to_str); rr[:label] = rr[:label].downcase end
# Puppet.debug("----New RR---- label: #{rr[:label]}")
rr[:ttl] = line[1]
# Puppet.debug("RR TTL: #{rr[:ttl]}")
rr[:scope] = line[2]
# Puppet.debug("RR scope: #{rr[:scope]}")
rr[:type] = line[3]
# Puppet.debug("RR type: #{rr[:type]}")
rr[:data] = if line[4].respond_to?(:to_str)
line[4].tr('\"', '')
else
line[4]
end
# context.debug("RR data: #{rr[:data]}")
rr[:zone] = currentzone + '.'
# context.debug("RR zone: #{rr[:zone]}")
@records << {
title: "#{rr[:label]} #{rr[:zone]} #{rr[:type]} #{rr[:data]}",
ensure: 'present',
record: rr[:label].to_s,
zone: rr[:zone].to_s,
type: rr[:type].to_s,
data: rr[:data].to_s,
ttl: rr[:ttl].to_s,
}
end
end
# context.debug("#{records.inspect}")
end

def get(context)
context.debug('Returning pre-canned example data')
[
{
name: 'foo',
ensure: 'present',
},
{
name: 'bar',
ensure: 'present',
},
]
Puppet.debug("get called, context: #{context}")
if @records.empty?
initialize
end
@records
end

def create(context, name, should)
Puppet.debug("create called, context: #{context}")
context.notice("Creating '#{name}' with #{should.inspect}")

# I dislike having to send an individual nsupdate for each record, it'd be preferable to
# build a request for each managed zone on run, append all records we
# need to act on, then send a bulk nsupdate for each zone - this would require a legacy provider's flush operation
cmd = if should[:type] == 'TXT'
"echo 'zone #{should[:zone]}
update add #{should[:record]} #{should[:ttl]} #{should[:type]} \"#{should[:data]}\"
send
quit
' | nsupdate -4 -l"
else
"echo 'zone #{should[:zone]}
update add #{should[:record]} #{should[:ttl]} #{should[:type]} #{should[:data]}
send
quit
' | nsupdate -4 -l"
end
system(cmd)

# FIXME: This will generate PTR records, but assumes the arpa zones are preexisting.
if should[:type] == 'A'
unless @heldptr.key? should[:data].to_sym
if should[:ptrhold]
context.debug("Adding sticky PTR entry for #{should[:data]}->#{should[:record]}")
@heldptr[should[:data].to_sym] = should[:record]
end
fqdn = should[:record]
if fqdn[fqdn.length - 1] != '.'
fqdn += should[:zone]
end
reverse = IPAddr.new(should[:data]).reverse
cmd = "echo 'update delete #{reverse} PTR
update add #{reverse} #{should[:ttl]} PTR #{fqdn}
send
quit
' | nsupdate -4 -l"
system(cmd)
end
end
@records << {
title: "#{should[:record]} #{should[:zone]} #{should[:type]} #{should[:data]}",
ensure: 'present',
record: should[:record].to_s,
zone: should[:zone].to_s,
type: should[:type].to_s,
data: should[:data].to_s,
ttl: should[:ttl].to_s,
}
end

def update(context, name, should)
context.notice("Updating '#{name}' with #{should.inspect}")
Puppet.debug("update called, context: #{context}")
context.notice("Updating '#{name.inspect}' with #{should.inspect}")
cmd = if should[:type] == 'TXT'
"echo 'zone #{should[:zone]}
update delete #{name[:record]} #{name[:type]} #{name[:data]}
update add #{should[:record]} #{should[:ttl]} #{should[:type]} \"#{should[:data]}\"
send
quit
' | nsupdate -4 -l"
else
"echo 'zone #{should[:zone]}
update delete #{name[:record]} #{name[:type]} #{name[:data]}
update add #{should[:record]} #{should[:ttl]} #{should[:type]} #{should[:data]}
send
quit
' | nsupdate -4 -l"
end
system(cmd)
if should[:type] == 'A'
unless @heldptr.key? should[:data].to_sym
if should[:ptrhold]
context.debug("Adding sticky PTR entry for #{should[:data]}->#{should[:record]}")
@heldptr[should[:data].to_sym] = should[:record]
end
fqdn = should[:record]
if fqdn[fqdn.length - 1] != '.'
fqdn += should[:zone]
end
reverse = IPAddr.new(should[:data]).reverse
context.debug("fqdn: #{fqdn}")
context.debug("reverse: #{reverse}")
cmd = "echo 'update delete #{reverse} PTR
update add #{reverse} #{should[:ttl]} PTR #{fqdn}
send
quit
' | nsupdate -4 -l"
system(cmd)
end
end
@records.reject! { |rr| rr[:title] == "#{name[:record]} #{name[:zone]} #{name[:type]} #{name[:data]}" }
@records << {
title: "#{should[:record]} #{should[:zone]} #{should[:type]} #{should[:data]}",
ensure: 'present',
record: should[:record].to_s,
zone: should[:zone].to_s,
type: should[:type].to_s,
data: should[:data].to_s,
ttl: should[:ttl].to_s,
}
end

def delete(context, name)
Puppet.debug("delete called, context: #{context}")
context.notice("Deleting '#{name}'")
cmd = "echo 'zone #{name[:zone]}
update delete #{name[:record]} #{name[:type]} #{name[:data]}
send
quit
' | nsupdate -4 -l"
system(cmd)
@records.reject! { |rr| rr[:title] == "#{name[:record]} #{name[:zone]} #{name[:type]} #{name[:data]}" }
end

def canonicalize(_context, resources)
def canonicalize(context, resources)
Puppet.debug("canonicalize called, context: #{context}")
resources.each do |r|
r[:record] = r[:record].downcase
r[:zone] = r[:zone].downcase
r[:type] = r[:type].upcase
context.debug(r.inspect)
if r[:record].respond_to?(:to_str)
r[:record] = r[:record].downcase.strip
end
if r[:zone].respond_to?(:to_str)
r[:zone] = r[:zone].downcase
end
if r[:type].respond_to?(:to_str)
r[:type] = r[:type].upcase
end
if r[:data].respond_to?(:to_str)
r[:data] = r[:data].tr('\"', '')
end
end
end
end
15 changes: 13 additions & 2 deletions lib/puppet/type/resource_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@
features: ['canonicalize'],
title_patterns: [
{
desc: 'name, zone (everything after the first dot), space, type',
pattern: %r{^(?<record>.*?[^.])\.(?<zone>.*[^ ]\.) +(?<type>.*)$},
desc: 'full name, space, zone (explicitly defined), space, type, space, data',
pattern: %r{^(?<record>.*?\.) (?<zone>[^ ]*\.) +(?<type>\w+) (?<data>.*)$},
},
{
desc: 'full name, space, zone (explicitly defined), space, type',
pattern: %r{^(?<record>.*?\.) (?<zone>[^ ]*\.) +(?<type>\w+)$},
},
{
desc: 'name and zone (everything after the first dot)',
Expand All @@ -43,6 +47,12 @@
desc: 'Whether this resource record should be present or absent on the target system.',
default: 'present',
},
ptrhold: {
type: 'Boolean',
desc: 'Make this record the only one used for an accompanying reverse record.',
behavior: :parameter,
default: false,
},
record: {
type: 'String',
desc: 'The name of the resource record, also known as the owner or label.',
Expand All @@ -61,6 +71,7 @@
data: {
type: 'String',
desc: 'The data for the resource record.',
behavior: :namevar,
},
ttl: {
type: 'Optional[String]',
Expand Down
21 changes: 0 additions & 21 deletions manifests/install.pp
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,6 @@
class bind::install {
assert_private()

if $bind::authoritative {
ensure_packages(
[
'g++',
'make',
],
{
ensure => installed,
before => Package['dnsruby'],
},
)

ensure_packages(
'dnsruby',
{
ensure => installed,
provider => puppet_gem,
},
)
}

if $bind::package_backport {
require apt::backports
}
Expand Down
6 changes: 5 additions & 1 deletion manifests/zone.pp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#
# @param allow_update Which hosts are allowed to submit Dynamic DNS updates to the zone.
#
# @param allow_query Hosts allowed to query the zone
#
# @param also_notify list of IP addresses of name servers that are also sent NOTIFY messages
# whenever a fresh copy of the zone is loaded, in addition to the servers listed in the zone’s NS
# records.
Expand Down Expand Up @@ -64,6 +66,7 @@
Pattern[/\.$/] $zone_name = $title,
Optional[Array[Variant[Stdlib::Host, Stdlib::IP::Address]]] $allow_transfer = undef,
Optional[Array[Variant[Stdlib::Host, Stdlib::IP::Address]]] $allow_update = undef,
Optional[Array[Variant[Stdlib::Host, Stdlib::IP::Address]]] $allow_query = undef,
Optional[Array[Variant[Stdlib::Host, Stdlib::IP::Address]]] $also_notify = undef,
Optional[Enum['allow', 'maintain', 'off']] $auto_dnssec = undef,
Optional[Enum['IN', 'HS', 'hesiod', 'CHAOS']] $class = undef,
Expand Down Expand Up @@ -107,6 +110,7 @@
'zone_name' => $zone_name,
'allow_transfer' => $allow_transfer,
'allow_update' => $allow_update,
'allow_query' => $allow_query,
'also_notify' => $also_notify,
'auto_dnssec' => $auto_dnssec,
'class' => $class,
Expand Down Expand Up @@ -206,7 +210,7 @@
}

$resource_records.each |$rrname, $attribs| {
resource_record { $rrname:
resource_record { "${attribs['record']} ${zone_name} ${attribs['type']} ${attribs['data']}":
zone => $zone_name,
* => $attribs,
}
Expand Down
22 changes: 0 additions & 22 deletions spec/classes/bind_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -217,28 +217,6 @@
end

it { is_expected.to compile.with_all_deps }

# dnsruby build dependencies
if os_facts[:os]['name'] == 'Debian'
[
'g++',
'make',
].each do |pkg|
it do
is_expected.to contain_package(pkg).with(
ensure: 'installed',
before: 'Package[dnsruby]',
)
end
end
end

it do
is_expected.to contain_package('dnsruby').with(
ensure: 'installed',
provider: 'puppet_gem',
)
end
end

context 'with dev packages' do
Expand Down
17 changes: 17 additions & 0 deletions templates/etc/bind/named.conf.epp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ options {
<%- } -%>
};
<%- } -%>
<%- if $options['allow_recursion'] { -%>
allow-recursion {
<%- $options['allow_recursion'].each |$address_match_list_element| { -%>
<%= $address_match_list_element -%>;
<%- } -%>
};
<%- } -%>
<%- if $options['allow-update'] { -%>
allow-update {
<%- $options['allow-update'].each |$address_match_list_element| { -%>
Expand Down Expand Up @@ -96,6 +103,16 @@ options {
<%- if $options['zone-statistics'] { -%>
zone-statistics <%= $options['zone-statistics'] %>;
<%- } -%>
<%- if $options['forward'] { -%>
forward <%= $options['forward'] %>;
<%- } -%>
<%- if $options['forwarders'] { -%>
forwarders {
<%- $options['forwarders'].each |$address_match_list_element| { -%>
<%= $address_match_list_element -%>;
<%- } -%>
};
<%- } -%>
};
<%- } -%>

Expand Down
Loading