pg_export 0.7.7 → 1.0.0.rc5

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.
Files changed (62) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +6 -3
  4. data/CHANGELOG.md +11 -0
  5. data/README.md +14 -11
  6. data/bin/pg_export +92 -26
  7. data/lib/pg_export.rb +5 -13
  8. data/lib/pg_export/configuration.rb +18 -18
  9. data/lib/pg_export/container.rb +5 -30
  10. data/lib/pg_export/import.rb +1 -1
  11. data/lib/pg_export/lib/pg_export/factories/cipher_factory.rb +7 -10
  12. data/lib/pg_export/lib/pg_export/factories/ftp_gateway_factory.rb +22 -0
  13. data/lib/pg_export/lib/pg_export/factories/ssh_gateway_factory.rb +22 -0
  14. data/lib/pg_export/lib/pg_export/{adapters/ftp_adapter.rb → gateways/ftp.rb} +11 -8
  15. data/lib/pg_export/lib/pg_export/gateways/ssh.rb +83 -0
  16. data/lib/pg_export/lib/pg_export/listeners/interactive/build_dump.rb +4 -4
  17. data/lib/pg_export/lib/pg_export/listeners/interactive/{close_ftp_connection.rb → close_connection.rb} +1 -1
  18. data/lib/pg_export/lib/pg_export/listeners/interactive/decrypt_dump.rb +2 -2
  19. data/lib/pg_export/lib/pg_export/listeners/interactive/{download_dump_from_ftp.rb → download_dump.rb} +3 -3
  20. data/lib/pg_export/lib/pg_export/listeners/interactive/encrypt_dump.rb +2 -2
  21. data/lib/pg_export/lib/pg_export/listeners/interactive/{fetch_dumps_from_ftp.rb → fetch_dumps.rb} +1 -1
  22. data/lib/pg_export/lib/pg_export/listeners/interactive/{open_ftp_connection.rb → open_connection.rb} +2 -2
  23. data/lib/pg_export/lib/pg_export/listeners/interactive/{remove_old_dumps_from_ftp.rb → remove_old_dumps.rb} +6 -6
  24. data/lib/pg_export/lib/pg_export/listeners/interactive/restore.rb +2 -2
  25. data/lib/pg_export/lib/pg_export/listeners/interactive/select_database.rb +12 -0
  26. data/lib/pg_export/lib/pg_export/listeners/interactive/select_dump.rb +12 -0
  27. data/lib/pg_export/lib/pg_export/listeners/interactive/{upload_dump_to_ftp.rb → upload_dump.rb} +3 -3
  28. data/lib/pg_export/lib/pg_export/listeners/interactive_listener.rb +2 -2
  29. data/lib/pg_export/lib/pg_export/listeners/plain/build_dump.rb +2 -2
  30. data/lib/pg_export/lib/pg_export/listeners/plain/{close_ftp_connection.rb → close_connection.rb} +2 -2
  31. data/lib/pg_export/lib/pg_export/listeners/plain/decrypt_dump.rb +2 -2
  32. data/lib/pg_export/lib/pg_export/listeners/plain/{download_dump_from_ftp.rb → download_dump.rb} +3 -3
  33. data/lib/pg_export/lib/pg_export/listeners/plain/encrypt_dump.rb +2 -2
  34. data/lib/pg_export/lib/pg_export/listeners/plain/fetch_dumps.rb +15 -0
  35. data/lib/pg_export/lib/pg_export/listeners/plain/open_connection.rb +15 -0
  36. data/lib/pg_export/lib/pg_export/listeners/plain/prepare_params.rb +15 -0
  37. data/lib/pg_export/lib/pg_export/listeners/plain/remove_old_dumps.rb +17 -0
  38. data/lib/pg_export/lib/pg_export/listeners/plain/restore.rb +1 -1
  39. data/lib/pg_export/lib/pg_export/listeners/plain/upload_dump.rb +15 -0
  40. data/lib/pg_export/lib/pg_export/listeners/plain_listener.rb +2 -2
  41. data/lib/pg_export/lib/pg_export/operations/{open_ftp_connection.rb → open_connection.rb} +5 -5
  42. data/lib/pg_export/lib/pg_export/operations/{remove_old_dumps_from_ftp.rb → remove_old_dumps.rb} +7 -7
  43. data/lib/pg_export/lib/pg_export/repositories/{ftp_dump_file_repository.rb → gateway_dump_file_repository.rb} +3 -3
  44. data/lib/pg_export/lib/pg_export/repositories/{ftp_dump_repository.rb → gateway_dump_repository.rb} +7 -7
  45. data/lib/pg_export/lib/pg_export/transactions/export_dump.rb +10 -10
  46. data/lib/pg_export/lib/pg_export/transactions/import_dump_interactively.rb +19 -19
  47. data/lib/pg_export/system/boot/config.rb +17 -1
  48. data/lib/pg_export/system/boot/ftp.rb +11 -0
  49. data/lib/pg_export/system/boot/interactive.rb +4 -20
  50. data/lib/pg_export/system/boot/operations.rb +17 -0
  51. data/lib/pg_export/system/boot/plain.rb +3 -20
  52. data/lib/pg_export/system/boot/ssh.rb +11 -0
  53. data/lib/pg_export/version.rb +1 -1
  54. data/pg_export.gemspec +9 -5
  55. metadata +101 -39
  56. data/lib/pg_export/build_logger.rb +0 -21
  57. data/lib/pg_export/lib/pg_export/factories/ftp_adapter_factory.rb +0 -22
  58. data/lib/pg_export/lib/pg_export/listeners/plain/fetch_dumps_from_ftp.rb +0 -15
  59. data/lib/pg_export/lib/pg_export/listeners/plain/open_ftp_connection.rb +0 -15
  60. data/lib/pg_export/lib/pg_export/listeners/plain/remove_old_dumps_from_ftp.rb +0 -17
  61. data/lib/pg_export/lib/pg_export/listeners/plain/upload_dump_to_ftp.rb +0 -15
  62. data/lib/pg_export/system/boot/logger.rb +0 -15
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ # auto_register: false
4
+
5
+ require 'pg_export/lib/pg_export/gateways/ftp'
6
+ require 'pg_export/import'
7
+
8
+ class PgExport
9
+ module Factories
10
+ class FtpGatewayFactory
11
+ include Import['config']
12
+
13
+ def gateway
14
+ ::PgExport::Gateways::Ftp.new(
15
+ host: config.gateway_host,
16
+ user: config.gateway_user,
17
+ password: config.gateway_password
18
+ )
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ # auto_register: false
4
+
5
+ require 'pg_export/lib/pg_export/gateways/ssh'
6
+ require 'pg_export/import'
7
+
8
+ class PgExport
9
+ module Factories
10
+ class SshGatewayFactory
11
+ include Import['config']
12
+
13
+ def gateway
14
+ ::PgExport::Gateways::Ssh.new(
15
+ host: config.gateway_host,
16
+ user: config.gateway_user,
17
+ password: config.gateway_password
18
+ )
19
+ end
20
+ end
21
+ end
22
+ end
@@ -5,28 +5,31 @@
5
5
  require 'net/ftp'
