diff --git a/lib/puppet/util/postgresql_validator.rb b/lib/puppet/util/postgresql_validator.rb index dccef31..d737f12 100644 --- a/lib/puppet/util/postgresql_validator.rb +++ b/lib/puppet/util/postgresql_validator.rb @@ -1,65 +1,65 @@ module Puppet module Util class PostgresqlValidator attr_reader :resource def initialize(resource) @resource = resource end def build_psql_cmd final_cmd = [] cmd_init = "#{@resource[:psql_path]} --tuples-only --quiet --no-psqlrc" final_cmd.push cmd_init cmd_parts = { - :host => "--host=#{@resource[:host]}", - :port => "--port=#{@resource[:port]}", - :db_username => "--username=#{@resource[:db_username]}", - :db_name => "--dbname=#{@resource[:db_name]}", - :command => "--command='#{@resource[:command]}'" + :host => "--host #{@resource[:host]}", + :port => "--port #{@resource[:port]}", + :db_username => "--username #{@resource[:db_username]}", + :db_name => "--dbname #{@resource[:db_name]}", + :command => "--command '#{@resource[:command]}'" } - cmd_parts[:db_password] = "--no-password " if @resource[:db_password] - cmd_parts.each do |k,v| final_cmd.push v if @resource[k] end final_cmd.join ' ' end def parse_connect_settings c_settings = @resource[:connect_settings] || {} c_settings.merge! ({ 'PGPASSWORD' => @resource[:db_password] }) if @resource[:db_password] return c_settings.map { |k,v| "#{k}=#{v}" } end def attempt_connection(sleep_length, tries) (0..tries-1).each do |try| Puppet.debug "PostgresqlValidator.attempt_connection: Attempting connection to #{@resource[:db_name]}" - if execute_command =~ /1/ - Puppet.debug "PostgresqlValidator.attempt_connection: Connection to #{@resource[:db_name]} successful!" + Puppet.debug "PostgresqlValidator.attempt_connection: #{build_validate_cmd}" + result = execute_command + if result && result.length > 0 + Puppet.debug "PostgresqlValidator.attempt_connection: Connection to #{@resource[:db_name] || parse_connect_settings.select { |elem| elem.match /PGDATABASE/ }} successful!" return true else Puppet.warning "PostgresqlValidator.attempt_connection: Sleeping for #{sleep_length} seconds" sleep sleep_length end end false end private def execute_command Execution.execute(build_validate_cmd, :uid => @resource[:run_as]) end def build_validate_cmd "#{parse_connect_settings.join(' ')} #{build_psql_cmd} " end end end end diff --git a/spec/acceptance/postgresql_conn_validator_spec.rb b/spec/acceptance/postgresql_conn_validator_spec.rb index d21d431..20d8422 100644 --- a/spec/acceptance/postgresql_conn_validator_spec.rb +++ b/spec/acceptance/postgresql_conn_validator_spec.rb @@ -1,76 +1,76 @@ require 'spec_helper_acceptance' describe 'postgresql_conn_validator', :unless => UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do let(:install_pp) { <<-EOS class { 'postgresql::server': postgres_password => 'space password', }-> postgresql::server::role { 'testuser': password_hash => postgresql_password('testuser','test1'), }-> postgresql::server::database { 'testdb': owner => 'testuser', require => Postgresql::Server::Role['testuser'] }-> postgresql::server::database_grant { 'allow connect for testuser': - privilege => 'CONNECT', + privilege => 'ALL', db => 'testdb', role => 'testuser', } EOS } context 'local connection' do it 'validates successfully with defaults' do pp = <<-EOS #{install_pp}-> postgresql_conn_validator { 'validate this': db_name => 'testdb', db_username => 'testuser', db_password => 'test1', host => 'localhost', psql_path => '/usr/bin/psql', } EOS apply_manifest(pp, :catch_failures => true) apply_manifest(pp, :catch_changes => true) end it 'works with connect settings hash' do pp = <<-EOS #{install_pp}-> postgresql_conn_validator { 'validate this': connect_settings => { 'PGDATABASE' => 'testdb', 'PGPORT' => '5432', 'PGUSER' => 'testuser', 'PGPASSWORD' => 'test1', 'PGHOST' => 'localhost' }, psql_path => '/usr/bin/psql' } EOS apply_manifest(pp, :catch_failures => true) apply_manifest(pp, :catch_changes => true) end it 'fails gracefully' do pp = <<-EOS #{install_pp}-> postgresql_conn_validator { 'validate this': psql_path => '/usr/bin/psql', tries => 3 } EOS result = apply_manifest(pp) expect(result.stderr).to match /Unable to connect to PostgreSQL server/ end end end diff --git a/spec/unit/puppet/provider/postgresql_conn_validator/ruby_spec.rb b/spec/unit/puppet/provider/postgresql_conn_validator/ruby_spec.rb index 6c3708e..3d678ea 100644 --- a/spec/unit/puppet/provider/postgresql_conn_validator/ruby_spec.rb +++ b/spec/unit/puppet/provider/postgresql_conn_validator/ruby_spec.rb @@ -1,66 +1,66 @@ require 'spec_helper' describe Puppet::Type.type(:postgresql_conn_validator).provider(:ruby) do let(:resource) { Puppet::Type.type(:postgresql_conn_validator).new({ :name => "testname" }.merge attributes) } let(:provider) { resource.provider } let(:attributes) do { :psql_path => '/usr/bin/psql', :host => 'db.test.com', :port => 4444, :db_username => 'testuser', :db_password => 'testpass' } end describe '#build_psql_cmd' do it 'contains expected commandline options' do - expect(provider.validator.build_psql_cmd).to match /\/usr\/bin\/psql.*--host=.*--port=.*--username=.*/ + expect(provider.validator.build_psql_cmd).to match /\/usr\/bin\/psql.*--host.*--port.*--username.*/ end end describe '#parse_connect_settings' do it 'returns array if password is present' do expect(provider.validator.parse_connect_settings).to eq(['PGPASSWORD=testpass']) end it 'returns an empty array if password is nil' do attributes.delete(:db_password) expect(provider.validator.parse_connect_settings).to eq([]) end let(:connect_settings) do { :connect_settings => { :PGPASSWORD => 'testpass', :PGHOST => 'db.test.com', :PGPORT => '1234' } } end it 'returns an array of settings' do attributes.delete(:db_password) attributes.merge! connect_settings expect(provider.validator.parse_connect_settings).to eq(['PGPASSWORD=testpass','PGHOST=db.test.com','PGPORT=1234']) end end describe '#attempt_connection' do let(:sleep_length) {1} let(:tries) {3} let(:exec) { provider.validator.stub(:execute_command).and_return(true) } it 'tries the correct number of times' do expect(provider.validator).to receive(:execute_command).exactly(3).times provider.validator.attempt_connection(sleep_length,tries) end end end