pgdump_scrambler 0.4.0 → 0.5.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/.github/workflows/main.yml +40 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +45 -1
- data/CHANGELOG.md +11 -0
- data/Gemfile +13 -2
- data/Gemfile.lock +148 -101
- data/README.md +1 -1
- data/Rakefile +5 -3
- data/bin/console +4 -3
- data/bin/pgdump-obfuscator +7 -3
- data/lib/config/table.rb +8 -10
- data/lib/pgdump_scrambler/config.rb +31 -30
- data/lib/pgdump_scrambler/dumper.rb +26 -18
- data/lib/pgdump_scrambler/railtie.rb +2 -1
- data/lib/pgdump_scrambler/s3_request.rb +31 -36
- data/lib/pgdump_scrambler/s3_uploader.rb +17 -8
- data/lib/pgdump_scrambler/utils.rb +21 -0
- data/lib/pgdump_scrambler/version.rb +2 -1
- data/lib/pgdump_scrambler.rb +6 -7
- data/lib/tasks/pgdump_scrambler_tasks.rake +8 -6
- data/pgdump_scrambler.gemspec +17 -24
- metadata +13 -67
- data/.rubocop_todo.yml +0 -173
- data/.ruby-version +0 -1
- data/.travis.yml +0 -5
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'yaml'
|
3
4
|
require 'erb'
|
4
5
|
require 'set'
|
@@ -19,14 +20,14 @@ module PgdumpScrambler
|
|
19
20
|
'prefix' => 'YOUR_S3_PATH_PREFIX',
|
20
21
|
'access_key_id' => "<%= ENV['AWS_ACCESS_KEY_ID'] %>",
|
21
22
|
'secret_key' => "<%= ENV['AWS_SECRET_KEY'] %>"
|
22
|
-
}
|
23
|
+
}.freeze
|
23
24
|
attr_reader :dump_path, :s3, :resolved_s3, :exclude_tables, :pgdump_args
|
24
25
|
|
25
|
-
def initialize(tables, dump_path, s3, exclude_tables, pgdump_args)
|
26
|
-
@table_hash = tables.sort_by(&:name).
|
26
|
+
def initialize(tables, dump_path, s3, exclude_tables, pgdump_args) # rubocop:disable Naming/MethodParameterName
|
27
|
+
@table_hash = tables.sort_by(&:name).to_h { |table| [table.name, table] }
|
27
28
|
@dump_path = dump_path
|
28
29
|
@s3 = s3
|
29
|
-
@resolved_s3 = s3.
|
30
|
+
@resolved_s3 = s3.transform_values { |v| ERB.new(v).result } if s3
|
30
31
|
@exclude_tables = exclude_tables
|
31
32
|
@pgdump_args = pgdump_args
|
32
33
|
end
|
@@ -45,7 +46,7 @@ module PgdumpScrambler
|
|
45
46
|
|
46
47
|
def update_with(other)
|
47
48
|
new_tables = @table_hash.map do |_, table|
|
48
|
-
if other_table = other.table(table.name)
|
49
|
+
if (other_table = other.table(table.name))
|
49
50
|
table.update_with(other_table)
|
50
51
|
else
|
51
52
|
table
|
@@ -66,15 +67,15 @@ module PgdumpScrambler
|
|
66
67
|
yml = {}
|
67
68
|
yml[KEY_DUMP_PATH] = @dump_path
|
68
69
|
yml[KEY_S3] = @s3 if @s3
|
69
|
-
yml[KEY_EXCLUDE_TABLES] = @exclude_tables if @exclude_tables.size
|
70
|
+
yml[KEY_EXCLUDE_TABLES] = @exclude_tables if @exclude_tables.size.positive?
|
70
71
|
yml[KEY_TABLES] = @table_hash.map do |_, table|
|
71
72
|
columns = table.columns
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
]
|
77
|
-
|
73
|
+
next if columns.empty?
|
74
|
+
|
75
|
+
[
|
76
|
+
table.name,
|
77
|
+
columns.to_h { |column| [column.name, column.scramble_method] }
|
78
|
+
]
|
78
79
|
end.compact.to_h
|
79
80
|
YAML.dump(yml, io)
|
80
81
|
end
|
@@ -92,21 +93,22 @@ module PgdumpScrambler
|
|
92
93
|
class << self
|
93
94
|
def read(io)
|
94
95
|
yml = YAML.safe_load(io, permitted_classes: [], permitted_symbols: [], aliases: true)
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
96
|
+
tables =
|
97
|
+
if yml[KEY_TABLES]
|
98
|
+
yml[KEY_TABLES].map do |table_name, columns|
|
99
|
+
Table.new(
|
100
|
+
table_name,
|
101
|
+
columns.map { |name, scramble_method| Column.new(name, scramble_method) }
|
102
|
+
)
|
103
|
+
end
|
104
|
+
else
|
105
|
+
[]
|
101
106
|
end
|
102
|
-
else
|
103
|
-
tables = []
|
104
|
-
end
|
105
107
|
Config.new(tables, yml[KEY_DUMP_PATH], yml[KEY_S3], yml[KEY_EXCLUDE_TABLES] || [], yml[KEY_PGDUMP_ARGS])
|
106
108
|
end
|
107
109
|
|
108
110
|
def read_file(path)
|
109
|
-
open(path, 'r') do |f|
|
111
|
+
File.open(path, 'r') do |f|
|
110
112
|
read(f)
|
111
113
|
end
|
112
114
|
end
|
@@ -118,18 +120,17 @@ module PgdumpScrambler
|
|
118
120
|
else
|
119
121
|
Rails.application.eager_load!
|
120
122
|
end
|
121
|
-
klasses_by_table = ActiveRecord::Base.descendants.
|
123
|
+
klasses_by_table = ActiveRecord::Base.descendants.to_h { |klass| [klass.table_name, klass] }
|
122
124
|
table_names = ActiveRecord::Base.connection.tables.sort - IGNORED_ACTIVE_RECORD_TABLES
|
123
125
|
tables = table_names.map do |table_name|
|
124
126
|
klass = klasses_by_table[table_name]
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
Column.new(name)
|
130
|
-
end
|
131
|
-
Table.new(table_name, columns)
|
127
|
+
next unless klass
|
128
|
+
|
129
|
+
column_names = klass.columns.map(&:name).reject do |name|
|
130
|
+
IGNORED_ACTIVE_RECORD_COLUMNS.member?(name)
|
132
131
|
end
|
132
|
+
columns = column_names.map { |name| Column.new(name) }
|
133
|
+
Table.new(table_name, columns)
|
133
134
|
end.compact
|
134
135
|
Config.new(tables, 'scrambled.dump.gz', Config::DEFAULT_S3_PROPERTIES, [], nil)
|
135
136
|
end
|
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pgdump_scrambler/utils'
|
2
4
|
require 'open3'
|
5
|
+
|
3
6
|
module PgdumpScrambler
|
4
7
|
class Dumper
|
5
8
|
def initialize(config, db_config = {})
|
@@ -9,48 +12,53 @@ module PgdumpScrambler
|
|
9
12
|
end
|
10
13
|
|
11
14
|
def run
|
12
|
-
puts
|
15
|
+
puts 'Executing pg_dump...'
|
13
16
|
puts full_command
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
raise "pg_dump failed!"
|
18
|
-
end
|
17
|
+
raise 'pg_dump failed!' unless system(env_vars, full_command)
|
18
|
+
|
19
|
+
puts 'Done!'
|
19
20
|
end
|
20
21
|
|
21
22
|
private
|
22
23
|
|
24
|
+
def env_vars
|
25
|
+
vars = {}
|
26
|
+
vars['PGPASSWORD'] = @db_config['password'] if @db_config['password']
|
27
|
+
vars
|
28
|
+
end
|
29
|
+
|
23
30
|
def full_command
|
24
31
|
[pgdump_command, obfuscator_command, 'gzip -c'].compact.join(' | ') + "> #{@output_path}"
|
25
32
|
end
|
26
33
|
|
27
34
|
def obfuscator_command
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
35
|
+
return unless (options = @config.obfuscator_options)
|
36
|
+
|
37
|
+
command = File.expand_path('../../bin/pgdump-obfuscator', __dir__)
|
38
|
+
"#{command} #{options}"
|
32
39
|
end
|
33
40
|
|
34
41
|
def pgdump_command
|
35
42
|
command = []
|
36
|
-
command << "PGPASSWORD=#{Shellwords.escape(@db_config['password'])}" if @db_config['password']
|
37
43
|
command << 'pg_dump'
|
38
44
|
command << @config.pgdump_args if @config.pgdump_args
|
39
45
|
command << "--username=#{Shellwords.escape(@db_config['username'])}" if @db_config['username']
|
40
46
|
command << "--host='#{@db_config['host']}'" if @db_config['host']
|
41
47
|
command << "--port='#{@db_config['port']}'" if @db_config['port']
|
42
|
-
|
48
|
+
if @config.exclude_tables.present?
|
49
|
+
command << @config.exclude_tables.map do |exclude_table|
|
50
|
+
"--exclude-table-data=#{exclude_table}"
|
51
|
+
end.join(' ')
|
52
|
+
end
|
43
53
|
command << @db_config['database']
|
44
54
|
command.join(' ')
|
45
55
|
end
|
46
56
|
|
47
57
|
def load_database_yml
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
db_config[Rails.env]
|
53
|
-
end
|
58
|
+
return unless defined?(Rails)
|
59
|
+
|
60
|
+
db_config = Utils.load_yaml_with_erb(Rails.root.join('config', 'database.yml'))
|
61
|
+
db_config[Rails.env]
|
54
62
|
end
|
55
63
|
end
|
56
64
|
end
|
@@ -1,8 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module PgdumpScrambler
|
3
4
|
class Railtie < ::Rails::Railtie
|
4
5
|
rake_tasks do
|
5
|
-
load File.expand_path('
|
6
|
+
load File.expand_path('../tasks/pgdump_scrambler_tasks.rake', __dir__)
|
6
7
|
end
|
7
8
|
end
|
8
9
|
end
|
@@ -1,11 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'uri'
|
3
4
|
require 'digest'
|
4
5
|
require 'openssl'
|
5
6
|
|
6
7
|
module PgdumpScrambler
|
7
8
|
class S3Request
|
8
|
-
def initialize(s3_path:, verb:, region:, bucket:, access_key_id:, secret_key:, time: nil)
|
9
|
+
def initialize(s3_path:, verb:, region:, bucket:, access_key_id:, secret_key:, time: nil) # rubocop:disable Metrics/ParameterLists
|
9
10
|
@s3_path = s3_path.start_with?('/') ? s3_path : "/#{s3_path}"
|
10
11
|
@verb = verb
|
11
12
|
@time = time || Time.now.utc
|
@@ -18,7 +19,7 @@ module PgdumpScrambler
|
|
18
19
|
def canonical_request
|
19
20
|
[
|
20
21
|
@verb,
|
21
|
-
|
22
|
+
self.class.uri_encode(@s3_path),
|
22
23
|
canonical_query_string,
|
23
24
|
"host:#{@bucket}.s3.amazonaws.com\n", # canonical headers
|
24
25
|
'host', # signed headers
|
@@ -38,13 +39,15 @@ module PgdumpScrambler
|
|
38
39
|
end
|
39
40
|
|
40
41
|
def url
|
41
|
-
|
42
|
+
encoded_path = self.class.uri_encode(@s3_path)
|
43
|
+
File.join("https://#{@bucket}.s3.amazonaws.com/",
|
44
|
+
"#{encoded_path}?#{canonical_query_string}&X-Amz-Signature=#{signature}")
|
42
45
|
end
|
43
46
|
|
44
47
|
private
|
45
48
|
|
46
49
|
def iso_time
|
47
|
-
@time.strftime(
|
50
|
+
@time.strftime('%Y%m%dT%H%M%SZ')
|
48
51
|
end
|
49
52
|
|
50
53
|
def iso_date
|
@@ -52,15 +55,17 @@ module PgdumpScrambler
|
|
52
55
|
end
|
53
56
|
|
54
57
|
def hmac_sha256(key, message)
|
55
|
-
OpenSSL::HMAC.digest(OpenSSL::Digest
|
58
|
+
OpenSSL::HMAC.digest(OpenSSL::Digest.new('SHA256'), key, message)
|
56
59
|
end
|
57
60
|
|
58
61
|
def hmac_sha256_hex(key, message)
|
59
|
-
OpenSSL::HMAC.hexdigest(OpenSSL::Digest
|
62
|
+
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('SHA256'), key, message)
|
60
63
|
end
|
61
64
|
|
62
65
|
def canonical_query_string
|
66
|
+
# rubocop:disable Layout/LineLength
|
63
67
|
"X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=#{@access_key_id}%2F#{iso_date}%2F#{@region}%2Fs3%2Faws4_request&X-Amz-Date=#{iso_time}&X-Amz-Expires=86400&X-Amz-SignedHeaders=host"
|
68
|
+
# rubocop:enable Layout/LineLength
|
64
69
|
end
|
65
70
|
|
66
71
|
def string_to_sign
|
@@ -68,39 +73,29 @@ module PgdumpScrambler
|
|
68
73
|
'AWS4-HMAC-SHA256',
|
69
74
|
iso_time,
|
70
75
|
"#{iso_date}/#{@region}/s3/aws4_request",
|
71
|
-
Digest::SHA256.hexdigest(canonical_request)
|
76
|
+
Digest::SHA256.hexdigest(canonical_request)
|
72
77
|
].join("\n")
|
73
78
|
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
if $0 == __FILE__
|
78
|
-
# https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html
|
79
|
-
require "minitest/autorun"
|
80
|
-
class TestS3Request < Minitest::Test
|
81
|
-
def setup
|
82
|
-
@s3_request = PgdumpScrambler::S3Request.new(verb: 'GET', s3_path: '/test.txt', region: 'us-east-1', bucket: 'examplebucket', access_key_id: 'AKIAIOSFODNN7EXAMPLE', secret_key: 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY', time: Time.utc(2013, 5, 24, 0, 0, 0))
|
83
|
-
end
|
84
|
-
|
85
|
-
def test_canonical_request
|
86
|
-
assert_equal <<~EOS.chomp, @s3_request.canonical_request
|
87
|
-
GET
|
88
|
-
/test.txt
|
89
|
-
X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20130524%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20130524T000000Z&X-Amz-Expires=86400&X-Amz-SignedHeaders=host
|
90
|
-
host:examplebucket.s3.amazonaws.com
|
91
|
-
|
92
|
-
host
|
93
|
-
UNSIGNED-PAYLOAD
|
94
|
-
EOS
|
95
|
-
end
|
96
|
-
|
97
|
-
def test_signature
|
98
|
-
assert_equal 'aeeed9bbccd4d02ee5c0109b86d86835f995330da4c265957d157751f604d404', @s3_request.signature
|
99
|
-
end
|
100
79
|
|
101
|
-
|
102
|
-
|
103
|
-
|
80
|
+
class << self
|
81
|
+
# https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html
|
82
|
+
# * URI encode every byte except the unreserved characters: 'A'-'Z', 'a'-'z', '0'-'9', '-', '.', '_', and '~'.
|
83
|
+
# * The space character is a reserved character and must be encoded as "%20" (and not as "+").
|
84
|
+
# * Each URI encoded byte is formed by a '%' and the two-digit hexadecimal value of the byte.
|
85
|
+
# * Letters in the hexadecimal value must be uppercase, for example "%1A".
|
86
|
+
# * Encode the forward slash character, '/', everywhere except in the object key name.
|
87
|
+
# For example, if the object key name is photos/Jan/sample.jpg,
|
88
|
+
# the forward slash in the key name is not encoded.
|
89
|
+
def uri_encode(str)
|
90
|
+
str.gsub(%r{[^A-Za-z0-9\-._~/]}) do
|
91
|
+
us = Regexp.last_match(0)
|
92
|
+
tmp = +''
|
93
|
+
us.each_byte do |uc|
|
94
|
+
tmp << sprintf('%%%02X', uc)
|
95
|
+
end
|
96
|
+
tmp
|
97
|
+
end.force_encoding(Encoding::US_ASCII)
|
98
|
+
end
|
104
99
|
end
|
105
100
|
end
|
106
101
|
end
|
@@ -1,11 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'net/http'
|
3
4
|
require 'uri'
|
4
|
-
require_relative '
|
5
|
+
require_relative 's3_request'
|
5
6
|
|
6
7
|
module PgdumpScrambler
|
7
8
|
class S3UploadError < StandardError
|
8
9
|
attr_reader :response
|
10
|
+
|
9
11
|
def initialize(response)
|
10
12
|
@response = response
|
11
13
|
super "S3 upload failed: #{response.body}"
|
@@ -13,17 +15,25 @@ module PgdumpScrambler
|
|
13
15
|
end
|
14
16
|
|
15
17
|
class S3Uploader
|
16
|
-
def initialize(s3_path:, local_path:, region:, bucket:, access_key_id:, secret_key:)
|
18
|
+
def initialize(s3_path:, local_path:, region:, bucket:, access_key_id:, secret_key:) # rubocop:disable Metrics/ParameterLists
|
17
19
|
raise 'missing access_key_id' if access_key_id.nil? || access_key_id.empty?
|
18
20
|
raise 'missing secret_key' if secret_key.nil? || secret_key.empty?
|
19
|
-
|
21
|
+
|
22
|
+
@s3_request = S3Request.new(
|
23
|
+
s3_path: s3_path,
|
24
|
+
verb: 'PUT',
|
25
|
+
region: region,
|
26
|
+
bucket: bucket,
|
27
|
+
access_key_id: access_key_id,
|
28
|
+
secret_key: secret_key
|
29
|
+
)
|
20
30
|
@local_path = local_path
|
21
31
|
end
|
22
32
|
|
23
33
|
def run
|
24
34
|
uri = URI.parse(@s3_request.url)
|
25
|
-
puts "
|
26
|
-
open(@local_path, 'r') do |io|
|
35
|
+
puts "Uploading #{@local_path} to #{uri.host}#{uri.path}"
|
36
|
+
File.open(@local_path, 'r') do |io|
|
27
37
|
uri_path = uri.path
|
28
38
|
uri_path += "?#{uri.query}" if uri.query
|
29
39
|
req = Net::HTTP::Put.new(uri_path)
|
@@ -33,10 +43,9 @@ module PgdumpScrambler
|
|
33
43
|
http = Net::HTTP.new(uri.host, uri.port)
|
34
44
|
http.use_ssl = true
|
35
45
|
res = http.request(req)
|
36
|
-
if res.code != '200'
|
37
|
-
raise S3UploadError.new(res)
|
38
|
-
end
|
46
|
+
raise S3UploadError, res if res.code != '200'
|
39
47
|
end
|
48
|
+
puts 'Done.'
|
40
49
|
end
|
41
50
|
end
|
42
51
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'erb'
|
5
|
+
|
6
|
+
module PgdumpScrambler
|
7
|
+
module Utils
|
8
|
+
module_function
|
9
|
+
|
10
|
+
def load_yaml_with_erb(path)
|
11
|
+
yaml_content = File.read(path)
|
12
|
+
resolved = ERB.new(yaml_content).result
|
13
|
+
YAML.safe_load(
|
14
|
+
resolved,
|
15
|
+
permitted_classes: [],
|
16
|
+
permitted_symbols: [],
|
17
|
+
aliases: true
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/pgdump_scrambler.rb
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
|
7
|
-
|
8
|
-
end
|
2
|
+
|
3
|
+
require 'pgdump_scrambler/version'
|
4
|
+
require 'pgdump_scrambler/config'
|
5
|
+
require 'pgdump_scrambler/dumper'
|
6
|
+
require 'pgdump_scrambler/s3_uploader'
|
7
|
+
require 'pgdump_scrambler/railtie' if defined?(Rails)
|
9
8
|
|
10
9
|
module PgdumpScrambler
|
11
10
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
namespace :pgdump_scrambler do
|
3
4
|
default_config_path = ENV['SCRAMBLER_CONFIG_PATH'] || 'config/pgdump_scrambler.yml'
|
4
5
|
|
@@ -6,15 +7,16 @@ namespace :pgdump_scrambler do
|
|
6
7
|
task config_from_db: :environment do
|
7
8
|
config =
|
8
9
|
if File.exist?(default_config_path)
|
9
|
-
puts "#{default_config_path} found!\
|
10
|
+
puts "#{default_config_path} found!\nMerging existing config with config from database"
|
10
11
|
PgdumpScrambler::Config
|
11
12
|
.read_file(default_config_path)
|
12
13
|
.update_with(PgdumpScrambler::Config.from_db)
|
13
14
|
else
|
14
|
-
puts
|
15
|
+
puts 'Creating a config file from database'
|
15
16
|
PgdumpScrambler::Config.from_db
|
16
17
|
end
|
17
18
|
config.write_file(default_config_path)
|
19
|
+
puts "Wrote to #{default_config_path}"
|
18
20
|
end
|
19
21
|
|
20
22
|
desc 'check if new columns exist'
|
@@ -24,7 +26,7 @@ namespace :pgdump_scrambler do
|
|
24
26
|
.update_with(PgdumpScrambler::Config.from_db)
|
25
27
|
unspecified_columns = config.unspecified_columns
|
26
28
|
count = unspecified_columns.sum { |_, columns| columns.size }
|
27
|
-
if count
|
29
|
+
if count.positive?
|
28
30
|
unspecified_columns.each_key do |table_name|
|
29
31
|
puts "#{table_name}:"
|
30
32
|
unspecified_columns[table_name].each do |column_name|
|
@@ -34,7 +36,7 @@ namespace :pgdump_scrambler do
|
|
34
36
|
puts "#{count} unspecified columns found!"
|
35
37
|
exit 1
|
36
38
|
else
|
37
|
-
puts
|
39
|
+
puts 'No unspecified columns found.'
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
@@ -47,7 +49,7 @@ namespace :pgdump_scrambler do
|
|
47
49
|
desc 'create scrambled dump'
|
48
50
|
task clear_dump: :environment do
|
49
51
|
config = PgdumpScrambler::Config.read_file(default_config_path)
|
50
|
-
if File.
|
52
|
+
if File.exist? config.dump_path
|
51
53
|
File.delete(config.dump_path)
|
52
54
|
puts "Dump file #{config.dump_path} has been deleted."
|
53
55
|
end
|
@@ -57,7 +59,7 @@ namespace :pgdump_scrambler do
|
|
57
59
|
task s3_upload: :environment do
|
58
60
|
config = PgdumpScrambler::Config.read_file(default_config_path)
|
59
61
|
uploader = PgdumpScrambler::S3Uploader.new(
|
60
|
-
s3_path: File.join(config.resolved_s3['prefix'], File
|
62
|
+
s3_path: File.join(config.resolved_s3['prefix'], File.basename(config.dump_path)),
|
61
63
|
local_path: config.dump_path,
|
62
64
|
region: config.resolved_s3['region'],
|
63
65
|
bucket: config.resolved_s3['bucket'],
|
data/pgdump_scrambler.gemspec
CHANGED
@@ -1,37 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
|
2
|
-
lib = File.expand_path(
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
3
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
5
|
+
require 'pgdump_scrambler/version'
|
5
6
|
|
6
7
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
8
|
+
spec.name = 'pgdump_scrambler'
|
8
9
|
spec.version = PgdumpScrambler::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
10
|
+
spec.authors = ['Shunichi Ikegami']
|
11
|
+
spec.email = ['sike.tm@gmail.com']
|
11
12
|
|
12
|
-
spec.summary =
|
13
|
-
spec.description =
|
13
|
+
spec.summary = 'Scramble pg_dump columns'
|
14
|
+
spec.description = 'Scramble pg_dump columns.'
|
14
15
|
spec.homepage = 'https://github.com/shunichi/pgdump_scrambler'
|
15
|
-
spec.license =
|
16
|
+
spec.license = 'MIT'
|
17
|
+
spec.required_ruby_version = '>= 3.0'
|
16
18
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
else
|
22
|
-
raise "RubyGems 2.0 or newer is required to protect against " \
|
23
|
-
"public gem pushes."
|
24
|
-
end
|
19
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
20
|
+
spec.metadata['source_code_uri'] = 'https://github.com/shunichi/pgdump_scrambler'
|
21
|
+
spec.metadata['changelog_uri'] = 'https://github.com/shunichi/pgdump_scrambler/blob/main/CHANGELOG.md'
|
22
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
25
23
|
|
26
|
-
spec.files
|
24
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
27
25
|
f.match(%r{^(test|spec|features)/})
|
28
26
|
end
|
29
|
-
spec.bindir =
|
27
|
+
spec.bindir = 'exe'
|
30
28
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
31
|
-
spec.require_paths = [
|
32
|
-
|
33
|
-
spec.add_development_dependency "rake", "~> 13.0"
|
34
|
-
spec.add_development_dependency "rspec", "~> 3.12"
|
35
|
-
spec.add_development_dependency "rails", "~> 7.0"
|
36
|
-
spec.add_development_dependency "rubocop"
|
29
|
+
spec.require_paths = ['lib']
|
37
30
|
end
|