fluentd 1.7.1 → 1.7.2

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of fluentd might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5bb8d41e15ede72bfbb90c06171c0eb4aa77d479cda1a8320f60e6166fbc27fc
4
- data.tar.gz: d781e152f408a74e1cfed6b2c37f593db814d551d9f9179d1c5d15581218bf43
3
+ metadata.gz: 1ce449e77af62c25fcef41773c3717738ec443550becdde0ca666710739f7eae
4
+ data.tar.gz: 00d125b1c53ac99c8d2edf8b915909b91e07642e7fdad35154147a3b5a472416
5
5
  SHA512:
6
- metadata.gz: 1f04e656acafae78bf4e2a770a5df16d549aa59ecd0a5883e97884b1de2dccc612108b11a1302b0655a2d56e3fb0b5f077da345441f34ce94a6bc5d31b3fac61
7
- data.tar.gz: d16a3635f5c9607de95f66f3b836c44786abd7db9a4bb369b51f41862df0279bc3812962c633fe8ac8ad9f4439fe22b8aaf18ff7aa099dafe531956c0a33985e
6
+ metadata.gz: d78a18ab98f55b3568b0e401f87d80444d14b09b544fc4962a14bf821180c5f97a155332888961ce096adfa9ae6d01def4a154dc4a769939b6256846cf0b14b3
7
+ data.tar.gz: cc36a5137a9753d9888f6669d04dbfe943d35d3cb030f5718fa439f957e8658632e96246b219151b73f46a2ac74191a0f6e87f049aae1fe446b2e62fc3c4a274
@@ -1,5 +1,22 @@
1
1
  # v1.7
2
2
 
3
+ ## Release v1.7.2 - 2019/09/19
4
+
5
+ ### Enhancement
6
+
7
+ * in_tcp: Add security/client to restrict access
8
+ https://github.com/fluent/fluentd/pull/2622
9
+
10
+ ### Bug fixes
11
+
12
+ * buf_file/buf_file_single: fix to handle compress data during restart
13
+ https://github.com/fluent/fluentd/pull/2620
14
+ * plugin: Use `__send__` to avoid conflict with user defined `send`
15
+ https://github.com/fluent/fluentd/pull/2614
16
+ * buffer: reject invalid timekey at configure phase
17
+ https://github.com/fluent/fluentd/pull/2615
18
+
19
+
3
20
  ## Release v1.7.1 - 2019/09/08
4
21
 
5
22
  ### Enhancement
@@ -146,7 +146,7 @@ module Fluent
146
146
  end
147
147
 
148
148
  begin
149
- chunk = Fluent::Plugin::Buffer::FileChunk.new(m, path, mode) # file chunk resumes contents of metadata
149
+ chunk = Fluent::Plugin::Buffer::FileChunk.new(m, path, mode, compress: @compress) # file chunk resumes contents of metadata
150
150
  rescue Fluent::Plugin::Buffer::FileChunk::FileChunkError => e
151
151
  handle_broken_files(path, mode, e)
152
152
  next
@@ -167,7 +167,7 @@ module Fluent
167
167
  end
168
168
 
169
169
  begin
170
- chunk = Fluent::Plugin::Buffer::FileSingleChunk.new(m, path, mode, @key_in_path)
170
+ chunk = Fluent::Plugin::Buffer::FileSingleChunk.new(m, path, mode, @key_in_path, compress: @compress)
171
171
  chunk.restore_size(@chunk_format) if @calc_num_records
172
172
  rescue Fluent::Plugin::Buffer::FileSingleChunk::FileChunkError => e
173
173
  handle_broken_files(path, mode, e)
@@ -41,6 +41,16 @@ module Fluent::Plugin
41
41
  desc 'The payload is read up to this character.'
42
42
  config_param :delimiter, :string, default: "\n" # syslog family add "\n" to each message and this seems only way to split messages in tcp stream
43
43
 
