flydata 0.3.13 → 0.3.14

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
2
  SHA1:
3
- metadata.gz: 317626ac900b0a0adf96c84648e554f6d2e7436a
4
- data.tar.gz: e54dcf2b46068be7c27e3d6ce63c338d111e0c20
3
+ metadata.gz: de14c5ba0b4b0b3c1b98e93f9e41c59a32db18fd
4
+ data.tar.gz: 685e70c882291fe387d7aaf14657a879b8c1d73e
5
5
  SHA512:
6
- metadata.gz: 935c6cc893c91fba078e92306b88a06697195c3a21b5241f0d08936a9cfb8acdff7c9eb32febbdc5c77a04b5dbe9627c757cf123ceee0420ae29784e4e10e1b4
7
- data.tar.gz: 593a4ade45a37713981a11c5d98456eaaa04a592870cab4b2aff48a162e17d36c4780a138df5c38636d07bc9c3879d3ddde02e6331c94be916c62cc9b1d2f58a
6
+ metadata.gz: c735cbf41f4e9448175bb38c5dac9b5e5365e7a8f9710f86e7399feab2eecd5e018165f2224e8749e8c7169941b33bc1a01e122d7eb1d510056010508c0a793a
7
+ data.tar.gz: efc559f6b9536c45078f63b1416fc5da759bbd99249176b51dc15e7ec4016a5dfb5942262db0e4a87d13ba843d90ae00a91a9b731d670881c5467b5b642fac87
data/Gemfile CHANGED
@@ -7,14 +7,13 @@ gem "activesupport", '~> 4.0.0'
7
7
  gem "json", '~> 1.8', '>= 1.8.0'
8
8
  gem "highline", '~> 1.6', '>= 1.6.19'
9
9
  gem "fluentd", "0.10.46"
10
- gem "ruby-binlog", '~> 1.0', '>= 1.0.2'
11
10
  gem "fluent-plugin-mysql-binlog", '~> 0.0', '>= 0.0.2'
12
- gem "mysql2", '~> 0.3', '>= 0.3.11'
11
+ gem "mysql2", '~> 0.3', '>= 0.3.17'
13
12
  gem "slop", '~> 3.4', '>= 3.4.6'
14
13
  gem "treetop", '~> 1.5', '>= 1.5.3'
15
14
  gem "sys-filesystem", '~> 1.1', '>= 1.1.3'
16
15
  gem "io-console", '~> 0.4.2', '>= 0.4.2'
17
- gem "kodama", '~> 0.1.2', '>= 0.1.2'
16
+ gem "kodama", '~> 0.1.2', '>= 0.1.3'
18
17
 
19
18
  group :development do
20
19
  gem "jeweler", '~> 1.8', '>= 1.8.8'
data/Gemfile.lock CHANGED
@@ -61,8 +61,8 @@ GEM
61
61
  rdoc
62
62
  json (1.8.1)
63
63
  jwt (1.0.0)
64
- kodama (0.1.2)
65
- ruby-binlog (>= 0.1.9)
64
+ kodama (0.1.3)
65
+ ruby-binlog (~> 1.0, >= 1.0.4)
66
66
  method_source (0.8.2)
67
67
  mime-types (2.3)
68
68
  minitest (4.7.5)
@@ -70,7 +70,7 @@ GEM
70
70
  multi_json (1.10.1)
71
71
  multi_xml (0.5.5)
72
72
  multipart-post (1.2.0)
73
- mysql2 (0.3.16)
73
+ mysql2 (0.3.18)
74
74
  netrc (0.7.7)
75
75
  nokogiri (1.5.10)
76
76
  oauth2 (1.0.0)
@@ -105,7 +105,7 @@ GEM
105
105
  rspec-mocks (3.0.3)
106
106
  rspec-support (~> 3.0.0)
107
107
  rspec-support (3.0.3)
108
- ruby-binlog (1.0.2)
108
+ ruby-binlog (1.0.4)
109
109
  ruby-prof (0.15.1)
110
110
  sigdump (0.2.2)
111
111
  slop (3.6.0)
@@ -133,13 +133,12 @@ DEPENDENCIES
133
133
  io-console (~> 0.4.2, >= 0.4.2)
134
134
  jeweler (~> 1.8, >= 1.8.8)
135
135
  json (~> 1.8, >= 1.8.0)
136
- kodama (~> 0.1.2, >= 0.1.2)
137
- mysql2 (~> 0.3, >= 0.3.11)
136
+ kodama (~> 0.1.2, >= 0.1.3)
137
+ mysql2 (~> 0.3, >= 0.3.17)
138
138
  protected_attributes (~> 1.0, >= 1.0.8)
139
139
  pry
140
140
  rest-client (~> 1.6, >= 1.6.7)
141
141
  rspec (~> 3.0)
142
- ruby-binlog (~> 1.0, >= 1.0.2)
143
142
  ruby-prof (~> 0.15, >= 0.15.1)
144
143
  slop (~> 3.4, >= 3.4.6)
145
144
  sqlite3 (~> 1.3, >= 1.3.9)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.13
1
+ 0.3.14
@@ -25,6 +25,9 @@ module FlydataCore
25
25
  # - discard_[data-port-id]_[data-entry-id]_[(schema-name.)table-name]
26
26
  #
27
27
  class UserMaintenance
28
+
29
+ SUPPORTED_MODES = [:maintenance, :discard]
30
+
28
31
  def initialize(base_dir_path)
29
32
  @base_dir_path = base_dir_path
30
33
  end
@@ -48,6 +51,18 @@ module FlydataCore
48
51
  mode_file_path(:discard, params)
49
52
  end
50
53
 
54
+ # /mnt/flydata/system/user_maintenance/[dp-id]/[mode]_[data-port-id]_[data-entry-id]_[table-name]
55
+ def mode_file_path(mode, params)
56
+ validate_mode(mode)
57
+ validate_params(params)
58
+ File.join(dp_mode_dir_path(params), mode_file_name(mode, params))
59
+ end
60
+
61
+ # /mnt/flydata/system/user_maintenance/[dp-id]
62
+ def dp_mode_dir_path(params)
63
+ File.join(@base_dir_path, params[:data_port_id].to_s)
64
+ end
65
+
51
66
  # For fluentd plugin and copy handler
52
67
 
53
68
  def maintenance_mode?(params)
@@ -70,6 +85,10 @@ module FlydataCore
70
85
 
71
86
  private
72
87
 
88
+ def validate_mode(mode)
89
+ raise ArgumentError.new("Unsupported mode:#{mode}") unless SUPPORTED_MODES.include?(mode)
90
+ end
91
+
73
92
  def validate_params(params)
