Skip to content

Commit a0cb8cd

Browse files
Dan BodeJeff McCune
authored andcommitted
Add function ensure_resource and defined_with_params
This commit adds 2 new functions with unit tests. defined_with_params works similarily to puppet's defined function, except it allows you to also specify a hash of params. defined_with_params will return true if a resource also exists that matches the specified type/title (just like with defined) as well as all of the specified params. ensure_resource is a function that basically combines defined_with_params with create_resources to conditionally create resources only if the specified resource (title, type, params) does not already exist. These functions are created to serve as an alternative to using defined as follows: if ! defined(Package['some_package']) { package { 'some_package': ensure => present, } The issue with this usage is that there is no guarentee about what parameters were set in the previous definition of the package that made its way into the catalog. ensure_resource could be used instead, as: ensure_resource('package', 'some_package', { 'ensure' => 'present' }) This will creat the package resources only if another resource does not exist with the specified parameters.
1 parent 9693c04 commit a0cb8cd

File tree

4 files changed

+127
-0
lines changed

4 files changed

+127
-0
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Test whether a given class or definition is defined
2+
require 'puppet/parser/functions'
3+
4+
Puppet::Parser::Functions.newfunction(:defined_with_params,
5+
:type => :rvalue,
6+
:doc => <<-'ENDOFDOC'
7+
Takes a resource reference and an optional hash of attributes.
8+
9+
Returns true if a resource with the specified attributes has already been added
10+
to the catalog, and false otherwise.
11+
12+
user { 'dan':
13+
ensure => present,
14+
}
15+
16+
if ! defined_with_params(User[dan], {'ensure' => 'present' }) {
17+
user { 'dan': ensure => present, }
18+
}
19+
ENDOFDOC
20+
) do |vals|
21+
reference, params = vals
22+
raise(ArgumentError, 'Must specify a reference') unless reference
23+
params ||= {}
24+
ret = false
25+
if resource = findresource(reference.to_s)
26+
matches = params.collect do |key, value|
27+
resource[key] == value
28+
end
29+
ret = params.empty? || !matches.include?(false)
30+
end
31+
Puppet.debug("Resource #{reference} was not determined to be defined")
32+
ret
33+
end
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Test whether a given class or definition is defined
2+
require 'puppet/parser/functions'
3+
4+
Puppet::Parser::Functions.newfunction(:ensure_resource,
5+
:type => :statement,
6+
:doc => <<-'ENDOFDOC'
7+
Takes a resource type, title, and a list of attributes that describe a
8+
resource.
9+
10+
user { 'dan':
11+
ensure => present,
12+
}
13+
14+
This example only creates the resource if it does not already exist:
15+
16+
ensure_resource('user, 'dan', {'ensure' => 'present' })
17+
ENDOFDOC
18+
) do |vals|
19+
type, title, params = vals
20+
raise(ArgumentError, 'Must specify a type') unless type
21+
raise(ArgumentError, 'Must specify a title') unless title
22+
params ||= {}
23+
if function_defined_with_params(["#{type}[#{title}]", params])
24+
Puppet.debug("Resource #{type}[#{title}] does not need to be created b/c it already exists")
25+
else
26+
function_create_resources([type.capitalize, { title => params }])
27+
end
28+
end
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#! /usr/bin/env ruby -S rspec
2+
require 'spec_helper'
3+
4+
require 'rspec-puppet'
5+
describe 'defined_with_params' do
6+
describe 'when a resource is not specified' do
7+
it { should run.with_params().and_raise_error(ArgumentError) }
8+
end
9+
describe 'when compared against a resource with no attributes' do
10+
let :pre_condition do
11+
'user { "dan": }'
12+
end
13+
it do
14+
should run.with_params('User[dan]', {}).and_return(true)
15+
should run.with_params('User[bob]', {}).and_return(false)
16+
should run.with_params('User[dan]', {'foo' => 'bar'}).and_return(false)
17+
end
18+
end
19+
20+
describe 'when comparted against a resource with attributes' do
21+
let :pre_condition do
22+
'user { "dan": ensure => present, shell => "/bin/csh", managehome => false}'
23+
end
24+
it do
25+
should run.with_params('User[dan]', {}).and_return(true)
26+
should run.with_params('User[dan]', {'ensure' => 'present'}).and_return(true)
27+
should run.with_params('User[dan]', {'ensure' => 'present', 'managehome' => false}).and_return(true)
28+
should run.with_params('User[dan]', {'ensure' => 'absent', 'managehome' => false}).and_return(false)
29+
end
30+
end
31+
end
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#! /usr/bin/env ruby -S rspec
2+
require 'spec_helper'
3+
4+
require 'rspec-puppet'
5+
describe 'ensure_resource' do
6+
describe 'when a type or title is not specified' do
7+
it do
8+
should run.with_params().and_raise_error(ArgumentError)
9+
should run.with_params(['type']).and_raise_error(ArgumentError)
10+
end
11+
end
12+
describe 'when compared against a resource with no attributes' do
13+
let :pre_condition do
14+
'user { "dan": }'
15+
end
16+
it do
17+
should run.with_params('user', 'dan', {})
18+
compiler.catalog.resource('User[dan]').to_s.should == 'User[dan]'
19+
end
20+
end
21+
22+
describe 'when comparted against a resource with attributes' do
23+
let :pre_condition do
24+
'user { "dan": ensure => present, shell => "/bin/csh", managehome => false}'
25+
end
26+
it do
27+
# these first three should not fail
28+
should run.with_params('User', 'dan', {})
29+
should run.with_params('User', 'dan', {'ensure' => 'present'})
30+
should run.with_params('User', 'dan', {'ensure' => 'present', 'managehome' => false})
31+
# test that this fails
32+
should run.with_params('User', 'dan', {'ensure' => 'absent', 'managehome' => false}).and_raise_error(Puppet::Error)
33+
end
34+
end
35+
end

0 commit comments

Comments
 (0)