From eca43f41cd6718023871ba21ae93fe0f7657528f Mon Sep 17 00:00:00 2001 From: Derek McEachern Date: Thu, 24 Mar 2016 14:23:05 -0500 Subject: [PATCH 01/10] Fixed typo 'absense' to 'absence' --- spec/unit/puppet/provider/file_line/ruby_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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', From 7e408ca7970fd172822db02227935798f9ff282f Mon Sep 17 00:00:00 2001 From: Johnson Earls Date: Mon, 28 Mar 2016 20:59:27 +0000 Subject: [PATCH 02/10] [MODULES-2370] file_line.rb: Fix `line` attribute validation `file_line` type: During validation, do not require `line` attribute if: * `ensure` is `absent`, * `match` is not empty, * and `match_for_absence` is `true`. Also update `spec` tests to reflect this. --- lib/puppet/type/file_line.rb | 9 +++++++-- spec/unit/puppet/type/file_line_spec.rb | 7 +++++-- 2 files changed, 12 insertions(+), 4 deletions(-) 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/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 From 0cea94a82ef277092897a03446f6e6fccba90d53 Mon Sep 17 00:00:00 2001 From: Felix Frank Date: Tue, 29 Mar 2016 01:59:54 +0200 Subject: [PATCH 03/10] catch StandardError rather than the gratuitous Exception --- lib/facter/facter_dot_d.rb | 8 ++++---- lib/puppet/parser/functions/hash.rb | 2 +- lib/puppet/parser/functions/parsejson.rb | 2 +- lib/puppet/parser/functions/parseyaml.rb | 2 +- lib/puppet/parser/functions/validate_cmd.rb | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) 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/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/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..9e84055 100644 --- a/lib/puppet/parser/functions/parseyaml.rb +++ b/lib/puppet/parser/functions/parseyaml.rb @@ -16,7 +16,7 @@ be returned if the parsing of YAML string have failed. begin YAML::load(arguments[0]) || arguments[1] - rescue Exception => e + rescue StandardError => e if arguments[1] arguments[1] else 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 From 27458aff988aac083007a677793081568356d85d Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Tue, 5 Apr 2016 14:32:06 +0100 Subject: [PATCH 04/10] (maint) Update to current modulesync_configs [953280c] This removes much of the assorted cruft that accumulated in the unmanaged files and moves the remaining necessary parts to spec_helper_local. --- .sync.yml | 9 ---- .travis.yml | 2 +- Gemfile | 72 ++++++++++------------------ Rakefile | 41 ++++++++++++++-- spec/puppetlabs_spec_helper_clone.rb | 34 ------------- spec/spec.opts | 6 --- spec/spec_helper.rb | 51 ++------------------ spec/spec_helper_local.rb | 29 +++++++++++ 8 files changed, 98 insertions(+), 146 deletions(-) delete mode 100644 .sync.yml delete mode 100644 spec/puppetlabs_spec_helper_clone.rb delete mode 100644 spec/spec.opts create mode 100644 spec/spec_helper_local.rb 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..588fb5b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,7 @@ 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: diff --git a/Gemfile b/Gemfile index 8221514..e490bc9 100644 --- a/Gemfile +++ b/Gemfile @@ -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/Rakefile b/Rakefile index e136b8e..7e9a13d 100644 --- a/Rakefile +++ b/Rakefile @@ -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/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 /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_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 From 3860512d5611d9c3a93f75d9594c2df43ee64acb Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Tue, 5 Apr 2016 14:42:53 +0100 Subject: [PATCH 05/10] (maint) remove failing test This removes the failing test special casing for puppet 4. --- spec/functions/get_module_path_spec.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) 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 From 5639828bffd1beb0e44e59554e17c1a891924145 Mon Sep 17 00:00:00 2001 From: David Schmitt Date: Thu, 7 Apr 2016 11:47:42 +0100 Subject: [PATCH 06/10] (maint) also catch Psych::SyntaxError Psych::SyntaxError is a RuntimeException. This still needs to catch that. This was uncovered by the recent move to catch StandardError rather than the catchall Exception that was here before. --- lib/puppet/parser/functions/parseyaml.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/puppet/parser/functions/parseyaml.rb b/lib/puppet/parser/functions/parseyaml.rb index 9e84055..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 StandardError => 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 From 44596e73da1b157ea931d5111f842e108ca203bb Mon Sep 17 00:00:00 2001 From: Alex Tomlins Date: Thu, 7 Apr 2016 22:22:17 +0100 Subject: [PATCH 07/10] (MODULES-3246) Fix concat with Hash arguments. 85d5ead Updated the concat function so that it wouldn't modify the original array. A side-effect of this change is that it now always calls `Array()` on the second argument. If thit is a Hash, this results in `to_a` being called on the hash, which converts it to an array or tuples. This is undesired. Update the behaviour so that it doesn't (indirectly) call `to_a` on anything, instead test for the type of the argument, wrapping it in an array if it's not already an array. --- lib/puppet/parser/functions/concat.rb | 2 +- spec/acceptance/concat_spec.rb | 14 ++++++++++++++ spec/functions/concat_spec.rb | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) 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/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 @@ -34,6 +34,20 @@ describe 'concat function', :unless => UNSUPPORTED_PLATFORMS.include?(fact('oper } EOS + 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 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'] From bfe6cf68b3b09f5927ec8f12f6661f45e9c1be58 Mon Sep 17 00:00:00 2001 From: Joseph Yaworski Date: Mon, 28 Mar 2016 13:18:28 -0400 Subject: [PATCH 08/10] Add validate_email_address function --- .../parser/functions/is_email_address.rb | 21 +++++++++++++ .../functions/validate_email_address.rb | 31 +++++++++++++++++++ spec/functions/is_email_address_spec.rb | 14 +++++++++ spec/functions/validate_email_address_spec.rb | 23 ++++++++++++++ 4 files changed, 89 insertions(+) create mode 100644 lib/puppet/parser/functions/is_email_address.rb create mode 100644 lib/puppet/parser/functions/validate_email_address.rb create mode 100755 spec/functions/is_email_address_spec.rb create mode 100644 spec/functions/validate_email_address_spec.rb 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..ab8d075 --- /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/validate_email_address.rb b/lib/puppet/parser/functions/validate_email_address.rb new file mode 100644 index 0000000..63f59a7 --- /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/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/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 From 0d46515b57cea60d4d5f1e4d81a75a448a7a73a8 Mon Sep 17 00:00:00 2001 From: Joseph Yaworski Date: Mon, 11 Apr 2016 22:09:24 -0400 Subject: [PATCH 09/10] Add support for regular expressions to delete --- README.markdown | 2 +- lib/puppet/parser/functions/delete.rb | 4 +--- spec/functions/delete_spec.rb | 7 ++++++- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/README.markdown b/README.markdown index 6cedc2a..2f5faf3 100644 --- a/README.markdown +++ b/README.markdown @@ -265,7 +265,7 @@ 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. 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']. *Type*: rvalue. #### `delete_at` diff --git a/lib/puppet/parser/functions/delete.rb b/lib/puppet/parser/functions/delete.rb index f548b44..8435163 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 @@ -34,7 +32,7 @@ string, or key from a hash. Array(arguments[1]).each do |item| case collection when Array, Hash - collection.delete item + collection.delete_if { |coll_item| coll_item =~ %r{#{item}} } when String collection.gsub! item, '' else diff --git a/spec/functions/delete_spec.rb b/spec/functions/delete_spec.rb index 6c4747b..998f9a6 100755 --- a/spec/functions/delete_spec.rb +++ b/spec/functions/delete_spec.rb @@ -12,6 +12,7 @@ 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(['one', 'two', 'three'], 'four').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']) } @@ -32,7 +33,7 @@ describe 'delete' do it { is_expected.to run.with_params('barfoobar', ['foo', 'barbar']).and_return('') } end - describe 'deleting from an array' do + describe 'deleting from a hash' do it { is_expected.to run.with_params({}, '').and_return({}) } it { is_expected.to run.with_params({}, 'key').and_return({}) } it { is_expected.to run.with_params({'key' => 'value'}, 'key').and_return({}) } @@ -44,6 +45,10 @@ describe 'delete' do .with_params({'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'}, ['key1', 'key2']) \ .and_return( {'key3' => 'value3'}) } + it { is_expected.to run \ + .with_params({'key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3'}, ['^key\d']) \ + .and_return({}) + } end it "should leave the original array intact" do From 085035dccebbf27cf2bfd7f1d9101c746f5178a2 Mon Sep 17 00:00:00 2001 From: Bryan Jen Date: Mon, 28 Mar 2016 17:42:22 -0700 Subject: [PATCH 10/10] (FM-5000) Release prep for 4.12.0. --- CHANGELOG.md | 19 +++++++++++++++++++ metadata.json | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2698dde..5d6a108 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +## Supported Release 4.12.0 +###Summary + +This release provides several new functions, bugfixes, 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 don't exist. +- Extends `suffix` to support applying a suffix to keys in a hash. + +####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. + ## Supported Release 4.11.0 ###Summary 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",