74
93
  raise ArgumentError.new("params must be hash") unless params.kind_of?(Hash)
75
94
  raise ArgumentError.new("params must have 'data_port_id' key") unless params[:data_port_id]
@@ -90,17 +109,6 @@ module FlydataCore
90
109
  Dir.glob("#{de_mode_file_path}_*").any?{|fp| File.join(File.dirname(fp), File.basename(fp).downcase) == tn_mode_file_path}
91
110
  end
92
111
 
93
- # /mnt/flydata/system/user_maintenance/[dp-id]/[mode]_[data-port-id]_[data-entry-id]_[table-name]
94
- def mode_file_path(mode, params)
95
- validate_params(params)
96
- File.join(dp_mode_dir_path(mode, params), mode_file_name(mode, params))
97
- end
98
-
99
- # /mnt/flydata/system/user_maintenance/[dp-id]
100
- def dp_mode_dir_path(mode, params)
101
- File.join(@base_dir_path, params[:data_port_id].to_s)
102
- end
103
-
104
112
  # [mode]_[data-port-id]_[data-entry-id]_[table-name]
105
113
  def mode_file_name(mode, params)
106
114
  return nil unless params[:data_port_id]
@@ -0,0 +1,21 @@
1
+ module FlydataCore
2
+ module Fluent
3
+ class ConfigHelper
4
+ ESCAPE_REGEXP = /\r|\n|\t|"|\\|/
5
+ ESCAPE_HASH_TABLE = {"\r" => "\\r", "\n" => "\\n", "\t" => "\\t", '"' => '\\"', "\\" => "\\\\"}
6
+
7
+ UNESCAPE_REGEXP = /\\r|\\n|\\t|\\"|\\\\|/
8
+ UNESCAPE_HASH_TABLE = {"\\r" => "\r", "\\n" => "\n", "\\t" => "\t", '\\"' => '"', "\\\\" => "\\"}
9
+
10
+ def self.escape_conf(str)
11
+ return "" if str.nil? || str.empty?
12
+ str.gsub(ESCAPE_REGEXP, ESCAPE_HASH_TABLE)
13
+ end
14
+
15
+ def self.unescape_conf(str)
16
+ return "" if str.nil? || str.empty?
17
+ str.gsub(UNESCAPE_REGEXP, UNESCAPE_HASH_TABLE)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -68,6 +68,16 @@ module FlydataCore::Config
68
68
  end
69
69
  end
70
70
 
71
+ describe '#mode_file_path' do
72
+ let(:mode) { nil }
73
+ subject { user_maintenance.mode_file_path(mode, params) }
74
+
75
+ context 'with invalid mode' do
76
+ let(:mode) { :unknown }
77
+ it { expect{ subject }.to raise_error(ArgumentError, "Unsupported mode:unknown") }
78
+ end
79
+ end
80
+
71
81
  describe '#maintenance_mode?' do
72
82
  subject { user_maintenance.maintenance_mode?(params) }
73
83
 
