Skip to content

Commit cde3a13

Browse files
committed
## v6.0.0, 2018-07-09
- Fix for pg_without_sudo; Wasn't adding -U to args - New feature that will ALTER USER/Password with any change to pg_password. Random passwords will cause each cap setup to run the ALTER USER, but that's fine as a user should technically only be using setup initially. It's not that hard to obtain the new password if this happens. - New redaction for logging of passwords & SSHKIT 1.17.0 in gemspec - README updates
1 parent 4a5adc9 commit cde3a13

7 files changed

Lines changed: 46 additions & 29 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
### master
44

5+
## v6.0.0, 2018-07-09
6+
- Fix for pg_without_sudo; Wasn't adding -U to args
7+
- New feature that will ALTER USER/Password with any change to pg_password. Random passwords will cause each cap setup to run the ALTER USER, but that's fine as a user should technically only be using setup initially. It's not that hard to obtain the new password if this happens.
8+
- New redaction for logging of passwords & SSHKIT 1.17.0 in gemspec
9+
- README updates
10+
511
## v5.0.1, 2018-06-05
612
- Quick fix for fetch(:pg_database) on extension adding
713

README.md

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Put the following in your application's `Gemfile`:
2727

2828
group :development do
2929
gem 'capistrano', '~> 3.2.0'
30-
gem 'capistrano-postgresql', '~> 5.0.0'
30+
gem 'capistrano-postgresql', '~> 6.0.0'
3131
end
3232