6
6
 
7
7
  class PgExport
8
- module Adapters
9
- class FtpAdapter
8
+ module Gateways
9
+ class Ftp
10
10
  CHUNK_SIZE = (2**16).freeze
11
11
 
12
12
  def initialize(host:, user:, password:)
13
13
  @host, @user, @password, @logger = host, user, password
14
- ObjectSpace.define_finalizer(self, proc { ftp.close if @ftp })
15
14
  end
16
15
 
17
- def open_ftp
16
+ def open
18
17
  @ftp = Net::FTP.new(host, user, password)
19
18
  @ftp.passive = true
20
19
  @ftp
21
20
  end
22
21
 
23
- def close_ftp
22
+ def welcome
23
+ open.welcome
24
+ end
25
+
26
+ def close
24
27
  @ftp&.close
25
28
  end
26
29
 
27
- def list(regex_string)
30
+ def list(name)
28
31
  ftp
29
- .list(regex_string)
32
+ .list([name, '*'].join('_'))
30
33
  .map { |row| extracted_meaningful_attributes(row) }
31
34
  .sort_by { |item| item[:name] }
32
35
  .reverse
@@ -49,7 +52,7 @@ class PgExport
49
52
  end
50
53
 
51
54
  def ftp
52
- @ftp ||= open_ftp
55
+ @ftp ||= open
53
56
  end