@@ -0,0 +1,78 @@
1
+ require_relative '../spec_helper'
2
+ require 'flydata-core/fluent/config_helper'
3
+
4
+ module FlydataCore::Fluent
5
+ describe ConfigHelper do
6
+ describe '.escape_conf' do
7
+
8
+ let(:input) { "" }
9
+ let(:output) { "" }
10
+ subject { ConfigHelper.escape_conf(input) }
11
+
12
+ shared_examples 'escape conf expectedly' do
13
+ it { is_expected.to eq(output) }
14
+ end
15
+
16
+ context 'when input contains escape characters' do
17
+ let(:input) { %Q|aa\nbb\r\ncc\tdd"ee\\ff| }
18
+ let(:output) { %Q|aa\\nbb\\r\\ncc\\tdd\\"ee\\\\ff| }
19
+
20
+ it_behaves_like 'escape conf expectedly'
21
+ end
22
+
23
+ context 'when input does not contain escape characters' do
24
+ let(:input) { %Q|aabbccddeeff| }
25
+ let(:output) { %Q|aabbccddeeff| }
26
+
27
+ it_behaves_like 'escape conf expectedly'
28
+ end
29
+
30
+ context 'when input is nil' do
31
+ let(:input) { nil }
32
+ it { is_expected.to eq("") }
33
+ end
34
+
35
+ context 'when input is empty' do
36
+ let(:input) { "" }
37
+ it { is_expected.to eq("") }
38
+ end
39
+ end
40
+
41
+ describe '.unescape_conf' do
42
+
43
+ let(:input) { "" }
44
+ let(:output) { "" }
45
+ subject { ConfigHelper.unescape_conf(input) }
46
+
47
+ shared_examples 'unescape conf expectedly' do
48
+ it { is_expected.to eq(output) }
49
+ end
50
+
51
+ context 'when input contains escaped characters' do
52
+ let(:input) { %Q|aa\\nbb\\r\\ncc\\tdd\\"ee\\\\ff| }
53
+ let(:output) { %Q|aa\nbb\r\ncc\tdd"ee\\ff| }
54
+
55
+ it_behaves_like 'unescape conf expectedly'
56
+ end
57
+
58
+ context 'when input does not contain escape characters' do
59
+ let(:input) { %Q|aabbccddeeff| }
60
+ let(:output) { %Q|aabbccddeeff| }
61
+
62
+ it_behaves_like 'unescape conf expectedly'
63
+ end
64
+
65
+ context 'when input is nil' do
66
+ let(:input) { nil }
67
+ it { is_expected.to eq("") }
68
+ end
69
+
70
+ context 'when input is empty' do
71
+ let(:input) { "" }
72
+ it { is_expected.to eq("") }
73
+ end
74
+ end
75
+ end
76
+ end
77
+
78
+
data/flydata.gemspec CHANGED
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: flydata 0.3.13 ruby lib
5
+ # stub: flydata 0.3.14 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "flydata"
9
- s.version = "0.3.13"
9
+ s.version = "0.3.14"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Koichi Fujikawa", "Masashi Miyazaki", "Matthew Luu", "Mak Inada", "Sriram NS"]
14
- s.date = "2015-04-09"
14
+ s.date = "2015-04-19"
15
15
  s.description = "FlyData Agent"
16
16
  s.email = "sysadmin@flydata.com"
17
17
  s.executables = ["fdmysqldump", "flydata", "serverinfo"]
@@ -45,12 +45,14 @@ Gem::Specification.new do |s|
45
45
  "flydata-core/lib/flydata-core/core_ext/object/prepend.rb",
46
46
  "flydata-core/lib/flydata-core/errors.rb",
47
47
  "flydata-core/lib/flydata-core/fluent-plugins/multi_buffer.rb",
48
+ "flydata-core/lib/flydata-core/fluent/config_helper.rb",
48
49
  "flydata-core/lib/flydata-core/logger.rb",
49
50
  "flydata-core/lib/flydata-core/table_def.rb",
50
51
  "flydata-core/lib/flydata-core/table_def/mysql_table_def.rb",
51
52
  "flydata-core/lib/flydata-core/table_def/redshift_table_def.rb",
52
53
  "flydata-core/lib/flydata-core/thread_context.rb",
53
54
  "flydata-core/spec/config/user_maintenance_spec.rb",
55
+ "flydata-core/spec/fluent/config_helper_spec.rb",
54
56
  "flydata-core/spec/logger_spec.rb",
55
57
  "flydata-core/spec/spec_helper.rb",
56
58
  "flydata-core/spec/table_def/mysql_table_def_spec.rb",
@@ -172,7 +174,7 @@ Gem::Specification.new do |s|
172
174
  ]
173
175
  s.homepage = "http://flydata.com/"
174
176
  s.licenses = ["All right reserved."]
175
- s.rubygems_version = "2.4.3"
177
+ s.rubygems_version = "2.4.6"
176
178
  s.summary = "FlyData Agent"
177
179
 
178
180
  if s.respond_to? :specification_version then
@@ -185,14 +187,13 @@ Gem::Specification.new do |s|
185
187
  s.add_runtime_dependency(%q<json>, [">= 1.8.0", "~> 1.8"])
186
188
  s.add_runtime_dependency(%q<highline>, [">= 1.6.19", "~> 1.6"])
187
189
  s.add_runtime_dependency(%q<fluentd>, ["= 0.10.46"])
188
- s.add_runtime_dependency(%q<ruby-binlog>, [">= 1.0.2", "~> 1.0"])
189
190
  s.add_runtime_dependency(%q<fluent-plugin-mysql-binlog>, [">= 0.0.2", "~> 0.0"])
190
- s.add_runtime_dependency(%q<mysql2>, [">= 0.3.11", "~> 0.3"])
191
+ s.add_runtime_dependency(%q<mysql2>, [">= 0.3.17", "~> 0.3"])
191
192
  s.add_runtime_dependency(%q<slop>, [">= 3.4.6", "~> 3.4"])
192
193
  s.add_runtime_dependency(%q<treetop>, [">= 1.5.3", "~> 1.5"])
193
194
  s.add_runtime_dependency(%q<sys-filesystem>, [">= 1.1.3", "~> 1.1"])
194
195
  s.add_runtime_dependency(%q<io-console>, [">= 0.4.2", "~> 0.4.2"])
195
- s.add_runtime_dependency(%q<kodama>, [">= 0.1.2", "~> 0.1.2"])
196
+ s.add_runtime_dependency(%q<kodama>, [">= 0.1.3", "~> 0.1.2"])
196
197
  s.add_development_dependency(%q<jeweler>, [">= 1.8.8", "~> 1.8"])
197
198
  s.add_development_dependency(%q<rspec>, ["~> 3.0"])
198
199
  s.add_development_dependency(%q<timecop>, [">= 0.7.1", "~> 0.7"])
@@ -209,14 +210,13 @@ Gem::Specification.new do |s|
209
210
  s.add_dependency(%q<json>, [">= 1.8.0", "~> 1.8"])
210
211
  s.add_dependency(%q<highline>, [">= 1.6.19", "~> 1.6"])
211
212
  s.add_dependency(%q<fluentd>, ["= 0.10.46"])
212
- s.add_dependency(%q<ruby-binlog>, [">= 1.0.2", "~> 1.0"])
213
213
  s.add_dependency(%q<fluent-plugin-mysql-binlog>, [">= 0.0.2", "~> 0.0"])
214
- s.add_dependency(%q<mysql2>, [">= 0.3.11", "~> 0.3"])
214
+ s.add_dependency(%q<mysql2>, [">= 0.3.17", "~> 0.3"])
215
215
  s.add_dependency(%q<slop>, [">= 3.4.6", "~> 3.4"])
216
216
  s.add_dependency(%q<treetop>, [">= 1.5.3", "~> 1.5"])
217
217
  s.add_dependency(%q<sys-filesystem>, [">= 1.1.3", "~> 1.1"])
218
218
  s.add_dependency(%q<io-console>, [">= 0.4.2", "~> 0.4.2"])
219
- s.add_dependency(%q<kodama>, [">= 0.1.2", "~> 0.1.2"])
219
+ s.add_dependency(%q<kodama>, [">= 0.1.3", "~> 0.1.2"])
220
220
  s.add_dependency(%q<jeweler>, [">= 1.8.8", "~> 1.8"])
221
221
  s.add_dependency(%q<rspec>, ["~> 3.0"])
222
222
  s.add_dependency(%q<timecop>, [">= 0.7.1", "~> 0.7"])
@@ -234,14 +234,13 @@ Gem::Specification.new do |s|
234
234
  s.add_dependency(%q<json>, [">= 1.8.0", "~> 1.8"])
235
235
  s.add_dependency(%q<highline>, [">= 1.6.19", "~> 1.6"])
236
236
  s.add_dependency(%q<fluentd>, ["= 0.10.46"])
237
- s.add_dependency(%q<ruby-binlog>, [">= 1.0.2", "~> 1.0"])
238
237
  s.add_dependency(%q<fluent-plugin-mysql-binlog>, [">= 0.0.2", "~> 0.0"])
239
- s.add_dependency(%q<mysql2>, [">= 0.3.11", "~> 0.3"])
238
+ s.add_dependency(%q<mysql2>, [">= 0.3.17", "~> 0.3"])
240
239
  s.add_dependency(%q<slop>, [">= 3.4.6", "~> 3.4"])
241
240
  s.add_dependency(%q<treetop>, [">= 1.5.3", "~> 1.5"])
242
241
  s.add_dependency(%q<sys-filesystem>, [">= 1.1.3", "~> 1.1"])
243
242
  s.add_dependency(%q<io-console>, [">= 0.4.2", "~> 0.4.2"])
244
- s.add_dependency(%q<kodama>, [">= 0.1.2", "~> 0.1.2"])
243
+ s.add_dependency(%q<kodama>, [">= 0.1.3", "~> 0.1.2"])
245
244
  s.add_dependency(%q<jeweler>, [">= 1.8.8", "~> 1.8"])
246
245
  s.add_dependency(%q<rspec>, ["~> 3.0"])
247
246
  s.add_dependency(%q<timecop>, [">= 0.7.1", "~> 0.7"])
@@ -30,6 +30,18 @@ module Flydata
30
30
  end
31
31
  end
32
32
  end
33
+
34
+ def show_purpose_name
35
+ de = data_entry
36
+ log_info_stdout("Your current application name is '#{de['purpose_name']}'")
37
+ end
38
+
39
+ def data_entry
40
+ @de ||= retrieve_data_entries.first
41
+ raise "There are no data entries." unless @de
42
+ @de
43
+ end
44
+
33
45
  def register_crontab
34
46
  data_entries = retrieve_data_entries
35
47
  if data_entries.any?{|e| e['log_deletion']}
@@ -5,6 +5,7 @@ module Flydata
5
5
  module Command
6
6
  class Status < Base
7
7
  def run
8
+ show_purpose_name
8
9
  sender = Flydata::Command::Sender.new
9
10
  sender.status
10
11
  end
@@ -137,6 +137,7 @@ EOS
137
137
  # Command: flydata sync:reset
138
138
  # - Entry method
139
139
  def reset(*tables)
140
+ show_purpose_name
140
141
  # Flush client buffer
141
142
  msg = tables.empty? ? '' : " for these tables : #{tables.join(" ")}"
142
143
  return unless ask_yes_no("This resets the current sync#{msg}. Are you sure?")
@@ -285,9 +286,10 @@ EOS
285
286
  de = data_entry
286
287
 
287
288
  unless @new_tables.empty?
289
+ show_purpose_name
288
290
  unsynced_table_message = "We've noticed that these tables have not been synced yet: #{@new_tables.join(", ")}\n"
289
291
  unless @ddl_tables.empty?
290
- unsynced_table_message <<
292
+ unsynced_table_message <<
291
293
  " WARNING: We've noticed that at least one of these tables have not had their DDL generated yet.\n" +
292
294
  " We recommend you run our 'flydata sync:generate_table_ddl > create_table.sql'\n" +
293
295
  " to generate SQL to run on Redshift to create the correct tables\n" +
@@ -385,6 +387,10 @@ FlyData Sync will start synchronizing the following database tables
385
387
  database: #{de['mysql_data_entry_preference']['database']}
386
388
  tables: #{tables.join(", ")}#{data_servers}
387
389
  EOM
390
+
391
+ confirmation_text << <<-EOM if de['mysql_data_entry_preference']['ssl_ca']
392
+ ssl: Yes
393
+ EOM
388
394
  confirmation_text << <<-EOM if file_dump
389
395
  dump file: #{fp}
390
396
 
@@ -884,11 +890,19 @@ Thank you for using FlyData!
884
890
  case de['type']
885
891
  when 'RedshiftMysqlDataEntry'
886
892
  mp = de['mysql_data_entry_preference']
893
+
887
894
  if mp['tables_append_only']
888
895
  mp['tables'] = (mp['tables'].split(",") + mp['tables_append_only'].split(",")).uniq
889
896
  else
890
897
  mp['tables'] = mp['tables'].split(",").uniq
891
898
  end
899
+
900
+ unless mp['ssl_ca_content'].to_s.strip.empty?
901
+ sync_fm = create_sync_file_manager(de)
902
+ sync_fm.save_ssl_ca(mp['ssl_ca_content'])
903
+ mp['ssl_ca'] = sync_fm.ssl_ca_path
904
+ mp['sslca'] = mp['ssl_ca']
905
+ end
892
906
  else
893
907
  raise SyncDataEntryError, "No supported data entry. Only mysql-redshift sync is supported."
894
908
  end
@@ -78,13 +78,16 @@ module Flydata
78
78
 
79
79
  SELECT_QUERY_TMPLT = "SELECT %s"
80
80
  BINLOG_RETENTION_HOURS = 24
81
+ SELECT_TABLE_INFO_TMPLT = "SELECT table_name, table_type, engine FROM information_schema.tables WHERE table_schema = '%s' and table_name in(%s)"
81
82
 
82
83
  #def initialize(de_hash, dump_dir=nil)
83
84
  def initialize(dp_hash, de_hash, options={})
84
85
  super
85
- @db_opts = [:host, :port, :username, :password, :database].inject({}) {|h, sym| h[sym] = de_hash[sym.to_s]; h}
86
+ @db_opts = [:host, :port, :username, :password, :database, :ssl_ca].inject({}) {|h, sym| h[sym] = de_hash[sym.to_s]; h}
87
+ @db_opts[:sslca] = @db_opts[:ssl_ca] # for mysql2 gem
86
88
  @dump_dir = options[:dump_dir] || nil
87
89
  @backup_dir = options[:backup_dir] || nil
90
+ @tables = de_hash['tables']
88
91
  end
89
92
 
90
93
  def print_errors
@@ -202,6 +205,22 @@ module Flydata
202
205
  end
203
206
  end
204
207
 
208
+ # If table_type='VIEW' or engine='MEMORY', raise error.
209
+ def check_mysql_table_types
210
+ return if @tables.empty?
211
+ client = Mysql2::Client.new(@db_opts)
212
+ sel_query = SELECT_TABLE_INFO_TMPLT % [client.escape(@db_opts[:database]), @tables.collect{|t| "'#{client.escape(t)}'"}.join(", ")]
213
+ begin
214
+ invalid_tables = []
215
+ client.query(sel_query).each do |r|
216
+ invalid_tables.push(r['table_name']) if r['table_type'] == 'VIEW' || r['engine'] == 'MEMORY'
217
+ end
218
+ raise MysqlCompatibilityError, "FlyData does not support VIEW and MEMORY ENGINE table. Remove following tables from data entry: #{invalid_tables.join(", ")}" unless invalid_tables.empty?
219
+ ensure
220
+ client.close
221
+ end
222
+ end
223
+
205
224
  def run_mysql_retention_check(mysql_client)
206
225
  expire_logs_days_limit = BINLOG_RETENTION_HOURS / 24
207
226
  sel_query = SELECT_QUERY_TMPLT % '@@expire_logs_days'
@@ -16,6 +16,7 @@ require 'flydata/fluent-plugins/mysql/binlog_record_dispatcher'
16
16
  require 'flydata/fluent-plugins/mysql/context'
17
17
  require 'flydata/fluent-plugins/idle_event_detector'
18
18
  require 'flydata/fluent-plugins/mysql/table_meta'
19
+ require 'flydata-core/fluent/config_helper'
19
20
 
20
21
  #Monkey-patch fluentd class (EngineClass) to support shutdown for input plugin.
21
22
  #This will be called when USR1 signal is received
@@ -53,6 +54,7 @@ class MysqlBinlogFlydataInput < MysqlBinlogInput
53
54
  config_param :initial_idle_interval, :integer, :default => 30
54
55
  config_param :continuous_idle_interval, :integer, :default => 600
55
56
  config_param :check_interval, :integer, :default => 5
57
+ config_param :ssl_ca_content, :string, :default => ''
56
58
 
57
59
  def configure(conf)
58
60
  super
@@ -65,9 +67,19 @@ class MysqlBinlogFlydataInput < MysqlBinlogInput
65
67
  @sent_position_file_path = @sync_fm.sent_binlog_path(@position_file)
66
68
 
67
69
  load_custom_conf
70
+
71
+ # SSL configuration
72
+ unless @ssl_ca_content.to_s.strip.empty?
73
+ @ssl_ca_path = @sync_fm.ssl_ca_path(@position_file)
74
+ @sync_fm.save_ssl_ca(FlydataCore::Fluent::ConfigHelper.unescape_conf(@ssl_ca_content), @ssl_ca_path)
75
+ end
76
+
77
+ # Db access opts
78
+ db_opts = { host: @host, port: @port, username: @username, password: @password, database: @database, ssl_ca: @ssl_ca_path }
79
+
68
80
  $log.info "mysql host:\"#{@host}\" port:\"#{@port}\" username:\"#{@username}\" database:\"#{@database}\" tables:\"#{@tables}\" tables_append_only:\"#{tables_append_only}\""
69
81
  $log.info "mysql client version: #{`mysql -V`}"
70
- server_version = `echo 'select version();' | #{Flydata::Util::MysqlUtil.generate_mysql_cmd(host: @host, port: @port, username: @username, password: @password)} 2>/dev/null`
82
+ server_version = `echo 'select version();' | #{Flydata::Util::MysqlUtil.generate_mysql_cmd(db_opts)} 2>/dev/null`
71
83
  $log.info "mysql server version: #{server_version}"
72
84
 
73
85
  @tables = @tables.split(/,\s*/)
@@ -77,19 +89,20 @@ class MysqlBinlogFlydataInput < MysqlBinlogInput
77
89
  @omit_events[table] = [:delete, :truncate_table]
78
90
  end
79
91
 
80
- #Remove tables that do not have pos files
92
+ # Remove tables that do not have pos files
81
93
  new_tables = @sync_fm.get_new_table_list(@tables, "pos")
82
94
  @tables -= new_tables
83
95
  $log.info "Not watching these tables: #{new_tables.join(", ")}"
84
96
 
85
- table_meta = Mysql::TableMeta.new(
86
- mysql_url: mysql_url, database: @database, tables: @tables)
97
+ table_meta = Mysql::TableMeta.new(db_opts.merge(tables: @tables))
87
98
 
88
99
  table_revs = tables.inject({}) do |h, table_name|
89
100
  h[table_name] = @sync_fm.table_rev(table_name)
90
101
  h
91
102
  end
92
103
 
104
+
105
+ # Set context
93
106
  @context = Mysql::Context.new(
94
107
  database: @database, tables: @tables,
95
108
  tag: @tag, sync_fm: @sync_fm, omit_events: @omit_events,
@@ -134,6 +147,11 @@ EOS
134
147
  @context.table_meta.update
135
148
  start_kodama(mysql_url) do |c|
136
149
  c.binlog_position_file = @position_file
150
+ if @ssl_ca_path.to_s != '' && c.respond_to?(:ssl_ca=)
151
+ $log.info "SSL is enabled. (ssl_ca: #{@ssl_ca_path})"
152
+ c.ssl_ca = @ssl_ca_path
153
+ end
154
+
137
155
  if c.respond_to?(:sent_binlog_position_file=)
138
156
  $log.info "Sent position feature is enabled. sent_position_file:#{@sent_position_file_path}"
139
157
  c.sent_binlog_position_file = @sent_position_file_path
@@ -3,9 +3,11 @@ require 'mysql2'
3
3
  module Mysql
4
4
  class TableMeta
5
5
  MANDATORY_OPTS = [
6
- :mysql_url, :database, :tables
6
+ :host, :port, :username, :password,
7
+ :database, :tables,
7
8
  ]
8
9
  OPTIONAL_OPTS = [
10
+ :ssl_ca
9
11
  ]
10
12
 
11
13
  GET_TABLE_META_SQL = <<EOT
@@ -24,14 +26,17 @@ EOT
24
26
  def initialize(opts)
25
27
  missing_opts = MANDATORY_OPTS - opts.keys
26
28
  raise "Mandatory option(s) are missing: #{missing_opts.join(', ')}" unless (missing_opts.empty?)
27
- @mysql_url = opts[:mysql_url]
29
+
30
+ @db_opts = [:host, :port, :username, :password, :database, :ssl_ca].inject({}) {|h, sym| h[sym] = opts[sym]; h}
31
+ @db_opts[:sslca] = @db_opts[:ssl_ca] # for mysql2 gem
32
+
28
33
  @database = opts[:database]
29
34
  @tables = opts[:tables]
30
35
  @table_meta = Hash.new{|h, k| h[k] = {}}
31
36
  end
32
37
 
33
38
  def update
34
- conn = Mysql2::Client.new(@mysql_url)
39
+ conn = Mysql2::Client.new(@db_opts)
35
40
  sql = GET_TABLE_META_SQL % {
36
41
  database: @database, tables: @tables.collect{|t| "'#{t}'"}.join(',') }
37
42
  columns = conn.query(sql)
@@ -76,6 +76,7 @@ module Fluent
76
76
  host: {},
77
77
  username: {},
78
78
  password: {encrypted: true},
79
+ ssl_ca_content: {},
79
80
  },
80
81
  }
81
82
 
@@ -7,7 +7,7 @@ module Flydata
7
7
 
8
8
  module MysqlAccessible
9
9
  def mysql_conf(conf)
10
- @mysql_conf = [:host, :port, :username, :password, :database].inject({}) {|h, sym| h[sym] = conf[sym.to_s]; h}
10
+ @mysql_conf = [:host, :port, :username, :password, :database, :ssl_ca, :sslca].inject({}) {|h, sym| h[sym] = conf[sym.to_s]; h}
11
11
  end
12
12
 
13
13
  def mysql_cli(conf = nil)
@@ -42,7 +42,7 @@ module Flydata
42
42
  class MysqlDumpGenerator
43
43
  def initialize(conf)
44
44
  @conf = conf
45
- @db_opts = [:host, :port, :username, :password, :database].inject({}) {|h, sym| h[sym] = conf[sym.to_s]; h}
45
+ @db_opts = [:host, :port, :username, :password, :database, :ssl_ca, :sslca].inject({}) {|h, sym| h[sym] = conf[sym.to_s]; h}
46
46
  end
47
47
 
48
48
  def dump(file_path)
@@ -1062,6 +1062,13 @@ grammar MysqlAlterTable
1062
1062
  }
1063
1063
  end
1064
1064
  }
