Skip to content

Instantly share code, notes, and snippets.

@masterzen
Created October 31, 2011 18:57
Show Gist options
  • Save masterzen/1328479 to your computer and use it in GitHub Desktop.
Save masterzen/1328479 to your computer and use it in GitHub Desktop.
Puppet Extension Point - part 2
commands ping => "/usr/bin/ping"
...
# we can use it later with:
# ping "www.puppetlabs.com"
dnszone {
"planetpuppet.org":
ensure => present,
email => "brice@planetpuppet.org"
}
dnsrr {
"www.planetpuppet.org":
type => "A",
value => "2.4.6.9",
ensure => present,
}
Puppet::Type.newtype(:dnsrr) do
@doc = "Manage a DNS Resource Record"
ensurable
newparam(:name) do
desc "RR name, this is usually a domain name, but for PTR resource record it will be an IP address"
isnamevar
end
newproperty(:type) do
defaultto(:A)
newvalues(:A, :AAAA, :CNAME, :MX, :SRV, :TXT, :PTR)
end
newproperty(:value) do
isrequired
validate do |value|
raise ArgumentError, "Empty values are not allowed" if value == ""
end
end
validate do
begin
case self[:type]
when :A, :AAAA
IPAddr.new(self[:value])
end
rescue
raise ArgumentError, "Invalid IP address #{self[:value]} for given type #{self[:type]}"
end
end
newparam(:zone) do
defaultto do
raise ArgumentError, "No zone defined and name is not a FQDN" unless @resource[:name].include?(".")
@resource[:name].gsub(/^[^.]+\./,'')
end
end
autorequire(:dnszone) do
[self[:zone]]
end
end
Puppet::Type.type(:dnszone).provide :fog, :parent => Puppet::Provider::Fog do
desc "Fog provider for DNS zones."
confine :feature => :fog
# This creates a bunch of getters/setters for our properties/parameters
# this is only for prefetch/flush providers
mk_resource_methods
def self.prefetch(resources)
resources.each do |name, resource|
dns = dns(resource[:yaml_fog_file])
if found = dns.zones.all.find { |z| z.domain =~ /^#{Regexp.quote(name)}\.?$/ }
result = { :ensure => :present }
result[:email] = found.email if found.respond_to?(:email)
result[:domain] = found.domain
resource.provider = new(found, result)
else
resource.provider = new(nil, :ensure => :absent)
end
resource.provider.dns = dns
end
end
def flush
case @property_hash[:ensure]
when :absent
@zone.destroy if @zone
when :present
if @properties[:ensure] == :absent
dns.zones.create(:domain => @property_hash[:domain], :email => @property_hash[:email])
else
@zone.domain = @property_hash[:domain]
@zone.email = @property_hash[:email] if @zone.respond_to?(:email)
@zone.save
end
end
@property_hash.clear
end
def self.instances
# I fear we can't find any instances without having access to the fog credentials
end
def create
@property_hash[:ensure] = :present
self.class.resource_type.validproperties.each do |property|
if val = resource.should(property)
@property_hash[property] = val
end
end
end
def destroy
@property_hash[:ensure] = :absent
end
def exists?
@property_hash[:ensure] != :absent
end
Puppet::Type.newtype(:dnszone) do
@doc = "Manage a DNS zone"
ensurable
newparam(:name) do
desc "Zone name, this must be a domain name"
isnamevar
end
newparam(:email) do
desc "E-mail admin of the zone"
end
newparam(:yaml_fog_file) do
desc "Path to a yaml file containing the fog credentials and provider - ignore if the dnszone puppet provider is not fog"
defaultto '/etc/puppet/fog.yaml'
end
autorequire(:file) do
[self[:yaml_fog_file]]
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment