pgchief 0.5.4 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +17 -0
- data/CHANGELOG.md +24 -3
- data/README.md +28 -10
- data/lib/pgchief/cli.rb +26 -6
- data/lib/pgchief/command/database_backup.rb +5 -1
- data/lib/pgchief/command/database_drop.rb +2 -2
- data/lib/pgchief/command/quick_backup.rb +15 -0
- data/lib/pgchief/command/quick_restore.rb +20 -0
- data/lib/pgchief/config.rb +34 -9
- data/lib/pgchief/database/backups.rb +3 -3
- data/lib/pgchief/version.rb +1 -1
- data/lib/pgchief.rb +17 -2
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 142a11a0be4792a8b0c428c25119c964fb899564db0f6ace3464fef0409017c6
|
4
|
+
data.tar.gz: d62cd7fd0b58525300e25065b3fff56b1e9bd157af9058f335c5436c88e0090f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c02ad41656562151ac067e33a8a61bf8c3c39a915d32b93eda8ed76df0b601bbc4b3bfd8ab5c9979492ae0bb3b543c1e806fbcc9dbfe6b5e9452111662415336
|
7
|
+
data.tar.gz: 9cc987456a024dd1abaa656b2a725152a3e16ec7f345ab8723e3d912bcae6b213b3329e383b73bf23491826f9b8f9769d1e36d67d5688d5ad53f1bc829b5a907
|
data/.rubocop.yml
CHANGED
@@ -6,3 +6,20 @@ plugins:
|
|
6
6
|
|
7
7
|
AllCops:
|
8
8
|
NewCops: enable
|
9
|
+
|
10
|
+
Style/Documentation:
|
11
|
+
Exclude:
|
12
|
+
- 'lib/pgchief.rb'
|
13
|
+
- 'spec/**/*.rb'
|
14
|
+
|
15
|
+
Metrics/AbcSize:
|
16
|
+
Exclude:
|
17
|
+
- 'lib/pgchief/config.rb'
|
18
|
+
|
19
|
+
Metrics/MethodLength:
|
20
|
+
Exclude:
|
21
|
+
- 'lib/pgchief/config.rb'
|
22
|
+
|
23
|
+
Metrics/CyclomaticComplexity:
|
24
|
+
Exclude:
|
25
|
+
- 'lib/pgchief/config.rb'
|
data/CHANGELOG.md
CHANGED
@@ -13,13 +13,34 @@ and this project will try its best to adhere to [Semantic Versioning](https://se
|
|
13
13
|
|
14
14
|
### Fixes
|
15
15
|
|
16
|
+
## [0.6.0]
|
17
|
+
|
18
|
+
### Additions
|
19
|
+
|
20
|
+
* Adds `--backup database_name` option to cli to quickly backup a provided database.
|
21
|
+
|
22
|
+
### Changes
|
23
|
+
|
24
|
+
* Update restore command to only act on objects `--if-exists` (if they exist)
|
25
|
+
* Allow for config to be set via ENV variables
|
26
|
+
* Don't raise error when a database doesn't exist when a drop is attempted - just notify
|
27
|
+
|
28
|
+
### Fixes
|
29
|
+
|
30
|
+
* Fix method signature in `Database::Backups` - `remote` should be a kwarg and should
|
31
|
+
pass it along as such.
|
32
|
+
* When backing up a database, we add the db name to the end of the pg connection string.
|
33
|
+
In cases where that DATABASE_URL already has the database name tacked on at the end,
|
34
|
+
make sure it's only there once.
|
35
|
+
|
16
36
|
## [0.5.4]
|
17
37
|
|
18
38
|
### Additions
|
19
39
|
|
20
|
-
* Improve CLI usability with
|
21
|
-
* Adds
|
22
|
-
* Modifies DatabaseRestore and prompt flows to conditionally operate on remote backups.
|
40
|
+
* Improve CLI usability with `--version` and `--help` flags.
|
41
|
+
* Adds `--remote-backup` and `--remote-restore` CLI options.
|
42
|
+
* Modifies `DatabaseRestore` and prompt flows to conditionally operate on remote backups.
|
43
|
+
* Adds `--restore database_name` option to cli to quickly restore latest backup for a provided database.
|
23
44
|
|
24
45
|
### Changes
|
25
46
|
|
data/README.md
CHANGED
@@ -24,7 +24,7 @@ below for the feature check-list and current progress.
|
|
24
24
|
## Usage
|
25
25
|
|
26
26
|
```sh
|
27
|
-
# System
|
27
|
+
# System dependencies `build-essential` and `libpq-dev` must be installed
|
28
28
|
gem install pgchief
|
29
29
|
|
30
30
|
# To initialize the config file at `~/.config/pgchief/config.toml`:
|
@@ -43,11 +43,13 @@ pgchief
|
|
43
43
|
|
44
44
|
$ pgchief --help
|
45
45
|
Options:
|
46
|
-
-
|
47
|
-
-
|
48
|
-
|
49
|
-
--remote-
|
50
|
-
|
46
|
+
-b, --backup string Quickly backup specific database. Pass name of db.
|
47
|
+
-h, --help Print usage.
|
48
|
+
-i, --init Initialize the TOML configuration file.
|
49
|
+
--remote-backup Backup a database to a remote location.
|
50
|
+
--remote-restore Restore a database from a remote backup.
|
51
|
+
-r, --restore string Quickly restore specific database. Pass name of db.
|
52
|
+
-v, --version Show the version.
|
51
53
|
```
|
52
54
|
|
53
55
|
> [!Note]
|
@@ -55,7 +57,7 @@ Options:
|
|
55
57
|
> Pressing the `esc` key at any point amidst a prompt will exit out of the
|
56
58
|
> program.
|
57
59
|
|
58
|
-
## Config
|
60
|
+
## Config via File
|
59
61
|
|
60
62
|
Format of `~/.config/pgchief/config.toml`
|
61
63
|
|
@@ -83,6 +85,22 @@ backup_dir = "~/.pgchief/backups"
|
|
83
85
|
# remote_backup = false # default: false
|
84
86
|
```
|
85
87
|
|
88
|
+
### OR ... Config via Environment Variables
|
89
|
+
|
90
|
+
The following environment variables will be picked up in the absence of a config
|
91
|
+
file.
|
92
|
+
|
93
|
+
```env
|
94
|
+
# Required
|
95
|
+
DATABASE_URL
|
96
|
+
|
97
|
+
# Optional
|
98
|
+
AWS_ACCESS_KEY_ID or AWS_ACCESS_KEY
|
99
|
+
AWS_SECRET_ACCESS_KEY or AWS_SECRET_KEY
|
100
|
+
AWS_DEFAULT_REGION or AWS_REGION
|
101
|
+
S3_BACKUPS_PATH
|
102
|
+
```
|
103
|
+
|
86
104
|
> [!IMPORTANT]
|
87
105
|
> Backup files must be named starting with `[Database Name]-` in order for the
|
88
106
|
> file(s) to be found for restoration. Eg: A database named
|
@@ -162,7 +180,7 @@ Give "rando-username" access to database(s):
|
|
162
180
|
* [x] Back up database to S3
|
163
181
|
* [x] Restore local database
|
164
182
|
* [x] Restore remote database @ S3
|
165
|
-
* [
|
166
|
-
* [
|
183
|
+
* [x] Quickly back up via command line option
|
184
|
+
* [x] Quickly restore via command line option
|
167
185
|
* [ ] Task for inclusion in a Rakefile
|
168
|
-
* [
|
186
|
+
* [x] Support environment variables in config
|
data/lib/pgchief/cli.rb
CHANGED
@@ -10,41 +10,61 @@ module Pgchief
|
|
10
10
|
option :init do
|
11
11
|
short '-i'
|
12
12
|
long '--init'
|
13
|
-
desc 'Initialize the TOML configuration file'
|
13
|
+
desc 'Initialize the TOML configuration file.'
|
14
14
|
end
|
15
15
|
|
16
16
|
option :version do
|
17
17
|
short '-v'
|
18
18
|
long '--version'
|
19
|
-
desc 'Show the version'
|
19
|
+
desc 'Show the version.'
|
20
20
|
end
|
21
21
|
|
22
22
|
option :'remote-restore' do
|
23
23
|
long '--remote-restore'
|
24
|
-
desc 'Restore a database from a remote backup'
|
24
|
+
desc 'Restore a database from a remote backup.'
|
25
25
|
end
|
26
26
|
|
27
27
|
option :'remote-backup' do
|
28
28
|
long '--remote-backup'
|
29
|
-
desc 'Backup a database to a remote location'
|
29
|
+
desc 'Backup a database to a remote location.'
|
30
|
+
end
|
31
|
+
|
32
|
+
option :restore do
|
33
|
+
short '-r'
|
34
|
+
long '--restore string'
|
35
|
+
arity 1
|
36
|
+
desc 'Quickly restore specific database. Pass name of db.'
|
37
|
+
end
|
38
|
+
|
39
|
+
option :backup do
|
40
|
+
short '-b'
|
41
|
+
long '--backup string'
|
42
|
+
arity 1
|
43
|
+
desc 'Quickly backup specific database. Pass name of db.'
|
30
44
|
end
|
31
45
|
|
32
46
|
flag :help do
|
33
47
|
short '-h'
|
34
48
|
long '--help'
|
35
|
-
desc 'Print usage'
|
49
|
+
desc 'Print usage.'
|
36
50
|
end
|
37
51
|
|
38
|
-
def run
|
52
|
+
def run # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
|
39
53
|
if params[:help]
|
40
54
|
print help
|
41
55
|
elsif params[:init]
|
42
56
|
Pgchief::Command::ConfigCreate.call
|
43
57
|
elsif params[:version]
|
44
58
|
puts Pgchief::VERSION
|
59
|
+
elsif params[:restore]
|
60
|
+
puts Pgchief::Command::QuickRestore.call(params, params[:restore])
|
61
|
+
elsif params[:backup]
|
62
|
+
puts Pgchief::Command::QuickBackup.call(params, params[:backup])
|
45
63
|
else
|
46
64
|
Pgchief::Prompt::Start.call(params)
|
47
65
|
end
|
66
|
+
rescue Pgchief::Error => e
|
67
|
+
puts e.message
|
48
68
|
end
|
49
69
|
end
|
50
70
|
end
|
@@ -35,7 +35,11 @@ module Pgchief
|
|
35
35
|
private
|
36
36
|
|
37
37
|
def backup!
|
38
|
-
`
|
38
|
+
# if the provided `pgurl` already has a database at the tail
|
39
|
+
# end of the string, remove it. We'll explicitly add it below.
|
40
|
+
pgurl = Pgchief::Config.pgurl.gsub(%r{/[a-zA-Z\-_]*$}, '')
|
41
|
+
|
42
|
+
`pg_dump -Fc #{pgurl}/#{database} -f #{local_location}`
|
39
43
|
end
|
40
44
|
|
41
45
|
def check_backup!
|
@@ -8,10 +8,10 @@ module Pgchief
|
|
8
8
|
|
9
9
|
def call
|
10
10
|
@database = params.first
|
11
|
-
raise Pgchief::Errors::DatabaseMissingError unless db_exists?
|
12
11
|
|
13
|
-
|
12
|
+
return "Database '#{database}' does not exist." unless db_exists?
|
14
13
|
|
14
|
+
conn.exec("DROP DATABASE #{database}")
|
15
15
|
"Database '#{database}' dropped successfully!"
|
16
16
|
rescue PG::Error => e
|
17
17
|
"Error: #{e.message}"
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pgchief
|
4
|
+
module Command
|
5
|
+
# Command object to quickly restore the latest backup for a database
|
6
|
+
class QuickBackup < Base
|
7
|
+
def call
|
8
|
+
database = params.last
|
9
|
+
Pgchief::Config.load_config!(params.first)
|
10
|
+
Pgchief::Config.set_up_file_structure!
|
11
|
+
Pgchief::Command::DatabaseBackup.call(database)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pgchief
|
4
|
+
module Command
|
5
|
+
# Command object to quickly restore the latest backup for a database
|
6
|
+
class QuickRestore < Base
|
7
|
+
def call
|
8
|
+
database = params.last
|
9
|
+
Pgchief::Config.load_config!(params.first)
|
10
|
+
Pgchief::Config.set_up_file_structure!
|
11
|
+
|
12
|
+
filename = Pgchief::Database
|
13
|
+
.backups_for(database, remote: Pgchief::Config.remote_restore)
|
14
|
+
.first
|
15
|
+
|
16
|
+
Pgchief::Command::DatabaseRestore.call(database, filename)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/pgchief/config.rb
CHANGED
@@ -5,6 +5,8 @@ require 'toml-rb'
|
|
5
5
|
module Pgchief
|
6
6
|
# Class to store configuration settings
|
7
7
|
class Config
|
8
|
+
DEFAULT_CONFIG = "#{Dir.home}/.config/pgchief/config.toml".freeze
|
9
|
+
|
8
10
|
class << self
|
9
11
|
attr_accessor \
|
10
12
|
:s3_key,
|
@@ -18,10 +20,18 @@ module Pgchief
|
|
18
20
|
attr_reader \
|
19
21
|
:s3_objects_path,
|
20
22
|
:backup_dir,
|
21
|
-
:credentials_file
|
23
|
+
:credentials_file,
|
24
|
+
:toml_file
|
25
|
+
|
26
|
+
# explicitly define getter so that pgurl is always available if
|
27
|
+
# load_config! is not run.
|
28
|
+
def pgurl
|
29
|
+
ENV.fetch('DATABASE_URL', ENV.fetch('DB_URL', @pgurl))
|
30
|
+
end
|
22
31
|
|
23
|
-
def load_config!(params, toml_file =
|
24
|
-
|
32
|
+
def load_config!(params, toml_file = DEFAULT_CONFIG)
|
33
|
+
@toml_file = toml_file
|
34
|
+
config = toml_config || env_config
|
25
35
|
self.backup_dir = config[:backup_dir]
|
26
36
|
self.credentials_file = config[:credentials_file]
|
27
37
|
self.pgurl = config[:pgurl]
|
@@ -35,7 +45,7 @@ module Pgchief
|
|
35
45
|
self.remote_backup = params[:'remote-backup'] == true ||
|
36
46
|
params[:'local-backup'] == false ||
|
37
47
|
config[:remote_backup]
|
38
|
-
rescue
|
48
|
+
rescue Pgchief::Errors::ConfigMissingError
|
39
49
|
puts config_missing_error(toml_file)
|
40
50
|
end
|
41
51
|
|
@@ -43,10 +53,6 @@ module Pgchief
|
|
43
53
|
@s3 ||= Pgchief::Config::S3.new(self)
|
44
54
|
end
|
45
55
|
|
46
|
-
def pgurl
|
47
|
-
ENV.fetch('DATABASE_URL', @pgurl)
|
48
|
-
end
|
49
|
-
|
50
56
|
def backup_dir=(value)
|
51
57
|
@backup_dir = value ? "#{value.chomp('/')}/".gsub('~', Dir.home) : '/tmp/'
|
52
58
|
end
|
@@ -68,8 +74,27 @@ module Pgchief
|
|
68
74
|
|
69
75
|
private
|
70
76
|
|
77
|
+
def toml_config
|
78
|
+
return unless File.exist?(toml_file.to_s)
|
79
|
+
|
80
|
+
TomlRB.load_file(toml_file, symbolize_keys: true)
|
81
|
+
end
|
82
|
+
|
83
|
+
def env_config
|
84
|
+
pgurl = ENV.fetch('DATABASE_URL', ENV.fetch('DB_URL', nil))
|
85
|
+
raise Pgchief::Errors::ConfigMissingError if pgurl.nil?
|
86
|
+
|
87
|
+
{
|
88
|
+
pgurl: pgurl,
|
89
|
+
s3_key: ENV.fetch('AWS_ACCESS_KEY_ID', ENV.fetch('AWS_ACCESS_KEY', nil)),
|
90
|
+
s3_secret: ENV.fetch('AWS_SECRET_ACCESS_KEY', ENV.fetch('AWS_SECRET_KEY', nil)),
|
91
|
+
s3_region: ENV.fetch('AWS_DEFAULT_REGION', ENV.fetch('AWS_REGION', nil)),
|
92
|
+
s3_objects_path: ENV.fetch('S3_BACKUPS_PATH', nil)
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
71
96
|
def config_missing_error(toml_file)
|
72
|
-
"You must create a config file at #{toml_file}.\n" \
|
97
|
+
"You must create a config file at #{toml_file || DEFAULT_CONFIG}.\n" \
|
73
98
|
'run `pgchief --init` to create it.'
|
74
99
|
end
|
75
100
|
end
|
@@ -10,13 +10,13 @@ module Pgchief
|
|
10
10
|
|
11
11
|
def_delegators :s3, :bucket, :path, :client
|
12
12
|
|
13
|
-
def self.for(database, remote)
|
14
|
-
new(database, remote).for
|
13
|
+
def self.for(database, remote:)
|
14
|
+
new(database, remote: remote).for
|
15
15
|
end
|
16
16
|
|
17
17
|
attr_reader :database, :remote
|
18
18
|
|
19
|
-
def initialize(database, remote)
|
19
|
+
def initialize(database, remote:)
|
20
20
|
@database = database
|
21
21
|
@remote = remote
|
22
22
|
end
|
data/lib/pgchief/version.rb
CHANGED
data/lib/pgchief.rb
CHANGED
@@ -36,6 +36,8 @@ require 'pgchief/command/database_drop'
|
|
36
36
|
require 'pgchief/command/database_list'
|
37
37
|
require 'pgchief/command/database_privileges_grant'
|
38
38
|
require 'pgchief/command/database_restore'
|
39
|
+
require 'pgchief/command/quick_restore'
|
40
|
+
require 'pgchief/command/quick_backup'
|
39
41
|
require 'pgchief/command/retrieve_connection_string'
|
40
42
|
require 'pgchief/command/s3_upload'
|
41
43
|
require 'pgchief/command/store_connection_string'
|
@@ -48,8 +50,21 @@ module Pgchief
|
|
48
50
|
|
49
51
|
module Errors
|
50
52
|
class UserExistsError < Error; end
|
51
|
-
|
52
|
-
class DatabaseMissingError < Error; end
|
53
|
+
|
53
54
|
class BackupError < Error; end
|
55
|
+
|
56
|
+
class ConfigMissingError < Error; end
|
57
|
+
|
58
|
+
class DatabaseExistsError < Error
|
59
|
+
def message
|
60
|
+
'The database already exists.'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
class DatabaseMissingError < Error
|
65
|
+
def message
|
66
|
+
'The database requested does not exist.'
|
67
|
+
end
|
68
|
+
end
|
54
69
|
end
|
55
70
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pgchief
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Oliveira
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: aws-sdk-s3
|
@@ -108,6 +108,8 @@ files:
|
|
108
108
|
- lib/pgchief/command/database_list.rb
|
109
109
|
- lib/pgchief/command/database_privileges_grant.rb
|
110
110
|
- lib/pgchief/command/database_restore.rb
|
111
|
+
- lib/pgchief/command/quick_backup.rb
|
112
|
+
- lib/pgchief/command/quick_restore.rb
|
111
113
|
- lib/pgchief/command/retrieve_connection_string.rb
|
112
114
|
- lib/pgchief/command/s3_upload.rb
|
113
115
|
- lib/pgchief/command/store_connection_string.rb
|
@@ -158,7 +160,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
158
160
|
- !ruby/object:Gem::Version
|
159
161
|
version: '0'
|
160
162
|
requirements: []
|
161
|
-
rubygems_version: 3.6.
|
163
|
+
rubygems_version: 3.6.8
|
162
164
|
specification_version: 4
|
163
165
|
summary: A simple ruby script to manage postgresql databases and users
|
164
166
|
test_files: []
|