1065
+ / auto_increment_opt opt_equal nsp ulong_num {
1066
+ def action
1067
+ { action: :auto_increment,
1068
+ support_level: :nonbreaking
1069
+ }
1070
+ end
1071
+ }
1065
1072
  #TODO - There are other rules which need to be implemented when required
1066
1073
  end
1067
1074
 
@@ -105,6 +105,21 @@ module Flydata
105
105
  "#{master_binlog_path[0..-5]}.sent.pos"
106
106
  end
107
107
 
108
+ # ssl_ca file path
109
+ def ssl_ca_path(master_binlog_path = binlog_path)
110
+ unless master_binlog_path && master_binlog_path.end_with?('binlog.pos')
111
+ raise ArgumentError.new("Invalid binlog path. binlog path needs to end with 'binlog.pos'")
112
+ end
113
+ # <data-entry-name>.ssl_ca.pem
114
+ "#{master_binlog_path[0..-12]}.ssl_ca.pem"
115
+ end
116
+
117
+ def save_ssl_ca(ssl_ca_content, path = ssl_ca_path)
118
+ File.open(path, 'w') do |f|
119
+ f.write(ssl_ca_content)
120
+ end
121
+ end
122
+
108
123
  # table files
109
124
  def reset_table_position_files(tables)
110
125
  tables.each do |table_name|
