diff options
60 files changed, 644 insertions, 454 deletions
diff --git a/.sync.yml b/.sync.yml deleted file mode 100644 index 21e872e..0000000 --- a/.sync.yml +++ /dev/null @@ -1,9 +0,0 @@ ---- -.travis.yml: - script: "\"bundle exec rake validate && bundle exec rake lint && bundle exec rake spec SPEC_OPTS='--color --format documentation'\"" -Rakefile: - unmanaged: true -Gemfile: - unmanaged: true -spec/spec_helper.rb: - unmanaged: true diff --git a/.travis.yml b/.travis.yml index 1f22c6c..4e2c66d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,18 +3,33 @@ sudo: false language: ruby cache: bundler -bundler_args: --without system_tests -script: "bundle exec rake validate && bundle exec rake lint && bundle exec rake spec SPEC_OPTS='--color --format documentation'" +script: "bundle exec rake validate lint spec" matrix: fast_finish: true include: - rvm: 2.1.6 + dist: trusty + env: PUPPET_INSTALL_TYPE=agent BEAKER_debug=true BEAKER_set=docker/ubuntu-14.04 + script: bundle exec rake beaker + services: docker + sudo: required + - rvm: 2.1.6 + dist: trusty + env: PUPPET_INSTALL_TYPE=agent BEAKER_debug=true BEAKER_set=docker/centos-7 + script: bundle exec rake beaker + services: docker + sudo: required + - rvm: 2.1.6 + bundler_args: --without system_tests env: PUPPET_GEM_VERSION="~> 4.0" STRICT_VARIABLES="yes" - rvm: 2.1.5 + bundler_args: --without system_tests env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes" - rvm: 2.1.5 + bundler_args: --without system_tests env: PUPPET_GEM_VERSION="~> 3.0" - rvm: 1.9.3 + bundler_args: --without system_tests env: PUPPET_GEM_VERSION="~> 3.0" notifications: email: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 2698dde..2bc584b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,28 @@ +## Supported Release 4.12.0 +###Summary + +This release provides several new functions, bugfixes, modulesync changes, and some documentation updates. + +####Features +- Adds `clamp`. This function keeps values within a specified range. +- Adds `validate_x509_rsa_key_pair`. This function validates an x509 RSA certificate and key pair. +- Adds `dig`. This function performs a deep lookup in nested hashes or arrays. +- Extends the `base64` support to fit `rfc2045` and `rfc4648`. +- Adds `is_ipv6_address` and `is_ipv4_address`. These functions validate the specified ipv4 or ipv6 addresses. +- Adds `enclose_ipv6`. This function encloses IPv6 addresses in square brackets. +- Adds `ensure_resources`. This function takes a list of resources and creates them if they do not exist. +- Extends `suffix` to support applying a suffix to keys in a hash. +- Apply modulesync changes. +- Add validate_email_address function. + +####Bugfixes +- Fixes `fqdn_rand_string` tests, since Puppet 4.4.0 and later have a higher `fqdn_rand` ceiling. +- (MODULES-3152) Adds a check to `package_provider` to prevent failures if Gem is not installed. +- Fixes to README.md. +- Fixes catch StandardError rather than the gratuitous Exception +- Fixes file_line attribute validation. +- Fixes concat with Hash arguments. + ## Supported Release 4.11.0 ###Summary @@ -1,61 +1,39 @@ -source ENV['GEM_SOURCE'] || 'https://rubygems.org' +#This file is generated by ModuleSync, do not edit. -def location_for(place, fake_version = nil) +source ENV['GEM_SOURCE'] || "https://rubygems.org" + +def location_for(place, version = nil) if place =~ /^(git[:@][^#]*)#(.*)/ - [fake_version, { :git => $1, :branch => $2, :require => false }].compact + [version, { :git => $1, :branch => $2, :require => false}].compact elsif place =~ /^file:\/\/(.*)/ - ['>= 0', { :path => File.expand_path($1), :require => false }] + ['>= 0', { :path => File.expand_path($1), :require => false}] else - [place, { :require => false }] + [place, version, { :require => false}].compact end end group :development, :unit_tests do - # rspec must be v2 for ruby 1.8.7 - if RUBY_VERSION >= '1.8.7' and RUBY_VERSION < '1.9' - gem 'rspec', '~> 2.0' - else - gem 'rspec', '~> 3.1.0', :require => false - end - - gem 'rake', '~> 10.1.0', :require => false - gem 'rspec-puppet', '~> 2.2', :require => false - gem 'mocha', :require => false - # keep for its rake task for now - gem 'puppetlabs_spec_helper', :require => false - gem 'puppet-lint', :require => false - gem 'metadata-json-lint', :require => false - gem 'pry', :require => false - gem 'simplecov', :require => false + gem 'json', :require => false + gem 'metadata-json-lint', :require => false + gem 'puppet_facts', :require => false + gem 'puppet-blacksmith', :require => false + gem 'puppetlabs_spec_helper', :require => false + gem 'rspec-puppet', '>= 2.3.2', :require => false + gem 'simplecov', :require => false end - -beaker_version = ENV['BEAKER_VERSION'] -beaker_rspec_version = ENV['BEAKER_RSPEC_VERSION'] group :system_tests do - if beaker_version - gem 'beaker', *location_for(beaker_version) - end - if beaker_rspec_version - gem 'beaker-rspec', *location_for(beaker_rspec_version) - else - gem 'beaker-rspec', :require => false - end - gem 'serverspec', :require => false - gem 'beaker-puppet_install_helper', :require => false + gem 'beaker-rspec', *location_for(ENV['BEAKER_RSPEC_VERSION'] || '>= 3.4') + gem 'beaker', *location_for(ENV['BEAKER_VERSION']) + gem 'serverspec', :require => false + gem 'beaker-puppet_install_helper', :require => false + gem 'master_manipulator', :require => false + gem 'beaker-hostgenerator', *location_for(ENV['BEAKER_HOSTGENERATOR_VERSION']) end -facterversion = ENV['GEM_FACTER_VERSION'] || ENV['FACTER_GEM_VERSION'] -if facterversion - gem 'facter', *location_for(facterversion) -else - gem 'facter', :require => false -end +gem 'facter', *location_for(ENV['FACTER_GEM_VERSION']) +gem 'puppet', *location_for(ENV['PUPPET_GEM_VERSION']) -puppetversion = ENV['GEM_PUPPET_VERSION'] || ENV['PUPPET_GEM_VERSION'] -if puppetversion - gem 'puppet', *location_for(puppetversion) -else - gem 'puppet', :require => false -end -# vim:ft=ruby +if File.exists? "#{__FILE__}.local" + eval(File.read("#{__FILE__}.local"), binding) +end diff --git a/README.markdown b/README.markdown index eff3b28..6a64b79 100644 --- a/README.markdown +++ b/README.markdown @@ -146,11 +146,9 @@ Converts any object to an array containing that object. Empty argument lists are #### `base64` -Converts a string to and from base64 encoding. -Requires an `action` ('encode', 'decode') and either a plain or base64-encoded `string`, -and an optional `method` ('default', 'strict', 'urlsafe') +Converts a string to and from base64 encoding. Requires an `action` ('encode', 'decode') and either a plain or base64-encoded `string`, and an optional `method` ('default', 'strict', 'urlsafe') -for backward compatibility, `metohd` will be set as `default` if not specified. +For backward compatibility, `method` will be set as `default` if not specified. *Examples:* ~~~ @@ -265,7 +263,11 @@ Takes a resource reference and an optional hash of attributes. Returns 'true' if #### `delete` -Deletes all instances of a given element from an array, substring from a string, or key from a hash. For example, `delete(['a','b','c','b'], 'b')` returns ['a','c']; `delete('abracadabra', 'bra')` returns 'acada'. `delete({'a' => 1,'b' => 2,'c' => 3},['b','c'])` returns {'a'=> 1}. *Type*: rvalue. +Deletes all instances of a given element from an array, substring from a string, or key from a hash. Arrays and hashes may also match on regular expressions by providing a full regular expression. + +For example, `delete(['a','b','c','b'], 'b')` returns ['a','c']; `delete('abracadabra', 'bra')` returns 'acada'. `delete({'a' => 1,'b' => 2,'c' => 3},['b','c'])` returns {'a'=> 1}, `delete(['abf', 'ab', 'ac'], '^ab.*')` returns ['ac']. `delete(['ab', 'b'], 'b')` returns ['ab']. + +*Type*: rvalue. #### `delete_at` @@ -346,8 +348,7 @@ Returns true if the argument is an array or hash that contains no elements, or a #### `enclose_ipv6` -Takes an array of ip addresses and encloses the ipv6 addresses with square -brackets. *Type*: rvalue. +Takes an array of ip addresses and encloses the ipv6 addresses with square brackets. *Type*: rvalue. #### `ensure_packages` @@ -359,7 +360,7 @@ For Array: For Hash: - ensure_packages({'ksh' => { enure => '20120801-1' } , 'mypackage' => { source => '/tmp/myrpm-1.0.0.x86_64.rpm', provider => "rpm" }}, {'ensure' => 'present'}) + ensure_packages({'ksh' => { ensure => '20120801-1' } , 'mypackage' => { source => '/tmp/myrpm-1.0.0.x86_64.rpm', provider => "rpm" }}, {'ensure' => 'present'}) #### `ensure_resource` @@ -851,6 +852,40 @@ Strips spaces to the right of the string. *Type*: rvalue. Takes an integer max value and a string seed value and returns a repeatable random integer smaller than max. Like `fqdn_rand`, but does not add node specific data to the seed. *Type*: rvalue. +#### `shell_escape` + +Escapes a string so that it can be safely used in a Bourne shell command line. Note that the resulting string should be used unquoted and is not intended for use in double quotes nor in single quotes. This function behaves the same as ruby's `Shellwords.shellescape()` function, also see the [ruby documentation](http://ruby-doc.org/stdlib-2.3.0/libdoc/shellwords/rdoc/Shellwords.html#method-c-shellescape). + +*Example:* +~~~ +shell_escape('foo b"ar') => 'foo\ b\"ar' +~~~ + +*Type*: rvalue. + +#### `shell_join` + +Builds a command line string from the given array of strings. Each array item is escaped for Bourne shell. All items are +then joined together, with a single space in between. This function behaves the same as ruby's `Shellwords.shelljoin()` function, also see the [ruby documentation](http://ruby-doc.org/stdlib-2.3.0/libdoc/shellwords/rdoc/Shellwords.html#method-c-shelljoin). + +*Example:* +~~~ +shell_join(['foo bar', 'ba"z']) => 'foo\ bar ba\"z' +~~~ + +*Type*: rvalue. + +#### `shell_split` + +Splits a string into an array of tokens in the same way the Bourne shell does. This function behaves the same as ruby's `Shellwords.shellsplit()` function, also see the [ruby documentation](http://ruby-doc.org/stdlib-2.3.0/libdoc/shellwords/rdoc/Shellwords.html#method-c-shellsplit). + +*Example:* +~~~ +shell_split('foo\ bar ba\"z') => ['foo bar', 'ba"z'] +~~~ + +*Type*: rvalue. + #### `shuffle` Randomizes the order of a string or array elements. *Type*: rvalue. @@ -1,7 +1,42 @@ -require 'rubygems' -# keep for compatibility for now -require 'puppetlabs_spec_helper/rake_tasks' +require 'puppet_blacksmith/rake_tasks' require 'puppet-lint/tasks/puppet-lint' +require 'puppetlabs_spec_helper/rake_tasks' + +PuppetLint.configuration.fail_on_warnings = true +PuppetLint.configuration.send('relative') PuppetLint.configuration.send('disable_80chars') +PuppetLint.configuration.send('disable_class_inherits_from_params_class') +PuppetLint.configuration.send('disable_documentation') +PuppetLint.configuration.send('disable_single_quote_string_with_variables') PuppetLint.configuration.ignore_paths = ["spec/**/*.pp", "pkg/**/*.pp"] +desc 'Generate pooler nodesets' +task :gen_nodeset do + require 'beaker-hostgenerator' + require 'securerandom' + require 'fileutils' + + agent_target = ENV['TEST_TARGET'] + if ! agent_target + STDERR.puts 'TEST_TARGET environment variable is not set' + STDERR.puts 'setting to default value of "redhat-64default."' + agent_target = 'redhat-64default.' + end + + master_target = ENV['MASTER_TEST_TARGET'] + if ! master_target + STDERR.puts 'MASTER_TEST_TARGET environment variable is not set' + STDERR.puts 'setting to default value of "redhat7-64mdcl"' + master_target = 'redhat7-64mdcl' + end + + targets = "#{master_target}-#{agent_target}" + cli = BeakerHostGenerator::CLI.new([targets]) + nodeset_dir = "tmp/nodesets" + nodeset = "#{nodeset_dir}/#{targets}-#{SecureRandom.uuid}.yaml" + FileUtils.mkdir_p(nodeset_dir) + File.open(nodeset, 'w') do |fh| + fh.print(cli.execute) + end + puts nodeset +end diff --git a/lib/facter/facter_dot_d.rb b/lib/facter/facter_dot_d.rb index d85940d..5c5fb1f 100644 --- a/lib/facter/facter_dot_d.rb +++ b/lib/facter/facter_dot_d.rb @@ -48,7 +48,7 @@ class Facter::Util::DotD end end end - rescue Exception => e + rescue StandardError => e Facter.warn("Failed to handle #{file} as text facts: #{e.class}: #{e}") end @@ -65,7 +65,7 @@ class Facter::Util::DotD setcode { v } end end - rescue Exception => e + rescue StandardError => e Facter.warn("Failed to handle #{file} as json facts: #{e.class}: #{e}") end @@ -77,7 +77,7 @@ class Facter::Util::DotD setcode { v } end end - rescue Exception => e + rescue StandardError => e Facter.warn("Failed to handle #{file} as yaml facts: #{e.class}: #{e}") end @@ -106,7 +106,7 @@ class Facter::Util::DotD end end end - rescue Exception => e + rescue StandardError => e Facter.warn("Failed to handle #{file} as script facts: #{e.class}: #{e}") Facter.debug(e.backtrace.join("\n\t")) end diff --git a/lib/puppet/parser/functions/any2bool.rb b/lib/puppet/parser/functions/any2bool.rb new file mode 100644 index 0000000..f0f8f83 --- /dev/null +++ b/lib/puppet/parser/functions/any2bool.rb @@ -0,0 +1,55 @@ +# +# any2bool.rb +# + +module Puppet::Parser::Functions + newfunction(:any2bool, :type => :rvalue, :doc => <<-EOS +This converts 'anything' to a boolean. In practise it does the following: + +* Strings such as Y,y,1,T,t,TRUE,yes,'true' will return true +* Strings such as 0,F,f,N,n,FALSE,no,'false' will return false +* Booleans will just return their original value +* Number (or a string representation of a number) > 0 will return true, otherwise false +* undef will return false +* Anything else will return true + EOS + ) do |arguments| + + raise(Puppet::ParseError, "any2bool(): Wrong number of arguments " + + "given (#{arguments.size} for 1)") if arguments.size < 1 + + # If argument is already Boolean, return it + if !!arguments[0] == arguments[0] + return arguments[0] + end + + arg = arguments[0] + + if arg == nil + return false + end + + if arg == :undef + return false + end + + valid_float = !!Float(arg) rescue false + + if arg.is_a?(Numeric) + return function_num2bool( [ arguments[0] ] ) + end + + if arg.is_a?(String) + if valid_float + return function_num2bool( [ arguments[0] ] ) + else + return function_str2bool( [ arguments[0] ] ) + end + end + + return true + + end +end + +# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/concat.rb b/lib/puppet/parser/functions/concat.rb index 618e62d..91edb4e 100644 --- a/lib/puppet/parser/functions/concat.rb +++ b/lib/puppet/parser/functions/concat.rb @@ -31,7 +31,7 @@ Would result in: arguments.shift arguments.each do |x| - result = result + Array(x) + result = result + (x.is_a?(Array) ? x : [x]) end return result diff --git a/lib/puppet/parser/functions/delete.rb b/lib/puppet/parser/functions/delete.rb index f548b44..814e1ad 100644 --- a/lib/puppet/parser/functions/delete.rb +++ b/lib/puppet/parser/functions/delete.rb @@ -2,8 +2,6 @@ # delete.rb # -# TODO(Krzysztof Wilczynski): We need to add support for regular expression ... - module Puppet::Parser::Functions newfunction(:delete, :type => :rvalue, :doc => <<-EOS Deletes all instances of a given element from an array, substring from a @@ -22,19 +20,23 @@ string, or key from a hash. delete('abracadabra', 'bra') Would return: 'acada' + + delete(['abracadabra'], '^.*bra.*$') + Would return: [] + + delete(['abracadabra'], '^.*jimbob.*$') + Would return: ['abracadabra'] EOS ) do |arguments| - if (arguments.size != 2) then - raise(Puppet::ParseError, "delete(): Wrong number of arguments "+ - "given #{arguments.size} for 2.") - end + raise(Puppet::ParseError, "delete(): Wrong number of arguments "+ + "given #{arguments.size} for 2") unless arguments.size == 2 collection = arguments[0].dup Array(arguments[1]).each do |item| case collection when Array, Hash - collection.delete item + collection.reject! { |coll_item| (coll_item =~ %r{\b#{item}\b}) } when String collection.gsub! item, '' else diff --git a/lib/puppet/parser/functions/hash.rb b/lib/puppet/parser/functions/hash.rb index 8cc4823..89d0e07 100644 --- a/lib/puppet/parser/functions/hash.rb +++ b/lib/puppet/parser/functions/hash.rb @@ -29,7 +29,7 @@ Would return: {'a'=>1,'b'=>2,'c'=>3} # This is to make it compatible with older version of Ruby ... array = array.flatten result = Hash[*array] - rescue Exception + rescue StandardError raise(Puppet::ParseError, 'hash(): Unable to compute ' + 'hash from array given') end diff --git a/lib/puppet/parser/functions/is_email_address.rb b/lib/puppet/parser/functions/is_email_address.rb new file mode 100644 index 0000000..4fb0229 --- /dev/null +++ b/lib/puppet/parser/functions/is_email_address.rb @@ -0,0 +1,21 @@ +# +# is_email_address.rb +# + +module Puppet::Parser::Functions + newfunction(:is_email_address, :type => :rvalue, :doc => <<-EOS +Returns true if the string passed to this function is a valid email address. + EOS + ) do |arguments| + if arguments.size != 1 + raise(Puppet::ParseError, 'is_email_address(): Wrong number of arguments '\ + "given #{arguments.size} for 1") + end + + # Taken from http://emailregex.com/ (simpler regex) + valid_email_regex = %r{\A([\w+\-].?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z} + return (arguments[0] =~ valid_email_regex) == 0 + end +end + +# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/parsejson.rb b/lib/puppet/parser/functions/parsejson.rb index b4af40e..f7c2896 100644 --- a/lib/puppet/parser/functions/parsejson.rb +++ b/lib/puppet/parser/functions/parsejson.rb @@ -15,7 +15,7 @@ be returned if the parsing of YAML string have failed. begin PSON::load(arguments[0]) || arguments[1] - rescue Exception => e + rescue StandardError => e if arguments[1] arguments[1] else diff --git a/lib/puppet/parser/functions/parseyaml.rb b/lib/puppet/parser/functions/parseyaml.rb index 66d0413..ba9d98a 100644 --- a/lib/puppet/parser/functions/parseyaml.rb +++ b/lib/puppet/parser/functions/parseyaml.rb @@ -16,7 +16,10 @@ be returned if the parsing of YAML string have failed. begin YAML::load(arguments[0]) || arguments[1] - rescue Exception => e + # in ruby 1.9.3 Psych::SyntaxError is a RuntimeException + # this still needs to catch that and work also on rubies that + # do not have Psych available. + rescue StandardError, Psych::SyntaxError => e if arguments[1] arguments[1] else diff --git a/lib/puppet/parser/functions/shell_escape.rb b/lib/puppet/parser/functions/shell_escape.rb new file mode 100644 index 0000000..447fe35 --- /dev/null +++ b/lib/puppet/parser/functions/shell_escape.rb @@ -0,0 +1,30 @@ +# +# shell_escape.rb +# + +require 'shellwords' + +module Puppet::Parser::Functions + newfunction(:shell_escape, :type => :rvalue, :doc => <<-EOS +Escapes a string so that it can be safely used in a Bourne shell command line. + +Note that the resulting string should be used unquoted and is not intended for use in double quotes nor in single +quotes. + +This function behaves the same as ruby's Shellwords.shellescape() function. + EOS + ) do |arguments| + + raise(Puppet::ParseError, "shell_escape(): Wrong number of arguments " + + "given (#{arguments.size} for 1)") if arguments.size != 1 + + # explicit conversion to string is required for ruby 1.9 + string = arguments[0].to_s + + result = Shellwords.shellescape(string) + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/shell_join.rb b/lib/puppet/parser/functions/shell_join.rb new file mode 100644 index 0000000..05aeb95 --- /dev/null +++ b/lib/puppet/parser/functions/shell_join.rb @@ -0,0 +1,31 @@ +# +# shell_join.rb +# + +require 'shellwords' + +module Puppet::Parser::Functions + newfunction(:shell_join, :type => :rvalue, :doc => <<-EOS +Builds a command line string from the given array of strings. Each array item is escaped for Bourne shell. All items are +then joined together, with a single space in between. + +This function behaves the same as ruby's Shellwords.shelljoin() function + EOS + ) do |arguments| + + raise(Puppet::ParseError, "shell_join(): Wrong number of arguments " + + "given (#{arguments.size} for 1)") if arguments.size != 1 + + array = arguments[0] + + raise Puppet::ParseError, ("First argument is not an Array: #{array.inspect}") unless array.is_a?(Array) + + # explicit conversion to string is required for ruby 1.9 + array = array.map { |item| item.to_s } + result = Shellwords.shelljoin(array) + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/shell_split.rb b/lib/puppet/parser/functions/shell_split.rb new file mode 100644 index 0000000..0446448 --- /dev/null +++ b/lib/puppet/parser/functions/shell_split.rb @@ -0,0 +1,26 @@ +# +# shell_split.rb +# + +require 'shellwords' + +module Puppet::Parser::Functions + newfunction(:shell_split, :type => :rvalue, :doc => <<-EOS +Splits a string into an array of tokens in the same way the Bourne shell does. + +This function behaves the same as ruby's Shellwords.shellsplit() function + EOS + ) do |arguments| + + raise(Puppet::ParseError, "shell_split(): Wrong number of arguments " + + "given (#{arguments.size} for 1)") if arguments.size != 1 + + string = arguments[0].to_s + + result = Shellwords.shellsplit(string) + + return result + end +end + +# vim: set ts=2 sw=2 et : diff --git a/lib/puppet/parser/functions/validate_cmd.rb b/lib/puppet/parser/functions/validate_cmd.rb index 5df3c60..685162b 100644 --- a/lib/puppet/parser/functions/validate_cmd.rb +++ b/lib/puppet/parser/functions/validate_cmd.rb @@ -53,7 +53,7 @@ module Puppet::Parser::Functions rescue Puppet::ExecutionFailure => detail msg += "\n#{detail}" raise Puppet::ParseError, msg - rescue Exception => detail + rescue StandardError => detail msg += "\n#{detail.class.name} #{detail}" raise Puppet::ParseError, msg ensure diff --git a/lib/puppet/parser/functions/validate_email_address.rb b/lib/puppet/parser/functions/validate_email_address.rb new file mode 100644 index 0000000..ddd0d25 --- /dev/null +++ b/lib/puppet/parser/functions/validate_email_address.rb @@ -0,0 +1,31 @@ +module Puppet::Parser::Functions + newfunction(:validate_email_address, :doc => <<-ENDHEREDOC + Validate that all values passed are valid email addresses. + Fail compilation if any value fails this check. + The following values will pass: + $my_email = "waldo@gmail.com" + validate_email_address($my_email) + validate_email_address("bob@gmail.com", "alice@gmail.com", $my_email) + + The following values will fail, causing compilation to abort: + $some_array = [ 'bad_email@/d/efdf.com' ] + validate_email_address($some_array) + ENDHEREDOC + ) do |args| + rescuable_exceptions = [ArgumentError] + + if args.empty? + raise Puppet::ParseError, "validate_email_address(): wrong number of arguments (#{args.length}; must be > 0)" + end + + args.each do |arg| + raise Puppet::ParseError, "#{arg.inspect} is not a string." unless arg.is_a?(String) + + begin + raise Puppet::ParseError, "#{arg.inspect} is not a valid email address" unless function_is_email_address([arg]) + rescue *rescuable_exceptions + raise Puppet::ParseError, "#{arg.inspect} is not a valid email address" + end + end + end +end diff --git a/lib/puppet/type/file_line.rb b/lib/puppet/type/file_line.rb index 77d3be2..f2c6937 100644 --- a/lib/puppet/type/file_line.rb +++ b/lib/puppet/type/file_line.rb @@ -111,8 +111,13 @@ Puppet::Type.newtype(:file_line) do end validate do - unless self[:line] and self[:path] - raise(Puppet::Error, "Both line and path are required attributes") + unless self[:line] + unless (self[:ensure].to_s == 'absent') and (self[:match_for_absence].to_s == 'true') and self[:match] + raise(Puppet::Error, "line is a required attribute") + end + end + unless self[:path] + raise(Puppet::Error, "path is a required attribute") end end end diff --git a/metadata.json b/metadata.json index a7ea0af..514023e 100644 --- a/metadata.json +++ b/metadata.json @@ -1,6 +1,6 @@ { "name": "puppetlabs-stdlib", - "version": "4.11.0", + "version": "4.12.0", "author": "puppetlabs", "summary": "Standard library of resources for Puppet modules.", "license": "Apache-2.0", diff --git a/spec/acceptance/concat_spec.rb b/spec/acceptance/concat_spec.rb index 06b649f..c472db6 100755 --- a/spec/acceptance/concat_spec.rb +++ b/spec/acceptance/concat_spec.rb @@ -36,5 +36,19 @@ describe 'concat function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('oper apply_manifest(pp, :catch_failures => true) end + it 'should concat hash arguments' do + pp = <<-EOS + $output = concat([{"a" => "b"}], {"c" => "d", "e" => "f"}) + validate_array($output) + if size($output) != 2 { + fail("${output} should have 2 elements.") + } + if $output[1] != {"c" => "d", "e" => "f"} { + fail("${output} does not have the expected hash for the second element.") + } + EOS + + apply_manifest(pp, :catch_failures => true) + end end end diff --git a/spec/acceptance/nodesets/centos-59-x64.yml b/spec/acceptance/nodesets/centos-59-x64.yml deleted file mode 100644 index 2ad90b8..0000000 --- a/spec/acceptance/nodesets/centos-59-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - centos-59-x64: - roles: - - master - platform: el-5-x86_64 - box : centos-59-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-59-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: git diff --git a/spec/acceptance/nodesets/centos-6-vcloud.yml b/spec/acceptance/nodesets/centos-6-vcloud.yml deleted file mode 100644 index ca9c1d3..0000000 --- a/spec/acceptance/nodesets/centos-6-vcloud.yml +++ /dev/null @@ -1,15 +0,0 @@ -HOSTS: - 'centos-6-vcloud': - roles: - - master - platform: el-6-x86_64 - hypervisor: vcloud - template: centos-6-x86_64 -CONFIG: - type: foss - ssh: - keys: "~/.ssh/id_rsa-acceptance" - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ diff --git a/spec/acceptance/nodesets/centos-64-x64-pe.yml b/spec/acceptance/nodesets/centos-64-x64-pe.yml deleted file mode 100644 index 7d9242f..0000000 --- a/spec/acceptance/nodesets/centos-64-x64-pe.yml +++ /dev/null @@ -1,12 +0,0 @@ -HOSTS: - centos-64-x64: - roles: - - master - - database - - dashboard - platform: el-6-x86_64 - box : centos-64-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: pe diff --git a/spec/acceptance/nodesets/centos-64-x64.yml b/spec/acceptance/nodesets/centos-64-x64.yml deleted file mode 100644 index 05540ed..0000000 --- a/spec/acceptance/nodesets/centos-64-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - centos-64-x64: - roles: - - master - platform: el-6-x86_64 - box : centos-64-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-64-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: foss diff --git a/spec/acceptance/nodesets/centos-65-x64.yml b/spec/acceptance/nodesets/centos-65-x64.yml deleted file mode 100644 index 4e2cb80..0000000 --- a/spec/acceptance/nodesets/centos-65-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - centos-65-x64: - roles: - - master - platform: el-6-x86_64 - box : centos-65-x64-vbox436-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-65-x64-virtualbox-nocm.box - hypervisor : vagrant -CONFIG: - type: foss diff --git a/spec/acceptance/nodesets/centos-7-x64.yml b/spec/acceptance/nodesets/centos-7-x64.yml new file mode 100644 index 0000000..1a40c89 --- /dev/null +++ b/spec/acceptance/nodesets/centos-7-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + centos-7-x64: + roles: + - agent + - default + platform: redhat-7-x86_64 + hypervisor: vagrant + box: puppetlabs/centos-7.2-64-nocm +CONFIG: + type: foss diff --git a/spec/acceptance/nodesets/debian-8-x64.yml b/spec/acceptance/nodesets/debian-8-x64.yml new file mode 100644 index 0000000..fef6e63 --- /dev/null +++ b/spec/acceptance/nodesets/debian-8-x64.yml @@ -0,0 +1,10 @@ +HOSTS: + debian-8-x64: + roles: + - agent + - default + platform: debian-8-amd64 + hypervisor: vagrant + box: puppetlabs/debian-8.2-64-nocm +CONFIG: + type: foss diff --git a/spec/acceptance/nodesets/default.yml b/spec/acceptance/nodesets/default.yml index 4e2cb80..dba339c 100644 --- a/spec/acceptance/nodesets/default.yml +++ b/spec/acceptance/nodesets/default.yml @@ -1,10 +1,10 @@ HOSTS: - centos-65-x64: + ubuntu-1404-x64: roles: - - master - platform: el-6-x86_64 - box : centos-65-x64-vbox436-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/centos-65-x64-virtualbox-nocm.box - hypervisor : vagrant + - agent + - default + platform: ubuntu-14.04-amd64 + hypervisor: vagrant + box: puppetlabs/ubuntu-14.04-64-nocm CONFIG: type: foss diff --git a/spec/acceptance/nodesets/docker/centos-7.yml b/spec/acceptance/nodesets/docker/centos-7.yml new file mode 100644 index 0000000..a3333aa --- /dev/null +++ b/spec/acceptance/nodesets/docker/centos-7.yml @@ -0,0 +1,12 @@ +HOSTS: + centos-7-x64: + platform: el-7-x86_64 + hypervisor: docker + image: centos:7 + docker_preserve_image: true + docker_cmd: '["/usr/sbin/init"]' + # install various tools required to get the image up to usable levels + docker_image_commands: + - 'yum install -y crontabs tar wget openssl sysvinit-tools iproute which initscripts' +CONFIG: + trace_limit: 200 diff --git a/spec/acceptance/nodesets/docker/debian-8.yml b/spec/acceptance/nodesets/docker/debian-8.yml new file mode 100644 index 0000000..df5c319 --- /dev/null +++ b/spec/acceptance/nodesets/docker/debian-8.yml @@ -0,0 +1,11 @@ +HOSTS: + debian-8-x64: + platform: debian-8-amd64 + hypervisor: docker + image: debian:8 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + - 'apt-get update && apt-get install -y net-tools wget locales strace lsof && echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && locale-gen' +CONFIG: + trace_limit: 200 diff --git a/spec/acceptance/nodesets/docker/ubuntu-14.04.yml b/spec/acceptance/nodesets/docker/ubuntu-14.04.yml new file mode 100644 index 0000000..b1efa58 --- /dev/null +++ b/spec/acceptance/nodesets/docker/ubuntu-14.04.yml @@ -0,0 +1,12 @@ +HOSTS: + ubuntu-1404-x64: + platform: ubuntu-14.04-amd64 + hypervisor: docker + image: ubuntu:14.04 + docker_preserve_image: true + docker_cmd: '["/sbin/init"]' + docker_image_commands: + # ensure that upstart is booting correctly in the container + - 'rm /usr/sbin/policy-rc.d && rm /sbin/initctl && dpkg-divert --rename --remove /sbin/initctl && apt-get update && apt-get install -y net-tools wget && locale-gen en_US.UTF-8' +CONFIG: + trace_limit: 200 diff --git a/spec/acceptance/nodesets/fedora-18-x64.yml b/spec/acceptance/nodesets/fedora-18-x64.yml deleted file mode 100644 index 1361649..0000000 --- a/spec/acceptance/nodesets/fedora-18-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - fedora-18-x64: - roles: - - master - platform: fedora-18-x86_64 - box : fedora-18-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/fedora-18-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: foss diff --git a/spec/acceptance/nodesets/sles-11-x64.yml b/spec/acceptance/nodesets/sles-11-x64.yml deleted file mode 100644 index 41abe21..0000000 --- a/spec/acceptance/nodesets/sles-11-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - sles-11-x64.local: - roles: - - master - platform: sles-11-x64 - box : sles-11sp1-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/sles-11sp1-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: foss diff --git a/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml b/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml deleted file mode 100644 index 5ca1514..0000000 --- a/spec/acceptance/nodesets/ubuntu-server-10044-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - ubuntu-server-10044-x64: - roles: - - master - platform: ubuntu-10.04-amd64 - box : ubuntu-server-10044-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-10044-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: foss diff --git a/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml b/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml deleted file mode 100644 index d065b30..0000000 --- a/spec/acceptance/nodesets/ubuntu-server-12042-x64.yml +++ /dev/null @@ -1,10 +0,0 @@ -HOSTS: - ubuntu-server-12042-x64: - roles: - - master - platform: ubuntu-12.04-amd64 - box : ubuntu-server-12042-x64-vbox4210-nocm - box_url : http://puppet-vagrant-boxes.puppetlabs.com/ubuntu-server-12042-x64-vbox4210-nocm.box - hypervisor : vagrant -CONFIG: - type: foss diff --git a/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml b/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml deleted file mode 100644 index cba1cd0..0000000 --- a/spec/acceptance/nodesets/ubuntu-server-1404-x64.yml +++ /dev/null @@ -1,11 +0,0 @@ -HOSTS: - ubuntu-server-1404-x64: - roles: - - master - platform: ubuntu-14.04-amd64 - box : puppetlabs/ubuntu-14.04-64-nocm - box_url : https://vagrantcloud.com/puppetlabs/ubuntu-14.04-64-nocm - hypervisor : vagrant -CONFIG: - log_level : debug - type: git diff --git a/spec/acceptance/nodesets/windows-2003-i386.yml b/spec/acceptance/nodesets/windows-2003-i386.yml deleted file mode 100644 index 47dadbd..0000000 --- a/spec/acceptance/nodesets/windows-2003-i386.yml +++ /dev/null @@ -1,26 +0,0 @@ -HOSTS: - ubuntu1204: - roles: - - master - - database - - dashboard - platform: ubuntu-12.04-amd64 - template: ubuntu-1204-x86_64 - hypervisor: vcloud - win2003_i386: - roles: - - agent - - default - platform: windows-2003-i386 - template: win-2003-i386 - hypervisor: vcloud -CONFIG: - nfs_server: none - ssh: - keys: "~/.ssh/id_rsa-acceptance" - consoleport: 443 - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ - pe_dir: http://neptune.puppetlabs.lan/3.2/ci-ready/ diff --git a/spec/acceptance/nodesets/windows-2003-x86_64.yml b/spec/acceptance/nodesets/windows-2003-x86_64.yml deleted file mode 100644 index 6a884bc..0000000 --- a/spec/acceptance/nodesets/windows-2003-x86_64.yml +++ /dev/null @@ -1,26 +0,0 @@ -HOSTS: - ubuntu1204: - roles: - - master - - database - - dashboard - platform: ubuntu-12.04-amd64 - template: ubuntu-1204-x86_64 - hypervisor: vcloud - win2003_x86_64: - roles: - - agent - - default - platform: windows-2003-x86_64 - template: win-2003-x86_64 - hypervisor: vcloud -CONFIG: - nfs_server: none - ssh: - keys: "~/.ssh/id_rsa-acceptance" - consoleport: 443 - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ - pe_dir: http://neptune.puppetlabs.lan/3.2/ci-ready/ diff --git a/spec/acceptance/nodesets/windows-2008-x86_64.yml b/spec/acceptance/nodesets/windows-2008-x86_64.yml deleted file mode 100644 index ae3c11d..0000000 --- a/spec/acceptance/nodesets/windows-2008-x86_64.yml +++ /dev/null @@ -1,26 +0,0 @@ -HOSTS: - ubuntu1204: - roles: - - master - - database - - dashboard - platform: ubuntu-12.04-amd64 - template: ubuntu-1204-x86_64 - hypervisor: vcloud - win2008_x86_64: - roles: - - agent - - default - platform: windows-2008-x86_64 - template: win-2008-x86_64 - hypervisor: vcloud -CONFIG: - nfs_server: none - ssh: - keys: "~/.ssh/id_rsa-acceptance" - consoleport: 443 - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ - pe_dir: http://neptune.puppetlabs.lan/3.2/ci-ready/ diff --git a/spec/acceptance/nodesets/windows-2008r2-x86_64.yml b/spec/acceptance/nodesets/windows-2008r2-x86_64.yml deleted file mode 100644 index 63923ac..0000000 --- a/spec/acceptance/nodesets/windows-2008r2-x86_64.yml +++ /dev/null @@ -1,26 +0,0 @@ -HOSTS: - ubuntu1204: - roles: - - master - - database - - dashboard - platform: ubuntu-12.04-amd64 - template: ubuntu-1204-x86_64 - hypervisor: vcloud - win2008r2: - roles: - - agent - - default - platform: windows-2008r2-x86_64 - template: win-2008r2-x86_64 - hypervisor: vcloud -CONFIG: - nfs_server: none - ssh: - keys: "~/.ssh/id_rsa-acceptance" - consoleport: 443 - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ - pe_dir: http://neptune.puppetlabs.lan/3.2/ci-ready/ diff --git a/spec/acceptance/nodesets/windows-2012-x86_64.yml b/spec/acceptance/nodesets/windows-2012-x86_64.yml deleted file mode 100644 index eaa4eca..0000000 --- a/spec/acceptance/nodesets/windows-2012-x86_64.yml +++ /dev/null @@ -1,26 +0,0 @@ -HOSTS: - ubuntu1204: - roles: - - master - - database - - dashboard - platform: ubuntu-12.04-amd64 - template: ubuntu-1204-x86_64 - hypervisor: vcloud - win2012: - roles: - - agent - - default - platform: windows-2012-x86_64 - template: win-2012-x86_64 - hypervisor: vcloud -CONFIG: - nfs_server: none - ssh: - keys: "~/.ssh/id_rsa-acceptance" - consoleport: 443 - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ - pe_dir: http://neptune.puppetlabs.lan/3.2/ci-ready/ diff --git a/spec/acceptance/nodesets/windows-2012r2-x86_64.yml b/spec/acceptance/nodesets/windows-2012r2-x86_64.yml deleted file mode 100644 index 1f0ea97..0000000 --- a/spec/acceptance/nodesets/windows-2012r2-x86_64.yml +++ /dev/null @@ -1,26 +0,0 @@ -HOSTS: - ubuntu1204: - roles: - - master - - database - - dashboard - platform: ubuntu-12.04-amd64 - template: ubuntu-1204-x86_64 - hypervisor: vcloud - win2012r2: - roles: - - agent - - default - platform: windows-2012r2-x86_64 - template: win-2012r2-x86_64 - hypervisor: vcloud -CONFIG: - nfs_server: none - ssh: - keys: "~/.ssh/id_rsa-acceptance" - consoleport: 443 - datastore: instance0 - folder: Delivery/Quality Assurance/Enterprise/Dynamic - resourcepool: delivery/Quality Assurance/Enterprise/Dynamic - pooling_api: http://vcloud.delivery.puppetlabs.net/ - pe_dir: http://neptune.puppetlabs.lan/3.2/ci-ready/ diff --git a/spec/functions/any2bool_spec.rb b/spec/functions/any2bool_spec.rb new file mode 100755 index 0000000..9d351ce --- /dev/null +++ b/spec/functions/any2bool_spec.rb @@ -0,0 +1,42 @@ +require 'spec_helper' + +describe 'any2bool' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + + it { is_expected.to run.with_params(true).and_return(true) } + it { is_expected.to run.with_params(false).and_return(false) } + + it { is_expected.to run.with_params('1.5').and_return(true) } + + describe 'when testing stringy values that mean "true"' do + [ 'TRUE','1', 't', 'y', 'true', 'yes'].each do |value| + it { is_expected.to run.with_params(value).and_return(true) } + end + end + + describe 'when testing stringy values that mean "false"' do + [ 'FALSE','', '0', 'f', 'n', 'false', 'no', 'undef', 'undefined', nil, :undef ].each do |value| + it { is_expected.to run.with_params(value).and_return(false) } + end + end + + describe 'when testing numeric values that mean "true"' do + [ 1,'1',1.5, '1.5'].each do |value| + it { is_expected.to run.with_params(value).and_return(true) } + end + end + + describe 'when testing numeric that mean "false"' do + [ -1, '-1', -1.5, '-1.5', '0', 0 ].each do |value| + it { is_expected.to run.with_params(value).and_return(false) } + end + end + + describe 'everything else returns true' do + [ [], {}, ['1'], [1], {:one => 1} ].each do |value| + it { is_expected.to run.with_params(value).and_return(true) } + end + end + +end diff --git a/spec/functions/concat_spec.rb b/spec/functions/concat_spec.rb index 1694d5e..eb76233 100755 --- a/spec/functions/concat_spec.rb +++ b/spec/functions/concat_spec.rb @@ -11,6 +11,7 @@ describe 'concat' do it { is_expected.to run.with_params(['1','2','3'],[['4','5'],'6']).and_return(['1','2','3',['4','5'],'6']) } it { is_expected.to run.with_params(['1','2'],['3','4'],['5','6']).and_return(['1','2','3','4','5','6']) } it { is_expected.to run.with_params(['1','2'],'3','4',['5','6']).and_return(['1','2','3','4','5','6']) } + it { is_expected.to run.with_params([{"a" => "b"}], {"c" => "d", "e" => "f"}).and_return([{"a" => "b"}, {"c" => "d", "e" => "f"}]) } it "should leave the original array intact" do argument1 = ['1','2','3'] diff --git a/spec/functions/delete_spec.rb b/spec/functions/delete_spec.rb index 6c4747b..fd2a8ad 100755 --- a/spec/functions/delete_spec.rb +++ b/spec/functions/delete_spec.rb @@ -4,6 +4,7 @@ describe 'delete' do it { is_expected.not_to eq(nil) } it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError) } it { is_expected.to run.with_params([]).and_raise_error(Puppet::ParseError) } + it { is_expected.to run.with_params([], 'two') } it { is_expected.to run.with_params([], 'two', 'three').and_raise_error(Puppet::ParseError) } it { is_expected.to run.with_params(1, 'two').and_raise_error(TypeError) } @@ -12,10 +13,15 @@ describe 'delete' do it { is_expected.to run.with_params([], 'two').and_return([]) } it { is_expected.to run.with_params(['two'], 'two').and_return([]) } it { is_expected.to run.with_params(['two', 'two'], 'two').and_return([]) } + it { is_expected.to run.with_params(['one', 'two', 'three'], '^t.*').and_return(['one']) } + it { is_expected.to run.with_params(['ab', 'b', 'c', 'b'], 'b').and_return(['ab', 'c']) } it { is_expected.to run.with_params(['one', 'two', 'three'], 'four').and_return(['one', 'two', 'three']) } + it { is_expected.to run.with_params(['one', 'two', 'three'], 'e').and_return(['one', 'two', 'three']) } it { is_expected.to run.with_params(['one', 'two', 'three'], 'two').and_return(['one', 'three']) } it { is_expected.to run.with_params(['two', 'one', 'two', 'three', 'two'], 'two').and_return(['one', 'three']) } it { is_expected.to run.with_params(['one', 'two', 'three', 'two'], ['one', 'two']).and_return(['three']) } + it { is_expected.to run.with_params(['abracadabra'], 'abr').and_return(['abracadabra']) } + it { is_expected.to run.with_params(['abracadabra'], '^.*jimbob.*$').and_return(['abracadabra']) } end describe 'deleting from a string' do diff --git a/spec/functions/get_module_path_spec.rb b/spec/functions/get_module_path_spec.rb index b1f682f..a39e413 100755 --- a/spec/functions/get_module_path_spec.rb +++ b/spec/functions/get_module_path_spec.rb @@ -5,11 +5,7 @@ describe 'get_module_path' do it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /Wrong number of arguments, expects one/) } it { is_expected.to run.with_params('one', 'two').and_raise_error(Puppet::ParseError, /Wrong number of arguments, expects one/) } it { is_expected.to run.with_params('one', 'two', 'three').and_raise_error(Puppet::ParseError, /Wrong number of arguments, expects one/) } - if Puppet.version.to_f >= 4.0 - it { is_expected.to run.with_params('one').and_raise_error(Puppet::Environments::EnvironmentNotFound, /Could not find a directory environment/) } - else - it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /Could not find module/) } - end + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /Could not find module/) } class StubModule attr_reader :path diff --git a/spec/functions/is_email_address_spec.rb b/spec/functions/is_email_address_spec.rb new file mode 100755 index 0000000..8b7b358 --- /dev/null +++ b/spec/functions/is_email_address_spec.rb @@ -0,0 +1,14 @@ +require 'spec_helper' + +describe 'is_email_address' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params([], []).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('bob@gmail.com').and_return(true) } + it { is_expected.to run.with_params('alice+puppetlabs.com@gmail.com').and_return(true) } + it { is_expected.to run.with_params('peter.parker@gmail.com').and_return(true) } + it { is_expected.to run.with_params('1.2.3@domain').and_return(false) } + it { is_expected.to run.with_params('1.2.3.4.5@').and_return(false) } + it { is_expected.to run.with_params({}).and_return(false) } + it { is_expected.to run.with_params([]).and_return(false) } +end diff --git a/spec/functions/shell_escape_spec.rb b/spec/functions/shell_escape_spec.rb new file mode 100644 index 0000000..3061dec --- /dev/null +++ b/spec/functions/shell_escape_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +describe 'shell_escape' do + it { is_expected.not_to eq(nil) } + + describe 'signature validation' do + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('foo', 'bar').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + end + + describe 'stringification' do + it { is_expected.to run.with_params(10).and_return('10') } + it { is_expected.to run.with_params(false).and_return('false') } + end + + describe 'escaping' do + it { is_expected.to run.with_params('foo').and_return('foo') } + it { is_expected.to run.with_params('foo bar').and_return('foo\ bar') } + it { is_expected.to run.with_params('~`!@#$%^&*()_+-=[]\{}|;\':",./<>?') + .and_return('\~\`\!@\#\$\%\^\&\*\(\)_\+-\=\[\]\\\\\{\}\|\;\\\':\",./\<\>\?') } + end +end diff --git a/spec/functions/shell_join_spec.rb b/spec/functions/shell_join_spec.rb new file mode 100644 index 0000000..6815f7c --- /dev/null +++ b/spec/functions/shell_join_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +describe 'shell_join' do + it { is_expected.not_to eq(nil) } + + describe 'signature validation' do + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params(['foo'], ['bar']).and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('foo').and_raise_error(Puppet::ParseError, /is not an Array/i) } + end + + describe 'shell argument joining' do + it { is_expected.to run.with_params(['foo']).and_return('foo') } + it { is_expected.to run.with_params(['foo', 'bar']).and_return('foo bar') } + it { is_expected.to run.with_params(['foo', 'bar baz']).and_return('foo bar\ baz') } + it { is_expected.to run.with_params(['~`!@#$', '%^&*()_+-=', '[]\{}|;\':"', ',./<>?']) + .and_return('\~\`\!@\#\$ \%\^\&\*\(\)_\+-\= \[\]\\\\\{\}\|\;\\\':\" ,./\<\>\?') } + end + + describe 'stringification' do + it { is_expected.to run.with_params([10, false, 'foo']).and_return('10 false foo') } + end +end diff --git a/spec/functions/shell_split_spec.rb b/spec/functions/shell_split_spec.rb new file mode 100644 index 0000000..beeb977 --- /dev/null +++ b/spec/functions/shell_split_spec.rb @@ -0,0 +1,24 @@ +require 'spec_helper' + +describe 'shell_split' do + it { is_expected.not_to eq(nil) } + + describe 'signature validation' do + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + it { is_expected.to run.with_params('foo', 'bar').and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + end + + describe 'stringification' do + it { is_expected.to run.with_params(10).and_return(['10']) } + it { is_expected.to run.with_params(false).and_return(['false']) } + end + + describe 'shell line spliting' do + it { is_expected.to run.with_params('foo').and_return(['foo']) } + it { is_expected.to run.with_params('foo bar').and_return(['foo', 'bar']) } + it { is_expected.to run.with_params('\~\`\!@\#\$\%\^\&\*\(\)_\+-\=\[\]\\\\\{\}\|\;\\\':\",./\<\>\?') + .and_return(['~`!@#$%^&*()_+-=[]\{}|;\':",./<>?']) } + it { is_expected.to run.with_params('\~\`\!@\#\$ \%\^\&\*\(\)_\+-\= \[\]\\\\\{\}\|\;\\\':\" ,./\<\>\?') + .and_return(['~`!@#$', '%^&*()_+-=', '[]\{}|;\':"', ',./<>?']) } + end +end diff --git a/spec/functions/validate_email_address_spec.rb b/spec/functions/validate_email_address_spec.rb new file mode 100644 index 0000000..7628383 --- /dev/null +++ b/spec/functions/validate_email_address_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +describe 'validate_email_address' do + describe 'signature validation' do + it { is_expected.not_to eq(nil) } + it { is_expected.to run.with_params().and_raise_error(Puppet::ParseError, /wrong number of arguments/i) } + end + + describe 'valid inputs' do + it { is_expected.to run.with_params('bob@gmail.com') } + it { is_expected.to run.with_params('alice+puppetlabs.com@gmail.com') } + end + + describe 'invalid inputs' do + it { is_expected.to run.with_params({}).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params(1).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params(true).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('one').and_raise_error(Puppet::ParseError, /is not a valid email/) } + it { is_expected.to run.with_params('bob@gmail.com', {}).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('bob@gmail.com', true).and_raise_error(Puppet::ParseError, /is not a string/) } + it { is_expected.to run.with_params('bob@gmail.com', 'one').and_raise_error(Puppet::ParseError, /is not a valid email/) } + end +end diff --git a/spec/puppetlabs_spec_helper_clone.rb b/spec/puppetlabs_spec_helper_clone.rb deleted file mode 100644 index 6a94a3b..0000000 --- a/spec/puppetlabs_spec_helper_clone.rb +++ /dev/null @@ -1,34 +0,0 @@ -#This file pulls in only the minimum necessary to let unmigrated specs still work - -# Define the main module namespace for use by the helper modules -module PuppetlabsSpec - # FIXTURE_DIR represents the standard locations of all fixture data. Normally - # this represents <project>/spec/fixtures. This will be used by the fixtures - # library to find relative fixture data. - FIXTURE_DIR = File.join("spec", "fixtures") unless defined?(FIXTURE_DIR) -end - -# Require all necessary helper libraries so they can be used later -require 'puppetlabs_spec_helper/puppetlabs_spec/files' -require 'puppetlabs_spec_helper/puppetlabs_spec/fixtures' -#require 'puppetlabs_spec_helper/puppetlabs_spec/puppet_internals' -require 'puppetlabs_spec_helper/puppetlabs_spec/matchers' - -RSpec.configure do |config| - # Include PuppetlabsSpec helpers so they can be called at convenience - config.extend PuppetlabsSpec::Files - config.extend PuppetlabsSpec::Fixtures - config.include PuppetlabsSpec::Fixtures - - config.parser = 'future' if ENV['FUTURE_PARSER'] == 'yes' - config.strict_variables = true if ENV['STRICT_VARIABLES'] == 'yes' - config.stringify_facts = false if ENV['STRINGIFY_FACTS'] == 'no' - config.trusted_node_data = true if ENV['TRUSTED_NODE_DATA'] == 'yes' - config.ordering = ENV['ORDERING'] if ENV['ORDERING'] - - # This will cleanup any files that were created with tmpdir or tmpfile - config.after :each do - PuppetlabsSpec::Files.cleanup - end -end - diff --git a/spec/spec.opts b/spec/spec.opts deleted file mode 100644 index 91cd642..0000000 --- a/spec/spec.opts +++ /dev/null @@ -1,6 +0,0 @@ ---format -s ---colour ---loadby -mtime ---backtrace diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 416036b..22d5d68 100755 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,49 +1,8 @@ -#! /usr/bin/env ruby -S rspec -dir = File.expand_path(File.dirname(__FILE__)) -$LOAD_PATH.unshift File.join(dir, 'lib') - -# So everyone else doesn't have to include this base constant. -module PuppetSpec - FIXTURE_DIR = File.join(dir = File.expand_path(File.dirname(__FILE__)), "fixtures") unless defined?(FIXTURE_DIR) -end - -require 'puppet' -require 'rspec-puppet' +#This file is generated by ModuleSync, do not edit. require 'puppetlabs_spec_helper/module_spec_helper' -require 'monkey_patches/alias_should_to_must' -require 'mocha/api' -#require 'puppetlabs_spec_helper/module_spec_helper' -require 'puppetlabs_spec_helper_clone' - -# hack to enable all the expect syntax (like allow_any_instance_of) in rspec-puppet examples -RSpec::Mocks::Syntax.enable_expect(RSpec::Puppet::ManifestMatchers) - -RSpec.configure do |config| - config.module_path = File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'modules') - config.manifest_dir = File.join(File.dirname(File.expand_path(__FILE__)), 'fixtures', 'manifests') - config.environmentpath = spec_path = File.expand_path(File.join(Dir.pwd, 'spec')) - - config.add_setting :puppet_future - #config.puppet_future = (ENV['FUTURE_PARSER'] == 'yes' or Puppet.version.to_f >= 4.0) - config.puppet_future = Puppet.version.to_f >= 4.0 - - config.before :each do - # Ensure that we don't accidentally cache facts and environment between - # test cases. This requires each example group to explicitly load the - # facts being exercised with something like - # Facter.collection.loader.load(:ipaddress) - Facter.clear - Facter.clear_messages - - RSpec::Mocks.setup - end - - config.after :each do - RSpec::Mocks.verify - RSpec::Mocks.teardown - end -end -# Helper class to test handling of arguments which are derived from string -class AlsoString < String +# put local configuration and setup into spec_helper_local +begin + require 'spec_helper_local' +rescue LoadError end diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index eda0d1a..8a1907f 100755 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -25,7 +25,7 @@ RSpec.configure do |c| end def is_future_parser_enabled? - if default[:type] == 'aio' + if default[:type] == 'aio' || ENV['PUPPET_INSTALL_TYPE'] == 'agent' return true elsif default[:default_apply_opts] return default[:default_apply_opts][:parser] == 'future' diff --git a/spec/spec_helper_local.rb b/spec/spec_helper_local.rb new file mode 100644 index 0000000..023a862 --- /dev/null +++ b/spec/spec_helper_local.rb @@ -0,0 +1,29 @@ + +# hack to enable all the expect syntax (like allow_any_instance_of) in rspec-puppet examples +RSpec::Mocks::Syntax.enable_expect(RSpec::Puppet::ManifestMatchers) + +RSpec.configure do |config| + # supply tests with a possibility to test for the future parser + config.add_setting :puppet_future + config.puppet_future = Puppet.version.to_f >= 4.0 + + config.before :each do + # Ensure that we don't accidentally cache facts and environment between + # test cases. This requires each example group to explicitly load the + # facts being exercised with something like + # Facter.collection.loader.load(:ipaddress) + Facter.clear + Facter.clear_messages + + RSpec::Mocks.setup + end + + config.after :each do + RSpec::Mocks.verify + RSpec::Mocks.teardown + end +end + +# Helper class to test handling of arguments which are derived from string +class AlsoString < String +end diff --git a/spec/unit/puppet/provider/file_line/ruby_spec.rb b/spec/unit/puppet/provider/file_line/ruby_spec.rb index 23e649c..fdeaf1a 100755 --- a/spec/unit/puppet/provider/file_line/ruby_spec.rb +++ b/spec/unit/puppet/provider/file_line/ruby_spec.rb @@ -398,7 +398,7 @@ describe provider_class do expect(File.read(@tmpfile)).to eql("foo1\nfoo2\n") end - it 'should ignore the match if match_for_absense is not specified' do + it 'should ignore the match if match_for_absence is not specified' do @resource = Puppet::Type::File_line.new( { :name => 'foo', @@ -416,7 +416,7 @@ describe provider_class do expect(File.read(@tmpfile)).to eql("foo1\nfoo\n") end - it 'should ignore the match if match_for_absense is false' do + it 'should ignore the match if match_for_absence is false' do @resource = Puppet::Type::File_line.new( { :name => 'foo', diff --git a/spec/unit/puppet/type/file_line_spec.rb b/spec/unit/puppet/type/file_line_spec.rb index f1430f2..48e2670 100755 --- a/spec/unit/puppet/type/file_line_spec.rb +++ b/spec/unit/puppet/type/file_line_spec.rb @@ -41,10 +41,13 @@ describe Puppet::Type.type(:file_line) do expect { file_line[:path] = 'file' }.to raise_error(Puppet::Error, /File paths must be fully qualified/) end it 'should require that a line is specified' do - expect { Puppet::Type.type(:file_line).new(:name => 'foo', :path => '/tmp/file') }.to raise_error(Puppet::Error, /Both line and path are required attributes/) + expect { Puppet::Type.type(:file_line).new(:name => 'foo', :path => '/tmp/file') }.to raise_error(Puppet::Error, /line is a required attribute/) + end + it 'should not require that a line is specified when matching for absence' do + expect { Puppet::Type.type(:file_line).new(:name => 'foo', :path => '/tmp/file', :ensure => :absent, :match_for_absence => :true, :match => 'match') }.not_to raise_error end it 'should require that a file is specified' do - expect { Puppet::Type.type(:file_line).new(:name => 'foo', :line => 'path') }.to raise_error(Puppet::Error, /Both line and path are required attributes/) + expect { Puppet::Type.type(:file_line).new(:name => 'foo', :line => 'path') }.to raise_error(Puppet::Error, /path is a required attribute/) end it 'should default to ensure => present' do expect(file_line[:ensure]).to eq :present |