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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 18f14f5aa7cb056405bcddd04145128861746e81
4
- data.tar.gz: 7137aa3faffbc50cdadf71a54e22f50c59f7beb4
2
+ SHA256:
3
+ metadata.gz: 35a3d0077661045cac6a3431b1e26370d9d4b3c3734ad13fd41ab3e06e99530e
4
+ data.tar.gz: 32e5f53766192e1a9ecb384176314095018ee5ee2c1b751ec140a479e8c578ed
5
5
  SHA512:
6
- metadata.gz: 515cc0f4a0520fc9c6f2573eb457d903dd83c43c6ff8ef114659b8e6050d67c3984e2ecc4acbfeba8307b12e4db383b1039df4647ede956c0d52799a465b6a6c
7
- data.tar.gz: e2ea17f5471e190d8bcc718db2da8136bff4677337f60fb5e1f7da4011fb41de5081c9efad491bd8ebe1043296e26a969a55845a6b3446764e573d022cfad3f8
6
+ metadata.gz: cd8938432ec340ae74f8f4968d4282c3e42532c54a61c2fa7aef43177d0d0a72847d3059e21a9c777d12ba2a3940a51c93505048c6ab00e5a53e1d4092fe646e
7
+ data.tar.gz: 280fda7d5b9cff89f079196d5ea86c35178afafc94bef9e3be48fb0cb4c0594a08201568d56eef7dea3ffcd1e9f6d48181986c71f276db0f3f602aa963afaddc
data/.gitsha ADDED
@@ -0,0 +1 @@
1
+ d37dcb936ffe8940b3dd34695df8291b8ea92e5b
@@ -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", '~> 1.8', '>= 1.8.8'
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
@@ -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.3.6)
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.8.9)
27
- multipart-post (~> 1.2.0)
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.2.8)
41
- github_api (0.10.1)
42
- addressable
43
- faraday (~> 0.8.1)
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 (~> 1.4)
46
- nokogiri (~> 1.5.2)
49
+ multi_json (>= 1.7.5, < 2.0)
50
+ nokogiri (~> 1.6.0)
47
51
  oauth2
48
- hashie (3.2.0)
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.8.8)
57
+ jeweler (2.1.2)
54
58
  builder
55
- bundler (~> 1.0)
59
+ bundler (>= 1.0)
56
60
  git (>= 1.2.5)
57
- github_api (= 0.10.1)
61
+ github_api (~> 0.11.0)
58
62
  highline (>= 1.6.15)
59
- nokogiri (= 1.5.10)
63
+ nokogiri (>= 1.5.10)
60
64
  rake
61
65
  rdoc
66
+ semver
62
67
  json (1.8.1)
63
- jwt (1.0.0)
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.5.5)
72
- multipart-post (1.2.0)
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.5.10)
76
- oauth2 (1.0.0)
77
- faraday (>= 0.8, < 0.10)
78
- jwt (~> 1.0)
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 (~> 1.2)
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
- rack (1.5.2)
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 (4.1.1)
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 (~> 1.8, >= 1.8.8)
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.13.7
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
- # dependencies defined in Gemfile
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
@@ -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!"
@@ -380,6 +380,9 @@ end
380
380
  class PostgresqlCompatibilityError < CompatibilityError
381
381
  end
382
382
 
383
+ class MissingExecutePermissionMysqlCompatibilityError < MysqlCompatibilityError
384
+ end
385
+
383
386
  ## Error container
384
387
 
385
388
  class DataDeliveryErrorThreadContext
@@ -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 <= EXPIRE_LOGS_DAYS_LIMIT
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
- "'#{self.parse_date(remove_single_quote(default_value))}'"
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
- value_str = value.to_s
521
- dt = Date.parse(convert_date(value_str))
522
- dt.strftime('%Y-%m-%d')
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