@@ -12,6 +12,7 @@ module Flydata
12
12
  # - password
13
13
  # - database
14
14
  # - tables # array
15
+ # - ssl_ca
15
16
  # - custom_option # string
16
17
  def self.generate_mysql_cmd(option)
17
18
  raise ArgumentError.new("option must be hash.") unless option.kind_of?(Hash)
@@ -21,13 +22,18 @@ module Flydata
21
22
  port = option[:port] ? "-P #{option[:port]}" : nil
22
23
  username = option[:username] ? "-u#{option[:username]}" : nil
23
24
  password = if !(option[:password].to_s.empty?)
24
- "-p\"#{option[:password].gsub('`', '\\\`')}\""
25
+ "-p\"#{option[:password].gsub('$','\\$').gsub('"','\\"').gsub('`', '\\\`')}\""
25
26
  else
26
27
  nil
27
28
  end
28
29
  database = option[:database]
29
30
  tables = option[:tables] ? option[:tables].join(' ') : nil
30
- default_option = option[:no_default_option] ? nil : DEFAULT_MYSQL_CMD_OPTION
31
+ ssl_ca = option[:ssl_ca] ? option[:ssl_ca] : nil
32
+
33
+ default_option = option[:no_default_option] ? "" : DEFAULT_MYSQL_CMD_OPTION
34
+ default_option += " --ssl-ca=#{ssl_ca}" if ssl_ca
35
+ default_option = nil if default_option == ''
36
+
31
37
  custom_option = option[:custom_option]
