Skip to content

Commit

Permalink
Merge pull request #162 from cirrax/add_autoprimaries
Browse files Browse the repository at this point in the history
add type/provider for autoprimary
  • Loading branch information
ju5t authored Dec 5, 2023
2 parents d020471 + 8df34bc commit 9608f86
Show file tree
Hide file tree
Showing 8 changed files with 200 additions and 0 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,21 @@ Remark: if the target\_zone is not managed with powerdns\_zone resource, powerdn

Passwords can be passed either as plain-text strings or as [Puppet's Sensitive type](https://www.puppet.com/docs/puppet/7/lang_data_sensitive.html) when appropriate encrypted backend is configured on Puppet server.

### Manage autoprimaries (automatic provisioning of secondaries)
It's possible to manage the the 'autoprimaries' with puppet (For a decription of the autoprimary functionality in
powerdns see [powerdns manual](https://doc.powerdns.com/authoritative/modes-of-operation.html#autoprimary-automatic-provisioning-of-secondaries).
The autoprimaries are set with the powerdns\_autoprimary resource. As an example we add the primary 1.2.3.4 named ns1.example.org whith the account 'test'
``` yaml
powerdns_autoprimary{'[email protected]':
ensure => 'present',
account => 'test',
}
```
As an alternative, you can set the autoprimaries parameter of the powerdns class to achive the same (eg. if you use hiera).

For removal of an autoprimary set ensure to 'absent' or set the parameter purge\_autoprimaries of the powerdns class to true which willa
remove all autoprimaries that are not present in the puppet manifest.

## Reference

### Parameters
Expand Down
64 changes: 64 additions & 0 deletions lib/puppet/provider/powerdns_autoprimary/pdnsutil.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# frozen_string_literal: true

Puppet::Type.type(:powerdns_autoprimary).provide(:pdnsutil) do
desc "@summary provider which provides autprimary,
using the pdnsutil command."

commands pdnsutil: 'pdnsutil'

def initialize(value = {})
super(value)
@property_flush = {}
end

def self.instances
pdnsutil('list-autoprimaries').split("\n").map do |line|
raise Puppet::Error, "Cannot parse invalid autoprimary line: #{line}" unless line =~ %r{^IP=(\S+),\s+NS=(\S+),\s+account=(\S*)$}
new(
ensure: :present,
name: Regexp.last_match(1) + '@' + Regexp.last_match(2),
account: Regexp.last_match(3),
)
end
end

def self.prefetch(resources)
autoprimaries = instances
resources.each_key do |name|
if (provider = autoprimaries.find { |aprim| aprim.name == name })
resources[name].provider = provider
end
end
end

def create
pdnsutil('add-autoprimary', resource[:name].split('@'), resource[:account])
@property_hash[:ensure] = :present
end

def destroy
pdnsutil('remove-autoprimary', resource[:name].split('@'))
@property_hash[:ensure] = :absent
end

def account
@property_hash[:account]
end

def account=(account)
pdnsutil('remove-autoprimary', resource[:name].split('@'))
pdnsutil('add-autoprimary', resource[:name].split('@'), account)
@property_hash[:ensure] = account
end

def exists?
@property_hash[:ensure] == :present
end

def flush
return if @property_flush.empty?
content = @property_flush[:content] || @resource[:content]
virsh_define(content)
@property_flush.clear
end
end
33 changes: 33 additions & 0 deletions lib/puppet/type/powerdns_autoprimary.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# frozen_string_literal: true

require 'puppet/parameter/boolean'

Puppet::Type.newtype(:powerdns_autoprimary) do
@doc = 'ensures autoprimary servers (for automatic provisioning of secondaries)
'

ensurable do
desc 'Manage the state of this type.'
defaultvalues
defaultto :present
end

newparam(:name, namevar: true) do
desc 'name of the autoprimary in the format IP@NAMESERVER'

newvalues(%r{^\S+@\S+$})
end

newproperty(:account) do
desc 'account to ensure (default to no account)'
defaultto ''

validate do |value|
raise ArgumentError, 'ip needs to be a string' unless value.is_a?(String)
end
end

autorequire(:service) do
['pdns']
end
end
15 changes: 15 additions & 0 deletions manifests/init.pp
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
# powerdns
#
# @param autoprimaries
# Hash of autoprimaries the ensurce (with resource powerdns_autoprimary)
# @param purge_autoprimaries
# Set this to true if you like to purge all autoprimaries not managed with puppet
#
class powerdns (
Boolean $authoritative = true,
Boolean $recursor = false,
Expand All @@ -25,6 +31,8 @@
String[1] $mysql_schema_file = $powerdns::params::mysql_schema_file,
String[1] $pgsql_schema_file = $powerdns::params::pgsql_schema_file,
Hash $forward_zones = {},
Powerdns::Autoprimaries $autoprimaries = {},
Boolean $purge_autoprimaries = false,
) inherits powerdns::params {
# Do some additional checks. In certain cases, some parameters are no longer optional.
if $authoritative {
Expand Down Expand Up @@ -68,4 +76,11 @@
$powerdns_recursor_defaults = { 'type' => 'recursor' }
create_resources(powerdns::config, $powerdns_recursor_config, $powerdns_recursor_defaults)
}

if $purge_autoprimaries {
resources { 'powerdns_autoprimary':
purge => true,
}
}
create_resources('powerdns_autoprimary', $autoprimaries)
}
34 changes: 34 additions & 0 deletions spec/type_aliases/autoprimaries_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require 'spec_helper'

describe 'Powerdns::Autoprimaries' do
describe 'valid types' do
context 'with valid types' do
[
{},
{ '[email protected]' => {} },
{ '2001:db8::[email protected]' => { 'account' => 'test' } },
].each do |value|
describe value.inspect do
it { is_expected.to allow_value(value) }
end
end
end
end

describe 'invalid types' do
context 'with garbage inputs' do
[
true,
nil,
{ 'foo' => 'bar' },
'55555',
{ '@ns1.example.org' => {} },
{ '1.2.3.4@' => {} },
].each do |value|
describe value.inspect do
it { is_expected.not_to allow_value(value) }
end
end
end
end
end
20 changes: 20 additions & 0 deletions spec/unit/puppet/provider/powerdns_autoprimary/pdnsutil_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

require 'spec_helper'

provider_class = Puppet::Type.type(:powerdns_autoprimary).provider(:pdnsutil)

describe provider_class do
let(:resource) do
Puppet::Type::Powerdns_autoprimary.new(
name: '[email protected]',
provider: described_class.name,
)
end

let(:provider) { provider_class.new(resource) }

it 'has its name set' do
expect(resource[:name]).to eq('[email protected]')
end
end
13 changes: 13 additions & 0 deletions spec/unit/puppet/type/powerdns_autoprimary_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require 'puppet'
require 'puppet/type/powerdns_autoprimary'

describe Puppet::Type.type(:powerdns_autoprimary) do
let!(:autoprimary) { Puppet::Type.type(:powerdns_autoprimary).new(name: '[email protected]') }

it 'has its name set' do
expect(autoprimary[:name]).to eq('[email protected]')
end
it 'has set account to empty string' do
expect(autoprimary[:account]).to eq('')
end
end
6 changes: 6 additions & 0 deletions types/autoprimaries.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
type Powerdns::Autoprimaries=Hash[
Pattern[/.+@.+/],
Struct[{
account => Optional[String],
}]
]

0 comments on commit 9608f86

Please sign in to comment.