54
57
 
55
58
  private
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ # auto_register: false
4
+
5
+ require 'ed25519'
6
+ require 'net/ssh'
7
+ require 'net/scp'
8
+
9
+ class PgExport
10
+ module Gateways
11
+ class Ssh
12
+ CHUNK_SIZE = (2**16).freeze
13
+
14
+ def initialize(host:, user:, password:)
15
+ @host, @user, @password, @logger = host, user, password
16
+ end
17
+
18
+ def open
19
+ @ssh =
20
+ if password.nil?
21
+ Net::SSH.start(host, user)
22
+ else
23
+ Net::SSH.start(host, user, password)
24
+ end
25
+ end
26
+
27
+ def welcome
28
+ open.exec!('hostname')
29
+ end
30
+
31
+ def close
32
+ @ssh&.close
33
+ end
34
+
35
+ def list(name)
36
+ grep =
37
+ if name.nil? || name.empty?
38
+ ''
39
+ else
40
+ " | grep #{name}"
41
+ end
42
+
43
+ ssh
44
+ .exec!("ls -l#{grep}")
45
+ .split("\n").map { |row| extract_meaningful_attributes(row) }
46
+ .reject { |item| item[:name].nil? }
47
+ .sort_by { |item| item[:name] }
48
+ .reverse
49
+ end
50
+
51
+ def delete(name)
52
+ # @TODO
53
+ end
54
+
55
+ def persist(file, name)
56
+ ssh.scp.upload(file.path, name).wait
57
+ end
58
+
59
+ def get(file, name)
60
+ ssh.scp.download(name, file.path).wait
61
+ end
62
+
63
+ def to_s
64
+ host
65
+ end
66
+
67
+ def ssh
68
+ @ssh ||= open
69
+ end
70
+
71
+ private
72
+
73
+ attr_reader :host, :user, :password
74
+
75
+ def extract_meaningful_attributes(item)
76
+ MEANINGFUL_KEYS.zip(item.split(' ').values_at(8, 4)).to_h
77
+ end
78
+
79
+ MEANINGFUL_KEYS = %i[name size].freeze
80
+ private_constant :MEANINGFUL_KEYS
81
+ end
82
+ end
83
+ end
@@ -6,12 +6,12 @@ class PgExport
6
6
  module Listeners
7
7
  class Interactive
8
8
  class BuildDump < InteractiveListener
9
- def on_step(step_name:, args:)
10
- @spinner = build_spinner("Dumping database #{args.first[:database_name]}")
9
+ def on_step(event)
10
+ @spinner = build_spinner("Dumping database #{event[:args].first[:database_name]}")
11
11
  end
12
12
 
13
- def on_step_succeeded(step_name:, args:, value:)
14
- @spinner.success([success, value[:dump]].join(' '))
13
+ def on_step_succeeded(event)
14
+ @spinner.success([success, event[:value][:dump]].join(' '))
15
15
  end
16
16
  end
17
17
  end
@@ -5,7 +5,7 @@ require_relative '../interactive_listener'
5
5
  class PgExport
6
6
  module Listeners
7
7
  class Interactive
8
- class CloseFtpConnection < InteractiveListener
8
+ class CloseConnection < InteractiveListener
9
9
  def on_step(*)
10
10
  @spinner = build_spinner('Closing FTP')
11
11
  end
@@ -10,8 +10,8 @@ class PgExport
10
10
  @spinner = build_spinner('Decrypting')
11
11
  end
12
12
 
13
- def on_step_succeeded(step_name:, args:, value:)
14
- @spinner.success([success, value[:dump]].join(' '))
13
+ def on_step_succeeded(event)
14
+ @spinner.success([success, event[:value][:dump]].join(' '))
15
15
  end