44
+ # in_forward like host/network restriction
45
+ config_section :security, required: false, multi: false do
46
+ config_section :client, param_name: :clients, required: true, multi: true do
47
+ desc 'The IP address or host name of the client'
48
+ config_param :host, :string, default: nil
49
+ desc 'Network address specification'
50
+ config_param :network, :string, default: nil
51
+ end
52
+ end
53
+
44
54
  def configure(conf)
45
55
  compat_parameters_convert(conf, :parser)
46
56
  parser_config = conf.elements('parse').first
@@ -51,6 +61,33 @@ module Fluent::Plugin
51
61
  @_event_loop_blocking_timeout = @blocking_timeout
52
62
  @source_hostname_key ||= @source_host_key if @source_host_key
53
63
 
64
+ @nodes = nil
65
+ if @security
66
+ @nodes = []
67
+ @security.clients.each do |client|
68
+ if client.host && client.network
69
+ raise Fluent::ConfigError, "both of 'host' and 'network' are specified for client"
70
+ end
71
+ if !client.host && !client.network
72
+ raise Fluent::ConfigError, "Either of 'host' and 'network' must be specified for client"
73
+ end
74
+ source = nil
75
+ if client.host
76
+ begin
77
+ source = IPSocket.getaddress(client.host)
78
+ rescue SocketError
79
+ raise Fluent::ConfigError, "host '#{client.host}' cannot be resolved"
80
+ end
81
+ end
82
+ source_addr = begin
83
+ IPAddr.new(source || client.network)
84
+ rescue ArgumentError
85
+ raise Fluent::ConfigError, "network '#{client.network}' address format is invalid"
86
+ end
87
+ @nodes.push(source_addr)
88
+ end
89
+ end
90
+
54
91
  @parser = parser_create(conf: parser_config)
55
92
  end
56
93
 
@@ -64,6 +101,11 @@ module Fluent::Plugin
64
101
  del_size = @delimiter.length
65
102
  if @_extract_enabled && @_extract_tag_key
66
103
  server_create(:in_tcp_server_single_emit, @port, bind: @bind, resolve_name: !!@source_hostname_key) do |data, conn|
104
+ unless check_client(conn)
105
+ conn.close
106
+ next
107
+ end
108
+
67
109
  conn.buffer << data
68
110
  buf = conn.buffer
69
111
  pos = 0
@@ -89,6 +131,11 @@ module Fluent::Plugin
89
131
  end
90
132
  else
91
133
  server_create(:in_tcp_server_batch_emit, @port, bind: @bind, resolve_name: !!@source_hostname_key) do |data, conn|
134
+ unless check_client(conn)
135
+ conn.close
136
+ next
137
+ end
138
+
92
139
  conn.buffer << data
93
140
  buf = conn.buffer
94
141
  pos = 0
@@ -114,5 +161,20 @@ module Fluent::Plugin
114
161
  end
115
162
  end
116
163
  end
164
+
165
+ private
166
+
167
+ def check_client(conn)
168
+ if @nodes
169
+ remote_addr = conn.remote_addr
170
+ node = @nodes.find { |n| n.include?(remote_addr) rescue false }
171
+ unless node
172
+ log.warn "anonymous client '#{remote_addr}' denied"
173
+ return false
174
+ end
175
+ end
176
+
177
+ true
178
+ end
117
179
  end
118
180
  end
@@ -94,7 +94,7 @@ module Fluent
94
94
  @outputs.each do |o|
95
95
  begin
96
96
  log.debug "calling #{method_name} on output plugin dynamically created", type: Fluent::Plugin.lookup_type_from_class(o.class), plugin_id: o.plugin_id
97
- o.send(method_name) unless o.send(checker_name)
97
+ o.__send__(method_name) unless o.__send__(checker_name)
98
98
  rescue Exception => e
99
99
  log.warn "unexpected error while calling #{method_name} on output plugin dynamically created", plugin: o.class, plugin_id: o.plugin_id, error: e
100
100
  log.warn_backtrace
@@ -310,6 +310,9 @@ module Fluent
310
310
  Fluent::Timezone.validate!(@buffer_config.timekey_zone)
