diff --git a/manifests/fragment.pp b/manifests/fragment.pp index 9cfae66..0c64ace 100644 --- a/manifests/fragment.pp +++ b/manifests/fragment.pp @@ -1,55 +1,55 @@ # == Define: concat::fragment # # Creates a concat_fragment in the catalogue # # === Options: # # [*target*] # The file that these fragments belong to # [*content*] # If present puts the content into the file # [*source*] # If content was not specified, use the source # [*order*] # By default all files gets a 10_ prefix in the directory you can set it to # anything else using this to influence the order of the content in the file # define concat::fragment( $target, $ensure = undef, $content = undef, $source = undef, $order = '10', ) { validate_string($target) if $ensure != undef { warning('The $ensure parameter to concat::fragment is deprecated and has no effect.') } validate_string($content) if !(is_string($source) or is_array($source)) { fail('$source is not a string or an Array.') } if !(is_string($order) or is_integer($order)) { fail('$order is not a string or integer.') } elsif (is_string($order) and $order =~ /[:\n\/]/) { fail("Order cannot contain '/', ':', or '\n'.") } if ! ($content or $source) { crit('No content, source or symlink specified') } elsif ($content and $source) { fail("Can't use 'source' and 'content' at the same time") } - $safe_target_name = regsubst($target, '[/:\n\s]', '_', 'GM') + $safe_target_name = regsubst($target, '[/:\n\s\(\)]', '_', 'GM') concat_fragment { $name: tag => $safe_target_name, order => $order, content => $content, source => $source, } } diff --git a/manifests/init.pp b/manifests/init.pp index 46d4896..e481fc0 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,127 +1,127 @@ # == 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 # [*warn*] # Adds a normal shell style comment top of the file indicating that it is # built by puppet. # Before 2.0.0, this parameter would add a newline at the end of the warn # message. To improve flexibilty, this was removed. Please add it explicitely # if you need it. # [*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*] # Select whether to order associated fragments by 'alpha' or 'numeric'. # Defaults to 'alpha'. # [*ensure_newline*] # Specifies whether to ensure there's a new line at the end of each fragment. # Valid options: 'true' and 'false'. Default value: 'false'. # [*validate_cmd*] # Specifies a validation command to apply to the destination file. # Requires Puppet version 3.5 or newer. Valid options: a string to be passed # to a file resource. Default value: undefined. # define concat( $ensure = 'present', $path = $name, $owner = undef, $group = undef, $mode = '0644', $warn = false, $force = undef, $backup = 'puppet', $replace = true, $order = 'alpha', $ensure_newline = false, $validate_cmd = 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') } if ! 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 $force != undef { warning('The $force parameter to concat is deprecated and has no effect.') } - $safe_name = regsubst($name, '[/:\n\s]', '_', 'G') + $safe_name = regsubst($name, '[/:\n\s\(\)]', '_', 'G') $default_warn_message = "# This file is managed by Puppet. DO NOT EDIT.\n" case $warn { true: { $warn_message = $default_warn_message $_append_header = true } false: { $warn_message = '' $_append_header = false } default: { $warn_message = $warn $_append_header = true } } if $ensure == 'present' { concat_file { $name: tag => $safe_name, path => $path, owner => $owner, group => $group, mode => $mode, replace => $replace, backup => $backup, order => $order, ensure_newline => $ensure_newline, validate_cmd => $validate_cmd, } if $_append_header { concat_fragment { "${name}_header": tag => $safe_name, content => $warn_message, order => '0', } } } else { concat_file { $name: ensure => $ensure, tag => $safe_name, path => $path, backup => $backup, } } } diff --git a/spec/acceptance/concat_spec.rb b/spec/acceptance/concat_spec.rb index c281954..fd130fe 100644 --- a/spec/acceptance/concat_spec.rb +++ b/spec/acceptance/concat_spec.rb @@ -1,153 +1,185 @@ require 'spec_helper_acceptance' case fact('osfamily') when 'AIX' username = 'root' groupname = 'system' scriptname = 'concatfragments.rb' vardir = default['puppetvardir'] when 'Darwin' username = 'root' groupname = 'wheel' 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.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 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 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 + context 'works when set to present with path that has special characters' do + before(:all) do + pp = <<-EOS + file { '#{basedir}': + ensure => directory, + } + EOS + apply_manifest(pp) + end + pp=" + concat { 'file(a:b)': + ensure => present, + path => '#{basedir}/file(a:b)', + mode => '0644', + } + concat::fragment { '1': + target => 'file(a:b)', + content => '1', + order => '01', + } + " + + it_behaves_like 'successfully_applied', pp + + describe file("#{basedir}/file(a:b)") 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 end end