16
16
  end
17
17
  end
@@ -5,13 +5,13 @@ require_relative '../interactive_listener'
5
5
  class PgExport
6
6
  module Listeners
7
7
  class Interactive
8
- class DownloadDumpFromFtp < InteractiveListener
8
+ class DownloadDump < InteractiveListener
9
9
  def on_step(*)
10
10
  @spinner = build_spinner('Downloading')
11
11
  end
12
12
 
13
- def on_step_succeeded(step_name:, args:, value:)
14
- @spinner.success([success, value[:dump]].join(' '))
13
+ def on_step_succeeded(event)
14
+ @spinner.success([success, event[:value][:dump]].join(' '))
15
15
  end
16
16
  end
17
17
  end
@@ -10,8 +10,8 @@ class PgExport
10
10
  @spinner = build_spinner('Encrypting')
11
11
  end
12
12
 
13
- def on_step_succeeded(step_name:, args:, value:)
14
- @spinner.success([success, value[:dump]].join(' '))
13
+ def on_step_succeeded(event)
14
+ @spinner.success([success, event[:value][:dump]].join(' '))
15
15
  end
16
16
  end
17
17
  end
@@ -5,7 +5,7 @@ require_relative '../interactive_listener'
5
5
  class PgExport
6
6
  module Listeners
7
7
  class Interactive
8
- class FetchDumpsFromFtp < InteractiveListener
8
+ class FetchDumps < InteractiveListener
9
9
  def on_step(*)
10
10
  @spinner = build_spinner('Fetching dumps')
11
11
  end
@@ -5,9 +5,9 @@ require_relative '../interactive_listener'
5
5
  class PgExport
6
6
  module Listeners
7
7
  class Interactive
8
- class OpenFtpConnection < InteractiveListener
8
+ class OpenConnection < InteractiveListener
9
9
  def on_step(*)
10
- @spinner = build_spinner('Opening ftp connection')
10
+ @spinner = build_spinner('Opening connection')
11
11
  end
12
12
 
13
13
  def on_step_succeeded(*)
@@ -5,14 +5,14 @@ require_relative '../interactive_listener'
5
5
  class PgExport
6
6
  module Listeners
7
7
  class Interactive
8
- class RemoveOldDumpsFromFtp < InteractiveListener
9
- def on_step(step_name:, args:)
10
- @spinner = build_spinner("Checking for old dumps on #{args.first[:ftp_adapter]}")
8
+ class RemoveOldDumps < InteractiveListener
9
+ def on_step(event)
10
+ @spinner = build_spinner("Checking for old dumps on #{event[:args].first[:gateway]}")
11
11
  end
12
12
 
13
- def on_step_succeeded(step_name:, args:, value:)
14
- if value[:removed_dumps].any?
15
- @spinner.success([success, value[:removed_dumps].map { |filename| " #{filename} removed" }].join("\n"))
13
+ def on_step_succeeded(event)
14
+ if event[:value][:removed_dumps].any?
15
+ @spinner.success([success, event[:value][:removed_dumps].map { |filename| " #{filename} removed" }].join("\n"))
16
16
  else
17
17
  @spinner.success([success, 'nothing to remove'].join(' '))
18
18
  end
@@ -6,8 +6,8 @@ class PgExport
6
6
  module Listeners
7
7
  class Interactive
8
8
  class Restore < InteractiveListener
9
- def on_step(step_name:, args:)
10
- @spinner = build_spinner("Restoring dump to database #{args.first[:database]}")
9
+ def on_step(event)
10
+ @spinner = build_spinner("Restoring dump to database #{event[:args].first[:database]}")
11
11
  end
12
12
 
13
13
  def on_step_succeeded(*)
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../interactive_listener'
4
+
5
+ class PgExport
6
+ module Listeners
7
+ class Interactive
8
+ class SelectDatabase < InteractiveListener
9
+ end
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../interactive_listener'
4
+
5
+ class PgExport
6
+ module Listeners
7
+ class Interactive
8
+ class SelectDump < InteractiveListener
9
+ end
10
+ end
11
+ end
12
+ end
@@ -5,9 +5,9 @@ require_relative '../interactive_listener'
5
5
  class PgExport
