flydata 0.8.9 → 0.8.9.11

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 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