Skip to content

Commit

Permalink
Add apache_directive type and provider
Browse files Browse the repository at this point in the history
  • Loading branch information
raphink committed Feb 25, 2014
1 parent 2686233 commit 4753799
Show file tree
Hide file tree
Showing 8 changed files with 619 additions and 0 deletions.
42 changes: 42 additions & 0 deletions docs/examples/apache_directive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
## apache_directive provider

This is a custom type and provider supplied by `augeasproviders`.

### manage simple entry

apache_directive { "StartServers":
args => 4,
ensure => present,
}

### delete entry

apache_directive { "ServerName":
args => "foo.example.com",
ensure => absent,
}

### manage entry in another config location

apache_directive { "SetEnv":
args => ["SPECIAL_PATH", "/foo/bin"],
args_params => 1,
ensure => present,
target => "/etc/httpd/conf.d/app.conf",
}

The `SetEnv` directive is not unique per scope: the first arg identifies the entry we want to update, and needs to be taken into account. For this reason, we set `args_params` to `1`.

### set a value in a given context

apache_directive { 'StartServers for mpm_prefork_module':
ensure => present,
name => 'StartServers',
context => 'IfModule[arg="mpm_prefork_module"]',
args => 4,
}


The directive is nested in the context of the `mpm_prefork_module` module, so we specify this with the `context` parameter.

The value of `StartServers` for the `mpm_prefork_module` module will be set/updated to `4`. Note that the `IfModule` entry will not be created if it is missing.
98 changes: 98 additions & 0 deletions lib/puppet/provider/apache_directive/augeas.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Manages an Apache directive
#
# Copyright (c) 2013 Raphaël Pinson
# Licensed under the Apache License, Version 2.0

require File.dirname(__FILE__) + '/../../../augeasproviders/provider'

Puppet::Type.type(:apache_directive).provide(:augeas) do
desc 'Use the Augeas API to update a directive in Apache'

include AugeasProviders::Provider

lens { 'Httpd.lns' }

default_file do
case Facter.value(:osfamily)
when 'RedHat'
'/etc/httpd/conf/httpd.conf'
when 'Debian'
'/etc/apache2/apache2.conf'
end
end

resource_path do |resource|
path = '$target'
path += "/#{resource[:context]}" unless resource[:context].empty?
path += "/directive[.='#{resource[:name]}'"
if resource[:args]
resource[:args][0, resource[:args_params].to_i].each_with_index do |a, i|
path += " and arg[#{i+1}]='#{a}'"
end
end
path += ']'
path
end

confine :feature => :augeas

def self.instances
augopen do |aug|
aug.match('$target//directive').map do |spath|
# Find path
context = spath.slice("/files#{target}".length+1..-1).sub(%r{/?directive.*}, '')
args = aug.match("#{spath}/arg").map do |apath|
aug.get(apath)
end
new({
:name => aug.get(spath),
:ensure => :present,
:args => args,
:context => context,
:args_params => 0
})
end
end
end

def create
augopen! do |aug|
top_path = '$target'
top_path += "/#{resource[:context]}" unless resource[:context].empty?
last_path = "#{top_path}/directive[.='#{resource[:name]}'][last()]"
if aug.match(last_path).empty?
aug.clear("#{top_path}/directive[last()+1]")
else
# Prefer to insert the new node after the last directive with the same name
aug.insert(last_path, 'directive', false)
end

# The new node is the only directive without a value
aug.defvar('new', "#{top_path}/directive[.='']")
aug.set('$new', resource[:name])
resource[:args].each_with_index do |a,i|
aug.set("$new/arg[#{i+1}]", a)
end
end
end

def args
augopen do |aug|
aug.match('$resource[last()]/arg').map do |apath|
aug.get(apath)
end
end
end

def args=(args)
augopen! do |aug|
aug.rm("#{resource_path}[position()!=last()]")
setvars(aug)
# Remove all options and replace them
aug.rm('$resource/arg')
args.each do |a|
aug.set("$resource/arg[.='#{a}']", a)
end
end
end
end
41 changes: 41 additions & 0 deletions lib/puppet/type/apache_directive.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# Manages Apache directives
#
# Copyright (c) 2013 Raphaël Pinson
# Licensed under the Apache License, Version 2.0

require File.dirname(__FILE__) + '/../../augeasproviders/type'

Puppet::Type.newtype(:apache_directive) do
@doc = 'Manages Apache directives'

extend AugeasProviders::Type

ensurable

newparam(:name) do
desc 'The directive name'
isnamevar
end

newparam(:context) do
desc 'The path where the directive is located. Expressed as an Augeas path expression.'
defaultto ''
end

newproperty(:args, :array_matching => :all) do
desc 'An array of directive arguments'
end

newparam(:args_params) do
desc 'How many arguments are to be used as params'
defaultto 0

validate do |value|
raise "Wrong args_params value '#{value}'" unless value.to_i >= 0
end
end

newparam(:target) do
desc 'The config file to use'
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<foo
Empty file.
Loading

0 comments on commit 4753799

Please sign in to comment.