pg_export 1.0.0.rc4 → 1.0.0.rc8
Sign up to get free protection for your applications and to get access to all the features.
- 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
@@ -1,42 +1,85 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
4
|
-
require 'dry-struct'
|
3
|
+
require 'optparse'
|
5
4
|
|
6
5
|
class PgExport
|
7
|
-
class Configuration
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
gateway_host: env['PG_EXPORT_GATEWAY_HOST'],
|
21
|
-
gateway_user: env['PG_EXPORT_GATEWAY_USER'],
|
22
|
-
gateway_password: env['PG_EXPORT_GATEWAY_PASSWORD'] == '' ? nil : env['PG_EXPORT_GATEWAY_PASSWORD'],
|
23
|
-
logger_format: env['LOGGER_FORMAT'] || 'plain',
|
24
|
-
keep_dumps: env['KEEP_DUMPS'] || 10
|
25
|
-
)
|
26
|
-
rescue Dry::Struct::Error => e
|
27
|
-
raise PgExport::InitializationError, e.message.gsub('[PgExport::Configuration.new] ', '')
|
28
|
-
end
|
6
|
+
class Configuration
|
7
|
+
ATTRS = %i[
|
8
|
+
encryption_key
|
9
|
+
encryption_algorithm
|
10
|
+
gateway_host
|
11
|
+
gateway_user
|
12
|
+
gateway_password
|
13
|
+
logger_format
|
14
|
+
keep_dumps
|
15
|
+
gateway mode
|
16
|
+
database
|
17
|
+
command
|
18
|
+
].freeze
|
29
19
|
|
30
|
-
|
31
|
-
|
32
|
-
|
20
|
+
attr_reader *ATTRS
|
21
|
+
|
22
|
+
def initialize(
|
23
|
+
encryption_key: nil,
|
24
|
+
encryption_algorithm: nil,
|
25
|
+
gateway_host: nil,
|
26
|
+
gateway_user: nil,
|
27
|
+
gateway_password: nil,
|
28
|
+
logger_format: nil,
|
29
|
+
keep_dumps: nil,
|
30
|
+
gateway: nil,
|
31
|
+
mode: nil,
|
32
|
+
database: nil,
|
33
|
+
command: nil
|
34
|
+
)
|
35
|
+
|
36
|
+
@encryption_key = String(encryption_key)
|
37
|
+
raise ArgumentError, 'Encryption key must be 16 chars long' if @encryption_key.length != 16
|
38
|
+
|
39
|
+
@encryption_algorithm = String(encryption_algorithm)
|
40
|
+
@encryption_algorithm = 'AES-128-CBC' if @encryption_algorithm.empty?
|
41
|
+
|
42
|
+
@gateway_host = String(gateway_host)
|
43
|
+
raise ArgumentError, 'Gatway host must not be empty' if @gateway_host.empty?
|
44
|
+
|
45
|
+
@gateway_user = String(gateway_user)
|
46
|
+
raise ArgumentError, 'Gatway user must not be empty' if @gateway_user.empty?
|
33
47
|
|
34
|
-
|
35
|
-
|
48
|
+
@gateway_password = nil if gateway_password.nil? || gateway_password.to_s.empty?
|
49
|
+
|
50
|
+
@logger_format = logger_format.to_s.to_sym
|
51
|
+
@logger_format = :plain if @logger_format.empty?
|
52
|
+
unless %i[plain timestamped muted].include?(@logger_format)
|
53
|
+
raise ArgumentError, 'Logger format must be one of: plain, timestamped, muted'
|
54
|
+
end
|
55
|
+
|
56
|
+
@keep_dumps = Integer(keep_dumps || 10)
|
57
|
+
raise ArgumentError, 'Keep dumps must greater or equal to 1' unless @keep_dumps >= 1
|
58
|
+
|
59
|
+
@gateway = gateway.to_s.to_sym
|
60
|
+
@gateway = :ftp if @gateway.empty?
|
61
|
+
raise ArgumentError, 'Gateway must be one of: ftp, ssh' unless %i[ftp ssh].include?(@gateway)
|
62
|
+
|
63
|
+
@mode = mode.to_s.to_sym
|
64
|
+
@mode = :plain if @mode.empty?
|
65
|
+
raise ArgumentError, 'Mode must be one of: plain, interactive' unless %i[plain interactive].include?(@mode)
|
66
|
+
|
67
|
+
@database = String(database) unless database.nil?
|
68
|
+
|
69
|
+
@command = command.to_s.to_sym
|
70
|
+
@command = :export_dump if @command.empty?
|
36
71
|
end
|
37
72
|
|
38
|
-
def
|
39
|
-
|
73
|
+
def to_s
|
74
|
+
ATTRS.map do |name|
|
75
|
+
value = public_send(name)
|
76
|
+
|
77
|
+
if %i[encryption_key gateway_password].include?(name)
|
78
|
+
" #{name} #{value.nil? ? '' : value[0..2] + '***'}"
|
79
|
+
else
|
80
|
+
" #{name} #{value}"
|
81
|
+
end
|
82
|
+
end.join("\n")
|
40
83
|
end
|
41
84
|
end
|
42
85
|
end
|
@@ -0,0 +1,126 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'pg_export/configuration'
|
5
|
+
|
6
|
+
class PgExport
|
7
|
+
class ConfigurationParser
|
8
|
+
class Error < OptionParser::ParseError; end
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def parse
|
12
|
+
h = {
|
13
|
+
encryption_key: ENV['PG_EXPORT_ENCRYPTION_KEY'],
|
14
|
+
encryption_algorithm: ENV['PG_EXPORT_ENCRYPTION_ALGORITHM'],
|
15
|
+
gateway_user: ENV['PG_EXPORT_GATEWAY_USER'],
|
16
|
+
gateway_host: ENV['PG_EXPORT_GATEWAY_HOST'],
|
17
|
+
gateway_password: ENV['PG_EXPORT_GATEWAY_PASSWORD'],
|
18
|
+
logger_format: ENV['PG_EXPORT_LOGGER_FORMAT'],
|
19
|
+
keep_dumps: ENV['PG_EXPORT_KEEP_DUMPS'],
|
20
|
+
gateway: ENV['PG_EXPORT_GATEWAY'],
|
21
|
+
database: ENV['PG_EXPORT_DATABASE'],
|
22
|
+
mode: ENV['PG_EXPORT_MODE'],
|
23
|
+
command: :export_dump
|
24
|
+
}
|
25
|
+
|
26
|
+
option_parser(h).parse!
|
27
|
+
h[:database] = ARGV.first unless ARGV.empty?
|
28
|
+
|
29
|
+
Configuration.new(**h)
|
30
|
+
rescue OptionParser::ParseError => e
|
31
|
+
error = Error.new(*e.args)
|
32
|
+
error.reason = e.reason
|
33
|
+
raise error
|
34
|
+
end
|
35
|
+
|
36
|
+
def help
|
37
|
+
option_parser.to_s
|
38
|
+
end
|
39
|
+
|
40
|
+
BANNER = <<~TXT
|
41
|
+
NAME
|
42
|
+
pg_export - CLI for exporting/importing PostgreSQL dumps via FTP/SSH
|
43
|
+
|
44
|
+
SYNOPSIS
|
45
|
+
pg_export DATABASE [OPTION..]
|
46
|
+
pg_export --interactive DATABASE [OPTION..]
|
47
|
+
|
48
|
+
EXIT VALUES
|
49
|
+
0 - Success
|
50
|
+
1 - Error
|
51
|
+
|
52
|
+
ARGUMENTS
|
53
|
+
DATABASE - database name to export (when default mode)
|
54
|
+
- phrase to filter database dumps by (when interactive mode)
|
55
|
+
|
56
|
+
OPTIONS
|
57
|
+
TXT
|
58
|
+
|
59
|
+
EXAMPLE = <<~TXT
|
60
|
+
ENV
|
61
|
+
Each of the above options can be also set using enviromental variables.
|
62
|
+
Use full option names prepending with PG_EXPORT_ phrase.
|
63
|
+
Command line options takes precedence over the ENVs.
|
64
|
+
|
65
|
+
Eg. below two commands are equivalent:
|
66
|
+
pg_export -s -U user -H host database_name -k 10
|
67
|
+
|
68
|
+
Is equivalent to:
|
69
|
+
export PG_EXPORT_GATEWAY_USER=user
|
70
|
+
export PG_EXPORT_GATEWAY_HOST=host
|
71
|
+
export PG_EXPORT_KEEP=20
|
72
|
+
pg_export -s database_name -k 10
|
73
|
+
TXT
|
74
|
+
|
75
|
+
N = "\n "
|
76
|
+
|
77
|
+
O = {
|
78
|
+
g: 'Allowed values: ftp, ssh. Default: ftp',
|
79
|
+
U: 'Gateway (ftp or ssh) user',
|
80
|
+
H: 'Gateway (ftp or ssh) host',
|
81
|
+
P: 'Gateway (ftp or ssh) password',
|
82
|
+
d: "In plain mode: database name to export;#{N}In interactive mode: phrase to filter by",
|
83
|
+
e: 'Dumps will be SSL encrypted using this key. Should have exactly 16 characters',
|
84
|
+
a: "Encryption cipher algorithm (default: AES-128-CBC);#{N}For available option see `$ openssl list -cipher-algorithms`",
|
85
|
+
k: 'Number of dump files to keep on FTP (default: 10)',
|
86
|
+
s: 'Same as "--gateway ssh". When set, the --gateway option is ignored',
|
87
|
+
f: 'Same as "--gateway ftp". When set, the --gateway option is ignored',
|
88
|
+
t: 'Prepends log messages with timestamps',
|
89
|
+
m: 'Mutes log messages. When set, the -t option is ignored. Prints message only on error',
|
90
|
+
i: 'Interactive mode, for importing dumps. Whan set, the -t and -m options are ignored',
|
91
|
+
w: 'Try connecting to the gateway (FTP or SSH) to verify the connection and exit',
|
92
|
+
c: 'Print the configuration and exit',
|
93
|
+
v: 'Print version',
|
94
|
+
h: 'Print this message and exit'
|
95
|
+
}.freeze
|
96
|
+
private_constant :BANNER, :EXAMPLE, :N, :O
|
97
|
+
|
98
|
+
def option_parser(h = {})
|
99
|
+
OptionParser.new do |o|
|
100
|
+
o.banner = BANNER
|
101
|
+
o.program_name = 'pg_export'
|
102
|
+
o.version = PgExport::VERSION
|
103
|
+
o.on('-g', '--gateway GATEWAY', %w[ftp ssh], O[:g]) { |v| h[:gateway] = v }
|
104
|
+
o.on('-U', '--user USER', String, O[:U]) { |v| h[:gateway_user] = v }
|
105
|
+
o.on('-H', '--host HOST', String, O[:H]) { |v| h[:gateway_host] = v }
|
106
|
+
o.on('-P', '--password PASSWORD', String, O[:P]) { |v| h[:gateway_password] = v }
|
107
|
+
o.on('-d', '--database DATABASE', String, O[:d]) { |v| h[:database] = v }
|
108
|
+
o.on('-e', '--encryption_key KEY', String, O[:e]) { |v| h[:encryption_key] = v }
|
109
|
+
o.on('-a', '--algorithm ALGORITHM', String, O[:a]) { |v| h[:encryption_algorithm] = v }
|
110
|
+
o.on('-k', '--keep KEEP', Integer, O[:k]) { |v| h[:keep_dumps] = v }
|
111
|
+
o.on('-s', '--ssh', O[:s]) { h[:gateway] = 'ssh' }
|
112
|
+
o.on('-f', '--ftp', O[:f]) { h[:gateway] = 'ftp' }
|
113
|
+
o.on('-t', '--timestamped', O[:t]) { h[:logger_format] = 'timestamped' }
|
114
|
+
o.on('-m', '--muted', O[:m]) { h[:logger_format] = 'muted' }
|
115
|
+
o.on('-i', '--interactive', O[:i]) { h[:command] = :import_dump_interactively }
|
116
|
+
o.on('-w', '--welcome', O[:w]) { h[:command] = :gateway_welcome }
|
117
|
+
o.on('-c', '--configuration', O[:c]) { h[:command] = :print_configuration }
|
118
|
+
o.on('-v', '--version', O[:v]) { h[:command] = :print_version }
|
119
|
+
o.on('-h', '--help', O[:h]) { h[:command] = :print_help }
|
120
|
+
o.separator ''
|
121
|
+
o.separator EXAMPLE
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class PgExport
|
4
|
+
module Entities
|
5
|
+
class Dump
|
6
|
+
attr_reader :name, :type, :database, :file
|
7
|
+
|
8
|
+
def initialize(name: nil, type: nil, database: nil, file: nil)
|
9
|
+
@name = String(name)
|
10
|
+
raise ArgumentError, 'Dump name must not be empty' if @name.empty?
|
11
|
+
raise ArgumentError, 'Dump name does not match criteria' unless /.+_20[0-9]{6}_[0-9]{6}\Z/.match?(@name)
|
12
|
+
|
13
|
+
@type = String(type)
|
14
|
+
@type = 'plain' if @type.empty?
|
15
|
+
raise ArgumentError, 'Dump type must be one of: plain, encrypted' unless %w[plain encrypted].include?(@type)
|
16
|
+
|
17
|
+
@database = database
|
18
|
+
|
19
|
+
@file = file
|
20
|
+
@file = ValueObjects::DumpFile.new if @file.nil?
|
21
|
+
raise ArgumentError, "Invalid file type: #{@file.class}" unless @file.is_a?(ValueObjects::DumpFile)
|
22
|
+
end
|
23
|
+
|
24
|
+
def encrypt(cipher_factory:)
|
25
|
+
self.file = file.copy(cipher: cipher_factory.encryptor)
|
26
|
+
self.type = :encrypted
|
27
|
+
|
28
|
+
self
|
29
|
+
end
|
30
|
+
|
31
|
+
def decrypt(cipher_factory:)
|
32
|
+
self.file = file.copy(cipher: cipher_factory.decryptor)
|
33
|
+
self.type = :plain
|
34
|
+
|
35
|
+
self
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_s
|
39
|
+
"#{name} (#{file.size_human})"
|
40
|
+
end
|
41
|
+
|
42
|
+
def file=(f)
|
43
|
+
@file = f
|
44
|
+
|
45
|
+
raise ArgumentError, "Invalid file type: '#{f}'" unless @file.is_a?(ValueObjects::DumpFile)
|
46
|
+
end
|
47
|
+
|
48
|
+
protected
|
49
|
+
|
50
|
+
def type=(t)
|
51
|
+
@type = t.to_s
|
52
|
+
|
53
|
+
raise ArgumentError, "Dump type '#{t}' must be one of: plain, encrypted" unless %w[plain encrypted].include?(@type)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -1,12 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'openssl'
|
4
|
-
require 'pg_export/import'
|
5
4
|
|
6
5
|
class PgExport
|
7
6
|
module Factories
|
8
7
|
class CipherFactory
|
9
|
-
|
8
|
+
def initialize(encryption_algorithm:, encryption_key:)
|
9
|
+
@encryption_algorithm = encryption_algorithm
|
10
|
+
@encryption_key = encryption_key
|
11
|
+
end
|
10
12
|
|
11
13
|
def encryptor
|
12
14
|
build_cipher(:encrypt)
|
@@ -18,10 +20,12 @@ class PgExport
|
|
18
20
|
|
19
21
|
private
|
20
22
|
|
23
|
+
attr_reader :encryption_algorithm, :encryption_key
|
24
|
+
|
21
25
|
def build_cipher(type)
|
22
|
-
cipher = OpenSSL::Cipher.new(
|
26
|
+
cipher = OpenSSL::Cipher.new(encryption_algorithm)
|
23
27
|
cipher.public_send(type)
|
24
|
-
cipher.key =
|
28
|
+
cipher.key = encryption_key
|
25
29
|
cipher
|
26
30
|
end
|
27
31
|
end
|
@@ -1,14 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
require 'pg_export/lib/pg_export/gateways/ftp'
|
6
|
-
require 'pg_export/import'
|
3
|
+
require 'pg_export/gateways/ftp'
|
7
4
|
|
8
5
|
class PgExport
|
9
6
|
module Factories
|
10
7
|
class FtpGatewayFactory
|
11
|
-
|
8
|
+
def initialize(config:)
|
9
|
+
@config = config
|
10
|
+
end
|
12
11
|
|
13
12
|
def gateway
|
14
13
|
::PgExport::Gateways::Ftp.new(
|
@@ -17,6 +16,10 @@ class PgExport
|
|
17
16
|
password: config.gateway_password
|
18
17
|
)
|
19
18
|
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_reader :config
|
20
23
|
end
|
21
24
|
end
|
22
25
|
end
|
@@ -1,13 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'open3'
|
4
|
-
require 'pg_export/
|
5
|
-
require 'pg_export/
|
6
|
-
require 'pg_export/lib/pg_export/value_objects/dump_file'
|
4
|
+
require 'pg_export/entities/dump'
|
5
|
+
require 'pg_export/value_objects/dump_file'
|
7
6
|
|
8
7
|
class PgExport
|
9
|
-
module
|
10
|
-
class
|
8
|
+
module Factories
|
9
|
+
class GatewayDumpFileFactory
|
11
10
|
def by_name(name:, gateway:)
|
12
11
|
file = ValueObjects::DumpFile.new
|
13
12
|
gateway.get(file, name)
|
@@ -1,14 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
require 'pg_export/lib/pg_export/gateways/ssh'
|
6
|
-
require 'pg_export/import'
|
3
|
+
require 'pg_export/gateways/ssh'
|
7
4
|
|
8
5
|
class PgExport
|
9
6
|
module Factories
|
10
7
|
class SshGatewayFactory
|
11
|
-
|
8
|
+
def initialize(config:)
|
9
|
+
@config = config
|
10
|
+
end
|
12
11
|
|
13
12
|
def gateway
|
14
13
|
::PgExport::Gateways::Ssh.new(
|
@@ -17,6 +16,10 @@ class PgExport
|
|
17
16
|
password: config.gateway_password
|
18
17
|
)
|
19
18
|
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_reader :config
|
20
23
|
end
|
21
24
|
end
|
22
25
|
end
|
@@ -1,13 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# auto_register: false
|
4
|
-
|
5
3
|
require 'net/ftp'
|
6
4
|
|
7
5
|
class PgExport
|
8
6
|
module Gateways
|
9
7
|
class Ftp
|
10
|
-
CHUNK_SIZE = (2**16)
|
8
|
+
CHUNK_SIZE = (2**16)
|
11
9
|
|
12
10
|
def initialize(host:, user:, password:)
|
13
11
|
@host, @user, @password, @logger = host, user, password
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# auto_register: false
|
4
|
-
|
5
3
|
require 'ed25519'
|
6
4
|
require 'net/ssh'
|
7
5
|
require 'net/scp'
|
@@ -9,8 +7,6 @@ require 'net/scp'
|
|
9
7
|
class PgExport
|
10
8
|
module Gateways
|
11
9
|
class Ssh
|
12
|
-
CHUNK_SIZE = (2**16).freeze
|
13
|
-
|
14
10
|
def initialize(host:, user:, password:)
|
15
11
|
@host, @user, @password, @logger = host, user, password
|
16
12
|
end
|
@@ -25,7 +21,7 @@ class PgExport
|
|
25
21
|
end
|
26
22
|
|
27
23
|
def welcome
|
28
|
-
open.exec!('hostname')
|
24
|
+
open.exec!('hostname; whoami')
|
29
25
|
end
|
30
26
|
|
31
27
|
def close
|
@@ -49,7 +45,7 @@ class PgExport
|
|
49
45
|
end
|
50
46
|
|
51
47
|
def delete(name)
|
52
|
-
#
|
48
|
+
ssh.exec!("rm #{name}")
|
53
49
|
end
|
54
50
|
|
55
51
|
def persist(file, name)
|
@@ -7,7 +7,7 @@ class PgExport
|
|
7
7
|
class Interactive
|
8
8
|
class BuildDump < InteractiveListener
|
9
9
|
def on_step(event)
|
10
|
-
@spinner = build_spinner("Dumping database #{event[:
|
10
|
+
@spinner = build_spinner("Dumping database #{event[:value][:database_name]}")
|
11
11
|
end
|
12
12
|
|
13
13
|
def on_step_succeeded(event)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -7,7 +7,7 @@ class PgExport
|
|
7
7
|
class Interactive
|
8
8
|
class RemoveOldDumps < InteractiveListener
|
9
9
|
def on_step(event)
|
10
|
-
@spinner = build_spinner("Checking for old dumps on #{event[:
|
10
|
+
@spinner = build_spinner("Checking for old dumps on #{event[:value][:gateway]}")
|
11
11
|
end
|
12
12
|
|
13
13
|
def on_step_succeeded(event)
|
@@ -7,7 +7,7 @@ class PgExport
|
|
7
7
|
class Interactive
|
8
8
|
class Restore < InteractiveListener
|
9
9
|
def on_step(event)
|
10
|
-
@spinner = build_spinner("Restoring dump to database #{event[:
|
10
|
+
@spinner = build_spinner("Restoring dump to database #{event[:value][:database]}")
|
11
11
|
end
|
12
12
|
|
13
13
|
def on_step_succeeded(*)
|
@@ -7,7 +7,7 @@ class PgExport
|
|
7
7
|
class Interactive
|
8
8
|
class UploadDump < InteractiveListener
|
9
9
|
def on_step(event)
|
10
|
-
@spinner = build_spinner("Uploading #{event[:
|
10
|
+
@spinner = build_spinner("Uploading #{event[:value][:dump]} to #{event[:value][:gateway]}")
|
11
11
|
end
|
12
12
|
|
13
13
|
def on_step_succeeded(*)
|
@@ -1,13 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# auto_register: false
|
4
|
-
|
5
|
-
require 'pg_export/import'
|
6
3
|
require 'tty-spinner'
|
7
4
|
|
8
5
|
class PgExport
|
9
6
|
module Listeners
|
10
7
|
class InteractiveListener
|
8
|
+
def on_step(*); end
|
9
|
+
|
10
|
+
def on_step_succeeded(*); end
|
11
|
+
|
11
12
|
def on_step_failed(event)
|
12
13
|
@spinner.error([error, self.class.red(event[:value][:message])].join("\n"))
|
13
14
|
end
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -1,17 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# auto_register: false
|
4
|
-
|
5
|
-
require 'pg_export/import'
|
6
|
-
|
7
3
|
class PgExport
|
8
4
|
module Listeners
|
9
5
|
class PlainListener
|
10
|
-
|
6
|
+
def initialize(logger:)
|
7
|
+
@logger = logger
|
8
|
+
end
|
9
|
+
|
10
|
+
def on_step(*); end
|
11
|
+
|
12
|
+
def on_step_succeeded(*); end
|
11
13
|
|
12
14
|
def on_step_failed(event)
|
13
15
|
logger.info("Error: #{event[:value][:message]}")
|
14
16
|
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_reader :logger
|
15
21
|
end
|
16
22
|
end
|
17
23
|
end
|