diff --git a/files/concatfragments.sh b/files/concatfragments.sh deleted file mode 100755 index 7e6b0f5..0000000 --- a/files/concatfragments.sh +++ /dev/null @@ -1,140 +0,0 @@ -#!/bin/sh - -# Script to concat files to a config file. -# -# Given a directory like this: -# /path/to/conf.d -# |-- fragments -# | |-- 00_named.conf -# | |-- 10_domain.net -# | `-- zz_footer -# -# The script supports a test option that will build the concat file to a temp location and -# use /usr/bin/cmp to verify if it should be run or not. This would result in the concat happening -# twice on each run but gives you the option to have an unless option in your execs to inhibit rebuilds. -# -# Without the test option and the unless combo your services that depend on the final file would end up -# restarting on each run, or in other manifest models some changes might get missed. -# -# OPTIONS: -# -o The file to create from the sources -# -d The directory where the fragments are kept -# -t Test to find out if a build is needed, basically concats the files to a temp -# location and compare with what's in the final location, return codes are designed -# for use with unless on an exec resource -# -w Add a shell style comment at the top of the created file to warn users that it -# is generated by puppet -# -f Enables the creation of empty output files when no fragments are found -# -n Sort the output numerically rather than the default alpha sort -# -# the command: -# -# concatfragments.sh -o /path/to/conffile.cfg -d /path/to/conf.d -# -# creates /path/to/conf.d/fragments.concat and copies the resulting -# file to /path/to/conffile.cfg. The files will be sorted alphabetically -# pass the -n switch to sort numerically. -# -# The script does error checking on the various dirs and files to make -# sure things don't fail. - -OUTFILE="" -WORKDIR="" -TEST="" -FORCE="" -WARN="" -SORTARG="" -ENSURE_NEWLINE="" - -PATH=/sbin:/usr/sbin:/bin:/usr/bin - -## Well, if there's ever a bad way to do things, Nexenta has it. -## http://nexenta.org/projects/site/wiki/Personalities -unset SUN_PERSONALITY - -while getopts "o:s:d:tnw:fl" options; do - case $options in - o ) OUTFILE=$OPTARG;; - d ) WORKDIR=$OPTARG;; - n ) SORTARG="-n";; - w ) WARNMSG="$OPTARG";; - f ) FORCE="true";; - t ) TEST="true";; - l ) ENSURE_NEWLINE="true";; - * ) echo "Specify output file with -o and fragments directory with -d" - exit 1;; - esac -done - -# do we have -o? -if [ "x${OUTFILE}" = "x" ]; then - echo "Please specify an output file with -o" - exit 1 -fi - -# do we have -d? -if [ "x${WORKDIR}" = "x" ]; then - echo "Please fragments directory with -d" - exit 1 -fi - -# can we write to -o? -if [ -f "${OUTFILE}" ]; then - if [ ! -w "${OUTFILE}" ]; then - echo "Cannot write to ${OUTFILE}" - exit 1 - fi -else - if [ ! -w `dirname "${OUTFILE}"` ]; then - echo "Cannot write to `dirname \"${OUTFILE}\"` to create ${OUTFILE}" - exit 1 - fi -fi - -# do we have a fragments subdir inside the work dir? -if [ ! -d "${WORKDIR}/fragments" ] && [ ! -x "${WORKDIR}/fragments" ]; then - echo "Cannot access the fragments directory" - exit 1 -fi - -# are there actually any fragments? -if [ ! "$(ls -A """${WORKDIR}/fragments""")" ]; then - if [ "x${FORCE}" = "x" ]; then - echo "The fragments directory is empty, cowardly refusing to make empty config files" - exit 1 - fi -fi - -cd "${WORKDIR}" - -if [ "x${WARNMSG}" = "x" ]; then - : > "fragments.concat" -else - printf '%s\n' "$WARNMSG" > "fragments.concat" -fi - -# find all the files in the fragments directory, sort them numerically and concat to fragments.concat in the working dir -IFS_BACKUP=$IFS -IFS=' -' -for fragfile in `find fragments/ -type f -follow -print0 | xargs -0 -n1 basename | LC_ALL=C sort ${SORTARG}` -do - cat "fragments/$fragfile" >> "fragments.concat" - # Handle newlines. - if [ "x${ENSURE_NEWLINE}" != "x" ]; then - echo >> "fragments.concat" - fi -done -IFS=$IFS_BACKUP - -if [ "x${TEST}" = "x" ]; then - # This is a real run, copy the file to outfile - cp fragments.concat "${OUTFILE}" - RETVAL=$? -else - # Just compare the result to outfile to help the exec decide - cmp "${OUTFILE}" fragments.concat - RETVAL=$? -fi - -exit $RETVAL diff --git a/manifests/init.pp b/manifests/init.pp index 1727bec..78c4081 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,264 +1,264 @@ # == Define: concat # # Sets up so that you can use fragments to build a final config file, # # === Options: # # [*ensure*] # Present/Absent # [*path*] # The path to the final file. Use this in case you want to differentiate # between the name of a resource and the file path. Note: Use the name you # provided in the target of your fragments. # [*owner*] # Who will own the file # [*group*] # Who will own the file # [*mode*] # The mode of the final file # [*force*] # Enables creating empty files if no fragments are present # [*warn*] # Adds a normal shell style comment top of the file indicating that it is # built by puppet # [*force*] # [*backup*] # Controls the filebucketing behavior of the final file and see File type # reference for its use. Defaults to 'puppet' # [*replace*] # Whether to replace a file that already exists on the local system # [*order*] # [*ensure_newline*] # [*gnu*] # Deprecated # # === Actions: # * Creates fragment directories if it didn't exist already -# * Executes the concatfragments.sh script to build the final file, this +# * Executes the concatfragments.rb script to build the final file, this # script will create directory/fragments.concat. Execution happens only # when: # * The directory changes # * fragments.concat != final destination, this means rebuilds will happen # whenever someone changes or deletes the final file. Checking is done # using /usr/bin/cmp. # * The Exec gets notified by something else - like the concat::fragment # define # * Copies the file over to the final destination using a file resource # # === Aliases: # # * The exec can notified using Exec["concat_/path/to/file"] or # Exec["concat_/path/to/directory"] # * The final file can be referenced as File["/path/to/file"] or # File["concat_/path/to/file"] # define concat( $ensure = 'present', $path = $name, $owner = undef, $group = undef, $mode = '0644', $warn = false, $force = false, $backup = 'puppet', $replace = true, $order = 'alpha', $ensure_newline = false, $validate_cmd = undef, $gnu = undef ) { validate_re($ensure, '^present$|^absent$') validate_absolute_path($path) validate_string($owner) validate_string($group) validate_string($mode) if ! (is_string($warn) or $warn == true or $warn == false) { fail('$warn is not a string or boolean') } validate_bool($force) if ! concat_is_bool($backup) and ! is_string($backup) { fail('$backup must be string or bool!') } validate_bool($replace) validate_re($order, '^alpha$|^numeric$') validate_bool($ensure_newline) if $validate_cmd and ! is_string($validate_cmd) { fail('$validate_cmd must be a string') } if $gnu { warning('The $gnu parameter to concat is deprecated and has no effect') } include concat::setup $safe_name = regsubst($name, '[/:]', '_', 'G') $concatdir = $concat::setup::concatdir $fragdir = "${concatdir}/${safe_name}" $concat_name = 'fragments.concat.out' $script_command = $concat::setup::script_command $default_warn_message = '# This file is managed by Puppet. DO NOT EDIT.' $bool_warn_message = 'Using stringified boolean values (\'true\', \'yes\', \'on\', \'false\', \'no\', \'off\') to represent boolean true/false as the $warn parameter to concat is deprecated and will be treated as the warning message in a future release' case $warn { true: { $warn_message = $default_warn_message } 'true', 'yes', 'on': { warning($bool_warn_message) $warn_message = $default_warn_message } false: { $warn_message = '' } 'false', 'no', 'off': { warning($bool_warn_message) $warn_message = '' } default: { $warn_message = $warn } } $warnmsg_escaped = regsubst($warn_message, '\'', '\'\\\'\'', 'G') $warnflag = $warnmsg_escaped ? { '' => '', default => "-w '${warnmsg_escaped}'" } $forceflag = $force ? { true => '-f', false => '', } $orderflag = $order ? { 'numeric' => '-n', 'alpha' => '', } $newlineflag = $ensure_newline ? { true => '-l', false => '', } File { backup => false, } # reset poisoned Exec defaults Exec { user => undef, group => undef, } if $ensure == 'present' { file { $fragdir: ensure => directory, mode => '0750', } file { "${fragdir}/fragments": ensure => directory, mode => '0750', force => true, ignore => ['.svn', '.git', '.gitignore'], notify => Exec["concat_${name}"], purge => true, recurse => true, } file { "${fragdir}/fragments.concat": ensure => present, mode => '0640', } file { "${fragdir}/${concat_name}": ensure => present, mode => '0640', } file { $name: ensure => present, owner => $owner, group => $group, mode => $mode, replace => $replace, path => $path, alias => "concat_${name}", source => "${fragdir}/${concat_name}", backup => $backup, } # Only newer versions of puppet 3.x support the validate_cmd parameter if $validate_cmd { File[$name] { validate_cmd => $validate_cmd, } } # remove extra whitespace from string interpolation to make testing easier $command = strip(regsubst("${script_command} -o \"${fragdir}/${concat_name}\" -d \"${fragdir}\" ${warnflag} ${forceflag} ${orderflag} ${newlineflag}", '\s+', ' ', 'G')) # make sure ruby is in the path for PE if $::is_pe { if $::kernel == 'windows' { $command_path = "${::env_windows_installdir}/bin:${::path}" } else { $command_path = "/opt/puppet/bin:${::path}" } } else { $command_path = $::path } # if puppet is running as root, this exec should also run as root to allow - # the concatfragments.sh script to potentially be installed in path that + # the concatfragments.rb script to potentially be installed in path that # may not be accessible by a target non-root owner. exec { "concat_${name}": alias => "concat_${fragdir}", command => $command, notify => File[$name], subscribe => File[$fragdir], unless => "${command} -t", path => $command_path, require => [ File[$fragdir], File["${fragdir}/fragments"], File["${fragdir}/fragments.concat"], ], } } else { file { [ $fragdir, "${fragdir}/fragments", "${fragdir}/fragments.concat", "${fragdir}/${concat_name}" ]: ensure => absent, force => true, } file { $path: ensure => absent, backup => $backup, } $absent_exec_command = $::kernel ? { 'windows' => 'cmd.exe /c exit 0', default => 'true', } $absent_exec_path = $::kernel ? { 'windows' => $::path, default => '/bin:/usr/bin', } # Need to have an unless here for idempotency. exec { "concat_${name}": alias => "concat_${fragdir}", command => $absent_exec_command, unless => $absent_exec_command, path => $absent_exec_path, } } } # vim:sw=2:ts=2:expandtab:textwidth=79 diff --git a/manifests/setup.pp b/manifests/setup.pp index f04f2d7..a2da1ed 100644 --- a/manifests/setup.pp +++ b/manifests/setup.pp @@ -1,64 +1,56 @@ # === Class: concat::setup # # Sets up the concat system. This is a private class. # # [$concatdir] # is where the fragments live and is set on the fact concat_basedir. # Since puppet should always manage files in $concatdir and they should # not be deleted ever, /tmp is not an option. # # It also copies out the concatfragments.{sh,rb} file to ${concatdir}/bin # class concat::setup { if $caller_module_name != $module_name { warning("${name} is deprecated as a public API of the ${module_name} module and should no longer be directly included in the manifest.") } if $::concat_basedir { $concatdir = $::concat_basedir } else { fail ('$concat_basedir not defined. Try running again with pluginsync=true on the [master] and/or [main] section of your node\'s \'/etc/puppet/puppet.conf\'.') } # owner and mode of fragment files (on windows owner and access rights should # be inherited from concatdir and not explicitly set to avoid problems) $fragment_owner = $::osfamily ? { 'windows' => undef, default => $::id } $fragment_mode = $::osfamily ? { 'windows' => undef, default => '0640' } - # PR #174 introduced changes to the concatfragments.sh script that are - # incompatible with Solaris 10 but reportedly OK on Solaris 11. As a work - # around we are enable the .rb concat script on all Solaris versions. If - # this goes smoothly, we should move towards completely eliminating the .sh - # version. - $script_name = $::osfamily? { - /(?i:(Windows|Solaris|AIX))/ => 'concatfragments.rb', - default => 'concatfragments.sh' - } + $script_name = 'concatfragments.rb' $script_path = "${concatdir}/bin/${script_name}" $script_owner = $::osfamily ? { 'windows' => undef, default => $::id } $script_mode = $::osfamily ? { 'windows' => undef, default => '0755' } $script_command = $::osfamily? { 'windows' => "ruby.exe '${script_path}'", default => $script_path } File { backup => false, } file { $script_path: ensure => file, owner => $script_owner, mode => $script_mode, source => "puppet:///modules/concat/${script_name}", } file { [ $concatdir, "${concatdir}/bin" ]: ensure => directory, mode => '0755', } } diff --git a/spec/acceptance/concat_spec.rb b/spec/acceptance/concat_spec.rb index 7a6d95c..c5c9727 100644 --- a/spec/acceptance/concat_spec.rb +++ b/spec/acceptance/concat_spec.rb @@ -1,217 +1,217 @@ require 'spec_helper_acceptance' case fact('osfamily') when 'AIX' username = 'root' groupname = 'system' - scriptname = 'concatfragments.sh' + scriptname = 'concatfragments.rb' vardir = default['puppetvardir'] when 'Darwin' username = 'root' groupname = 'wheel' - scriptname = 'concatfragments.sh' + scriptname = 'concatfragments.rb' vardir = default['puppetvardir'] when 'windows' username = 'Administrator' groupname = 'Administrators' scriptname = 'concatfragments.rb' result = on default, "echo #{default['puppetvardir']}" vardir = result.raw_output.chomp when 'Solaris' username = 'root' groupname = 'root' scriptname = 'concatfragments.rb' vardir = default['puppetvardir'] else username = 'root' groupname = 'root' - scriptname = 'concatfragments.sh' + scriptname = 'concatfragments.rb' vardir = default['puppetvardir'] end describe 'basic concat test' do basedir = default.tmpdir('concat') safe_basedir = basedir.gsub(/[\/:]/, '_') shared_examples 'successfully_applied' do |pp| it 'applies the manifest twice with no stderr' do apply_manifest(pp, :catch_failures => true) apply_manifest(pp, :catch_changes => true) end describe file("#{vardir}/concat") do it { should be_directory } it { should be_owned_by username } it("should be mode", :unless => (fact('osfamily') == 'AIX' or fact('osfamily') == 'windows')) { should be_mode 755 } end describe file("#{vardir}/concat/bin") do it { should be_directory } it { should be_owned_by username } it("should be mode", :unless => (fact('osfamily') == 'AIX' or fact('osfamily') == 'windows')) { should be_mode 755 } end describe file("#{vardir}/concat/bin/#{scriptname}") do it { should be_file } it { should be_owned_by username } it("should be mode", :unless => (fact('osfamily') == 'AIX' or fact('osfamily') == 'windows')) { should be_mode 755 } end describe file("#{vardir}/concat/#{safe_basedir}_file") do it { should be_directory } it { should be_owned_by username } it("should be mode", :unless => (fact('osfamily') == 'AIX' or fact('osfamily') == 'windows')) { should be_mode 750 } end describe file("#{vardir}/concat/#{safe_basedir}_file/fragments") do it { should be_directory } it { should be_owned_by username } it("should be mode", :unless => (fact('osfamily') == 'AIX' or fact('osfamily') == 'windows')) { should be_mode 750 } end describe file("#{vardir}/concat/#{safe_basedir}_file/fragments.concat") do it { should be_file } it { should be_owned_by username } it("should be mode", :unless => (fact('osfamily') == 'AIX' or fact('osfamily') == 'windows')) { should be_mode 640 } end describe file("#{vardir}/concat/#{safe_basedir}_file/fragments.concat.out") do it { should be_file } it { should be_owned_by username } it("should be mode", :unless => (fact('osfamily') == 'AIX' or fact('osfamily') == 'windows')) { should be_mode 640 } end end context 'owner/group root' do before(:all) do pp = <<-EOS file { '#{basedir}': ensure => directory, } EOS apply_manifest(pp) end pp = <<-EOS concat { '#{basedir}/file': owner => '#{username}', group => '#{groupname}', mode => '0644', } concat::fragment { '1': target => '#{basedir}/file', content => '1', order => '01', } concat::fragment { '2': target => '#{basedir}/file', content => '2', order => '02', } EOS it_behaves_like 'successfully_applied', pp describe file("#{basedir}/file") do it { should be_file } it { should be_owned_by username } it("should be group", :unless => (fact('osfamily') == 'windows')) { should be_grouped_into groupname } it("should be mode", :unless => (fact('osfamily') == 'AIX' or fact('osfamily') == 'windows')) { should be_mode 644 } its(:content) { should match '1' should match '2' } end describe file("#{vardir}/concat/#{safe_basedir}_file/fragments/01_1") do it { should be_file } it { should be_owned_by username } it("should be mode", :unless => (fact('osfamily') == 'AIX' or fact('osfamily') == 'windows')) { should be_mode 640 } end describe file("#{vardir}/concat/#{safe_basedir}_file/fragments/02_2") do it { should be_file } it { should be_owned_by username } it("should be mode", :unless => (fact('osfamily') == 'AIX' or fact('osfamily') == 'windows')) { should be_mode 640 } end end context 'ensure' do context 'works when set to present with path set' do before(:all) do pp = <<-EOS file { '#{basedir}': ensure => directory, } EOS apply_manifest(pp) end pp=" concat { 'file': ensure => present, path => '#{basedir}/file', mode => '0644', } concat::fragment { '1': target => 'file', content => '1', order => '01', } " it_behaves_like 'successfully_applied', pp describe file("#{basedir}/file") do it { should be_file } it("should be mode", :unless => (fact('osfamily') == 'AIX' or fact('osfamily') == 'windows')) { should be_mode 644 } its(:content) { should match '1' } end end context 'works when set to absent with path set' do before(:all) do pp = <<-EOS file { '#{basedir}': ensure => directory, } EOS apply_manifest(pp) end pp=" concat { 'file': ensure => absent, path => '#{basedir}/file', mode => '0644', } concat::fragment { '1': target => 'file', content => '1', order => '01', } " it 'applies the manifest twice with no stderr' do apply_manifest(pp, :catch_failures => true) apply_manifest(pp, :catch_changes => true) end describe file("#{basedir}/file") do it { should_not be_file } end end end end diff --git a/spec/unit/classes/concat_setup_spec.rb b/spec/unit/classes/concat_setup_spec.rb index 2aac763..e97a29c 100644 --- a/spec/unit/classes/concat_setup_spec.rb +++ b/spec/unit/classes/concat_setup_spec.rb @@ -1,96 +1,96 @@ require 'spec_helper' describe 'concat::setup', :type => :class do shared_examples 'setup' do |concatdir| concatdir = '/foo' if concatdir.nil? let(:facts) do { :concat_basedir => concatdir, :caller_module_name => 'Test', :osfamily => 'Debian', :id => 'root', :is_pe => false, } end it do - should contain_file("#{concatdir}/bin/concatfragments.sh").with({ + should contain_file("#{concatdir}/bin/concatfragments.rb").with({ :mode => '0755', - :source => 'puppet:///modules/concat/concatfragments.sh', + :source => 'puppet:///modules/concat/concatfragments.rb', :backup => false, }) end [concatdir, "#{concatdir}/bin"].each do |file| it do should contain_file(file).with({ :ensure => 'directory', :mode => '0755', :backup => false, }) end end end context 'facts' do context 'concat_basedir =>' do context '/foo' do it_behaves_like 'setup', '/foo' end end end # facts context 'deprecated as a public class' do it 'should create a warning' do skip('rspec-puppet support for testing warning()') end end context "on osfamily Solaris" do concatdir = '/foo' let(:facts) do { :concat_basedir => concatdir, :caller_module_name => 'Test', :osfamily => 'Solaris', :id => 'root', :is_pe => false, } end it do should contain_file("#{concatdir}/bin/concatfragments.rb").with({ :ensure => 'file', :owner => 'root', :mode => '0755', :source => 'puppet:///modules/concat/concatfragments.rb', :backup => false, }) end end # on osfamily Solaris context "on osfamily windows" do concatdir = '/foo' let(:facts) do { :concat_basedir => concatdir, :caller_module_name => 'Test', :osfamily => 'windows', :id => 'batman', :is_pe => false, } end it do should contain_file("#{concatdir}/bin/concatfragments.rb").with({ :ensure => 'file', :owner => nil, :mode => nil, :source => 'puppet:///modules/concat/concatfragments.rb', :backup => false, }) end end # on osfamily windows end diff --git a/spec/unit/defines/concat_spec.rb b/spec/unit/defines/concat_spec.rb index de12ab9..a748f96 100644 --- a/spec/unit/defines/concat_spec.rb +++ b/spec/unit/defines/concat_spec.rb @@ -1,416 +1,416 @@ require 'spec_helper' describe 'concat', :type => :define do shared_examples 'concat' do |title, params, id| params = {} if params.nil? id = 'root' if id.nil? # default param values p = { :ensure => 'present', :path => title, :owner => nil, :group => nil, :mode => '0644', :warn => false, :force => false, :backup => 'puppet', :replace => true, :order => 'alpha', :ensure_newline => false, :validate_cmd => nil, }.merge(params) safe_name = title.gsub('/', '_') concatdir = '/var/lib/puppet/concat' fragdir = "#{concatdir}/#{safe_name}" concat_name = 'fragments.concat.out' default_warn_message = '# This file is managed by Puppet. DO NOT EDIT.' file_defaults = { :backup => false, } let(:title) { title } let(:params) { params } let(:facts) do { :concat_basedir => concatdir, :id => id, :osfamily => 'Debian', :path => '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin', :kernel => 'Linux', :is_pe => false, } end if p[:ensure] == 'present' it do should contain_file(fragdir).with(file_defaults.merge({ :ensure => 'directory', :mode => '0750', })) end it do should contain_file("#{fragdir}/fragments").with(file_defaults.merge({ :ensure => 'directory', :mode => '0750', :force => true, :ignore => ['.svn', '.git', '.gitignore'], :purge => true, :recurse => true, })) end [ "#{fragdir}/fragments.concat", "#{fragdir}/#{concat_name}", ].each do |file| it do should contain_file(file).with(file_defaults.merge({ :ensure => 'present', :mode => '0640', })) end end it do should contain_file(title).with(file_defaults.merge({ :ensure => 'present', :owner => p[:owner], :group => p[:group], :mode => p[:mode], :replace => p[:replace], :path => p[:path], :alias => "concat_#{title}", :source => "#{fragdir}/#{concat_name}", :validate_cmd => p[:validate_cmd], :backup => p[:backup], })) end - cmd = "#{concatdir}/bin/concatfragments.sh " + + cmd = "#{concatdir}/bin/concatfragments.rb " + "-o \"#{concatdir}/#{safe_name}/fragments.concat.out\" " + "-d \"#{concatdir}/#{safe_name}\"" # flag order: fragdir, warnflag, forceflag, orderflag, newlineflag if p.has_key?(:warn) case p[:warn] when TrueClass message = default_warn_message when 'true', 'yes', 'on' # should generate a stringified boolean warning message = default_warn_message when FalseClass message = nil when 'false', 'no', 'off' # should generate a stringified boolean warning message = nil else message = p[:warn] end unless message.nil? cmd += " -w \'#{message}\'" end end cmd += " -f" if p[:force] cmd += " -n" if p[:order] == 'numeric' cmd += " -l" if p[:ensure_newline] == true it do should contain_exec("concat_#{title}").with({ :alias => "concat_#{fragdir}", :command => cmd, :unless => "#{cmd} -t", }) end else [ fragdir, "#{fragdir}/fragments", "#{fragdir}/fragments.concat", "#{fragdir}/#{concat_name}", ].each do |file| it do should contain_file(file).with(file_defaults.merge({ :ensure => 'absent', :backup => false, :force => true, })) end end it do should contain_file(title).with(file_defaults.merge({ :ensure => 'absent', :backup => p[:backup], })) end it do should contain_exec("concat_#{title}").with({ :alias => "concat_#{fragdir}", :command => 'true', :unless => 'true', :path => '/bin:/usr/bin', }) end end end context 'title' do context 'without path param' do # title/name is the default value for the path param. therefore, the # title must be an absolute path unless path is specified ['/foo', '/foo/bar', '/foo/bar/baz'].each do |title| context title do it_behaves_like 'concat', '/etc/foo.bar' end end ['./foo', 'foo', 'foo/bar'].each do |title| context title do let(:title) { title } it 'should fail' do expect { should }.to raise_error(Puppet::Error, /is not an absolute path/) end end end end context 'with path param' do ['./foo', 'foo', 'foo/bar'].each do |title| context title do it_behaves_like 'concat', title, { :path => '/etc/foo.bar' } end end end end # title => context 'as non-root user' do it_behaves_like 'concat', '/etc/foo.bar', {}, 'bob' end context 'ensure =>' do ['present', 'absent'].each do |ens| context ens do it_behaves_like 'concat', '/etc/foo.bar', { :ensure => ens } end end context 'invalid' do let(:title) { '/etc/foo.bar' } let(:params) {{ :ensure => 'invalid' }} it 'should fail' do expect { should }.to raise_error(Puppet::Error, /#{Regexp.escape('does not match "^present$|^absent$"')}/) end end end # ensure => context 'path =>' do context '/foo' do it_behaves_like 'concat', '/etc/foo.bar', { :path => '/foo' } end ['./foo', 'foo', 'foo/bar', false].each do |path| context path do let(:title) { '/etc/foo.bar' } let(:params) {{ :path => path }} it 'should fail' do expect { should }.to raise_error(Puppet::Error, /is not an absolute path/) end end end end # path => context 'owner =>' do context 'apenney' do it_behaves_like 'concat', '/etc/foo.bar', { :owner => 'apenny' } end context 'false' do let(:title) { '/etc/foo.bar' } let(:params) {{ :owner => false }} it 'should fail' do expect { should }.to raise_error(Puppet::Error, /is not a string/) end end end # owner => context 'group =>' do context 'apenney' do it_behaves_like 'concat', '/etc/foo.bar', { :group => 'apenny' } end context 'false' do let(:title) { '/etc/foo.bar' } let(:params) {{ :group => false }} it 'should fail' do expect { should }.to raise_error(Puppet::Error, /is not a string/) end end end # group => context 'mode =>' do context '1755' do it_behaves_like 'concat', '/etc/foo.bar', { :mode => '1755' } end context 'false' do let(:title) { '/etc/foo.bar' } let(:params) {{ :mode => false }} it 'should fail' do expect { should }.to raise_error(Puppet::Error, /is not a string/) end end end # mode => context 'warn =>' do [true, false, '# foo'].each do |warn| context warn do it_behaves_like 'concat', '/etc/foo.bar', { :warn => warn } end end context '(stringified boolean)' do ['true', 'yes', 'on', 'false', 'no', 'off'].each do |warn| context warn do it_behaves_like 'concat', '/etc/foo.bar', { :warn => warn } it 'should create a warning' do skip('rspec-puppet support for testing warning()') end end end end context '123' do let(:title) { '/etc/foo.bar' } let(:params) {{ :warn => 123 }} it 'should fail' do expect { should }.to raise_error(Puppet::Error, /is not a string or boolean/) end end end # warn => context 'force =>' do [true, false].each do |force| context force do it_behaves_like 'concat', '/etc/foo.bar', { :force => force } end end context '123' do let(:title) { '/etc/foo.bar' } let(:params) {{ :force => 123 }} it 'should fail' do expect { should }.to raise_error(Puppet::Error, /is not a boolean/) end end end # force => context 'backup =>' do context 'reverse' do it_behaves_like 'concat', '/etc/foo.bar', { :backup => 'reverse' } end context 'false' do it_behaves_like 'concat', '/etc/foo.bar', { :backup => false } end context 'true' do it_behaves_like 'concat', '/etc/foo.bar', { :backup => true } end context 'true' do let(:title) { '/etc/foo.bar' } let(:params) {{ :backup => [] }} it 'should fail' do expect { should }.to raise_error(Puppet::Error, /backup must be string or bool/) end end end # backup => context 'replace =>' do [true, false].each do |replace| context replace do it_behaves_like 'concat', '/etc/foo.bar', { :replace => replace } end end context '123' do let(:title) { '/etc/foo.bar' } let(:params) {{ :replace => 123 }} it 'should fail' do expect { should }.to raise_error(Puppet::Error, /is not a boolean/) end end end # replace => context 'order =>' do ['alpha', 'numeric'].each do |order| context order do it_behaves_like 'concat', '/etc/foo.bar', { :order => order } end end context 'invalid' do let(:title) { '/etc/foo.bar' } let(:params) {{ :order => 'invalid' }} it 'should fail' do expect { should }.to raise_error(Puppet::Error, /#{Regexp.escape('does not match "^alpha$|^numeric$"')}/) end end end # order => context 'ensure_newline =>' do [true, false].each do |ensure_newline| context 'true' do it_behaves_like 'concat', '/etc/foo.bar', { :ensure_newline => ensure_newline} end end context '123' do let(:title) { '/etc/foo.bar' } let(:params) {{ :ensure_newline => 123 }} it 'should fail' do expect { should }.to raise_error(Puppet::Error, /is not a boolean/) end end end # ensure_newline => context 'validate_cmd =>' do context '/usr/bin/test -e %' do it_behaves_like 'concat', '/etc/foo.bar', { :validate_cmd => '/usr/bin/test -e %' } end [ 1234, true ].each do |cmd| context cmd do let(:title) { '/etc/foo.bar' } let(:params) {{ :validate_cmd => cmd }} it 'should fail' do expect { should }.to raise_error(Puppet::Error, /\$validate_cmd must be a string/) end end end end # validate_cmd => describe 'deprecated parameter' do context 'gnu =>' do context 'foo' do it_behaves_like 'concat', '/etc/foo.bar', { :gnu => 'foo'} it 'should create a warning' do skip('rspec-puppet support for testing warning()') end end end end end # vim:sw=2:ts=2:expandtab:textwidth=79