pg_export 1.0.0.rc4 → 1.0.0.rc8
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 +42 -6
- data/CHANGELOG.md +10 -5
- data/README.md +63 -32
- data/bin/pg_export +15 -134
- data/lib/pg_export/{lib/pg_export/adapters/bash_adapter.rb → adapters/shell_adapter.rb} +1 -1
- data/lib/pg_export/commands_factory.rb +158 -0
- data/lib/pg_export/configuration.rb +74 -31
- data/lib/pg_export/configuration_parser.rb +126 -0
- data/lib/pg_export/entities/dump.rb +57 -0
- data/lib/pg_export/{lib/pg_export/factories → factories}/cipher_factory.rb +8 -4
- data/lib/pg_export/{lib/pg_export/factories → factories}/dump_factory.rb +1 -2
- data/lib/pg_export/{lib/pg_export/factories → factories}/ftp_gateway_factory.rb +8 -5
- data/lib/pg_export/{lib/pg_export/repositories/gateway_dump_file_repository.rb → factories/gateway_dump_file_factory.rb} +4 -5
- data/lib/pg_export/{lib/pg_export/factories → factories}/ssh_gateway_factory.rb +8 -5
- data/lib/pg_export/{lib/pg_export/gateways → gateways}/ftp.rb +1 -3
- data/lib/pg_export/{lib/pg_export/gateways → gateways}/ssh.rb +2 -6
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive/build_dump.rb +1 -1
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive/close_connection.rb +1 -1
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive/decrypt_dump.rb +0 -0
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive/download_dump.rb +0 -0
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive/encrypt_dump.rb +0 -0
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive/fetch_dumps.rb +0 -0
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive/open_connection.rb +0 -0
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive/remove_old_dumps.rb +1 -1
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive/restore.rb +1 -1
- data/lib/pg_export/listeners/interactive/select_database.rb +12 -0
- data/lib/pg_export/listeners/interactive/select_dump.rb +12 -0
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive/upload_dump.rb +1 -1
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/interactive_listener.rb +4 -3
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain/build_dump.rb +0 -0
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain/close_connection.rb +0 -0
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain/decrypt_dump.rb +0 -0
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain/download_dump.rb +0 -0
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain/encrypt_dump.rb +0 -0
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain/fetch_dumps.rb +0 -0
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain/open_connection.rb +0 -0
- data/lib/pg_export/listeners/plain/prepare_params.rb +15 -0
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain/remove_old_dumps.rb +0 -0
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain/restore.rb +0 -0
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain/upload_dump.rb +0 -0
- data/lib/pg_export/{lib/pg_export/listeners → listeners}/plain_listener.rb +11 -5
- data/lib/pg_export/operations/decrypt_dump.rb +30 -0
- data/lib/pg_export/operations/encrypt_dump.rb +27 -0
- data/lib/pg_export/operations/open_connection.rb +28 -0
- data/lib/pg_export/operations/remove_old_dumps.rb +34 -0
- data/lib/pg_export/{lib/pg_export/repositories → repositories}/gateway_dump_repository.rb +4 -9
- data/lib/pg_export/transactions/evaluator.rb +59 -0
- data/lib/pg_export/transactions/export_dump.rb +62 -0
- data/lib/pg_export/transactions/import_dump_interactively.rb +78 -0
- data/lib/pg_export/{lib/pg_export/ui → ui}/interactive/input.rb +0 -0
- data/lib/pg_export/{lib/pg_export/ui → ui}/plain/input.rb +0 -0
- data/lib/pg_export/{lib/pg_export/value_objects → value_objects}/dump_file.rb +2 -2
- data/lib/pg_export/value_objects/result.rb +49 -0
- data/lib/pg_export/version.rb +1 -1
- data/lib/pg_export.rb +14 -11
- data/pg_export.gemspec +2 -9
- metadata +57 -129
- data/lib/pg_export/container.rb +0 -23
- data/lib/pg_export/import.rb +0 -7
- data/lib/pg_export/lib/pg_export/entities/dump.rb +0 -45
- data/lib/pg_export/lib/pg_export/operations/decrypt_dump.rb +0 -20
- data/lib/pg_export/lib/pg_export/operations/encrypt_dump.rb +0 -18
- data/lib/pg_export/lib/pg_export/operations/open_connection.rb +0 -19
- data/lib/pg_export/lib/pg_export/operations/remove_old_dumps.rb +0 -26
- data/lib/pg_export/lib/pg_export/transactions/export_dump.rb +0 -56
- data/lib/pg_export/lib/pg_export/transactions/import_dump_interactively.rb +0 -67
- data/lib/pg_export/lib/pg_export/types.rb +0 -14
- data/lib/pg_export/system/boot/config.rb +0 -27
- data/lib/pg_export/system/boot/ftp.rb +0 -11
- data/lib/pg_export/system/boot/interactive.rb +0 -26
- data/lib/pg_export/system/boot/operations.rb +0 -17
- data/lib/pg_export/system/boot/plain.rb +0 -27
- data/lib/pg_export/system/boot/ssh.rb +0 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 653b33873daaa6f1c9c23e494f140980d8618d811b4cbff5e7209cd20d854b23
|
|
4
|
+
data.tar.gz: 4aeedec88429805b47e15fd389c02a2a870ec7aeb1b81b7d1e782c57536bce90
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 43af8e5f80571fb4de1e361097719e89732c99d0e85c4c488d3644a76d31eafd44cc12b0e82258a1d849d393c4324f03e29385dcda725d0606379ee3a9e38a58
|
|
7
|
+
data.tar.gz: 284bb265abde342da455849a18e4a27af9e20d2ae4fe38960b7b3b118f20154828348b9cb2f33b4c9e6c81fdd19a7f0b68a0e8f290a261f193bf1e100ac322fa
|
data/.rubocop.yml
CHANGED
|
@@ -2,21 +2,57 @@ AllCops:
|
|
|
2
2
|
TargetRubyVersion: 2.3
|
|
3
3
|
|
|
4
4
|
Metrics/BlockLength:
|
|
5
|
-
Exclude:
|
|
6
|
-
- 'bin/pg_export'
|
|
7
5
|
ExcludedMethods: ['describe', 'context']
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
Max:
|
|
7
|
+
Layout/LineLength:
|
|
8
|
+
Max: 140
|
|
11
9
|
|
|
12
10
|
Style/ParallelAssignment:
|
|
13
11
|
Enabled: false
|
|
14
12
|
|
|
15
|
-
Naming/
|
|
13
|
+
Naming/MethodParameterName:
|
|
16
14
|
Enabled: false
|
|
17
15
|
|
|
18
|
-
Documentation:
|
|
16
|
+
Style/Documentation:
|
|
19
17
|
Enabled: false
|
|
20
18
|
|
|
21
19
|
Lint/UnusedMethodArgument:
|
|
22
20
|
Enabled: false
|
|
21
|
+
|
|
22
|
+
Metrics/MethodLength:
|
|
23
|
+
Max: 50
|
|
24
|
+
|
|
25
|
+
Metrics/CyclomaticComplexity:
|
|
26
|
+
Max: 30
|
|
27
|
+
|
|
28
|
+
Style/TrailingCommaInHashLiteral:
|
|
29
|
+
Enabled: false
|
|
30
|
+
|
|
31
|
+
Metrics/AbcSize:
|
|
32
|
+
Max: 30
|
|
33
|
+
Exclude:
|
|
34
|
+
- 'lib/pg_export/configuration_parser.rb'
|
|
35
|
+
- 'lib/pg_export/configuration.rb'
|
|
36
|
+
|
|
37
|
+
Metrics/PerceivedComplexity:
|
|
38
|
+
Max: 30
|
|
39
|
+
|
|
40
|
+
Lint/AmbiguousOperator:
|
|
41
|
+
Enabled: false
|
|
42
|
+
|
|
43
|
+
Metrics/ClassLength:
|
|
44
|
+
Max: 200
|
|
45
|
+
|
|
46
|
+
Layout/ExtraSpacing:
|
|
47
|
+
Exclude:
|
|
48
|
+
- 'lib/pg_export/configuration_parser.rb'
|
|
49
|
+
|
|
50
|
+
Metrics/ParameterLists:
|
|
51
|
+
Exclude:
|
|
52
|
+
- 'lib/pg_export/configuration.rb'
|
|
53
|
+
|
|
54
|
+
Metrics/ParameterLists:
|
|
55
|
+
Enabled: false
|
|
56
|
+
|
|
57
|
+
Style/Semicolon:
|
|
58
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
### 1.0.0 -
|
|
1
|
+
### 1.0.0 - 2022.05.18
|
|
2
2
|
- Make it compatible with Ruby 3.0
|
|
3
3
|
- Change configuration envs:
|
|
4
4
|
- BACKUP_FTP_HOST -> PG_EXPORT_GATEWAY_HOST
|
|
@@ -7,15 +7,20 @@
|
|
|
7
7
|
- DUMP_ENCRYPTION_KEY -> PG_EXPORT_ENCRYPTION_KEY
|
|
8
8
|
- Drop Ruby 2.3 support
|
|
9
9
|
- Add SSH option
|
|
10
|
-
- Add
|
|
10
|
+
- Add `encryption_algorithm` option
|
|
11
|
+
- All command line options has now their equivalents in ENVs (and vice-versa)
|
|
12
|
+
- Remove dry libraries dependencies
|
|
13
|
+
- In case of failure bin/pg_export now returns exit value 1
|
|
14
|
+
- Improve performance
|
|
15
|
+
- Improve error handling
|
|
11
16
|
|
|
12
17
|
### 0.7.7 - 2020.09.07
|
|
13
18
|
|
|
14
|
-
- Upgrade dry-initializer
|
|
19
|
+
- Upgrade dry-initializer
|
|
15
20
|
|
|
16
21
|
### 0.7.6 - 2020.09.05
|
|
17
22
|
|
|
18
|
-
- Upgrade dry-types, dry-struct dry-system
|
|
23
|
+
- Upgrade dry-types, dry-struct dry-system
|
|
19
24
|
|
|
20
25
|
### 0.7.0 - 2018.10.18
|
|
21
26
|
|
|
@@ -41,7 +46,7 @@
|
|
|
41
46
|
|
|
42
47
|
### 0.5.0 - 2017.03.11
|
|
43
48
|
|
|
44
|
-
- Add restriction on DUMP_ENCRYPTION_KEY, to be exactly 16 characters length
|
|
49
|
+
- Add restriction on DUMP_ENCRYPTION_KEY, to be exactly 16 characters length
|
|
45
50
|
- Make interactive mode more verbose by adding more messages
|
|
46
51
|
- Fix concurrently opening ftp connection
|
|
47
52
|
- Add closing ftp connection while importing dump in interactive mode
|
data/README.md
CHANGED
|
@@ -11,7 +11,7 @@ Can be used for backups or synchronizing databases between production and develo
|
|
|
11
11
|
Example:
|
|
12
12
|
|
|
13
13
|
pg_export --database database_name --keep 5
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
Above command will perform database dump, encrypt it, upload it to FTP and remove old dumps from FTP, keeping newest 5.
|
|
16
16
|
|
|
17
17
|
FTP connection params and encryption key are configured by env variables.
|
|
@@ -50,20 +50,52 @@ Or install it yourself as:
|
|
|
50
50
|
|
|
51
51
|
$ pg_export -h
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
53
|
+
SYNOPSIS
|
|
54
|
+
pg_export DATABASE [OPTION..]
|
|
55
|
+
pg_export --interactive DATABASE [OPTION..]
|
|
56
|
+
|
|
57
|
+
EXIT VALUES
|
|
58
|
+
0 - Success
|
|
59
|
+
1 - Error
|
|
60
|
+
|
|
61
|
+
ARGUMENTS
|
|
62
|
+
DATABASE - database name to export (when default mode)
|
|
63
|
+
- phrase to filter database dumps by (when interactive mode)
|
|
64
|
+
|
|
65
|
+
OPTIONS
|
|
66
|
+
-g, --gateway GATEWAY Allowed values: ftp, ssh. Default: ftp. Credentials need to be set via ENVs
|
|
67
|
+
-U, --user USER Gateway (ftp or ssh) user
|
|
68
|
+
-H, --host HOST Gateway (ftp or ssh) host
|
|
69
|
+
-P, --password PASSWORD Gateway (ftp or ssh) password
|
|
70
|
+
-d, --database DATABASE In plain mode: database name to export;
|
|
71
|
+
In interactive mode: phrase to filter by
|
|
72
|
+
-e, --encryption_key KEY Dumps will be SSL encrypted using this key. Should have exactly 16 characters
|
|
73
|
+
-a, --algorithm ALGORITHM Encryption cipher algorithm (default: AES-128-CBC);
|
|
74
|
+
For available option see `$ openssl list -cipher-algorithms`
|
|
75
|
+
-k, --keep KEEP Number of dump files to keep on FTP (default: 10)
|
|
76
|
+
-s, --ssh Same as "--gateway ssh". When set, the --gateway option is ignored
|
|
77
|
+
-f, --ftp Same as "--gateway ftp". When set, the --gateway option is ignored
|
|
78
|
+
-t, --timestamped Prepends log messages with timestamps
|
|
79
|
+
-m, --muted Mutes log messages. When set, the -t option is ignored. Prints message only on error
|
|
80
|
+
-i, --interactive Interactive mode, for importing dumps. Whan set, the -t and -m options are ignored
|
|
81
|
+
-w, --welcome Try connecting to the gateway (FTP or SSH) to verify the connection and exit
|
|
82
|
+
-c, --configuration Print the configuration and exit
|
|
83
|
+
-v, --version Print version
|
|
84
|
+
-h, --help Print this message and exit
|
|
85
|
+
|
|
86
|
+
ENV
|
|
87
|
+
Each of the above options can be also set using enviromental variables.
|
|
88
|
+
Use full option names prepending with PG_EXPORT_ phrase.
|
|
89
|
+
Command line options takes precedence over the ENVs.
|
|
90
|
+
|
|
91
|
+
Eg. below two commands are equivalent:
|
|
92
|
+
pg_export -s -U user -H host database_name -k 10
|
|
93
|
+
|
|
94
|
+
Is equivalent to:
|
|
95
|
+
export PG_EXPORT_GATEWAY_USER=user
|
|
96
|
+
export PG_EXPORT_GATEWAY_HOST=host
|
|
97
|
+
export PG_EXPORT_KEEP=20
|
|
98
|
+
pg_export -s database_name -k 10
|
|
67
99
|
|
|
68
100
|
## How to start
|
|
69
101
|
|
|
@@ -73,42 +105,41 @@ __Step 1.__ Prepare ENV variables.
|
|
|
73
105
|
PG_EXPORT_GATEWAY_HOST=yourftp.example.com
|
|
74
106
|
PG_EXPORT_GATEWAY_USER=user
|
|
75
107
|
PG_EXPORT_GATEWAY_PASSWORD=password
|
|
76
|
-
|
|
108
|
+
|
|
77
109
|
/* Encryption key should have exactly 16 characters. */
|
|
78
110
|
/* Dumps will be SSL(AES-128-CBC) encrypted using this key. */
|
|
79
111
|
PG_EXPORT_ENCRYPTION_KEY=1234567890abcdef
|
|
80
|
-
|
|
81
|
-
/* Dumps to be kept on FTP */
|
|
82
|
-
/* Optional, defaults to 10 */
|
|
83
|
-
KEEP_DUMPS=5
|
|
84
|
-
|
|
85
|
-
Note, that variables cannot include `#` sign, [more info](http://serverfault.com/questions/539730/environment-variable-in-etc-environment-with-pound-hash-sign-in-the-value).
|
|
86
112
|
|
|
87
113
|
__Step 2.__ Print the configuration to verify if env variables has been loaded properly.
|
|
88
114
|
|
|
89
115
|
$ pg_export --configuration
|
|
90
|
-
=>
|
|
91
|
-
|
|
92
|
-
|
|
116
|
+
=> encryption_key k4***
|
|
117
|
+
gateway_host yourftp.example.com
|
|
118
|
+
gateway_user your_gateway_user
|
|
119
|
+
gateway_password
|
|
120
|
+
logger_format plain
|
|
121
|
+
keep_dumps 10
|
|
122
|
+
....
|
|
123
|
+
|
|
93
124
|
__Step 3.__ Try connecting to FTP to verify the connection.
|
|
94
125
|
|
|
95
126
|
$ pg_export --gateway ftp --welcome
|
|
96
127
|
=> 230 User your_ftp_user logged in
|
|
97
|
-
|
|
128
|
+
|
|
98
129
|
__Step 4.__ Perform database export.
|
|
99
130
|
|
|
100
|
-
$ pg_export -d your_database
|
|
101
|
-
=> Dump database your_database to
|
|
102
|
-
Encrypt
|
|
131
|
+
$ pg_export -d your_database -k 5
|
|
132
|
+
=> Dump database your_database to database_name (1.36MB)
|
|
133
|
+
Encrypt database_name_20181016_121314 (1.34MB)
|
|
103
134
|
Connect to yourftp.example.com
|
|
104
|
-
Upload
|
|
135
|
+
Upload database_name_20181016_121314 (1.34MB) to yourftp.example.com
|
|
105
136
|
Close FTP
|
|
106
|
-
|
|
137
|
+
|
|
107
138
|
## How to restore a dump?
|
|
108
139
|
|
|
109
140
|
Run interactive mode and follow the instructions:
|
|
110
141
|
|
|
111
|
-
pg_export [-d
|
|
142
|
+
pg_export [-d database_name] -i
|
|
112
143
|
|
|
113
144
|
## Development
|
|
114
145
|
|
data/bin/pg_export
CHANGED
|
@@ -1,147 +1,28 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
lib = File.expand_path('../lib', __dir__)
|
|
5
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
6
|
|
|
6
7
|
require 'pg_export'
|
|
7
8
|
|
|
8
|
-
ENV['KEEP_DUMPS'] = ENV['KEEP_DUMPS'] || '10'
|
|
9
|
-
ENV['GATEWAY'] = 'ftp'
|
|
10
|
-
ENV['PG_EXPORT_MODE'] = 'plain'
|
|
11
|
-
ENV['PG_EXPORT_ENCRYPTION_ALGORITHM'] = 'AES-128-CBC'
|
|
12
|
-
|
|
13
|
-
database = nil
|
|
14
|
-
|
|
15
|
-
option_parser = OptionParser.new do |opts|
|
|
16
|
-
opts.banner = <<~TXT
|
|
17
|
-
NAME
|
|
18
|
-
pg_export - CLI for exporting/importing PostgreSQL dumps via FTP/SSH
|
|
19
|
-
|
|
20
|
-
SYNOPSIS (default mode)
|
|
21
|
-
pg_export DATABASE [options]
|
|
22
|
-
|
|
23
|
-
SYNOPSIS (interactive mode)
|
|
24
|
-
pg_export --interactive [DATABASE] [options]
|
|
25
|
-
|
|
26
|
-
ARGUMENTS
|
|
27
|
-
DATABASE - database name to export (when default mode)
|
|
28
|
-
- phrase to filter database dumps by (when interactive mode)
|
|
29
|
-
|
|
30
|
-
OPTIONS
|
|
31
|
-
TXT
|
|
32
|
-
|
|
33
|
-
opts.program_name = 'pg_export'
|
|
34
|
-
opts.version = PgExport::VERSION
|
|
35
|
-
|
|
36
|
-
opts.on('-g', '--gateway GATEWAY', %w[ftp ssh], 'Allowed values: ftp, ssh. Default: ftp. Credentials need to be set via ENVs') do |g|
|
|
37
|
-
ENV['GATEWAY'] = g
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
opts.on('-s', '--ssh', 'Same as "--gateway ssh"') do
|
|
41
|
-
ENV['GATEWAY'] = 'ssh'
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
opts.on('-f', '--ftp', 'Same as "--gateway ftp"') do
|
|
45
|
-
ENV['GATEWAY'] = 'ftp'
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
opts.on('-d', '--database DATABASE', String, 'Alternative way of specifying name of the database to export or phrase to filter by') do |d|
|
|
49
|
-
database = d
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
opts.on('-e', '--encryption_key KEY', String, 'Dumps will be SSL encrypted using this key. Should have exactly 16 characters. Overwrites PG_EXPORT_ENCRYPTION_KEY env') do |key|
|
|
53
|
-
ENV['PG_EXPORT_ENCRYPTION_KEY'] = key
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
opts.on('-a', '--algorithm ALGORITHM', String, 'Encryption cipher algorithm (default: AES-128-CBC). Overwrites PG_EXPORT_ENCRYPTION_ALGORITHM env. For available option see `$ openssl list -cipher-algorithms`') do |key|
|
|
57
|
-
ENV['PG_EXPORT_ENCRYPTION_KEY'] = key
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
opts.on('-k', '--keep KEEP', String, 'Number of dump files to keep on FTP (default: 10). Overwrites KEEP_DUMPS env') do |keep|
|
|
61
|
-
ENV['KEEP_DUMPS'] = keep
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
opts.on('-t', '--timestamped', 'Enables log messages with timestamps') do
|
|
65
|
-
ENV['LOGGER_FORMAT'] = 'timestamped'
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
opts.on('-m', '--muted', 'Mutes log messages (overrides -t option)') do
|
|
69
|
-
ENV['LOGGER_FORMAT'] = 'muted'
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
opts.on('-i', '--interactive', 'Interactive mode, for importing dumps') do
|
|
73
|
-
ENV['PG_EXPORT_MODE'] = 'interactive'
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
opts.on('-v', '--version', 'Show version') do
|
|
77
|
-
puts PgExport::VERSION
|
|
78
|
-
exit
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
opts.on('-h', '--help', 'Show this message') do
|
|
82
|
-
puts opts
|
|
83
|
-
exit
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
opts.separator <<~TXT
|
|
87
|
-
|
|
88
|
-
ENV
|
|
89
|
-
PG_EXPORT_GATEWAY_HOST required
|
|
90
|
-
PG_EXPORT_GATEWAY_USER required
|
|
91
|
-
PG_EXPORT_GATEWAY_PASSWORD optional when eg. authorized key is added
|
|
92
|
-
PG_EXPORT_ENCRYPTION_KEY required or set by --encryption_key)
|
|
93
|
-
PG_EXPORT_ENCRYPTION_ALGORITHM required or set by --algorithm)
|
|
94
|
-
TXT
|
|
95
|
-
|
|
96
|
-
opts.separator "\nTEST RUN"
|
|
97
|
-
|
|
98
|
-
opts.on('-c', '--configuration', 'Print the configuration') do
|
|
99
|
-
require 'pg_export/container'
|
|
100
|
-
PgExport::Container.start(:config)
|
|
101
|
-
puts PgExport::Container['config'].to_h
|
|
102
|
-
exit
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
opts.on('-w', '--welcome', 'Try connecting to the gateway (FTP or SSH) to verify the connection') do
|
|
106
|
-
require 'pg_export/container'
|
|
107
|
-
PgExport::Container.start(ENV['GATEWAY'].to_sym)
|
|
108
|
-
gateway = PgExport::Container['factories.gateway_factory'].gateway
|
|
109
|
-
puts gateway.welcome
|
|
110
|
-
exit
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
if ARGV.empty?
|
|
114
|
-
puts opts
|
|
115
|
-
exit
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
|
|
119
9
|
begin
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
10
|
+
config = PgExport::ConfigurationParser.parse
|
|
11
|
+
pg_export = PgExport.new(config)
|
|
12
|
+
result = pg_export.call
|
|
13
|
+
result
|
|
14
|
+
.on_success { |outcome| puts outcome if outcome }
|
|
15
|
+
.on_failure { |outcome| warn outcome[:message]; exit 1 }
|
|
16
|
+
rescue PgExport::ConfigurationParser::Error => e
|
|
123
17
|
warn e.message.capitalize
|
|
124
|
-
warn 'Details:'
|
|
125
|
-
warn option_parser.to_s.split("\n").grep(/ #{e.args.first}/).join("\n")
|
|
126
|
-
warn 'Type "pg_export" for available options'
|
|
127
|
-
exit
|
|
128
|
-
end
|
|
129
18
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
pg_export = PgExport.boot
|
|
134
|
-
rescue PgExport::InitializationError => e
|
|
135
|
-
warn 'Unable to initialize PgExport due to invalid configuration. Check you ENVs.'
|
|
136
|
-
warn "Detailed message: #{e.message}"
|
|
137
|
-
exit
|
|
138
|
-
end
|
|
139
|
-
|
|
140
|
-
begin
|
|
141
|
-
pg_export.call(database) do |result|
|
|
142
|
-
result.success { puts 'Success' }
|
|
143
|
-
result.failure { |outcome| warn outcome[:message] }
|
|
19
|
+
if e.reason == 'missing argument'
|
|
20
|
+
warn "\nHint for the #{e.args.first} option:"
|
|
21
|
+
warn PgExport::ConfigurationParser.help.to_s.split("\n").grep(/ #{e.args.first}/).join("\n")
|
|
144
22
|
end
|
|
23
|
+
|
|
24
|
+
warn 'Type "pg_export -h" to print options.'
|
|
25
|
+
exit 1
|
|
145
26
|
rescue Interrupt
|
|
146
27
|
puts
|
|
147
28
|
end
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'pg_export/value_objects/result'
|
|
4
|
+
|
|
5
|
+
class PgExport
|
|
6
|
+
class CommandsFactory
|
|
7
|
+
attr_reader :config
|
|
8
|
+
|
|
9
|
+
def initialize(config:)
|
|
10
|
+
@config = config
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def print_configuration
|
|
14
|
+
->(_) { ValueObjects::Success.new(config) }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def gateway_welcome
|
|
18
|
+
->(_) { ValueObjects::Success.new(gateway_factory.gateway.welcome) }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def print_version
|
|
22
|
+
->(_) { ValueObjects::Success.new(PgExport::VERSION) }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def print_help
|
|
26
|
+
->(_) { ValueObjects::Success.new(PgExport::ConfigurationParser.help) }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def export_dump
|
|
30
|
+
require 'pg_export/transactions/export_dump'
|
|
31
|
+
require 'pg_export/factories/dump_factory'
|
|
32
|
+
require 'pg_export/adapters/shell_adapter'
|
|
33
|
+
require 'pg_export/operations/encrypt_dump'
|
|
34
|
+
require 'pg_export/operations/open_connection'
|
|
35
|
+
require 'pg_export/operations/remove_old_dumps'
|
|
36
|
+
require 'pg_export/repositories/gateway_dump_repository'
|
|
37
|
+
|
|
38
|
+
PgExport::Transactions::ExportDump.new(
|
|
39
|
+
dump_factory: Factories::DumpFactory.new,
|
|
40
|
+
shell_adapter: Adapters::ShellAdapter.new,
|
|
41
|
+
encrypt_dump: Operations::EncryptDump.new(cipher_factory: cipher_factory),
|
|
42
|
+
open_connection: Operations::OpenConnection.new(gateway_factory: gateway_factory),
|
|
43
|
+
remove_old_dumps: Operations::RemoveOldDumps.new(
|
|
44
|
+
gateway_dump_repository: Repositories::GatewayDumpRepository.new,
|
|
45
|
+
keep: config.keep_dumps
|
|
46
|
+
),
|
|
47
|
+
listeners: plain_listeners
|
|
48
|
+
)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def import_dump_interactively
|
|
52
|
+
require 'pg_export/transactions/import_dump_interactively'
|
|
53
|
+
require 'pg_export/ui/interactive/input'
|
|
54
|
+
require 'pg_export/adapters/shell_adapter'
|
|
55
|
+
require 'pg_export/factories/gateway_dump_file_factory'
|
|
56
|
+
require 'pg_export/repositories/gateway_dump_repository'
|
|
57
|
+
require 'pg_export/operations/open_connection'
|
|
58
|
+
require 'pg_export/operations/decrypt_dump'
|
|
59
|
+
|
|
60
|
+
PgExport::Transactions::ImportDumpInteractively.new(
|
|
61
|
+
input: Ui::Interactive::Input.new,
|
|
62
|
+
shell_adapter: Adapters::ShellAdapter.new,
|
|
63
|
+
gateway_dump_file_factory: Factories::GatewayDumpFileFactory.new,
|
|
64
|
+
gateway_dump_repository: Repositories::GatewayDumpRepository.new,
|
|
65
|
+
open_connection: Operations::OpenConnection.new(gateway_factory: gateway_factory),
|
|
66
|
+
decrypt_dump: Operations::DecryptDump.new(cipher_factory: cipher_factory),
|
|
67
|
+
listeners: interactive_listeners
|
|
68
|
+
)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
private
|
|
72
|
+
|
|
73
|
+
def gateway_factory
|
|
74
|
+
if config.gateway == :ftp
|
|
75
|
+
require 'pg_export/factories/ftp_gateway_factory'
|
|
76
|
+
|
|
77
|
+
Factories::FtpGatewayFactory.new(config: config)
|
|
78
|
+
elsif config.gateway == :ssh
|
|
79
|
+
require 'pg_export/factories/ssh_gateway_factory'
|
|
80
|
+
|
|
81
|
+
Factories::SshGatewayFactory.new(config: config)
|
|
82
|
+
else
|
|
83
|
+
raise ArgumentError, "Unknown gateway #{config.gateway}"
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def cipher_factory
|
|
88
|
+
require 'pg_export/factories/cipher_factory'
|
|
89
|
+
|
|
90
|
+
Factories::CipherFactory.new(
|
|
91
|
+
encryption_algorithm: config.encryption_algorithm,
|
|
92
|
+
encryption_key: config.encryption_key
|
|
93
|
+
)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def plain_listeners
|
|
97
|
+
require 'pg_export/listeners/plain/prepare_params'
|
|
98
|
+
require 'pg_export/listeners/plain/build_dump'
|
|
99
|
+
require 'pg_export/listeners/plain/close_connection'
|
|
100
|
+
require 'pg_export/listeners/plain/decrypt_dump'
|
|
101
|
+
require 'pg_export/listeners/plain/download_dump'
|
|
102
|
+
require 'pg_export/listeners/plain/encrypt_dump'
|
|
103
|
+
require 'pg_export/listeners/plain/fetch_dumps'
|
|
104
|
+
require 'pg_export/listeners/plain/open_connection'
|
|
105
|
+
require 'pg_export/listeners/plain/remove_old_dumps'
|
|
106
|
+
require 'pg_export/listeners/plain/restore'
|
|
107
|
+
require 'pg_export/listeners/plain/upload_dump'
|
|
108
|
+
|
|
109
|
+
logger = build_logger(config.logger_format)
|
|
110
|
+
|
|
111
|
+
{
|
|
112
|
+
prepare_params: Listeners::Plain::PrepareParams.new(logger: logger),
|
|
113
|
+
build_dump: Listeners::Plain::BuildDump.new(logger: logger),
|
|
114
|
+
encrypt_dump: Listeners::Plain::EncryptDump.new(logger: logger),
|
|
115
|
+
open_connection: Listeners::Plain::OpenConnection.new(logger: logger),
|
|
116
|
+
upload_dump: Listeners::Plain::UploadDump.new(logger: logger),
|
|
117
|
+
remove_old_dumps: Listeners::Plain::RemoveOldDumps.new(logger: logger),
|
|
118
|
+
close_connection: Listeners::Plain::CloseConnection.new(logger: logger)
|
|
119
|
+
}
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def interactive_listeners
|
|
123
|
+
require 'pg_export/listeners/interactive/open_connection'
|
|
124
|
+
require 'pg_export/listeners/interactive/fetch_dumps'
|
|
125
|
+
require 'pg_export/listeners/interactive/select_dump'
|
|
126
|
+
require 'pg_export/listeners/interactive/download_dump'
|
|
127
|
+
require 'pg_export/listeners/interactive/close_connection'
|
|
128
|
+
require 'pg_export/listeners/interactive/decrypt_dump'
|
|
129
|
+
require 'pg_export/listeners/interactive/select_database'
|
|
130
|
+
require 'pg_export/listeners/interactive/restore'
|
|
131
|
+
|
|
132
|
+
{
|
|
133
|
+
open_connection: Listeners::Interactive::OpenConnection.new,
|
|
134
|
+
fetch_dumps: Listeners::Interactive::FetchDumps.new,
|
|
135
|
+
select_dump: Listeners::Interactive::SelectDump.new,
|
|
136
|
+
download_dump: Listeners::Interactive::DownloadDump.new,
|
|
137
|
+
close_connection: Listeners::Interactive::CloseConnection.new,
|
|
138
|
+
decrypt_dump: Listeners::Interactive::DecryptDump.new,
|
|
139
|
+
select_database: Listeners::Interactive::SelectDatabase.new,
|
|
140
|
+
restore: Listeners::Interactive::Restore.new,
|
|
141
|
+
}
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def build_logger(logger_format)
|
|
145
|
+
require 'logger'
|
|
146
|
+
|
|
147
|
+
formatters = {
|
|
148
|
+
plain: ->(_, _, _, message) { "#{message}\n" },
|
|
149
|
+
muted: ->(*) {},
|
|
150
|
+
timestamped: lambda do |severity, datetime, progname, message|
|
|
151
|
+
"#{datetime} #{Process.pid} TID-#{Thread.current.object_id.to_s(36)}#{progname} #{severity}: #{message}\n"
|
|
152
|
+
end
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
Logger.new($stdout, formatter: formatters.fetch(logger_format))
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
end
|