Using enviromental varables to hide actual password in psql commands displayed in output and reports.
This commit is contained in:
parent
0f4c71850e
commit
cfbf2f9308
7 changed files with 111 additions and 28 deletions
|
@ -14,7 +14,7 @@ Puppet::Type.type(:postgresql_psql).provide(:ruby) do
|
|||
command = [resource[:psql_path]]
|
||||
command.push("-d", resource[:db]) if resource[:db]
|
||||
command.push("-p", resource[:port]) if resource[:port]
|
||||
command.push("-t", "-c", sql)
|
||||
command.push("-t", "-c", '"' + sql.gsub('"', '\"') + '"')
|
||||
|
||||
if resource[:cwd]
|
||||
Dir.chdir resource[:cwd] do
|
||||
|
@ -27,9 +27,34 @@ Puppet::Type.type(:postgresql_psql).provide(:ruby) do
|
|||
|
||||
private
|
||||
|
||||
def get_environment
|
||||
environment = {}
|
||||
if envlist = resource[:environment]
|
||||
envlist = [envlist] unless envlist.is_a? Array
|
||||
envlist.each do |setting|
|
||||
if setting =~ /^(\w+)=((.|\n)+)$/
|
||||
env_name = $1
|
||||
value = $2
|
||||
if environment.include?(env_name) || environment.include?(env_name.to_sym)
|
||||
warning "Overriding environment setting '#{env_name}' with '#{value}'"
|
||||
end
|
||||
environment[env_name] = value
|
||||
else
|
||||
warning "Cannot understand environment setting #{setting.inspect}"
|
||||
end
|
||||
end
|
||||
end
|
||||
return environment
|
||||
end
|
||||
|
||||
def run_command(command, user, group)
|
||||
command = command.join ' '
|
||||
environment = get_environment
|
||||
if Puppet::PUPPETVERSION.to_f < 3.4
|
||||
Puppet::Util::SUIDManager.run_and_capture(command, user, group)
|
||||
require 'puppet/util/execution'
|
||||
Puppet::Util::Execution.withenv environment do
|
||||
Puppet::Util::SUIDManager.run_and_capture(command, user, group)
|
||||
end
|
||||
else
|
||||
output = Puppet::Util::Execution.execute(command, {
|
||||
:uid => user,
|
||||
|
@ -37,7 +62,7 @@ Puppet::Type.type(:postgresql_psql).provide(:ruby) do
|
|||
:failonfail => false,
|
||||
:combine => true,
|
||||
:override_locale => true,
|
||||
:custom_environment => {}
|
||||
:custom_environment => environment
|
||||
})
|
||||
[output, $CHILD_STATUS.dup]
|
||||
end
|
||||
|
|
|
@ -80,6 +80,21 @@ Puppet::Type.newtype(:postgresql_psql) do
|
|||
defaultto("/tmp")
|
||||
end
|
||||
|
||||
newparam(:environment) do
|
||||
desc "Any additional environment variables you want to set for a
|
||||
SQL command. Multiple environment variables should be
|
||||
specified as an array."
|
||||
|
||||
validate do |values|
|
||||
values = [values] unless values.is_a? Array
|
||||
values.each do |value|
|
||||
unless value =~ /\w+=/
|
||||
raise ArgumentError, "Invalid environment setting '#{value}'"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
newparam(:refreshonly, :boolean => true) do
|
||||
desc "If 'true', then the SQL will only be executed via a notify/subscribe event."
|
||||
|
||||
|
|
|
@ -12,22 +12,25 @@ class postgresql::server::passwd {
|
|||
# without specifying a password ('ident' or 'trust' security). This is
|
||||
# the default for pg_hba.conf.
|
||||
$escaped = postgresql_escape($postgres_password)
|
||||
$env = "env PGPASSWORD='${postgres_password}'"
|
||||
exec { 'set_postgres_postgrespw':
|
||||
# This command works w/no password because we run it as postgres system
|
||||
# user
|
||||
command => "${psql_path} -c 'ALTER ROLE \"${user}\" PASSWORD ${escaped}'",
|
||||
user => $user,
|
||||
group => $group,
|
||||
logoutput => true,
|
||||
cwd => '/tmp',
|
||||
command => "${psql_path} -c \"ALTER ROLE \\\"${user}\\\" PASSWORD \${NEWPASSWD_ESCAPED}\"",
|
||||
user => $user,
|
||||
group => $group,
|
||||
logoutput => true,
|
||||
cwd => '/tmp',
|
||||
environment => [
|
||||
"PGPASSWORD='${postgres_password}'",
|
||||
"NEWPASSWD_ESCAPED='${escaped}'",
|
||||
],
|
||||
# With this command we're passing -h to force TCP authentication, which
|
||||
# does require a password. We specify the password via the PGPASSWORD
|
||||
# environment variable. If the password is correct (current), this
|
||||
# command will exit with an exit code of 0, which will prevent the main
|
||||
# command from running.
|
||||
unless => "${env} ${psql_path} -h localhost -p ${port} -c 'select 1' > /dev/null",
|
||||
path => '/usr/bin:/usr/local/bin:/bin',
|
||||
unless => "${psql_path} -h localhost -p ${port} -c 'select 1' > /dev/null",
|
||||
path => '/usr/bin:/usr/local/bin:/bin',
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,9 +24,11 @@ define postgresql::server::role(
|
|||
$superuser_sql = $superuser ? { true => 'SUPERUSER', default => 'NOSUPERUSER' }
|
||||
$replication_sql = $replication ? { true => 'REPLICATION', default => '' }
|
||||
if ($password_hash != false) {
|
||||
$password_sql = "ENCRYPTED PASSWORD '${password_hash}'"
|
||||
$environment = "NEWPGPASSWD=${password_hash}"
|
||||
$password_sql = "ENCRYPTED PASSWORD '\$NEWPGPASSWD'"
|
||||
} else {
|
||||
$password_sql = ''
|
||||
$environment = []
|
||||
}
|
||||
|
||||
Postgresql_psql {
|
||||
|
@ -35,12 +37,17 @@ define postgresql::server::role(
|
|||
psql_user => $psql_user,
|
||||
psql_group => $psql_group,
|
||||
psql_path => $psql_path,
|
||||
require => [ Postgresql_psql["CREATE ROLE \"${username}\" ${password_sql} ${login_sql} ${createrole_sql} ${createdb_sql} ${superuser_sql} ${replication_sql} CONNECTION LIMIT ${connection_limit}"], Class['postgresql::server'] ],
|
||||
require => [
|
||||
Postgresql_psql["CREATE ROLE ${username} ENCRYPTED PASSWORD ****"],
|
||||
Class['postgresql::server'],
|
||||
],
|
||||
}
|
||||
|
||||
postgresql_psql {"CREATE ROLE \"${username}\" ${password_sql} ${login_sql} ${createrole_sql} ${createdb_sql} ${superuser_sql} ${replication_sql} CONNECTION LIMIT ${connection_limit}":
|
||||
unless => "SELECT rolname FROM pg_roles WHERE rolname='${username}'",
|
||||
require => Class['Postgresql::Server'],
|
||||
postgresql_psql { "CREATE ROLE ${username} ENCRYPTED PASSWORD ****":
|
||||
command => "CREATE ROLE \"${username}\" ${password_sql} ${login_sql} ${createrole_sql} ${createdb_sql} ${superuser_sql} ${replication_sql} CONNECTION LIMIT ${connection_limit}",
|
||||
unless => "SELECT rolname FROM pg_roles WHERE rolname='${username}'",
|
||||
require => Class['Postgresql::Server'],
|
||||
environment => $environment,
|
||||
}
|
||||
|
||||
postgresql_psql {"ALTER ROLE \"${username}\" ${superuser_sql}":
|
||||
|
@ -86,8 +93,10 @@ define postgresql::server::role(
|
|||
$pwd_md5 = md5("${password_hash}${username}")
|
||||
$pwd_hash_sql = "md5${pwd_md5}"
|
||||
}
|
||||
postgresql_psql {"ALTER ROLE \"${username}\" ${password_sql}":
|
||||
unless => "SELECT usename FROM pg_shadow WHERE usename='${username}' and passwd='${pwd_hash_sql}'",
|
||||
postgresql_psql { "ALTER ROLE ${username} ENCRYPTED PASSWORD ****":
|
||||
command => "ALTER ROLE \"${username}\" ${password_sql}",
|
||||
unless => "SELECT usename FROM pg_shadow WHERE usename='${username}' and passwd='${pwd_hash_sql}'",
|
||||
environment => $environment,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,12 +26,29 @@ describe 'postgresql::server', :type => :class do
|
|||
end
|
||||
|
||||
describe 'service_ensure => running' do
|
||||
let(:params) {{ :service_ensure => 'running' }}
|
||||
let(:params) do
|
||||
{
|
||||
:service_ensure => 'running',
|
||||
:postgres_password => 'new-p@s$word-to-set'
|
||||
}
|
||||
end
|
||||
it { is_expected.to contain_class("postgresql::params") }
|
||||
it { is_expected.to contain_class("postgresql::server") }
|
||||
it { is_expected.to contain_class("postgresql::server::passwd") }
|
||||
it 'should validate connection' do
|
||||
is_expected.to contain_postgresql__validate_db_connection('validate_service_is_running')
|
||||
end
|
||||
it 'should set postgres password' do
|
||||
is_expected.to contain_exec('set_postgres_postgrespw').with({
|
||||
'command' => '/usr/bin/psql -c "ALTER ROLE \"postgres\" PASSWORD ${NEWPASSWD_ESCAPED}"',
|
||||
'user' => 'postgres',
|
||||
'environment' => [
|
||||
"PGPASSWORD='new-p@s$word-to-set'",
|
||||
"NEWPASSWD_ESCAPED='$$new-p@s$word-to-set$$'"
|
||||
],
|
||||
'unless' => "/usr/bin/psql -h localhost -c 'select 1' > /dev/null",
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
describe 'service_ensure => stopped' do
|
||||
|
|
|
@ -19,7 +19,7 @@ describe 'postgresql::server::role', :type => :define do
|
|||
|
||||
let :params do
|
||||
{
|
||||
:password_hash => 'test',
|
||||
:password_hash => 'new-pa$s',
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -28,4 +28,18 @@ describe 'postgresql::server::role', :type => :define do
|
|||
end
|
||||
|
||||
it { is_expected.to contain_postgresql__server__role('test') }
|
||||
it 'should have create role for "test" user with password as ****' do
|
||||
is_expected.to contain_postgresql_psql('CREATE ROLE test ENCRYPTED PASSWORD ****').with({
|
||||
'command' => "CREATE ROLE \"test\" ENCRYPTED PASSWORD '$NEWPGPASSWD' LOGIN NOCREATEROLE NOCREATEDB NOSUPERUSER CONNECTION LIMIT -1",
|
||||
'environment' => "NEWPGPASSWD=new-pa$s",
|
||||
'unless' => "SELECT rolname FROM pg_roles WHERE rolname='test'",
|
||||
})
|
||||
end
|
||||
it 'should have alter role for "test" user with password as ****' do
|
||||
is_expected.to contain_postgresql_psql('ALTER ROLE test ENCRYPTED PASSWORD ****').with({
|
||||
'command' => "ALTER ROLE \"test\" ENCRYPTED PASSWORD '$NEWPGPASSWD'",
|
||||
'environment' => "NEWPGPASSWD=new-pa$s",
|
||||
'unless' => "SELECT usename FROM pg_shadow WHERE usename='test' and passwd='md5b6f7fcbbabb4befde4588a26c1cfd2fa'",
|
||||
})
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,10 +14,10 @@ describe Puppet::Type.type(:postgresql_psql).provider(:ruby) do
|
|||
|
||||
it "executes with the given psql_path on the given DB" do
|
||||
expect(provider).to receive(:run_command).with(['psql', '-d',
|
||||
attributes[:db], '-t', '-c', 'SELECT something'], 'postgres',
|
||||
attributes[:db], '-t', '-c', '"SELECT \'something\' as \"Custom column\""'], 'postgres',
|
||||
'postgres')
|
||||
|
||||
provider.run_sql_command("SELECT something")
|
||||
provider.run_sql_command('SELECT \'something\' as "Custom column"')
|
||||
end
|
||||
end
|
||||
describe "with psql_path and db" do
|
||||
|
@ -32,10 +32,10 @@ describe Puppet::Type.type(:postgresql_psql).provider(:ruby) do
|
|||
it "executes with the given psql_path on the given DB" do
|
||||
expect(Dir).to receive(:chdir).with(attributes[:cwd]).and_yield
|
||||
expect(provider).to receive(:run_command).with([attributes[:psql_path],
|
||||
'-d', attributes[:db], '-t', '-c', 'SELECT something'],
|
||||
'-d', attributes[:db], '-t', '-c', '"SELECT \'something\' as \"Custom column\""'],
|
||||
attributes[:psql_user], attributes[:psql_group])
|
||||
|
||||
provider.run_sql_command("SELECT something")
|
||||
provider.run_sql_command('SELECT \'something\' as "Custom column"')
|
||||
end
|
||||
end
|
||||
describe "with search_path string" do
|
||||
|
@ -45,10 +45,10 @@ describe Puppet::Type.type(:postgresql_psql).provider(:ruby) do
|
|||
|
||||
it "executes with the given search_path" do
|
||||
expect(provider).to receive(:run_command).with(['psql', '-t', '-c',
|
||||
'set search_path to schema1; SELECT something'],
|
||||
'"set search_path to schema1; SELECT \'something\' as \"Custom column\""'],
|
||||
'postgres', 'postgres')
|
||||
|
||||
provider.run_sql_command("SELECT something")
|
||||
provider.run_sql_command('SELECT \'something\' as "Custom column"')
|
||||
end
|
||||
end
|
||||
describe "with search_path array" do
|
||||
|
@ -58,12 +58,12 @@ describe Puppet::Type.type(:postgresql_psql).provider(:ruby) do
|
|||
|
||||
it "executes with the given search_path" do
|
||||
expect(provider).to receive(:run_command).with(['psql', '-t', '-c',
|
||||
'set search_path to schema1,schema2; SELECT something'],
|
||||
'"set search_path to schema1,schema2; SELECT \'something\' as \"Custom column\""'],
|
||||
'postgres',
|
||||
'postgres'
|
||||
)
|
||||
|
||||
provider.run_sql_command("SELECT something")
|
||||
provider.run_sql_command('SELECT \'something\' as "Custom column"')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue