flydata 0.8.9 → 0.8.9.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitsha +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +2 -1
- data/Gemfile.lock +38 -27
- data/Rakefile +4 -1
- data/VERSION +1 -1
- data/circle.yml +1 -1
- data/fd-build +26 -0
- data/flydata-core/lib/flydata-core/errors.rb +3 -0
- data/flydata-core/lib/flydata-core/mysql/compatibility_checker.rb +39 -1
- data/flydata-core/lib/flydata-core/table_def/redshift_table_def.rb +14 -4
- data/flydata-core/spec/mysql/compatibility_checker_spec.rb +140 -0
- data/flydata.gemspec +0 -0
- data/gemset.nix +580 -0
- data/lib/flydata/cli.rb +3 -0
- data/lib/flydata/error_reporting.rb +89 -0
- data/lib/flydata/fluent-plugins/in_mysql_binlog_flydata.rb +2 -0
- data/lib/flydata/fluent-plugins/in_postgresql_query_based_flydata.rb +5 -1
- data/lib/flydata/query_based_sync/client.rb +6 -1
- data/lib/flydata/source_mysql/mysql_compatibility_check.rb +9 -1
- data/replication.nix +30 -0
- data/shell.nix +47 -0
- data/spec/flydata/error_reporting_spec.rb +107 -0
- data/spec/flydata/source_mysql/mysql_compatibility_check_spec.rb +38 -0
- data/spec/flydata/source_mysql/parser/dump_parser_spec.rb +3 -1
- data/spec/flydata/source_mysql/sync_generate_table_ddl_spec.rb +12 -0
- metadata +122 -100
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 35a3d0077661045cac6a3431b1e26370d9d4b3c3734ad13fd41ab3e06e99530e
|
4
|
+
data.tar.gz: 32e5f53766192e1a9ecb384176314095018ee5ee2c1b751ec140a479e8c578ed
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cd8938432ec340ae74f8f4968d4282c3e42532c54a61c2fa7aef43177d0d0a72847d3059e21a9c777d12ba2a3940a51c93505048c6ab00e5a53e1d4092fe646e
|
7
|
+
data.tar.gz: 280fda7d5b9cff89f079196d5ea86c35178afafc94bef9e3be48fb0cb4c0594a08201568d56eef7dea3ffcd1e9f6d48181986c71f276db0f3f602aa963afaddc
|
data/.gitsha
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
d37dcb936ffe8940b3dd34695df8291b8ea92e5b
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.0.0-p648
|
data/Gemfile
CHANGED
@@ -18,7 +18,7 @@ gem "kodama", '~> 0.1', '>= 0.1.12'
|
|
18
18
|
gem "serverengine", '~> 1.5'
|
19
19
|
|
20
20
|
group :development do
|
21
|
-
gem "jeweler", '~>
|
21
|
+
gem "jeweler", '~> 2.0', '>= 2.0.1'
|
22
22
|
gem "rspec", '~> 3.0'
|
23
23
|
gem 'test-unit'
|
24
24
|
gem 'timecop', '~> 0.7', '>= 0.7.1'
|
@@ -31,4 +31,5 @@ group :development do
|
|
31
31
|
gem 'rake'
|
32
32
|
#gem 'ruby-oci8'
|
33
33
|
gem 'rake-compiler', '~> 0.9', '>= 0.9.5'
|
34
|
+
gem 'rollbar'
|
34
35
|
end
|
data/Gemfile.lock
CHANGED
@@ -17,14 +17,17 @@ GEM
|
|
17
17
|
multi_json (~> 1.3)
|
18
18
|
thread_safe (~> 0.1)
|
19
19
|
tzinfo (~> 0.3.37)
|
20
|
-
addressable (2.
|
20
|
+
addressable (2.5.2)
|
21
|
+
public_suffix (>= 2.0.2, < 4.0)
|
21
22
|
arel (4.0.2)
|
22
23
|
builder (3.1.4)
|
23
24
|
coderay (1.1.0)
|
24
25
|
cool.io (1.4.1)
|
26
|
+
descendants_tracker (0.0.4)
|
27
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
25
28
|
diff-lcs (1.2.5)
|
26
|
-
faraday (0.
|
27
|
-
multipart-post (
|
29
|
+
faraday (0.9.2)
|
30
|
+
multipart-post (>= 1.2, < 3)
|
28
31
|
ffi (1.9.6)
|
29
32
|
fluent-plugin-mysql-binlog (0.0.2)
|
30
33
|
activesupport
|
@@ -37,48 +40,52 @@ GEM
|
|
37
40
|
msgpack (>= 0.4.4, < 0.6.0, != 0.5.3, != 0.5.2, != 0.5.1, != 0.5.0)
|
38
41
|
sigdump (~> 0.2.2)
|
39
42
|
yajl-ruby (~> 1.0)
|
40
|
-
git (1.
|
41
|
-
github_api (0.
|
42
|
-
addressable
|
43
|
-
|
43
|
+
git (1.5.0)
|
44
|
+
github_api (0.11.3)
|
45
|
+
addressable (~> 2.3)
|
46
|
+
descendants_tracker (~> 0.0.1)
|
47
|
+
faraday (~> 0.8, < 0.10)
|
44
48
|
hashie (>= 1.2)
|
45
|
-
multi_json (
|
46
|
-
nokogiri (~> 1.
|
49
|
+
multi_json (>= 1.7.5, < 2.0)
|
50
|
+
nokogiri (~> 1.6.0)
|
47
51
|
oauth2
|
48
|
-
hashie (3.
|
52
|
+
hashie (3.6.0)
|
49
53
|
highline (1.6.21)
|
50
54
|
http_parser.rb (0.6.0)
|
51
55
|
i18n (0.6.11)
|
52
56
|
io-console (0.4.6)
|
53
|
-
jeweler (1.
|
57
|
+
jeweler (2.1.2)
|
54
58
|
builder
|
55
|
-
bundler (
|
59
|
+
bundler (>= 1.0)
|
56
60
|
git (>= 1.2.5)
|
57
|
-
github_api (
|
61
|
+
github_api (~> 0.11.0)
|
58
62
|
highline (>= 1.6.15)
|
59
|
-
nokogiri (
|
63
|
+
nokogiri (>= 1.5.10)
|
60
64
|
rake
|
61
65
|
rdoc
|
66
|
+
semver
|
62
67
|
json (1.8.1)
|
63
|
-
jwt (1.
|
68
|
+
jwt (1.5.6)
|
64
69
|
kodama (0.1.12)
|
65
70
|
ruby-binlog (~> 1.0, >= 1.0.10)
|
66
71
|
method_source (0.8.2)
|
67
72
|
mime-types (2.3)
|
73
|
+
mini_portile2 (2.1.0)
|
68
74
|
minitest (4.7.5)
|
69
75
|
msgpack (0.5.8)
|
70
76
|
multi_json (1.10.1)
|
71
|
-
multi_xml (0.
|
72
|
-
multipart-post (
|
77
|
+
multi_xml (0.6.0)
|
78
|
+
multipart-post (2.0.0)
|
73
79
|
mysql2 (0.3.18)
|
74
80
|
netrc (0.7.7)
|
75
|
-
nokogiri (1.
|
76
|
-
|
77
|
-
|
78
|
-
|
81
|
+
nokogiri (1.6.8.1)
|
82
|
+
mini_portile2 (~> 2.1.0)
|
83
|
+
oauth2 (1.4.1)
|
84
|
+
faraday (>= 0.8, < 0.16.0)
|
85
|
+
jwt (>= 1.0, < 3.0)
|
79
86
|
multi_json (~> 1.3)
|
80
87
|
multi_xml (~> 0.5)
|
81
|
-
rack (
|
88
|
+
rack (>= 1.2, < 3)
|
82
89
|
pg (0.18.4)
|
83
90
|
polyglot (0.3.5)
|
84
91
|
power_assert (1.0.1)
|
@@ -88,15 +95,17 @@ GEM
|
|
88
95
|
coderay (~> 1.1.0)
|
89
96
|
method_source (~> 0.8.1)
|
90
97
|
slop (~> 3.4)
|
91
|
-
|
98
|
+
public_suffix (2.0.5)
|
99
|
+
rack (1.6.11)
|
92
100
|
rake (10.3.2)
|
93
101
|
rake-compiler (0.9.5)
|
94
102
|
rake
|
95
|
-
rdoc (
|
96
|
-
json (~> 1.4)
|
103
|
+
rdoc (5.1.0)
|
97
104
|
rest-client (1.7.2)
|
98
105
|
mime-types (>= 1.16, < 3.0)
|
99
106
|
netrc (~> 0.7)
|
107
|
+
rollbar (2.18.0)
|
108
|
+
multi_json
|
100
109
|
rspec (3.0.0)
|
101
110
|
rspec-core (~> 3.0.0)
|
102
111
|
rspec-expectations (~> 3.0.0)
|
@@ -111,6 +120,7 @@ GEM
|
|
111
120
|
rspec-support (3.0.3)
|
112
121
|
ruby-binlog (1.0.10)
|
113
122
|
ruby-prof (0.15.1)
|
123
|
+
semver (1.0.1)
|
114
124
|
serverengine (1.5.10)
|
115
125
|
sigdump (~> 0.2.2)
|
116
126
|
sigdump (0.2.2)
|
@@ -139,7 +149,7 @@ DEPENDENCIES
|
|
139
149
|
highline (~> 1.6, >= 1.6.19)
|
140
150
|
i18n (~> 0.6, >= 0.6.5)
|
141
151
|
io-console (~> 0.4.6, >= 0.4.6)
|
142
|
-
jeweler (~>
|
152
|
+
jeweler (~> 2.0, >= 2.0.1)
|
143
153
|
json (~> 1.8, >= 1.8.0)
|
144
154
|
kodama (~> 0.1, >= 0.1.12)
|
145
155
|
mysql2 (~> 0.3, >= 0.3.17)
|
@@ -149,6 +159,7 @@ DEPENDENCIES
|
|
149
159
|
rake
|
150
160
|
rake-compiler (~> 0.9, >= 0.9.5)
|
151
161
|
rest-client (~> 1.6, >= 1.6.7)
|
162
|
+
rollbar
|
152
163
|
rspec (~> 3.0)
|
153
164
|
ruby-prof (~> 0.15, >= 0.15.1)
|
154
165
|
serverengine (~> 1.5)
|
@@ -160,4 +171,4 @@ DEPENDENCIES
|
|
160
171
|
treetop (~> 1.5, >= 1.5.3)
|
161
172
|
|
162
173
|
BUNDLED WITH
|
163
|
-
1.
|
174
|
+
1.17.1
|
data/Rakefile
CHANGED
@@ -21,7 +21,10 @@ Jeweler::Tasks.new do |gem|
|
|
21
21
|
gem.description = %Q{FlyData Agent}
|
22
22
|
gem.email = "sysadmin@flydata.com"
|
23
23
|
gem.authors = ["Koichi Fujikawa", "Masashi Miyazaki", "Matthew Luu", "Mak Inada", "Sriram NS", "Chie Inada"]
|
24
|
-
|
24
|
+
|
25
|
+
sha=`git rev-parse --verify HEAD`
|
26
|
+
File.open(File.join(File.dirname(__FILE__), ".gitsha"), "w") { |f| f << sha }
|
27
|
+
gem.files << ".gitsha"
|
25
28
|
end
|
26
29
|
Jeweler::RubygemsDotOrgTasks.new
|
27
30
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.8.9
|
1
|
+
0.8.9.11
|
data/circle.yml
CHANGED
@@ -6,7 +6,7 @@ dependencies:
|
|
6
6
|
pre:
|
7
7
|
- sudo dpkg -l |grep libboost|grep 1.48|awk '{print $2}'|xargs sudo apt-get purge -y
|
8
8
|
- sudo apt-get autoremove
|
9
|
-
- sudo apt-get update
|
9
|
+
- sudo apt-get update || true
|
10
10
|
- sudo apt-get install -y libboost-system1.54.0
|
11
11
|
- sudo apt-get install -y libboost-system1.54-dev
|
12
12
|
- sudo apt-get install -y libboost-thread1.54.0
|
data/fd-build
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#! /usr/bin/env bash
|
2
|
+
|
3
|
+
set -e
|
4
|
+
set -o pipefail
|
5
|
+
|
6
|
+
SOURCE="${BASH_SOURCE[0]}"
|
7
|
+
while [ -h "$SOURCE" ]; do
|
8
|
+
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
9
|
+
SOURCE="$(readlink "$SOURCE")"
|
10
|
+
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
|
11
|
+
done
|
12
|
+
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
|
13
|
+
|
14
|
+
FD_BUILD=$(which fd-build)
|
15
|
+
source $(dirname $FD_BUILD)/../lib/fd-scripts/utils.sh
|
16
|
+
|
17
|
+
cd $DIR
|
18
|
+
|
19
|
+
# bundle to install gems.
|
20
|
+
nix-shell --run "bundle install --path vendor/bundle"
|
21
|
+
nix-shell --run "bundle exec rake compile"
|
22
|
+
|
23
|
+
# Bundix updates the gemset.nix file so that nix-build can operate using fixed builds.
|
24
|
+
$(nix-build '<nixpkgs>' -A fd-bundix --no-out-link --show-trace)/bin/bundix --ruby=fd-ruby
|
25
|
+
|
26
|
+
echo -e "${BLUE}Done!${RESTORE} Everything should be up to date!"
|
@@ -61,6 +61,8 @@ module FlydataCore
|
|
61
61
|
def rds?(hostname = @option[:host])
|
62
62
|
return true if hostname.match(/rds.amazonaws.com$/) != nil
|
63
63
|
|
64
|
+
ExecutePrivilegeChecker.new(@option).do_check
|
65
|
+
|
64
66
|
# To distinguish RDS customers using Secure Tunnel
|
65
67
|
begin
|
66
68
|
exec_query(RDS_CHECK_QUERY)
|
@@ -358,7 +360,7 @@ EOT
|
|
358
360
|
param_hash = convert_result_to_hash(result)
|
359
361
|
|
360
362
|
if param_hash["expire_logs_days"].to_s != '0' &&
|
361
|
-
param_hash["expire_logs_days"].to_i
|
363
|
+
param_hash["expire_logs_days"].to_i < EXPIRE_LOGS_DAYS_LIMIT
|
362
364
|
raise FlydataCore::MysqlCompatibilityError,
|
363
365
|
"Binary log retention is too short\n " +
|
364
366
|
" We recommend the system variable '@@expire_logs_days' to be either set to 0 or at least #{EXPIRE_LOGS_DAYS_LIMIT} day(s)"
|
@@ -389,6 +391,12 @@ EOT
|
|
389
391
|
"call mysql.rds_show_configuration;"
|
390
392
|
end
|
391
393
|
|
394
|
+
def do_check(option = @option, &block)
|
395
|
+
ExecutePrivilegeChecker.new(option).do_check
|
396
|
+
|
397
|
+
super(option, &block)
|
398
|
+
end
|
399
|
+
|
392
400
|
def check_result(result, option = @option)
|
393
401
|
if result.first["name"] == "binlog retention hours"
|
394
402
|
if result.first["value"].nil? ||
|
@@ -403,5 +411,35 @@ EOT
|
|
403
411
|
end
|
404
412
|
end
|
405
413
|
end
|
414
|
+
|
415
|
+
class ExecutePrivilegeChecker < MysqlCompatibilityChecker
|
416
|
+
def create_query(option = @option)
|
417
|
+
"SHOW GRANTS FOR '#{option[:username]}'"
|
418
|
+
end
|
419
|
+
|
420
|
+
def check_result(result, option = @option)
|
421
|
+
valid_privileges = ['EXECUTE', 'ALL PRIVILEGES']
|
422
|
+
|
423
|
+
get_grant_regex = /GRANT (?<privs>.*) ON (`)?(?<db_name>[^`]*)(`)?\.\* TO '#{option[:username]}/
|
424
|
+
|
425
|
+
result.each do |res|
|
426
|
+
# SHOW GRANTS should only return one column
|
427
|
+
res_value = res.values.first
|
428
|
+
matched_values = res_value.match(get_grant_regex)
|
429
|
+
|
430
|
+
next unless matched_values
|
431
|
+
matched_privileges = matched_values['privs'].split(', ')
|
432
|
+
|
433
|
+
next unless ['*', option[:database]].include?(matched_values['db_name'])
|
434
|
+
next if (matched_privileges & valid_privileges).empty? # array intersection
|
435
|
+
|
436
|
+
return true
|
437
|
+
end
|
438
|
+
|
439
|
+
error_text = "The user '#{option[:username]}' does not have the EXECUTE permission"
|
440
|
+
|
441
|
+
raise MissingExecutePermissionMysqlCompatibilityError, error_text
|
442
|
+
end
|
443
|
+
end
|
406
444
|
end
|
407
445
|
end
|
@@ -301,7 +301,12 @@ EOS
|
|
301
301
|
"'#{self.parse_timestamp(remove_single_quote(default_value))}'"
|
302
302
|
end
|
303
303
|
when 'date'
|
304
|
-
|
304
|
+
val = self.parse_date(remove_single_quote(default_value))
|
305
|
+
if val =~ /SYSDATE/
|
306
|
+
"#{val}"
|
307
|
+
else
|
308
|
+
"'#{val}'"
|
309
|
+
end
|
305
310
|
when 'boolean'
|
306
311
|
default_value.to_s.upcase
|
307
312
|
else
|
@@ -517,9 +522,14 @@ EOS
|
|
517
522
|
|
518
523
|
def self.parse_date(value)
|
519
524
|
return nil if value.nil?
|
520
|
-
|
521
|
-
|
522
|
-
|
525
|
+
case value.to_s.upcase
|
526
|
+
when /^CURRENT_TIMESTAMP\b/, /^CURRENT_TIME\b/, /^NOW\(\)/
|
527
|
+
'SYSDATE'
|
528
|
+
else
|
529
|
+
value_str = value.to_s
|
530
|
+
dt = Date.parse(convert_date(value_str))
|
531
|
+
dt.strftime('%Y-%m-%d')
|
532
|
+
end
|
523
533
|
rescue ArgumentError => ae
|
524
534
|
# '0000-00-00' is valid for mysql date column
|
525
535
|
return '0001-01-01' if value_str == '0000-00-00'
|
@@ -52,6 +52,21 @@ module FlydataCore
|
|
52
52
|
describe '#rds?' do
|
53
53
|
subject { subject_object.rds? }
|
54
54
|
|
55
|
+
let(:execute_privilege_checker) { ExecutePrivilegeChecker.new }
|
56
|
+
|
57
|
+
before do
|
58
|
+
allow(ExecutePrivilegeChecker).to receive(:new).and_return(execute_privilege_checker)
|
59
|
+
allow(execute_privilege_checker).to receive(:do_check).and_return(nil)
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'calls ExecutePrivilegeChecker' do
|
63
|
+
allow(subject_object).to receive(:exec_query).with(MysqlCompatibilityChecker::RDS_CHECK_QUERY).and_return(nil)
|
64
|
+
|
65
|
+
expect(execute_privilege_checker).to receive(:do_check)
|
66
|
+
|
67
|
+
subject
|
68
|
+
end
|
69
|
+
|
55
70
|
context 'When called for non-rds host' do
|
56
71
|
let(:mysql2_error_msg) { "PROCEDURE mysql.rds_show_configuration does not exist" }
|
57
72
|
before do
|
@@ -107,6 +122,18 @@ module FlydataCore
|
|
107
122
|
expect { subject }.to raise_error(Mysql2::Error, mysql2_error_msg)
|
108
123
|
end
|
109
124
|
end
|
125
|
+
|
126
|
+
context 'when FlydataCore::MissingExecutePermissionMysqlCompatibilityError raised' do
|
127
|
+
let(:error_msg) { "The user 'sync' does not have the EXECUTE permission" }
|
128
|
+
|
129
|
+
before do
|
130
|
+
allow(ExecutePrivilegeChecker).to receive(:new).and_return(execute_privilege_checker)
|
131
|
+
allow(execute_privilege_checker).to receive(:do_check).and_raise(FlydataCore::MissingExecutePermissionMysqlCompatibilityError, error_msg)
|
132
|
+
end
|
133
|
+
it do
|
134
|
+
expect { subject }.to raise_error(FlydataCore::MissingExecutePermissionMysqlCompatibilityError, error_msg)
|
135
|
+
end
|
136
|
+
end
|
110
137
|
end
|
111
138
|
end
|
112
139
|
|
@@ -339,6 +366,119 @@ EOT
|
|
339
366
|
end
|
340
367
|
end
|
341
368
|
end
|
369
|
+
|
370
|
+
describe ExecutePrivilegeChecker do
|
371
|
+
let(:subject_object) { described_class.new(option.merge(username: 'sync')) }
|
372
|
+
|
373
|
+
describe '#check_result' do
|
374
|
+
subject { subject_object.check_result(result) }
|
375
|
+
|
376
|
+
context 'when ALL PRIVILEGES is granted' do
|
377
|
+
let(:result) do
|
378
|
+
[{"Grants for sync@%" => "GRANT ALL PRIVILEGES ON *.* TO 'sync'@'%' IDENTIFIED BY PASSWORD 'password'"}]
|
379
|
+
end
|
380
|
+
|
381
|
+
it { expect{subject}.to_not raise_error }
|
382
|
+
end
|
383
|
+
|
384
|
+
context 'when EXECUTE privilege is granted in all databases' do
|
385
|
+
let(:result) do
|
386
|
+
[{"Grants for sync@%" => "GRANT SELECT, RELOAD, LOCK TABLES, REPLICATION SLAVE, REPLICATION CLIENT, EXECUTE ON *.* TO 'sync'@'%' IDENTIFIED BY PASSWORD 'password'"}]
|
387
|
+
end
|
388
|
+
|
389
|
+
it { expect{subject}.to_not raise_error }
|
390
|
+
end
|
391
|
+
|
392
|
+
context 'when EXECUTE privilege is granted in the test_db database' do
|
393
|
+
let(:result) do
|
394
|
+
[{"Grants for sync@%" => "GRANT SELECT, RELOAD, LOCK TABLES, REPLICATION SLAVE, REPLICATION CLIENT, EXECUTE ON test_db.* TO 'sync'@'%' IDENTIFIED BY PASSWORD 'password'"}]
|
395
|
+
end
|
396
|
+
|
397
|
+
it { expect{subject}.to_not raise_error }
|
398
|
+
end
|
399
|
+
|
400
|
+
context 'when ALL PRIVILEGES is granted in a different database' do
|
401
|
+
let(:result) do
|
402
|
+
[{"Grants for sync@%" => "GRANT ALL PRIVILEGES ON different_db.* TO 'sync'@'%' IDENTIFIED BY PASSWORD 'password'"}]
|
403
|
+
end
|
404
|
+
|
405
|
+
it { expect{subject}.to raise_error(FlydataCore::MissingExecutePermissionMysqlCompatibilityError, "The user 'sync' does not have the EXECUTE permission") }
|
406
|
+
end
|
407
|
+
|
408
|
+
context 'when EXECUTE privilege is granted in a different database' do
|
409
|
+
let(:result) do
|
410
|
+
[{"Grants for sync@%" => "GRANT SELECT, RELOAD, LOCK TABLES, REPLICATION SLAVE, REPLICATION CLIENT, EXECUTE ON different_db.* TO 'sync'@'%' IDENTIFIED BY PASSWORD 'password'"}]
|
411
|
+
end
|
412
|
+
|
413
|
+
it { expect{subject}.to raise_error(FlydataCore::MissingExecutePermissionMysqlCompatibilityError, "The user 'sync' does not have the EXECUTE permission") }
|
414
|
+
end
|
415
|
+
|
416
|
+
context 'when EXECUTE privilege is not granted' do
|
417
|
+
let(:result) do
|
418
|
+
[{"Grants for sync@%" => "GRANT SELECT, RELOAD, LOCK TABLES, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'sync'@'%' IDENTIFIED BY PASSWORD 'password'"}]
|
419
|
+
end
|
420
|
+
|
421
|
+
it { expect{subject}.to raise_error(FlydataCore::MissingExecutePermissionMysqlCompatibilityError, "The user 'sync' does not have the EXECUTE permission") }
|
422
|
+
end
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
describe RdsRetentionChecker do
|
427
|
+
let(:options) { option.merge(username: 'sync') }
|
428
|
+
let(:mysql_options) { options.merge(port: nil, password: nil, ssl_ca: nil, ssl_cipher: nil) }
|
429
|
+
let(:subject_object) { described_class.new(options) }
|
430
|
+
|
431
|
+
describe '#do_check' do
|
432
|
+
subject { subject_object.do_check }
|
433
|
+
|
434
|
+
let(:execute_privilege_checker) { ExecutePrivilegeChecker.new(options) }
|
435
|
+
|
436
|
+
before do
|
437
|
+
@rds_show_configuration_result = [{name: 'binlog retention hours', value: '144'}]
|
438
|
+
|
439
|
+
allow(subject_object).to receive(:create_query).and_return('call mysql.rds_show_configuration;')
|
440
|
+
allow(subject_object).to receive(:exec_query).with('call mysql.rds_show_configuration;').and_return(@rds_show_configuration_result)
|
441
|
+
allow(subject_object).to receive(:check_result).with(@rds_show_configuration_result, mysql_options).and_return(nil)
|
442
|
+
|
443
|
+
allow(ExecutePrivilegeChecker).to receive(:new).and_return(execute_privilege_checker)
|
444
|
+
allow(execute_privilege_checker).to receive(:do_check).and_return(nil)
|
445
|
+
end
|
446
|
+
|
447
|
+
it { expect{subject}.to_not raise_error }
|
448
|
+
|
449
|
+
it 'calls ExecutePrivilegeChecker' do
|
450
|
+
expect(execute_privilege_checker).to receive(:do_check)
|
451
|
+
|
452
|
+
subject
|
453
|
+
end
|
454
|
+
|
455
|
+
context 'when database user has EXECUTE privilege' do
|
456
|
+
it { expect{subject}.to_not raise_error }
|
457
|
+
|
458
|
+
context 'when binlog is too low' do
|
459
|
+
before do
|
460
|
+
@error_message = "Binary log retention is too short\n" +
|
461
|
+
" We recommend setting RDS binlog retention " +
|
462
|
+
"to be at least 96 hours. To do this, " +
|
463
|
+
"run this on your RDS MySQL database:\n" +
|
464
|
+
" $> call mysql.rds_set_configuration('binlog retention hours', 96);"
|
465
|
+
|
466
|
+
allow(subject_object).to receive(:check_result).with(@rds_show_configuration_result, mysql_options).and_raise(FlydataCore::MysqlCompatibilityError, @error_message)
|
467
|
+
end
|
468
|
+
|
469
|
+
it { expect{subject}.to raise_error(FlydataCore::MysqlCompatibilityError, @error_message) }
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
473
|
+
context 'when database user does not have EXECUTE privilege' do
|
474
|
+
before do
|
475
|
+
allow(execute_privilege_checker).to receive(:do_check).and_raise(FlydataCore::MissingExecutePermissionMysqlCompatibilityError, "The user 'sync' does not have the EXECUTE permission")
|
476
|
+
end
|
477
|
+
|
478
|
+
it { expect{subject}.to raise_error(FlydataCore::MissingExecutePermissionMysqlCompatibilityError, "The user 'sync' does not have the EXECUTE permission") }
|
479
|
+
end
|
480
|
+
end
|
481
|
+
end
|
342
482
|
end
|
343
483
|
|
344
484
|
describe BinlogParameterChecker do
|