3333
Then:
@@ -45,42 +45,44 @@ require 'capistrano/postgresql'
4545
You need to include ONLY ONE of the following in your config/deploy/*.rb files:
4646

4747
```
48-
set :pg_password, ENV['DATABASE_USER_PASSWORD']
49-
set :pg_ask_for_password, true
50-
set :pg_generate_random_password, true
48+
set :pg_password, ENV['DATABASE_USER_PASSWORD'] # Example is an ENV value, but you can use a string instead
49+
set :pg_ask_for_password, true # Prompts user for password on execution of setup
50+
set :pg_generate_random_password, true # Generates a random password on each setup
5151
```
5252

53+
##### Execution of `cap ENV setup` will run ALTER USER on pg_username if there is a different password. If you're using :pg_generate_random_password, you'll get a new random password on each run.
54+
5355
Example config:
5456

5557
```
56-
server 'growtrader.dev', user: 'growtrader', roles: %w{app db}
58+
server 'yoursite.net', user: 'growtrader', roles: %w{app db}
5759
set :stage, :development
5860
set :branch, 'development'
5961
# ==================
6062
# Postgresql setup
6163
set :pg_without_sudo, false
62-
set :pg_host, 'growtrader.dev'
63-
set :pg_database, 'growtrader'
64-
set :pg_username, 'growtrader'
64+
set :pg_host, 'db.yoursite.net'
65+
set :pg_database, 'pg_database_name_here'
66+
set :pg_username, 'pg_username_here'
6567
#set :pg_generate_random_password, true
6668
#set :pg_ask_for_password, true
67-
set :pg_password, ENV['GROWTRADER_PGPASS']
69+
set :pg_password, ENV['yoursite_PGPASS']
6870
set :pg_extensions, ['citext','hstore']
6971
set :pg_encoding, 'UTF-8'
7072
set :pg_pool, '100'
7173
```
7274

7375
Finally, to setup the server(s), run:
7476

75-
$ bundle exec cap production setup
77+
$ bundle exec cap development setup
7678

7779
### Requirements
78-
7980
* Be sure to remove `config/database.yml` from your application's version control.
80-
* Your pg_hba.conf must include `local all all trust`
81+
* Your pg_hba.conf must include `local all all trust`. We ssh into the servers to execute psql commands.
8182
* Make sure the `deploy_to` path exists and has the right privileges on your servers. The ~ symbol (i.e. `~/myapp`) is not supported.
82-
* Within your app/config/deploy/{env}.rb files, you need to specify at least one :app and one :db server.
83+
* Within your app/config/deploy/{env}.rb files, you need to specify at least one :app and one :db server (they can be on the same host; `roles: %w{web app db}`)
8384
* If you have multiple :db role hosts, it's necessary to specify `:primary => true` on the end of your primary :db server.
85+
* gem >= 6.0.0 requires SSHKIT >= 1.17.0 as passwords are redacted from logging.
8486

8587
### How it works
8688

capistrano-postgresql.gemspec

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,6 @@ Gem::Specification.new do |gem|
2424
gem.require_paths = ['lib']
2525

2626
gem.add_dependency 'capistrano', '>= 3.0'
27+
gem.add_dependency 'sshkit', '>= 1.17.0' # 1.17.0 required for log/password redaction
2728
gem.add_development_dependency 'rake'
2829
end

lib/capistrano/postgresql/helper_methods.rb

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def remove_extensions
2020
end
2121
end
2222

23-
def generate_database_yml_io(password=fetch(:pg_password))
23+
def generate_database_yml_io
2424
StringIO.open do |s|
2525
s.puts "#{fetch(:pg_env)}:"
2626
{
@@ -29,7 +29,7 @@ def generate_database_yml_io(password=fetch(:pg_password))
2929
database: fetch(:pg_database),
3030
pool: fetch(:pg_pool),
3131
username: fetch(:pg_username),
32-
password: password,
32+
password: fetch(:pg_password),
3333
host: fetch(:pg_host),
3434
socket: fetch(:pg_socket),
3535
port: fetch(:pg_port),
@@ -45,12 +45,7 @@ def pg_template(update=false,archetype_file=nil)
4545
raise('Regeneration of archetype database.yml need the original file to update from.') if archetype_file.nil?
4646
raise('Cannot update a custom postgresql.yml.erb file.') if File.exists?(config_file) # Skip custom postgresql.yml.erb if we're updating. It's not supported
4747
# Update yml file from settings
48-
if fetch(:pg_generate_random_password) || !fetch(:pg_password) # We need to prevent updating the archetype file if we've done a random or "ask"ed password
49-
current_password = archetype_file.split("\n").grep(/password/)[0].split('password:')[1].strip
50-
generate_database_yml_io(current_password)
51-
else
52-
generate_database_yml_io
53-
end
48+
generate_database_yml_io
5449
else
5550
if File.exists?(config_file) # If there is a customized file in your rails app template directory, use it and convert any ERB
5651
StringIO.new ERB.new(File.read(config_file)).result(binding)

lib/capistrano/postgresql/psql_helpers.rb

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,32 @@ module Postgresql
33
module PsqlHelpers
44

55
def psql(type, database, *args)
6-
cmd = [ :psql, "-d #{database}", *args ]
76
if fetch(:pg_without_sudo)
8-
args.unshift("-U #{fetch(:pg_system_user)}") # Add the :pg_system_user to psql command since we aren't using sudo anymore
7+
# Add the :pg_system_user to psql command since we aren't using sudo anymore
8+
cmd = [ :psql, "-d #{database}", *args.unshift("-U #{fetch(:pg_system_user)}") ]
99
else
1010
cmd = [:sudo, "-i -u #{fetch(:pg_system_user)}", *cmd]
1111
end
12+
# Allow us to execute the different sshkit commands
1213
if type == 'test'
13-
test *cmd.flatten
14+
test *cmd
15+
elsif type == 'capture'
16+
capture *cmd
1417
else
15-
execute *cmd.flatten
18+
execute *cmd
1619
end
1720
end
1821

1922
def database_user_exists?
2023
psql 'test', fetch(:pg_system_db),'-tAc', %Q{"SELECT 1 FROM pg_roles WHERE rolname='#{fetch(:pg_username)}';" | grep -q 1}
2124
end
2225

26+
def database_user_password_different?
27+
current_password_md5 = psql 'capture', fetch(:pg_system_db),'-tAc', %Q{"select passwd from pg_shadow WHERE usename='#{fetch(:pg_username)}';"}
28+
new_password_md5 = "md5#{Digest::MD5.hexdigest("#{fetch(:pg_password)}#{fetch(:pg_username)}")}"
29+
current_password_md5 == new_password_md5 ? false : true
30+
end
31+
2332
def database_exists?
2433
psql 'test', fetch(:pg_system_db), '-tAc', %Q{"SELECT 1 FROM pg_database WHERE datname='#{fetch(:pg_database)}';" | grep -q 1}
2534
end
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
module Capistrano
22
module Postgresql
3-
VERSION = '5.0.1'
3+
VERSION = '6.0.0'
44
end
55
end

lib/capistrano/tasks/postgresql.rake

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,12 +82,16 @@ namespace :postgresql do
8282
end
8383
end
8484

85-
desc 'Create pg_username in database'
85+
desc 'Create or update pg_username in database'
8686
task :create_database_user do
8787
on roles :db do
8888
unless database_user_exists?
8989
# If you use CREATE USER instead of CREATE ROLE the LOGIN right is granted automatically; otherwise you must specify it in the WITH clause of the CREATE statement.
90-
psql 'execute', fetch(:pg_system_db), '-c', %Q{"CREATE USER \\"#{fetch(:pg_username)}\\" PASSWORD '#{fetch(:pg_password)}';"}
90+
psql 'execute', fetch(:pg_system_db), '-c', %Q{"CREATE USER \\"#{fetch(:pg_username)}\\" PASSWORD}, redact("'#{fetch(:pg_password)}'"), %Q{;"}
91+
end
92+
if database_user_password_different?
93+
# Ensure updating the password in your deploy/ENV.rb files updates the user, server side
94+
psql 'execute', fetch(:pg_system_db), '-c', %Q{"ALTER USER \\"#{fetch(:pg_username)}\\" WITH PASSWORD}, redact("'#{fetch(:pg_password)}'"), %Q{;"}
9195
end
9296
end
9397
end
@@ -140,14 +144,14 @@ namespace :postgresql do
140144
if release_roles(:app).empty?
141145
warn " WARNING: There are no servers in your app/config/deploy/#{fetch(:rails_env)}.rb with a :app role... Skipping Postgresql setup."
142146
else
143-
invoke 'postgresql:remove_app_database_yml_files' # Deletes old yml files from all servers. Allows you to avoid having to manually delete the files on your app servers to get a new pool size for example. Don't touch the archetype file to avoid deleting generated passwords.
144147
if release_roles(:db).empty? # Test to be sure we have a :db role host
145148
warn " WARNING: There is no server in your app/config/deploy/#{fetch(:rails_env)}.rb with a :db role... Skipping Postgresql setup."
146149
elsif !fetch(:pg_password) && !fetch(:pg_generate_random_password) && !fetch(:pg_ask_for_password)
147150
warn " WARNING: There is no :pg_password set in your app/config/deploy/#{fetch(:rails_env)}.rb.\n If you don't wish to set it, 'set :pg_generate_random_password, true' or 'set :pg_ask_for_password, true' are available!"
148151
elsif fetch(:pg_generate_random_password) && fetch(:pg_ask_for_password)
149152
warn " WARNING: You cannot have both :pg_generate_random_password and :pg_ask_for_password enabled in app/config/deploy/#{fetch(:rails_env)}.rb."
150153
else
154+
invoke 'postgresql:remove_app_database_yml_files' # Deletes old yml files from all servers. Allows you to avoid having to manually delete the files on your app servers to get a new pool size for example. Don't touch the archetype file to avoid deleting generated passwords.
151155
invoke 'postgresql:create_database_user'
152156
invoke 'postgresql:create_database'
153157
invoke 'postgresql:add_extensions'

0 commit comments

Comments
 (0)