32
38
 
33
39
  [command, host, port, username, password, default_option,
@@ -7,13 +7,15 @@ module Command
7
7
  describe Base do
8
8
  subject { described_class.new }
9
9
  let(:data_entries) {
10
- [{"id"=>4, "data_port_id"=>1, "name"=>"flydata_sync_mysql_2", "log_path"=>nil, "created_at"=>"2015-03-02T03:06:25.000Z", "updated_at"=>"2015-03-02T03:08:02.000Z", "log_deletion"=>nil, "display_name"=>"synctest", "heroku_resource_id"=>nil, "heroku_log_type"=>nil, "log_file_type"=>nil, "log_file_delimiter"=>nil, "enabled"=>true, "type"=>"RedshiftMysqlDataEntry", "tag_name"=>"flydata.c5c0eb3d_dp1.flydata_sync_mysql_2", "tag_name_dev"=>"flydata.c5c0eb3d_dp1.flydata_sync_mysql_2.dev", "data_port_key"=>"c5c0eb3d", "schema_name"=>"", "table_name"=>"", "redshift_schema_name"=>"", "redshift_table_name"=>"", "mysql_data_entry_preference"=>{"host"=>"ubertas.flydata.co", "port"=>3306, "username"=>"mak", "password"=>password, "database"=>"mak_development", "tables"=>"items,orders", "tables_append_only"=>""}}]
10
+ [{"id"=>4, "data_port_id"=>1, "name"=>"flydata_sync_mysql_2", "log_path"=>nil, "created_at"=>"2015-03-02T03:06:25.000Z", "updated_at"=>"2015-03-02T03:08:02.000Z", "log_deletion"=>nil, "display_name"=>"synctest", "heroku_resource_id"=>nil, "heroku_log_type"=>nil, "log_file_type"=>nil, "log_file_delimiter"=>nil, "enabled"=>true, "type"=>"RedshiftMysqlDataEntry", "tag_name"=>"flydata.c5c0eb3d_dp1.flydata_sync_mysql_2", "tag_name_dev"=>"flydata.c5c0eb3d_dp1.flydata_sync_mysql_2.dev", "data_port_key"=>"c5c0eb3d", "purpose_name" => "Test app", "schema_name"=>"", "table_name"=>"", "redshift_schema_name"=>"", "redshift_table_name"=>"", "mysql_data_entry_preference"=>{"host"=>"ubertas.flydata.co", "port"=>3306, "username"=>"mak", "password"=>password, "database"=>"mak_development", "tables"=>"items,orders", "tables_append_only"=>""}}]
11
11
  }
12
12
  let(:flydata) { double('flydata') }
13
13
  let(:path) { '/data_entries' }
14
14
  let(:response_body) { data_entries }
15
15
  let(:response) { double('response') }
16
16
  let(:response_code) { 200 }
17
+ let(:password) { '' }
18
+
17
19
  before do
18
20
  allow(response).to receive(:code).and_return(response_code)
19
21
  allow(flydata).to receive(:get).with(path).and_return(response_body)
@@ -37,8 +39,13 @@ describe Base do
37
39
  end
38
40
  end
39
41
 
42
+ describe "#show_purpose_name" do
43
+ it "calls log_info_stdout with appropriate message" do
44
+ expect(subject).to receive(:log_info_stdout).with("Your current application name is 'Test app'")
45
+ subject.show_purpose_name
46
+ end
47
+ end
40
48
  end
41
49
 
42
50
  end
43
51
  end
44
-
@@ -8,6 +8,7 @@ module Flydata
8
8
  let(:sender) { double("sender") }
9
9
 
10
10
  it do
11
+ expect(subject).to receive(:show_purpose_name)
11
12
  expect(Flydata::Command::Sender).to receive(:new).and_return(sender)
12
13
  expect(sender).to receive(:status)
13
14
  subject.run
@@ -138,6 +138,49 @@ module Flydata
138
138
  end
139
139
  end
140
140
  end
141
- end
142
141
 
142
+ describe "#check_mysql_table_types" do
143
+ let(:test_data_entry) do
144
+ { "host" => "test",
145
+ "port" => 1234,
146
+ "username" => "test",
147
+ "password" => "password",
148
+ "database" => "test_db",
149
+ "tables"=>["normal_table", "engine_table", "view_table"] }
150
+ end
151
+ let(:normal_table) { {"table_name"=>"normal_table", "table_type"=>"BASE TABLE", "engine"=>"InnoDB"} }
152
+ let(:engine_table) { {"table_name"=>"engine_table", "table_type"=>"BASE TABLE", "engine"=>"MEMORY"} }
153
+ let(:view) { {"table_name"=>"view_table", "table_type"=>"VIEW", "engine"=>nil} }
154
+ let(:client) { double('client') }
155
+ let(:subject_object) { MysqlCompatibilityCheck.new(:default_data_port,test_data_entry, {}) }
156
+ let(:error) { Flydata::MysqlCompatibilityCheck::MysqlCompatibilityError }
157
+ let(:base_error_msg) { "FlyData does not support VIEW and MEMORY ENGINE table. Remove following tables from data entry: %s" }
158
+ subject { subject_object.check_mysql_table_types }
159
+ before do
160
+ allow(Mysql2::Client).to receive(:new).and_return(client)
161
+ allow(client).to receive(:query).and_return(table_list)
162
+ allow(client).to receive(:escape).and_return("aaa")
163
+ allow(client).to receive(:close)
164
+ end
165
+ context "where data entry has VIEW and MEMORY engine table" do
166
+ let(:error_msg) { base_error_msg % engine_table['table_name'] + ', ' + view['table_name'] }
167
+ let(:table_list) { [ engine_table, view ] }
168
+ it { expect{subject}.to raise_error(error, /#{error_msg}/) }
169
+ end
170
+ context "where data entry has MEMORY engine table" do
171
+ let(:error_msg) { base_error_msg % engine_table['table_name'] }
172
+ let(:table_list) { [ engine_table ] }
173
+ it { expect{subject}.to raise_error(error, /#{error_msg}/) }
174
+ end
175
+ context "where data entry has the VIEW" do
176
+ let(:error_msg) { base_error_msg % view['table_name'] }
177
+ let(:table_list) { [ view ] }
178
+ it { expect{subject}.to raise_error(error, /#{error_msg}/) }
179
+ end
180
+ context "where data entry does not have either VIEW and ENGINE table" do
181
+ let(:table_list) { [ normal_table ] }
182
+ it { expect{subject}.to_not raise_error }
183
+ end
184
+ end
185
+ end
143
186
  end
@@ -3,13 +3,12 @@ require 'flydata/fluent-plugins/mysql/table_meta'
3
3
 
4
4
  module Mysql
5
5
  describe TableMeta do
6
- let(:mysql_url) { double('mysql_url') }
6
+ let(:db_opts) { { host: 'test-host', port: 3306, username: 'test-user', password: 'test-pswd', database: 'test-db' } }
7
7
  let(:database) { 'test-db' }
8
8
  let(:tables) { %w(a_table b_table c_table) }
9
9
 
10
10
  let(:conn) { double('conn') }
11
- let(:table_meta) { TableMeta.new(
12
- mysql_url: mysql_url, database: database, tables: tables) }
11
+ let(:table_meta) { TableMeta.new(db_opts.merge(database: database, tables: tables)) }
13
12
 
14
13
  before do
15
14
  allow(conn).to receive(:close)
@@ -1365,6 +1365,17 @@ describe 'MysqlAlterTableParser' do
1365
1365
  let(:alter_table_action) { "engine#{equal} #{storage_engine}"}
1366
1366
  it_behaves_like "test optional equal", "test storage engines", "a parser parsing a nonbreaking query"
1367
1367
  end
1368
+ context "set auto increment" do
1369
+ let(:action) { :auto_increment }
1370
+ context "single digit number" do
1371
+ let(:alter_table_action) { "auto_increment#{equal} 1"}
1372
+ it_behaves_like "test optional equal", "a parser parsing a nonbreaking query"
1373
+ end
1374
+ context "multi digit number" do
1375
+ let(:alter_table_action) { "AUTO_INCREMENT#{equal} 1234"}
1376
+ it_behaves_like "test optional equal", "a parser parsing a nonbreaking query"
1377
+ end
1378
+ end
1368
1379
  end
1369
1380
  context "force" do
1370
1381
  let(:alter_table_action) { "force" }
@@ -194,6 +194,36 @@ module Flydata
194
194
  end
195
195
  end
196
196
 
197
+ describe '#ssl_ca_path' do
198
+ context 'with no args' do
199
+ subject { default_sfm.ssl_ca_path }
200
+ it { is_expected.to eq("#{FLYDATA_HOME}/flydata_sync_mysql.ssl_ca.pem") }
201
+ end
202
+ context 'with invalid args' do
203
+ subject { default_sfm.ssl_ca_path('/home/ec2-user/.flydata/flydata_sync.pos') }
204
+ it { expect{subject}.to raise_error(ArgumentError) }
205
+ end
206
+ context 'with valid args' do
207
+ subject { default_sfm.ssl_ca_path('/home/ec2-user/.flydata/flydata_sync.binlog.pos') }
208
+ it { is_expected.to eq('/home/ec2-user/.flydata/flydata_sync.ssl_ca.pem') }
209
+ end
210
+ end
211
+
212
+ describe '#save_ssl_ca_path' do
213
+ let(:ssl_ca_path) { default_sfm.ssl_ca_path }
214
+ let(:ssl_ca_content) { 'aaaaabbbbbccccc' }
215
+ subject { default_sfm.save_ssl_ca(ssl_ca_content) }
216
+
217
+ after do
218
+ File.delete(ssl_ca_path)
219
+ end
220
+
221
+ it 'write a ssl_ca_content to ssl_ca_path' do
222
+ subject
223
+ expect(IO.read(ssl_ca_path)).to eq(ssl_ca_content)
224
+ end
225
+ end
226
+
197
227
  describe '#increment_and_save_table_position' do
198
228
  let(:test_table) { 'test_table' }
199
229
  before do
@@ -1,4 +1,5 @@
1
1
  require 'spec_helper'
2
+ require 'flydata/util/mysql_util'
2
3
 
3
4
  module Flydata
4
5
  module Util
@@ -13,6 +14,7 @@ module Flydata
13
14
  database: 'testdb',
14
15
  } }
15
16
  let(:option) { default_option }
17
+ let(:cmd_pswd_check) { 'mysqldump -h test-host -P 3306 -utestuser -p%s --default-character-set=utf8 --protocol=tcp testdb' }
16
18
 
17
19
  describe '.generate_mysql_cmd' do
18
20
  subject { described_class.generate_mysql_cmd(option) }
@@ -50,11 +52,29 @@ module Flydata
50
52
  ) }
51
53
  end
52
54
 
53
- context 'when password is empty' do
55
+ context 'when password is not empty' do
54
56
  before { option[:password] = "abc`def" }
55
- it { is_expected.to eq(
56
- 'mysqldump -h test-host -P 3306 -utestuser -p"abc\\`def" --default-character-set=utf8 --protocol=tcp testdb'
57
- ) }
57
+ it { is_expected.to eq(cmd_pswd_check % '"abc\\`def"' ) }
58
+ end
59
+
60
+ context 'when password includes double quate' do
61
+ before { option[:password] = "abc\"def" }
62
+ it { is_expected.to eq(cmd_pswd_check % '"abc\\"def"') }
63
+ end
64
+
65
+ context 'when password includes dollars sign' do
66
+ before { option[:password] = "abc$def" }
67
+ it { is_expected.to eq(cmd_pswd_check % '"abc\\$def"' ) }
68
+ end
69
+
70
+ context 'when password includes multiple special characters' do
71
+ before { option[:password] = "ab\"\"c$$def" }
72
+ it { is_expected.to eq(cmd_pswd_check % '"ab\\"\\"c\\$\\$def"' ) }
73
+ end
74
+
75
+ context 'when password does not includes special characters' do
76
+ before { option[:password] = "abcdef" }
77
+ it { is_expected.to eq(cmd_pswd_check % '"abcdef"' ) }
58
78
  end
59
79
 
60
80
  context 'when tables are specified' do
@@ -64,6 +84,13 @@ module Flydata
64
84
  ) }
65
85
  end
66
86
 
87
+ context 'when ssl_ca is specified' do
88
+ before { option[:ssl_ca] = 'mysql_sync.ssl_ca.pem' }
89
+ it { is_expected.to eq(
90
+ 'mysqldump -h test-host -P 3306 -utestuser -p"testpassword" --default-character-set=utf8 --protocol=tcp --ssl-ca=mysql_sync.ssl_ca.pem testdb'
91
+ ) }
92
+ end
93
+
67
94
  context 'when no_default_option is turned on' do
68
95
  before { option[:no_default_option] = true }
69
96
  it { is_expected.to eq(
@@ -71,7 +98,6 @@ module Flydata
71
98
  ) }
72
99
  end
73
100
 
74
-
75
101
  context 'with options for mysql_protocol_tcp_compat' do
76
102
  before {
77
103
  option[:command] = 'mysql'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flydata
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.13
4
+ version: 0.3.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Koichi Fujikawa
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2015-04-09 00:00:00.000000000 Z
15
+ date: 2015-04-19 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rest-client
@@ -122,26 +122,6 @@ dependencies:
122
122
  - - '='
123
123
  - !ruby/object:Gem::Version
124
124
  version: 0.10.46
125
- - !ruby/object:Gem::Dependency
126
- name: ruby-binlog
127
- requirement: !ruby/object:Gem::Requirement
128
- requirements:
129
- - - '>='
130
- - !ruby/object:Gem::Version
131
- version: 1.0.2
132
- - - ~>
133
- - !ruby/object:Gem::Version
134
- version: '1.0'
135
- type: :runtime
136
- prerelease: false
137
- version_requirements: !ruby/object:Gem::Requirement
138
- requirements:
139
- - - '>='
140
- - !ruby/object:Gem::Version
141
- version: 1.0.2
142
- - - ~>
143
- - !ruby/object:Gem::Version
144
- version: '1.0'
145
125
  - !ruby/object:Gem::Dependency
146
126
  name: fluent-plugin-mysql-binlog
147
127
  requirement: !ruby/object:Gem::Requirement
@@ -168,7 +148,7 @@ dependencies:
168
148
  requirements:
169
149
  - - '>='
170
150
  - !ruby/object:Gem::Version
171
- version: 0.3.11
151
+ version: 0.3.17
172
152
  - - ~>
173
153
  - !ruby/object:Gem::Version
174
154
  version: '0.3'
@@ -178,7 +158,7 @@ dependencies:
178
158
  requirements:
179
159
  - - '>='
180
160
  - !ruby/object:Gem::Version
181
- version: 0.3.11
161
+ version: 0.3.17
182
162
  - - ~>
183
163
  - !ruby/object:Gem::Version
184
164
  version: '0.3'
@@ -268,7 +248,7 @@ dependencies:
268
248
  requirements:
269
249
  - - '>='
270
250
  - !ruby/object:Gem::Version
271
- version: 0.1.2
251
+ version: 0.1.3
272
252
  - - ~>
273
253
  - !ruby/object:Gem::Version
274
254
  version: 0.1.2
@@ -278,7 +258,7 @@ dependencies:
278
258
  requirements:
279
259
  - - '>='
280
260
  - !ruby/object:Gem::Version
281
- version: 0.1.2
261
+ version: 0.1.3
282
262
  - - ~>
283
263
  - !ruby/object:Gem::Version
284
264
  version: 0.1.2
@@ -488,12 +468,14 @@ files:
488
468
  - flydata-core/lib/flydata-core/core_ext/object/prepend.rb
489
469
  - flydata-core/lib/flydata-core/errors.rb
490
470
  - flydata-core/lib/flydata-core/fluent-plugins/multi_buffer.rb
471
+ - flydata-core/lib/flydata-core/fluent/config_helper.rb
491
472
  - flydata-core/lib/flydata-core/logger.rb
492
473
  - flydata-core/lib/flydata-core/table_def.rb
493
474
  - flydata-core/lib/flydata-core/table_def/mysql_table_def.rb
494
475
  - flydata-core/lib/flydata-core/table_def/redshift_table_def.rb
495
476
  - flydata-core/lib/flydata-core/thread_context.rb
496
477
  - flydata-core/spec/config/user_maintenance_spec.rb
478
+ - flydata-core/spec/fluent/config_helper_spec.rb
497
479
  - flydata-core/spec/logger_spec.rb
498
480
  - flydata-core/spec/spec_helper.rb
499
481
  - flydata-core/spec/table_def/mysql_table_def_spec.rb
@@ -632,7 +614,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
632
614
  version: '0'
633
615
  requirements: []
634
616
  rubyforge_project:
635
- rubygems_version: 2.4.3
617
+ rubygems_version: 2.4.6
636
618
  signing_key:
637
619
  specification_version: 4
638
620
  summary: FlyData Agent