Skip to content
Next Next commit
Add onlyif parameter to postgresql_psql to only run command if onlyif…
… returns true
  • Loading branch information
kimor79 committed Nov 5, 2014
commit 0540059091c0200f90c2bd92659cf52738d7d998
24 changes: 24 additions & 0 deletions lib/puppet/type/postgresql_psql.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,28 @@ def matches(value)
end
end

newparam(:onlyif) do
desc "An optional SQL command to execute prior to the main :command; " +
"this is generally intended to be used for idempotency, to check " +
"for the existence of an object in the database to determine whether " +
"or not the main SQL command needs to be executed at all."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and there i thought SQL was supposed to be idempotent to begin with ;)


# Return true if a matching row is found
def matches(value)
if Puppet::PUPPETVERSION.to_f < 4
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you checking against puppet 4? run_unless_sql_command will return an array for version greater than 3.4, so this looks like your code won't work for 3.4 < x < 4

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I just copied another similar stanza

output, status = provider.run_unless_sql_command(value)
else
output = provider.run_unless_sql_command(value)
status = output.exitcode
end
self.fail("Error evaluating 'onlyif' clause, returned #{status}: '#{output}'") unless status == 0

result_count = output.strip.to_i
self.debug("Found #{result_count} row(s) executing 'onlyif' clause")
result_count > 0
end
end

newparam(:db) do
desc "The name of the database to execute the SQL command against."
end
Expand Down Expand Up @@ -88,7 +110,9 @@ def matches(value)
end

def should_run_sql(refreshing = false)
onlyif_param = @parameters[:onlyif]
unless_param = @parameters[:unless]
return false if !onlyif_param.nil? && !onlyif_param.value.nil? && !onlyif_param.matches(onlyif_param.value)
return false if !unless_param.nil? && !unless_param.value.nil? && unless_param.matches(unless_param.value)
return false if !refreshing && @parameters[:refreshonly].value == :true
true
Expand Down
30 changes: 30 additions & 0 deletions spec/acceptance/postgresql_psql_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,34 @@ class { 'postgresql::server': } ->
apply_manifest(pp, :expect_changes => true)
end
end

it 'should not run some SQL when the onlyif query returns no rows' do
pp = <<-EOS
class { 'postgresql::server': } ->
postgresql_psql { 'foobar':
db => 'postgres',
psql_user => 'postgres',
command => 'select 1',
onlyif => 'select 1 where 1=2',
}
EOS

apply_manifest(pp, :catch_failures => true)
apply_manifest(pp, :expect_changes => true)
end

it 'should run SQL when the onlyif query returns rows' do
pp = <<-EOS
class { 'postgresql::server': } ->
postgresql_psql { 'foobar':
db => 'postgres',
psql_user => 'postgres',
command => 'select * from pg_database limit 1',
onlfy => 'select 1 where 1=1',
}
EOS

apply_manifest(pp, :catch_failures => true)
apply_manifest(pp, :catch_changes => true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably need some validation here that the SQL did/didn't run....

end
end