diff options
-rw-r--r-- | Gemfile | 11 | ||||
-rw-r--r-- | README.markdown | 4 | ||||
-rw-r--r-- | lib/puppet/parser/functions/fqdn_rotate.rb | 16 | ||||
-rw-r--r-- | lib/puppet/parser/functions/is_domain_name.rb | 8 | ||||
-rw-r--r-- | lib/puppet/parser/functions/upcase.rb | 17 | ||||
-rwxr-xr-x | spec/functions/fqdn_rotate_spec.rb | 17 | ||||
-rwxr-xr-x | spec/functions/is_domain_name_spec.rb | 7 | ||||
-rwxr-xr-x | spec/functions/upcase_spec.rb | 27 |
8 files changed, 89 insertions, 18 deletions
@@ -12,6 +12,7 @@ end group :development, :unit_tests do gem 'rake', '~> 10.1.0', :require => false + gem 'rspec', '~> 3.1.0', :require => false gem 'rspec-puppet', :require => false gem 'puppetlabs_spec_helper', :require => false gem 'puppet-lint', :require => false @@ -24,8 +25,14 @@ group :system_tests do gem 'serverspec', :require => false end -ENV['GEM_PUPPET_VERSION'] ||= ENV['PUPPET_GEM_VERSION'] -puppetversion = ENV['GEM_PUPPET_VERSION'] +facterversion = ENV['GEM_FACTER_VERSION'] || ENV['FACTER_GEM_VERSION'] +if facterversion + gem 'facter', *location_for(facterversion) +else + gem 'facter', :require => false +end + +puppetversion = ENV['GEM_PUPPET_VERSION'] || ENV['PUPPET_GEM_VERSION'] if puppetversion gem 'puppet', *location_for(puppetversion) else diff --git a/README.markdown b/README.markdown index 3292d3e..ac0cae6 100644 --- a/README.markdown +++ b/README.markdown @@ -1,7 +1,5 @@ #stdlib -[](https://travis-ci.org/puppetlabs/puppetlabs-stdlib) - ####Table of Contents 1. [Overview](#overview) @@ -480,7 +478,7 @@ Takes a single string value as an argument. *Type*: rvalue You can also use this with arrays. For example, `unique(["a","a","b","b","c","c"])` returns ["a","b","c"]. *Type*: rvalue -* `upcase`: Converts a string or an array of strings to uppercase. For example, `upcase("abcd")` returns 'ABCD'. *Type*: rvalue +* `upcase`: Converts an object, array or hash of objects that respond to upcase to uppercase. For example, `upcase("abcd")` returns 'ABCD'. *Type*: rvalue * `uriescape`: Urlencodes a string or array of strings. Requires either a single string or an array as an input. *Type*: rvalue diff --git a/lib/puppet/parser/functions/fqdn_rotate.rb b/lib/puppet/parser/functions/fqdn_rotate.rb index 7f4d37d..cf22d36 100644 --- a/lib/puppet/parser/functions/fqdn_rotate.rb +++ b/lib/puppet/parser/functions/fqdn_rotate.rb @@ -31,8 +31,20 @@ Rotates an array a random number of times based on a nodes fqdn. elements = result.size - srand(Digest::MD5.hexdigest([lookupvar('::fqdn'),arguments].join(':')).hex) - rand(elements).times { + seed = Digest::MD5.hexdigest([lookupvar('::fqdn'),arguments].join(':')).hex + # deterministic_rand() was added in Puppet 3.2.0; reimplement if necessary + if Puppet::Util.respond_to?(:deterministic_rand) + offset = Puppet::Util.deterministic_rand(seed, elements).to_i + else + if defined?(Random) == 'constant' && Random.class == Class + offset = Random.new(seed).rand(elements) + else + srand(seed) + offset = rand(elements) + srand() + end + end + offset.times { result.push result.shift } diff --git a/lib/puppet/parser/functions/is_domain_name.rb b/lib/puppet/parser/functions/is_domain_name.rb index b3fee96..2860ded 100644 --- a/lib/puppet/parser/functions/is_domain_name.rb +++ b/lib/puppet/parser/functions/is_domain_name.rb @@ -13,16 +13,16 @@ Returns true if the string passed to this function is a syntactically correct do "given #{arguments.size} for 1") end - domain = arguments[0] + # Only allow string types + return false unless arguments[0].is_a?(String) + + domain = arguments[0].dup # Limits (rfc1035, 3.1) domain_max_length=255 label_min_length=1 label_max_length=63 - # Only allow string types - return false unless domain.is_a?(String) - # Allow ".", it is the top level domain return true if domain == '.' diff --git a/lib/puppet/parser/functions/upcase.rb b/lib/puppet/parser/functions/upcase.rb index 4302b29..0226a88 100644 --- a/lib/puppet/parser/functions/upcase.rb +++ b/lib/puppet/parser/functions/upcase.rb @@ -13,22 +13,27 @@ Converts a string or an array of strings to uppercase. Will return: ASDF - EOS + EOS ) do |arguments| raise(Puppet::ParseError, "upcase(): Wrong number of arguments " + - "given (#{arguments.size} for 1)") if arguments.size < 1 + "given (#{arguments.size} for 1)") if arguments.size != 1 value = arguments[0] - unless value.is_a?(Array) || value.is_a?(String) - raise(Puppet::ParseError, 'upcase(): Requires either ' + - 'array or string to work with') + unless value.is_a?(Array) || value.is_a?(Hash) || value.respond_to?(:upcase) + raise(Puppet::ParseError, 'upcase(): Requires an ' + + 'array, hash or object that responds to upcase in order to work') end if value.is_a?(Array) # Numbers in Puppet are often string-encoded which is troublesome ... - result = value.collect { |i| i.is_a?(String) ? i.upcase : i } + result = value.collect { |i| function_upcase([i]) } + elsif value.is_a?(Hash) + result = {} + value.each_pair do |k, v| + result[function_upcase([k])] = function_upcase([v]) + end else result = value.upcase end diff --git a/spec/functions/fqdn_rotate_spec.rb b/spec/functions/fqdn_rotate_spec.rb index 40057d4..673a8a3 100755 --- a/spec/functions/fqdn_rotate_spec.rb +++ b/spec/functions/fqdn_rotate_spec.rb @@ -40,4 +40,21 @@ describe "the fqdn_rotate function" do result = scope.function_fqdn_rotate([value]) result.size.should(eq(4)) end + + it "should use the Puppet::Util.deterministic_rand function if available" do + scope.expects(:lookupvar).with("::fqdn").returns("127.0.0.1") + if Puppet::Util.respond_to?(:deterministic_rand) + Puppet::Util.expects(:deterministic_rand).with(113646079810780526294648115052177588845,4) + end + scope.function_fqdn_rotate(["asdf"]) + end + + it "should not leave the global seed in a deterministic state" do + scope.expects(:lookupvar).with("::fqdn").returns("127.0.0.1").twice + scope.function_fqdn_rotate(["asdf"]) + rand1 = rand() + scope.function_fqdn_rotate(["asdf"]) + rand2 = rand() + expect(rand1).not_to eql(rand2) + end end diff --git a/spec/functions/is_domain_name_spec.rb b/spec/functions/is_domain_name_spec.rb index 4d05f5c..5ab8369 100755 --- a/spec/functions/is_domain_name_spec.rb +++ b/spec/functions/is_domain_name_spec.rb @@ -61,4 +61,11 @@ describe "the is_domain_name function" do result = scope.function_is_domain_name(["not valid"]) expect(result).to(be_falsey) end + + # Values obtained from Facter values will be frozen strings + # in newer versions of Facter: + it "should not throw an exception if passed a frozen string" do + result = scope.function_is_domain_name(["my.domain.name".freeze]) + expect(result).to(be_truthy) + end end diff --git a/spec/functions/upcase_spec.rb b/spec/functions/upcase_spec.rb index 3cf8b05..0689099 100755 --- a/spec/functions/upcase_spec.rb +++ b/spec/functions/upcase_spec.rb @@ -9,7 +9,7 @@ describe "the upcase function" do end it "should raise a ParseError if there is less than 1 arguments" do - expect { scope.function_upcase([]) }.to( raise_error(Puppet::ParseError)) + expect { scope.function_upcase([]) }.to(raise_error(Puppet::ParseError)) end it "should upcase a string" do @@ -30,4 +30,29 @@ describe "the upcase function" do result = scope.function_upcase([value]) result.should(eq('ABC')) end + + it 'should accept hashes and return uppercase' do + expect( + scope.function_upcase([{'test' => %w(this that and other thing)}]) + ).to eq({'TEST' => %w(THIS THAT AND OTHER THING)}) + end + + if :test.respond_to?(:upcase) + it 'should accept hashes of symbols' do + expect( + scope.function_upcase([{:test => [:this, :that, :other]}]) + ).to eq({:TEST => [:THIS, :THAT, :OTHER]}) + end + it 'should return upcase symbol' do + expect( + scope.function_upcase([:test]) + ).to eq(:TEST) + end + it 'should return mixed objects in upcease' do + expect( + scope.function_upcase([[:test, 'woot']]) + ).to eq([:TEST, 'WOOT']) + + end + end end |