311
311
  @timekey_zone = @buffer_config.timekey_use_utc ? '+0000' : @buffer_config.timekey_zone
312
312
  @timekey = @buffer_config.timekey
313
+ if @timekey <= 0
314
+ raise Fluent::ConfigError, "timekey should be greater than 0. current timekey: #{@timekey}"
315
+ end
313
316
  @timekey_use_utc = @buffer_config.timekey_use_utc
314
317
  @offset = Fluent::Timezone.utc_offset(@timekey_zone)
315
318
  @calculate_offset = @offset.respond_to?(:call) ? @offset : nil
@@ -103,7 +103,7 @@ module Fluent
103
103
  def formatter_operate(method_name, &block)
104
104
  @_formatters.each_pair do |usage, formatter|
105
105
  begin
106
- formatter.send(method_name)
106
+ formatter.__send__(method_name)
107
107
  block.call(formatter) if block_given?
108
108
  rescue => e
109
109
  log.error "unexpected error while #{method_name}", usage: usage, formatter: formatter, error: e
@@ -103,7 +103,7 @@ module Fluent
103
103
  def parser_operate(method_name, &block)
104
104
  @_parsers.each_pair do |usage, parser|
105
105
  begin
106
- parser.send(method_name)
106
+ parser.__send__(method_name)
107
107
  block.call(parser) if block_given?
108
108
  rescue => e
109
109
  log.error "unexpected error while #{method_name}", usage: usage, parser: parser, error: e
@@ -138,7 +138,7 @@ module Fluent
138
138
  @_storages.each_pair do |usage, s|
139
139
  begin
140
140
  block.call(s) if block_given?
141
- s.storage.send(method_name)
141
+ s.storage.__send__(method_name)
142
142
  rescue => e
143
143
  log.error "unexpected error while #{method_name}", usage: usage, storage: s.storage, error: e
144
144
  end
@@ -240,7 +240,7 @@ module Fluent
240
240
  lifecycle do |instance, kind|
241
241
  begin
242
242
  log.debug "calling #{method} on #{kind} plugin", type: Plugin.lookup_type_from_class(instance.class), plugin_id: instance.plugin_id
243
- instance.send(method) unless instance.send(checker)
243
+ instance.__send__(method) unless instance.__send__(checker)
244
244
  rescue Exception => e
245
245
  log.warn "unexpected error while calling #{method} on #{kind} plugin", plugin: instance.class, plugin_id: instance.plugin_id, error: e
246
246
  log.warn_backtrace
@@ -270,17 +270,17 @@ module Fluent
270
270
  operation = "preparing shutdown" # for logging
271
271
  log.debug "#{operation} #{kind} plugin", type: Plugin.lookup_type_from_class(instance.class), plugin_id: instance.plugin_id
272
272
  begin
273
- instance.send(:before_shutdown) unless instance.send(:before_shutdown?)
273
+ instance.__send__(:before_shutdown) unless instance.__send__(:before_shutdown?)
274
274
  rescue Exception => e
275
275
  log.warn "unexpected error while #{operation} on #{kind} plugin", plugin: instance.class, plugin_id: instance.plugin_id, error: e
276
276
  log.warn_backtrace
277
277
  end
278
278
  operation = "shutting down"
279
279
  log.info "#{operation} #{kind} plugin", type: Plugin.lookup_type_from_class(instance.class), plugin_id: instance.plugin_id
280
- instance.send(:shutdown) unless instance.send(:shutdown?)
280
+ instance.__send__(:shutdown) unless instance.__send__(:shutdown?)
281
281
  else
282
282
  log.debug "#{operation} #{kind} plugin", type: Plugin.lookup_type_from_class(instance.class), plugin_id: instance.plugin_id
283
- instance.send(method) unless instance.send(checker)
283
+ instance.__send__(method) unless instance.__send__(checker)
284
284
  end
285
285
  rescue Exception => e
286
286
  log.warn "unexpected error while #{operation} on #{kind} plugin", plugin: instance.class, plugin_id: instance.plugin_id, error: e
