From c3b06d6093b0aab210ec06b11e92a731c608fccd Mon Sep 17 00:00:00 2001 From: Ben Ford Date: Mon, 6 Jan 2020 09:57:52 -0800 Subject: [PATCH 1/2] Porting functions to the modern Puppet 4.x API --- .../postgresql_acls_to_resources_hash.rb | 102 ++++++++++++++++++ .../functions/postgresql/postgresql_escape.rb | 56 ++++++++++ .../postgresql/postgresql_password.rb | 49 +++++++++ ..._postgresql_acls_to_resources_hash_spec.rb | 41 +++++++ .../postgresql_postgresql_escape_spec.rb | 41 +++++++ .../postgresql_postgresql_password_spec.rb | 41 +++++++ 6 files changed, 330 insertions(+) create mode 100644 lib/puppet/functions/postgresql/postgresql_acls_to_resources_hash.rb create mode 100644 lib/puppet/functions/postgresql/postgresql_escape.rb create mode 100644 lib/puppet/functions/postgresql/postgresql_password.rb create mode 100644 spec/functions/postgresql_postgresql_acls_to_resources_hash_spec.rb create mode 100644 spec/functions/postgresql_postgresql_escape_spec.rb create mode 100644 spec/functions/postgresql_postgresql_password_spec.rb diff --git a/lib/puppet/functions/postgresql/postgresql_acls_to_resources_hash.rb b/lib/puppet/functions/postgresql/postgresql_acls_to_resources_hash.rb new file mode 100644 index 0000000000..ae735ece09 --- /dev/null +++ b/lib/puppet/functions/postgresql/postgresql_acls_to_resources_hash.rb @@ -0,0 +1,102 @@ +# This is an autogenerated function, ported from the original legacy version. +# It /should work/ as is, but will not have all the benefits of the modern +# function API. You should see the function docs to learn how to add function +# signatures for type safety and to document this function using puppet-strings. +# +# https://puppet.com/docs/puppet/latest/custom_functions_ruby.html +# +# ---- original file header ---- +# postgresql_acls_to_resources_hash.rb +# ---- original file header ---- +# +# @summary +# This internal function translates the ipv(4|6)acls format into a resource +# suitable for create_resources. It is not intended to be used outside of the +# postgresql internal classes/defined resources. +# +# @return This function accepts an array of strings that are pg_hba.conf rules. It +# will return a hash that can be fed into create_resources to create multiple +# individual pg_hba_rule resources. +# +# The second parameter is an identifier that will be included in the namevar +# to provide uniqueness. It must be a string. +# +# The third parameter is an order offset, so you can start the order at an +# arbitrary starting point. +# +# +Puppet::Functions.create_function(:'postgresql::postgresql_acls_to_resources_hash') do + # @param args + # The original array of arguments. Port this to individually managed params + # to get the full benefit of the modern function API. + # + # @return [Data type] + # Describe what the function returns here + # + dispatch :default_impl do + # Call the method named 'default_impl' when this is matched + # Port this to match individual params for better type safety + repeated_param 'Any', :args + end + + + def default_impl(*args) + + func_name = 'postgresql_acls_to_resources_hash()' + + if args.size != 3 + raise(Puppet::ParseError, "#{func_name}: Wrong number of arguments " \ + "given (#{args.size} for 3)") + end + + acls = args[0] + raise(Puppet::ParseError, "#{func_name}: first argument must be an array") \ + unless acls.instance_of? Array + + id = args[1] + raise(Puppet::ParseError, "#{func_name}: second argument must be a string") \ + unless id.instance_of? String + + offset = args[2].to_i + raise(Puppet::ParseError, "#{func_name}: third argument must be a number") \ + unless offset.is_a? Integer + + resources = {} + acls.each do |acl| + index = acls.index(acl) + + parts = acl.split + + unless parts.length >= 4 + raise(Puppet::ParseError, "#{func_name}: acl line #{index} does not " \ + 'have enough parts') + end + + resource = { + 'type' => parts[0], + 'database' => parts[1], + 'user' => parts[2], + 'order' => format('%03d', offset + index), # rubocop:disable Style/FormatString + } + if parts[0] == 'local' + resource['auth_method'] = parts[3] + if parts.length > 4 + resource['auth_option'] = parts.last(parts.length - 4).join(' ') + end + elsif parts[4] =~ %r{^\d} + resource['address'] = parts[3] + ' ' + parts[4] + resource['auth_method'] = parts[5] + + resource['auth_option'] = parts.last(parts.length - 6).join(' ') if parts.length > 6 + else + resource['address'] = parts[3] + resource['auth_method'] = parts[4] + + resource['auth_option'] = parts.last(parts.length - 5).join(' ') if parts.length > 5 + end + resources["postgresql class generated rule #{id} #{index}"] = resource + end + resources + + end +end diff --git a/lib/puppet/functions/postgresql/postgresql_escape.rb b/lib/puppet/functions/postgresql/postgresql_escape.rb new file mode 100644 index 0000000000..64687edb1d --- /dev/null +++ b/lib/puppet/functions/postgresql/postgresql_escape.rb @@ -0,0 +1,56 @@ +# This is an autogenerated function, ported from the original legacy version. +# It /should work/ as is, but will not have all the benefits of the modern +# function API. You should see the function docs to learn how to add function +# signatures for type safety and to document this function using puppet-strings. +# +# https://puppet.com/docs/puppet/latest/custom_functions_ruby.html +# +# ---- original file header ---- +require 'digest/md5' + +# postgresql_escape.rb +# ---- original file header ---- +# +# @summary +# This function safely escapes a string using a consistent random tag +# @return Safely escapes a string using $$ using a random tag which should be consistent +# +# +Puppet::Functions.create_function(:'postgresql::postgresql_escape') do + # @param args + # The original array of arguments. Port this to individually managed params + # to get the full benefit of the modern function API. + # + # @return [Data type] + # Describe what the function returns here + # + dispatch :default_impl do + # Call the method named 'default_impl' when this is matched + # Port this to match individual params for better type safety + repeated_param 'Any', :args + end + + + def default_impl(*args) + + + if args.size != 1 + raise(Puppet::ParseError, 'postgresql_escape(): Wrong number of arguments ' \ + "given (#{args.size} for 1)") + end + + password = args[0] + + if password !~ %r{\$\$} && password[-1] != '$' + retval = "$$#{password}$$" + else + escape = Digest::MD5.hexdigest(password)[0..5].gsub(%r{\d}, '') + until password !~ %r{#{escape}} + escape = Digest::MD5.hexdigest(escape)[0..5].gsub(%r{\d}, '') + end + retval = "$#{escape}$#{password}$#{escape}$" + end + retval + + end +end diff --git a/lib/puppet/functions/postgresql/postgresql_password.rb b/lib/puppet/functions/postgresql/postgresql_password.rb new file mode 100644 index 0000000000..35875acad2 --- /dev/null +++ b/lib/puppet/functions/postgresql/postgresql_password.rb @@ -0,0 +1,49 @@ +# This is an autogenerated function, ported from the original legacy version. +# It /should work/ as is, but will not have all the benefits of the modern +# function API. You should see the function docs to learn how to add function +# signatures for type safety and to document this function using puppet-strings. +# +# https://puppet.com/docs/puppet/latest/custom_functions_ruby.html +# +# ---- original file header ---- +# hash a string as mysql's "PASSWORD()" function would do it +require 'digest/md5' + +# postgresql_password.rb +# ---- original file header ---- +# +# @summary +# This function returns the postgresql password hash from the clear text username / password +# @return Returns the postgresql password hash from the clear text username / password. +# +# +Puppet::Functions.create_function(:'postgresql::postgresql_password') do + # @param args + # The original array of arguments. Port this to individually managed params + # to get the full benefit of the modern function API. + # + # @return [Data type] + # Describe what the function returns here + # + dispatch :default_impl do + # Call the method named 'default_impl' when this is matched + # Port this to match individual params for better type safety + repeated_param 'Any', :args + end + + + def default_impl(*args) + + + if args.size != 2 + raise(Puppet::ParseError, 'postgresql_password(): Wrong number of arguments ' \ + "given (#{args.size} for 2)") + end + + username = args[0] + password = args[1] + + 'md5' + Digest::MD5.hexdigest(password.to_s + username.to_s) + + end +end diff --git a/spec/functions/postgresql_postgresql_acls_to_resources_hash_spec.rb b/spec/functions/postgresql_postgresql_acls_to_resources_hash_spec.rb new file mode 100644 index 0000000000..9cf5dc35fa --- /dev/null +++ b/spec/functions/postgresql_postgresql_acls_to_resources_hash_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +describe 'postgresql::postgresql_acls_to_resources_hash' do + # without knowing details about the implementation, this is the only test + # case that we can autogenerate. You should add more examples below! + it { is_expected.not_to eq(nil) } + +################################# +# Below are some example test cases. You may uncomment and modify them to match +# your needs. Notice that they all expect the base error class of `StandardError`. +# This is because the autogenerated function uses an untyped array for parameters +# and relies on your implementation to do the validation. As you convert your +# function to proper dispatches and typed signatures, you should change the +# expected error of the argument validation examples to `ArgumentError`. +# +# Other error types you might encounter include +# +# * StandardError +# * ArgumentError +# * Puppet::ParseError +# +# Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ +# +# it 'raises an error if called with no argument' do +# is_expected.to run.with_params.and_raise_error(StandardError) +# end +# +# it 'raises an error if there is more than 1 arguments' do +# is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) +# end +# +# it 'raises an error if argument is not the proper type' do +# is_expected.to run.with_params('foo').and_raise_error(StandardError) +# end +# +# it 'returns the proper output' do +# is_expected.to run.with_params(123).and_return('the expected output') +# end +################################# + +end diff --git a/spec/functions/postgresql_postgresql_escape_spec.rb b/spec/functions/postgresql_postgresql_escape_spec.rb new file mode 100644 index 0000000000..473928ebce --- /dev/null +++ b/spec/functions/postgresql_postgresql_escape_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +describe 'postgresql::postgresql_escape' do + # without knowing details about the implementation, this is the only test + # case that we can autogenerate. You should add more examples below! + it { is_expected.not_to eq(nil) } + +################################# +# Below are some example test cases. You may uncomment and modify them to match +# your needs. Notice that they all expect the base error class of `StandardError`. +# This is because the autogenerated function uses an untyped array for parameters +# and relies on your implementation to do the validation. As you convert your +# function to proper dispatches and typed signatures, you should change the +# expected error of the argument validation examples to `ArgumentError`. +# +# Other error types you might encounter include +# +# * StandardError +# * ArgumentError +# * Puppet::ParseError +# +# Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ +# +# it 'raises an error if called with no argument' do +# is_expected.to run.with_params.and_raise_error(StandardError) +# end +# +# it 'raises an error if there is more than 1 arguments' do +# is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) +# end +# +# it 'raises an error if argument is not the proper type' do +# is_expected.to run.with_params('foo').and_raise_error(StandardError) +# end +# +# it 'returns the proper output' do +# is_expected.to run.with_params(123).and_return('the expected output') +# end +################################# + +end diff --git a/spec/functions/postgresql_postgresql_password_spec.rb b/spec/functions/postgresql_postgresql_password_spec.rb new file mode 100644 index 0000000000..42741053df --- /dev/null +++ b/spec/functions/postgresql_postgresql_password_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' + +describe 'postgresql::postgresql_password' do + # without knowing details about the implementation, this is the only test + # case that we can autogenerate. You should add more examples below! + it { is_expected.not_to eq(nil) } + +################################# +# Below are some example test cases. You may uncomment and modify them to match +# your needs. Notice that they all expect the base error class of `StandardError`. +# This is because the autogenerated function uses an untyped array for parameters +# and relies on your implementation to do the validation. As you convert your +# function to proper dispatches and typed signatures, you should change the +# expected error of the argument validation examples to `ArgumentError`. +# +# Other error types you might encounter include +# +# * StandardError +# * ArgumentError +# * Puppet::ParseError +# +# Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ +# +# it 'raises an error if called with no argument' do +# is_expected.to run.with_params.and_raise_error(StandardError) +# end +# +# it 'raises an error if there is more than 1 arguments' do +# is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) +# end +# +# it 'raises an error if argument is not the proper type' do +# is_expected.to run.with_params('foo').and_raise_error(StandardError) +# end +# +# it 'returns the proper output' do +# is_expected.to run.with_params(123).and_return('the expected output') +# end +################################# + +end From 2d9978f986dac59d6d128142ada2e30fb8bb3a45 Mon Sep 17 00:00:00 2001 From: Ben Ford Date: Mon, 6 Jan 2020 10:00:14 -0800 Subject: [PATCH 2/2] rubocop fixes --- .../postgresql_acls_to_resources_hash.rb | 3 - .../functions/postgresql/postgresql_escape.rb | 4 -- .../postgresql/postgresql_password.rb | 4 -- ..._postgresql_acls_to_resources_hash_spec.rb | 65 +++++++++---------- .../postgresql_postgresql_escape_spec.rb | 65 +++++++++---------- .../postgresql_postgresql_password_spec.rb | 65 +++++++++---------- 6 files changed, 96 insertions(+), 110 deletions(-) diff --git a/lib/puppet/functions/postgresql/postgresql_acls_to_resources_hash.rb b/lib/puppet/functions/postgresql/postgresql_acls_to_resources_hash.rb index ae735ece09..3a6f15e309 100644 --- a/lib/puppet/functions/postgresql/postgresql_acls_to_resources_hash.rb +++ b/lib/puppet/functions/postgresql/postgresql_acls_to_resources_hash.rb @@ -39,9 +39,7 @@ repeated_param 'Any', :args end - def default_impl(*args) - func_name = 'postgresql_acls_to_resources_hash()' if args.size != 3 @@ -97,6 +95,5 @@ def default_impl(*args) resources["postgresql class generated rule #{id} #{index}"] = resource end resources - end end diff --git a/lib/puppet/functions/postgresql/postgresql_escape.rb b/lib/puppet/functions/postgresql/postgresql_escape.rb index 64687edb1d..1555af0783 100644 --- a/lib/puppet/functions/postgresql/postgresql_escape.rb +++ b/lib/puppet/functions/postgresql/postgresql_escape.rb @@ -30,10 +30,7 @@ repeated_param 'Any', :args end - def default_impl(*args) - - if args.size != 1 raise(Puppet::ParseError, 'postgresql_escape(): Wrong number of arguments ' \ "given (#{args.size} for 1)") @@ -51,6 +48,5 @@ def default_impl(*args) retval = "$#{escape}$#{password}$#{escape}$" end retval - end end diff --git a/lib/puppet/functions/postgresql/postgresql_password.rb b/lib/puppet/functions/postgresql/postgresql_password.rb index 35875acad2..ee6c7ace7d 100644 --- a/lib/puppet/functions/postgresql/postgresql_password.rb +++ b/lib/puppet/functions/postgresql/postgresql_password.rb @@ -31,10 +31,7 @@ repeated_param 'Any', :args end - def default_impl(*args) - - if args.size != 2 raise(Puppet::ParseError, 'postgresql_password(): Wrong number of arguments ' \ "given (#{args.size} for 2)") @@ -44,6 +41,5 @@ def default_impl(*args) password = args[1] 'md5' + Digest::MD5.hexdigest(password.to_s + username.to_s) - end end diff --git a/spec/functions/postgresql_postgresql_acls_to_resources_hash_spec.rb b/spec/functions/postgresql_postgresql_acls_to_resources_hash_spec.rb index 9cf5dc35fa..2df689df18 100644 --- a/spec/functions/postgresql_postgresql_acls_to_resources_hash_spec.rb +++ b/spec/functions/postgresql_postgresql_acls_to_resources_hash_spec.rb @@ -5,37 +5,36 @@ # case that we can autogenerate. You should add more examples below! it { is_expected.not_to eq(nil) } -################################# -# Below are some example test cases. You may uncomment and modify them to match -# your needs. Notice that they all expect the base error class of `StandardError`. -# This is because the autogenerated function uses an untyped array for parameters -# and relies on your implementation to do the validation. As you convert your -# function to proper dispatches and typed signatures, you should change the -# expected error of the argument validation examples to `ArgumentError`. -# -# Other error types you might encounter include -# -# * StandardError -# * ArgumentError -# * Puppet::ParseError -# -# Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ -# -# it 'raises an error if called with no argument' do -# is_expected.to run.with_params.and_raise_error(StandardError) -# end -# -# it 'raises an error if there is more than 1 arguments' do -# is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) -# end -# -# it 'raises an error if argument is not the proper type' do -# is_expected.to run.with_params('foo').and_raise_error(StandardError) -# end -# -# it 'returns the proper output' do -# is_expected.to run.with_params(123).and_return('the expected output') -# end -################################# - + ################################# + # Below are some example test cases. You may uncomment and modify them to match + # your needs. Notice that they all expect the base error class of `StandardError`. + # This is because the autogenerated function uses an untyped array for parameters + # and relies on your implementation to do the validation. As you convert your + # function to proper dispatches and typed signatures, you should change the + # expected error of the argument validation examples to `ArgumentError`. + # + # Other error types you might encounter include + # + # * StandardError + # * ArgumentError + # * Puppet::ParseError + # + # Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ + # + # it 'raises an error if called with no argument' do + # is_expected.to run.with_params.and_raise_error(StandardError) + # end + # + # it 'raises an error if there is more than 1 arguments' do + # is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) + # end + # + # it 'raises an error if argument is not the proper type' do + # is_expected.to run.with_params('foo').and_raise_error(StandardError) + # end + # + # it 'returns the proper output' do + # is_expected.to run.with_params(123).and_return('the expected output') + # end + ################################# end diff --git a/spec/functions/postgresql_postgresql_escape_spec.rb b/spec/functions/postgresql_postgresql_escape_spec.rb index 473928ebce..947ee72423 100644 --- a/spec/functions/postgresql_postgresql_escape_spec.rb +++ b/spec/functions/postgresql_postgresql_escape_spec.rb @@ -5,37 +5,36 @@ # case that we can autogenerate. You should add more examples below! it { is_expected.not_to eq(nil) } -################################# -# Below are some example test cases. You may uncomment and modify them to match -# your needs. Notice that they all expect the base error class of `StandardError`. -# This is because the autogenerated function uses an untyped array for parameters -# and relies on your implementation to do the validation. As you convert your -# function to proper dispatches and typed signatures, you should change the -# expected error of the argument validation examples to `ArgumentError`. -# -# Other error types you might encounter include -# -# * StandardError -# * ArgumentError -# * Puppet::ParseError -# -# Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ -# -# it 'raises an error if called with no argument' do -# is_expected.to run.with_params.and_raise_error(StandardError) -# end -# -# it 'raises an error if there is more than 1 arguments' do -# is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) -# end -# -# it 'raises an error if argument is not the proper type' do -# is_expected.to run.with_params('foo').and_raise_error(StandardError) -# end -# -# it 'returns the proper output' do -# is_expected.to run.with_params(123).and_return('the expected output') -# end -################################# - + ################################# + # Below are some example test cases. You may uncomment and modify them to match + # your needs. Notice that they all expect the base error class of `StandardError`. + # This is because the autogenerated function uses an untyped array for parameters + # and relies on your implementation to do the validation. As you convert your + # function to proper dispatches and typed signatures, you should change the + # expected error of the argument validation examples to `ArgumentError`. + # + # Other error types you might encounter include + # + # * StandardError + # * ArgumentError + # * Puppet::ParseError + # + # Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ + # + # it 'raises an error if called with no argument' do + # is_expected.to run.with_params.and_raise_error(StandardError) + # end + # + # it 'raises an error if there is more than 1 arguments' do + # is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) + # end + # + # it 'raises an error if argument is not the proper type' do + # is_expected.to run.with_params('foo').and_raise_error(StandardError) + # end + # + # it 'returns the proper output' do + # is_expected.to run.with_params(123).and_return('the expected output') + # end + ################################# end diff --git a/spec/functions/postgresql_postgresql_password_spec.rb b/spec/functions/postgresql_postgresql_password_spec.rb index 42741053df..9678193dfb 100644 --- a/spec/functions/postgresql_postgresql_password_spec.rb +++ b/spec/functions/postgresql_postgresql_password_spec.rb @@ -5,37 +5,36 @@ # case that we can autogenerate. You should add more examples below! it { is_expected.not_to eq(nil) } -################################# -# Below are some example test cases. You may uncomment and modify them to match -# your needs. Notice that they all expect the base error class of `StandardError`. -# This is because the autogenerated function uses an untyped array for parameters -# and relies on your implementation to do the validation. As you convert your -# function to proper dispatches and typed signatures, you should change the -# expected error of the argument validation examples to `ArgumentError`. -# -# Other error types you might encounter include -# -# * StandardError -# * ArgumentError -# * Puppet::ParseError -# -# Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ -# -# it 'raises an error if called with no argument' do -# is_expected.to run.with_params.and_raise_error(StandardError) -# end -# -# it 'raises an error if there is more than 1 arguments' do -# is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) -# end -# -# it 'raises an error if argument is not the proper type' do -# is_expected.to run.with_params('foo').and_raise_error(StandardError) -# end -# -# it 'returns the proper output' do -# is_expected.to run.with_params(123).and_return('the expected output') -# end -################################# - + ################################# + # Below are some example test cases. You may uncomment and modify them to match + # your needs. Notice that they all expect the base error class of `StandardError`. + # This is because the autogenerated function uses an untyped array for parameters + # and relies on your implementation to do the validation. As you convert your + # function to proper dispatches and typed signatures, you should change the + # expected error of the argument validation examples to `ArgumentError`. + # + # Other error types you might encounter include + # + # * StandardError + # * ArgumentError + # * Puppet::ParseError + # + # Read more about writing function unit tests at https://rspec-puppet.com/documentation/functions/ + # + # it 'raises an error if called with no argument' do + # is_expected.to run.with_params.and_raise_error(StandardError) + # end + # + # it 'raises an error if there is more than 1 arguments' do + # is_expected.to run.with_params({ 'foo' => 1 }, 'bar' => 2).and_raise_error(StandardError) + # end + # + # it 'raises an error if argument is not the proper type' do + # is_expected.to run.with_params('foo').and_raise_error(StandardError) + # end + # + # it 'returns the proper output' do + # is_expected.to run.with_params(123).and_return('the expected output') + # end + ################################# end