6
6
  module Listeners
7
7
  class Interactive
8
- class UploadDumpToFtp < InteractiveListener
9
- def on_step(step_name:, args:)
10
- @spinner = build_spinner("Uploading #{args.first[:dump]} to #{args.first[:ftp_adapter]}")
8
+ class UploadDump < InteractiveListener
9
+ def on_step(event)
10
+ @spinner = build_spinner("Uploading #{event[:args].first[:dump]} to #{event[:args].first[:gateway]}")
11
11
  end
12
12
 
13
13
  def on_step_succeeded(*)
@@ -8,8 +8,8 @@ require 'tty-spinner'
8
8
  class PgExport
9
9
  module Listeners
10
10
  class InteractiveListener
11
- def on_step_failed(step_name:, args:, value:)
12
- @spinner.error([error, self.class.red(value[:message])].join("\n"))
11
+ def on_step_failed(event)
12
+ @spinner.error([error, self.class.red(event[:value][:message])].join("\n"))
13
13
  end
14
14
 
15
15
  class << self
@@ -6,8 +6,8 @@ class PgExport
6
6
  module Listeners
7
7
  class Plain
8
8
  class BuildDump < PlainListener
9
- def on_step_succeeded(step_name:, args:, value:)
10
- logger.info("Dump database #{value[:dump].database} to #{value[:dump]}")
9
+ def on_step_succeeded(event)
10
+ logger.info("Dump database #{event[:value][:dump].database} to #{event[:value][:dump]}")
11
11
  end
12
12
  end
13
13
  end
@@ -5,9 +5,9 @@ require_relative '../plain_listener'
5
5
  class PgExport
6
6
  module Listeners
7
7
  class Plain
8
- class CloseFtpConnection < PlainListener
8
+ class CloseConnection < PlainListener
9
9
  def on_step_succeeded(*)
10
- logger.info('Close FTP')
10
+ logger.info('Close connection')
11
11
  end
12
12
  end
13
13
  end
@@ -6,8 +6,8 @@ class PgExport
6
6
  module Listeners
7
7
  class Plain
8
8
  class DecryptDump < PlainListener
9
- def on_step_succeeded(step_name:, args:, value:)
10
- logger.info("Decrypt #{value[:dump]}")
9
+ def on_step_succeeded(event)
10
+ logger.info("Decrypt #{event[:value][:dump]}")
11
11
  end
12
12
  end
13
13
  end
@@ -5,9 +5,9 @@ require_relative '../plain_listener'
5
5
  class PgExport
6
6
  module Listeners
7
7
  class Plain
8
- class DownloadDumpFromFtp < PlainListener
9
- def on_step_succeeded(step_name:, args:, value:)
10
- logger.info("Download #{value[:dump]}")
8
+ class DownloadDump < PlainListener
9
+ def on_step_succeeded(event)
10
+ logger.info("Download #{event[:value][:dump]}")
11
11
  end
12
12
  end
13
13
  end
@@ -6,8 +6,8 @@ class PgExport
6
6
  module Listeners
7
7
  class Plain
8
8
  class EncryptDump < PlainListener
9
- def on_step_succeeded(step_name:, args:, value:)
10
- logger.info("Encrypt #{value[:dump]}")
9
+ def on_step_succeeded(event)
10
+ logger.info("Encrypt #{event[:value][:dump]}")
11
11
  end
12
12
  end
13
13
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../plain_listener'
4
+
5
+ class PgExport
6
+ module Listeners
7
+ class Plain
8
+ class FetchDumps < PlainListener
9
+ def on_step_succeeded(event)
10
+ logger.info("Fetch dumps (#{event[:value][:dumps].count} items)")
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../plain_listener'
4
+
5
+ class PgExport
6
+ module Listeners
7
+ class Plain
8
+ class OpenConnection < PlainListener
9
+ def on_step_succeeded(event)
10
+ logger.info("Connect to #{event[:value][:gateway]}")
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end