@@ -136,7 +136,7 @@ module Fluent
136
136
  supervisor_value = instance_variable_get("@#{param}")
137
137
  next if supervisor_value.nil? # it's not configured by command line options
138
138
 
139
- system.send("#{param}=", supervisor_value)
139
+ system.__send__("#{param}=", supervisor_value)
140
140
  end
141
141
  end
142
142
  }
@@ -179,7 +179,7 @@ module Fluent
179
179
  @_system_config = (defined?($_system_config) && $_system_config ? $_system_config : Fluent::Engine.system_config).dup
180
180
  end
181
181
  opts.each_pair do |key, value|
182
- @_system_config.send(:"#{key.to_s}=", value)
182
+ @_system_config.__send__(:"#{key.to_s}=", value)
183
183
  end
184
184
  end
185
185
  end
@@ -16,6 +16,6 @@
16
16
 
17
17
  module Fluent
18
18
 
19
- VERSION = '1.7.1'
19
+ VERSION = '1.7.2'
20
20
 
21
21
  end
@@ -163,6 +163,46 @@ class TcpInputTest < Test::Unit::TestCase
163
163
  assert_equal address, event[2]['addr']
164
164
  end
165
165
 
166
+ sub_test_case '<security>' do
167
+ test 'accept from allowed client' do
168
+ d = create_driver(CONFIG + %!
169
+ <security>
170
+ <client>
171
+ network 127.0.0.1
172
+ </client>
173
+ </security>
174
+ !)
175
+ d.run(expect_records: 1) do
176
+ create_tcp_socket('127.0.0.1', PORT) do |sock|
177
+ sock.send("hello\n", 0)
178
+ end
179
+ end
180
+
181
+ assert_equal 1, d.events.size
182
+ event = d.events[0]
183
+ assert_equal 'tcp', event[0]
184
+ assert_equal 'hello', event[2]['message']
185
+ end
186
+
187
+ test 'deny from disallowed client' do
188
+ d = create_driver(CONFIG + %!
189
+ <security>
190
+ <client>
191
+ network 200.0.0.0
192
+ </client>
193
+ </security>
194
+ !)
195
+ d.run(shutdown: false, expect_records: 1, timeout: 2) do
196
+ create_tcp_socket('127.0.0.1', PORT) do |sock|
197
+ sock.send("hello\n", 0)
198
+ end
199
+ end
200
+
201
+ assert_equal 1, d.instance.log.logs.count { |l| l =~ /anonymous client/ }
202
+ assert_equal 0, d.events.size
203
+ end
204
+ end
205
+
166
206
  sub_test_case '<extract>' do
167
207
  test 'extract tag from record field' do
168
208
  d = create_driver(BASE_CONFIG + %!
@@ -868,6 +868,23 @@ class OutputTest < Test::Unit::TestCase
868
868
  end
869
869
  end
870
870
 
871
+ test 'raises an error if timekey is less than equal 0' do
872
+ i = create_output(:delayed)
873
+ assert_raise Fluent::ConfigError.new('timekey should be greater than 0. current timekey: 0.0') do
874
+ i.configure(config_element('ROOT','',{},[config_element('buffer', 'time', { "timekey" => nil })]))
875
+ end
876
+
877
+ i = create_output(:delayed)
878
+ assert_raise Fluent::ConfigError.new('timekey should be greater than 0. current timekey: 0.0') do
879
+ i.configure(config_element('ROOT','',{},[config_element('buffer', 'time', { "timekey" => 0 })]))
880
+ end
881
+
882
+ i = create_output(:delayed)
883
+ assert_raise Fluent::ConfigError.new('timekey should be greater than 0. current timekey: -1.0') do
884
+ i.configure(config_element('ROOT','',{},[config_element('buffer', 'time', { "timekey" => -1 })]))
885
+ end
886
+ end
887
+
871
888
  sub_test_case 'sync output feature' do
872
889
  setup do
873
890
  @i = create_output(:sync)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluentd
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.1
4
+ version: 1.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sadayuki Furuhashi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-09 00:00:00.000000000 Z
11
+ date: 2019-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack