fluentd 1.9.0-x64-mingw32 → 1.9.1-x64-mingw32
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 +4 -4
- data/.github/PULL_REQUEST_TEMPLATE.md +2 -1
- data/CHANGELOG.md +24 -0
- data/Gemfile +0 -2
- data/appveyor.yml +5 -14
- data/fluentd.gemspec +2 -1
- data/lib/fluent/config/section.rb +4 -0
- data/lib/fluent/plugin/in_monitor_agent.rb +1 -1
- data/lib/fluent/plugin/in_tail.rb +12 -139
- data/lib/fluent/plugin/in_tail/position_file.rb +171 -0
- data/lib/fluent/plugin/out_forward.rb +3 -2
- data/lib/fluent/plugin/out_http.rb +10 -4
- data/lib/fluent/plugin/output.rb +1 -1
- data/lib/fluent/plugin/parser_syslog.rb +5 -2
- data/lib/fluent/plugin_helper/cert_option.rb +5 -2
- data/lib/fluent/plugin_helper/http_server.rb +62 -2
- data/lib/fluent/plugin_helper/http_server/compat/server.rb +14 -3
- data/lib/fluent/plugin_helper/http_server/compat/ssl_context_extractor.rb +52 -0
- data/lib/fluent/plugin_helper/http_server/server.rb +14 -8
- data/lib/fluent/plugin_helper/http_server/ssl_context_builder.rb +41 -0
- data/lib/fluent/plugin_helper/server.rb +5 -10
- data/lib/fluent/plugin_helper/socket.rb +4 -8
- data/lib/fluent/tls.rb +81 -0
- data/lib/fluent/version.rb +1 -1
- data/test/config/test_section.rb +0 -2
- data/test/plugin/in_tail/test_position_file.rb +192 -0
- data/test/plugin/test_in_tail.rb +13 -0
- data/test/plugin/test_out_http.rb +15 -2
- data/test/plugin/test_output_as_buffered_backup.rb +2 -1
- data/test/plugin/test_parser_syslog.rb +36 -0
- data/test/plugin_helper/data/cert/generate_cert.rb +87 -0
- data/test/plugin_helper/data/cert/with_ca/ca-cert-key-pass.pem +30 -0
- data/test/plugin_helper/data/cert/with_ca/ca-cert-key.pem +27 -0
- data/test/plugin_helper/data/cert/with_ca/ca-cert-pass.pem +20 -0
- data/test/plugin_helper/data/cert/with_ca/ca-cert.pem +20 -0
- data/test/plugin_helper/data/cert/with_ca/cert-key-pass.pem +30 -0
- data/test/plugin_helper/data/cert/with_ca/cert-key.pem +27 -0
- data/test/plugin_helper/data/cert/with_ca/cert-pass.pem +21 -0
- data/test/plugin_helper/data/cert/with_ca/cert.pem +21 -0
- data/test/plugin_helper/data/cert/without_ca/cert-key-pass.pem +30 -0
- data/test/plugin_helper/data/cert/without_ca/cert-key.pem +27 -0
- data/test/plugin_helper/data/cert/without_ca/cert-pass.pem +20 -0
- data/test/plugin_helper/data/cert/without_ca/cert.pem +20 -0
- data/test/plugin_helper/test_http_server_helper.rb +168 -7
- data/test/plugin_helper/test_server.rb +40 -9
- data/test/test_tls.rb +65 -0
- metadata +52 -4
data/lib/fluent/tls.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
#
|
2
|
+
# Fluentd
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
require 'openssl'
|
18
|
+
require 'fluent/config/error'
|
19
|
+
|
20
|
+
module Fluent
|
21
|
+
module TLS
|
22
|
+
DEFAULT_VERSION = :'TLSv1_2'
|
23
|
+
SUPPORTED_VERSIONS = if defined?(OpenSSL::SSL::TLS1_3_VERSION)
|
24
|
+
[:'TLSv1_1', :'TLSv1_2', :'TLSv1_3', :'TLS1_1', :'TLS1_2', :'TLS1_3'].freeze
|
25
|
+
else
|
26
|
+
[:'TLSv1_1', :'TLSv1_2', :'TLS1_1', :'TLS1_2'].freeze
|
27
|
+
end
|
28
|
+
### follow httpclient configuration by nahi
|
29
|
+
# OpenSSL 0.9.8 default: "ALL:!ADH:!LOW:!EXP:!MD5:+SSLv2:@STRENGTH"
|
30
|
+
CIPHERS_DEFAULT = "ALL:!aNULL:!eNULL:!SSLv2".freeze # OpenSSL >1.0.0 default
|
31
|
+
|
32
|
+
METHODS_MAP = begin
|
33
|
+
map = {
|
34
|
+
TLSv1: OpenSSL::SSL::TLS1_VERSION,
|
35
|
+
TLSv1_1: OpenSSL::SSL::TLS1_1_VERSION,
|
36
|
+
TLSv1_2: OpenSSL::SSL::TLS1_2_VERSION
|
37
|
+
}
|
38
|
+
map[:'TLSv1_3'] = OpenSSL::SSL::TLS1_3_VERSION if defined?(OpenSSL::SSL::TLS1_3_VERSION)
|
39
|
+
MIN_MAX_AVAILABLE = true
|
40
|
+
map.freeze
|
41
|
+
rescue NameError
|
42
|
+
# ruby 2.4 doesn't have OpenSSL::SSL::TLSXXX constants and min_version=/max_version= methods
|
43
|
+
map = {
|
44
|
+
TLS1: :'TLSv1',
|
45
|
+
TLS1_1: :'TLSv1_1',
|
46
|
+
TLS1_2: :'TLSv1_2',
|
47
|
+
}.freeze
|
48
|
+
MIN_MAX_AVAILABLE = false
|
49
|
+
map
|
50
|
+
end
|
51
|
+
private_constant :METHODS_MAP
|
52
|
+
|
53
|
+
# Helper for old syntax/method support:
|
54
|
+
# ruby 2.4 uses ssl_version= but this method is now deprecated.
|
55
|
+
# min_version=/max_version= use 'TLS1_2' but ssl_version= uses 'TLSv1_2'
|
56
|
+
def set_version_to_context(ctx, version, min_version, max_version)
|
57
|
+
if MIN_MAX_AVAILABLE
|
58
|
+
case
|
59
|
+
when min_version.nil? && max_version.nil?
|
60
|
+
min_version = METHODS_MAP[version] || version
|
61
|
+
max_version = METHODS_MAP[version] || version
|
62
|
+
when min_version.nil? && max_version
|
63
|
+
raise Fluent::ConfigError, "When you set max_version, must set min_version together"
|
64
|
+
when min_version && max_version.nil?
|
65
|
+
raise Fluent::ConfigError, "When you set min_version, must set max_version together"
|
66
|
+
else
|
67
|
+
min_version = METHODS_MAP[min_version] || min_version
|
68
|
+
max_version = METHODS_MAP[max_version] || max_version
|
69
|
+
end
|
70
|
+
ctx.min_version = min_version
|
71
|
+
ctx.max_version = max_version
|
72
|
+
else
|
73
|
+
ctx.ssl_version = METHODS_MAP[version] || version
|
74
|
+
end
|
75
|
+
|
76
|
+
ctx
|
77
|
+
end
|
78
|
+
module_function :set_version_to_context
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
data/lib/fluent/version.rb
CHANGED
data/test/config/test_section.rb
CHANGED
@@ -40,8 +40,6 @@ module Fluent::Config
|
|
40
40
|
assert_equal("email", s1.send)
|
41
41
|
assert_equal("normal", s1.klass)
|
42
42
|
assert_equal(5, s1.keys)
|
43
|
-
|
44
|
-
assert_raise(NoMethodError) { s1.dup }
|
45
43
|
end
|
46
44
|
|
47
45
|
test 'creates object which contains specified hash object itself, including fields with at prefix' do
|
@@ -0,0 +1,192 @@
|
|
1
|
+
require_relative '../../helper'
|
2
|
+
require 'fluent/plugin/in_tail/position_file'
|
3
|
+
|
4
|
+
class IntailPositionFileTest < Test::Unit::TestCase
|
5
|
+
setup do
|
6
|
+
@file = StringIO.new(+'')
|
7
|
+
end
|
8
|
+
|
9
|
+
UNWATCHED_STR = '%016x' % Fluent::Plugin::TailInput::PositionFile::UNWATCHED_POSITION
|
10
|
+
TEST_CONTENT = <<~EOF
|
11
|
+
valid_path\t0000000000000002\t0000000000000001
|
12
|
+
inode23bit\t0000000000000000\t00000000
|
13
|
+
invalidpath100000000000000000000000000000000
|
14
|
+
unwatched\t#{UNWATCHED_STR}\t0000000000000000
|
15
|
+
EOF
|
16
|
+
|
17
|
+
def write_data(f, content)
|
18
|
+
f.write(content)
|
19
|
+
f.seek(0)
|
20
|
+
end
|
21
|
+
|
22
|
+
sub_test_case '.compact' do
|
23
|
+
test 'compact invalid and convert 32 bit inode value' do
|
24
|
+
write_data(@file, TEST_CONTENT)
|
25
|
+
Fluent::Plugin::TailInput::PositionFile.compact(@file)
|
26
|
+
|
27
|
+
@file.seek(0)
|
28
|
+
lines = @file.readlines
|
29
|
+
assert_equal 2, lines.size
|
30
|
+
assert_equal "valid_path\t0000000000000002\t0000000000000001\n", lines[0]
|
31
|
+
assert_equal "inode23bit\t0000000000000000\t0000000000000000\n", lines[1]
|
32
|
+
end
|
33
|
+
|
34
|
+
test 'compact data if duplicated line' do
|
35
|
+
write_data(@file, <<~EOF)
|
36
|
+
valid_path\t0000000000000002\t0000000000000001
|
37
|
+
valid_path\t0000000000000003\t0000000000000004
|
38
|
+
EOF
|
39
|
+
Fluent::Plugin::TailInput::PositionFile.compact(@file)
|
40
|
+
|
41
|
+
@file.seek(0)
|
42
|
+
lines = @file.readlines
|
43
|
+
assert_equal "valid_path\t0000000000000003\t0000000000000004\n", lines[0]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
test '.parse' do
|
48
|
+
write_data(@file, TEST_CONTENT)
|
49
|
+
Fluent::Plugin::TailInput::PositionFile.parse(@file)
|
50
|
+
|
51
|
+
@file.seek(0)
|
52
|
+
lines = @file.readlines
|
53
|
+
assert_equal 2, lines.size
|
54
|
+
assert_equal "valid_path\t0000000000000002\t0000000000000001\n", lines[0]
|
55
|
+
assert_equal "inode23bit\t0000000000000000\t0000000000000000\n", lines[1]
|
56
|
+
end
|
57
|
+
|
58
|
+
sub_test_case '#[]' do
|
59
|
+
test 'return entry' do
|
60
|
+
write_data(@file, TEST_CONTENT)
|
61
|
+
pf = Fluent::Plugin::TailInput::PositionFile.parse(@file)
|
62
|
+
|
63
|
+
f = pf['valid_path']
|
64
|
+
assert_equal Fluent::Plugin::TailInput::FilePositionEntry, f.class
|
65
|
+
assert_equal 2, f.read_pos
|
66
|
+
assert_equal 1, f.read_inode
|
67
|
+
|
68
|
+
@file.seek(0)
|
69
|
+
lines = @file.readlines
|
70
|
+
assert_equal 2, lines.size
|
71
|
+
|
72
|
+
f = pf['nonexist_path']
|
73
|
+
assert_equal Fluent::Plugin::TailInput::FilePositionEntry, f.class
|
74
|
+
assert_equal 0, f.read_pos
|
75
|
+
assert_equal 0, f.read_inode
|
76
|
+
|
77
|
+
@file.seek(0)
|
78
|
+
lines = @file.readlines
|
79
|
+
assert_equal 3, lines.size
|
80
|
+
assert_equal "nonexist_path\t0000000000000000\t0000000000000000\n", lines[2]
|
81
|
+
end
|
82
|
+
|
83
|
+
test 'does not change other value position if other entry try to write' do
|
84
|
+
write_data(@file, TEST_CONTENT)
|
85
|
+
pf = Fluent::Plugin::TailInput::PositionFile.parse(@file)
|
86
|
+
|
87
|
+
f = pf['nonexist_path']
|
88
|
+
assert_equal 0, f.read_inode
|
89
|
+
assert_equal 0, f.read_pos
|
90
|
+
|
91
|
+
pf['valid_path'].update(1, 2)
|
92
|
+
|
93
|
+
f = pf['nonexist_path']
|
94
|
+
assert_equal 0, f.read_inode
|
95
|
+
assert_equal 0, f.read_pos
|
96
|
+
|
97
|
+
pf['nonexist_path'].update(1, 2)
|
98
|
+
assert_equal 1, f.read_inode
|
99
|
+
assert_equal 2, f.read_pos
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
sub_test_case '#unwatch' do
|
104
|
+
test 'deletes entry by path' do
|
105
|
+
write_data(@file, TEST_CONTENT)
|
106
|
+
pf = Fluent::Plugin::TailInput::PositionFile.parse(@file)
|
107
|
+
p1 = pf['valid_path']
|
108
|
+
assert_equal Fluent::Plugin::TailInput::FilePositionEntry, p1.class
|
109
|
+
|
110
|
+
pf.unwatch('valid_path')
|
111
|
+
assert_equal p1.read_pos, Fluent::Plugin::TailInput::PositionFile::UNWATCHED_POSITION
|
112
|
+
|
113
|
+
p2 = pf['valid_path']
|
114
|
+
assert_equal Fluent::Plugin::TailInput::FilePositionEntry, p2.class
|
115
|
+
|
116
|
+
assert_not_equal p1, p2
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
sub_test_case 'FilePositionEntry' do
|
121
|
+
FILE_POS_CONTENT = <<~EOF
|
122
|
+
valid_path\t0000000000000002\t0000000000000001
|
123
|
+
valid_path2\t0000000000000003\t0000000000000002
|
124
|
+
EOF
|
125
|
+
|
126
|
+
def build_files(file)
|
127
|
+
r = {}
|
128
|
+
|
129
|
+
file.each_line do |line|
|
130
|
+
m = /^([^\t]+)\t([0-9a-fA-F]+)\t([0-9a-fA-F]+)/.match(line)
|
131
|
+
path = m[1]
|
132
|
+
pos = m[2].to_i(16)
|
133
|
+
ino = m[3].to_i(16)
|
134
|
+
seek = file.pos - line.bytesize + path.bytesize + 1
|
135
|
+
r[path] = Fluent::Plugin::TailInput::FilePositionEntry.new(@file, Mutex.new, seek, pos, ino)
|
136
|
+
end
|
137
|
+
|
138
|
+
r
|
139
|
+
end
|
140
|
+
|
141
|
+
test '#update' do
|
142
|
+
write_data(@file, FILE_POS_CONTENT)
|
143
|
+
fs = build_files(@file)
|
144
|
+
f = fs['valid_path']
|
145
|
+
f.update(11, 10)
|
146
|
+
|
147
|
+
@file.seek(0)
|
148
|
+
lines = @file.readlines
|
149
|
+
assert_equal 2, lines.size
|
150
|
+
assert_equal "valid_path\t000000000000000a\t000000000000000b\n", lines[0]
|
151
|
+
assert_equal "valid_path2\t0000000000000003\t0000000000000002\n", lines[1]
|
152
|
+
end
|
153
|
+
|
154
|
+
test '#update_pos' do
|
155
|
+
write_data(@file, FILE_POS_CONTENT)
|
156
|
+
fs = build_files(@file)
|
157
|
+
f = fs['valid_path']
|
158
|
+
f.update_pos(10)
|
159
|
+
|
160
|
+
@file.seek(0)
|
161
|
+
lines = @file.readlines
|
162
|
+
assert_equal 2, lines.size
|
163
|
+
assert_equal "valid_path\t000000000000000a\t0000000000000001\n", lines[0]
|
164
|
+
assert_equal "valid_path2\t0000000000000003\t0000000000000002\n", lines[1]
|
165
|
+
end
|
166
|
+
|
167
|
+
test '#read_pos' do
|
168
|
+
write_data(@file, FILE_POS_CONTENT)
|
169
|
+
fs = build_files(@file)
|
170
|
+
f = fs['valid_path']
|
171
|
+
assert_equal 2, f.read_pos
|
172
|
+
|
173
|
+
f.update_pos(10)
|
174
|
+
assert_equal 10, f.read_pos
|
175
|
+
|
176
|
+
f.update(2, 11)
|
177
|
+
assert_equal 11, f.read_pos
|
178
|
+
end
|
179
|
+
|
180
|
+
test '#read_inode' do
|
181
|
+
write_data(@file, FILE_POS_CONTENT)
|
182
|
+
fs = build_files(@file)
|
183
|
+
f = fs['valid_path']
|
184
|
+
assert_equal 1, f.read_inode
|
185
|
+
f.update_pos(10)
|
186
|
+
assert_equal 1, f.read_inode
|
187
|
+
|
188
|
+
f.update(2, 11)
|
189
|
+
assert_equal 2, f.read_inode
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
data/test/plugin/test_in_tail.rb
CHANGED
@@ -84,6 +84,19 @@ class TailInputTest < Test::Unit::TestCase
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
+
test "multi paths with path_delimiter" do
|
88
|
+
c = config_element("ROOT", "", { "path" => "tail.txt|test2|tmp,dev", "tag" => "t1", "path_delimiter" => "|" })
|
89
|
+
d = create_driver(c + PARSE_SINGLE_LINE_CONFIG, false)
|
90
|
+
assert_equal ["tail.txt", "test2", "tmp,dev"], d.instance.paths
|
91
|
+
end
|
92
|
+
|
93
|
+
test "multi paths with invaid path_delimiter" do
|
94
|
+
c = config_element("ROOT", "", { "path" => "tail.txt|test2|tmp,dev", "tag" => "t1", "path_delimiter" => "*" })
|
95
|
+
assert_raise(Fluent::ConfigError) do
|
96
|
+
create_driver(c + PARSE_SINGLE_LINE_CONFIG, false)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
87
100
|
test "both enable_watch_timer and enable_stat_watcher are false" do
|
88
101
|
assert_raise(Fluent::ConfigError) do
|
89
102
|
create_driver(CONFIG_ENABLE_WATCH_TIMER + CONFIG_DISABLE_STAT_WATCHER + PARSE_SINGLE_LINE_CONFIG)
|
@@ -168,6 +168,19 @@ class HTTPOutputTest < Test::Unit::TestCase
|
|
168
168
|
assert_nil d.instance.headers
|
169
169
|
end
|
170
170
|
|
171
|
+
def test_configure_with_warn
|
172
|
+
d = create_driver(config)
|
173
|
+
assert_match(/Status code 503 is going to be removed/, d.instance.log.out.logs.join)
|
174
|
+
end
|
175
|
+
|
176
|
+
def test_configure_without_warn
|
177
|
+
d = create_driver(<<~CONFIG)
|
178
|
+
endpoint #{base_endpoint}/test
|
179
|
+
retryable_response_codes [503]
|
180
|
+
CONFIG
|
181
|
+
assert_not_match(/Status code 503 is going to be removed/, d.instance.log.out.logs.join)
|
182
|
+
end
|
183
|
+
|
171
184
|
data('json' => ['json', 'application/x-ndjson'],
|
172
185
|
'ltsv' => ['ltsv', 'text/tab-separated-values'],
|
173
186
|
'msgpack' => ['msgpack', 'application/x-msgpack'],
|
@@ -257,7 +270,7 @@ class HTTPOutputTest < Test::Unit::TestCase
|
|
257
270
|
d.feed(event)
|
258
271
|
}
|
259
272
|
end
|
260
|
-
assert_match(/got error response from.*404 Not Found Not Found/, d.instance.log.out.logs.
|
273
|
+
assert_match(/got error response from.*404 Not Found Not Found/, d.instance.log.out.logs.join)
|
261
274
|
d.instance_shutdown
|
262
275
|
end
|
263
276
|
|
@@ -313,7 +326,7 @@ class HTTPOutputTest < Test::Unit::TestCase
|
|
313
326
|
d.feed(event)
|
314
327
|
}
|
315
328
|
end
|
316
|
-
assert_match(/got unrecoverable error/, d.instance.log.out.logs.
|
329
|
+
assert_match(/got unrecoverable error/, d.instance.log.out.logs.join)
|
317
330
|
|
318
331
|
d.instance_shutdown
|
319
332
|
end
|
@@ -181,7 +181,8 @@ class BufferedOutputBackupTest < Test::Unit::TestCase
|
|
181
181
|
'type error' => TypeError,
|
182
182
|
'argument error' => ArgumentError,
|
183
183
|
'no method error' => NoMethodError,
|
184
|
-
'msgpack unpack error' => MessagePack::UnpackError
|
184
|
+
'msgpack unpack error' => MessagePack::UnpackError,
|
185
|
+
'encoding error' => EncodingError)
|
185
186
|
test 'backup chunk without secondary' do |error_class|
|
186
187
|
Fluent::SystemConfig.overwrite_system_config('root_dir' => TMP_DIR) do
|
187
188
|
id = 'backup_test'
|
@@ -188,6 +188,42 @@ class SyslogParserTest < ::Test::Unit::TestCase
|
|
188
188
|
@parser.instance.patterns['format'])
|
189
189
|
end
|
190
190
|
|
191
|
+
def test_parse_with_rfc5424_message_trailing_eol
|
192
|
+
@parser.configure(
|
193
|
+
'time_format' => '%Y-%m-%dT%H:%M:%S.%L%z',
|
194
|
+
'message_format' => 'rfc5424',
|
195
|
+
'with_priority' => true,
|
196
|
+
)
|
197
|
+
text = "<16>1 2017-02-06T13:14:15.003Z 192.168.0.1 fluentd - - - Hi, from Fluentd!\n"
|
198
|
+
@parser.instance.parse(text) do |time, record|
|
199
|
+
assert_equal(event_time("2017-02-06T13:14:15.003Z", format: '%Y-%m-%dT%H:%M:%S.%L%z'), time)
|
200
|
+
assert_equal "-", record["pid"]
|
201
|
+
assert_equal "-", record["msgid"]
|
202
|
+
assert_equal "-", record["extradata"]
|
203
|
+
assert_equal "Hi, from Fluentd!", record["message"]
|
204
|
+
end
|
205
|
+
assert_equal(Fluent::Plugin::SyslogParser::REGEXP_RFC5424_WITH_PRI,
|
206
|
+
@parser.instance.patterns['format'])
|
207
|
+
end
|
208
|
+
|
209
|
+
def test_parse_with_rfc5424_multiline_message
|
210
|
+
@parser.configure(
|
211
|
+
'time_format' => '%Y-%m-%dT%H:%M:%S.%L%z',
|
212
|
+
'message_format' => 'rfc5424',
|
213
|
+
'with_priority' => true,
|
214
|
+
)
|
215
|
+
text = "<16>1 2017-02-06T13:14:15.003Z 192.168.0.1 fluentd - - - Hi,\nfrom\nFluentd!"
|
216
|
+
@parser.instance.parse(text) do |time, record|
|
217
|
+
assert_equal(event_time("2017-02-06T13:14:15.003Z", format: '%Y-%m-%dT%H:%M:%S.%L%z'), time)
|
218
|
+
assert_equal "-", record["pid"]
|
219
|
+
assert_equal "-", record["msgid"]
|
220
|
+
assert_equal "-", record["extradata"]
|
221
|
+
assert_equal "Hi,\nfrom\nFluentd!", record["message"]
|
222
|
+
end
|
223
|
+
assert_equal(Fluent::Plugin::SyslogParser::REGEXP_RFC5424_WITH_PRI,
|
224
|
+
@parser.instance.patterns['format'])
|
225
|
+
end
|
226
|
+
|
191
227
|
def test_parse_with_rfc5424_message_and_without_priority
|
192
228
|
@parser.configure(
|
193
229
|
'time_format' => '%Y-%m-%dT%H:%M:%S.%L%z',
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'fluent/plugin_helper/cert_option'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module CertUtil
|
5
|
+
extend Fluent::PluginHelper::CertOption
|
6
|
+
end
|
7
|
+
|
8
|
+
WITHOUT_CA_DIR = './without_ca'.freeze
|
9
|
+
WITH_CA_DIR = './with_ca'.freeze
|
10
|
+
|
11
|
+
CA_OPTION = {
|
12
|
+
private_key_length: 2048,
|
13
|
+
country: 'US',
|
14
|
+
state: 'CA',
|
15
|
+
locality: 'Mountain View',
|
16
|
+
common_name: 'ca.testing.fluentd.org',
|
17
|
+
expiration: 30 * 86400,
|
18
|
+
digest: :sha256,
|
19
|
+
}
|
20
|
+
|
21
|
+
SERVER_OPTION = {
|
22
|
+
private_key_length: 2048,
|
23
|
+
country: 'US',
|
24
|
+
state: 'CA',
|
25
|
+
locality: 'Mountain View',
|
26
|
+
common_name: 'server.testing.fluentd.org',
|
27
|
+
expiration: 30 * 86400,
|
28
|
+
digest: :sha256,
|
29
|
+
}
|
30
|
+
|
31
|
+
def write_cert_and_key(cert_path, cert, key_path, key, passphrase)
|
32
|
+
File.open(cert_path, 'w') { |f| f.write(cert.to_pem) }
|
33
|
+
|
34
|
+
# Write the secret key (raw or encrypted by AES256) in PEM format
|
35
|
+
key_str = passphrase ? key.export(OpenSSL::Cipher.new('AES-256-CBC'), passphrase) : key.export
|
36
|
+
File.open(key_path, 'w') { |f| f.write(key_str) }
|
37
|
+
File.chmod(0o600, cert_path, key_path)
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_server_pair_signed_by_self(cert_path, private_key_path, passphrase)
|
41
|
+
cert, key, _ = CertUtil.cert_option_generate_server_pair_self_signed(SERVER_OPTION)
|
42
|
+
write_cert_and_key(cert_path, cert, private_key_path, key, passphrase)
|
43
|
+
cert
|
44
|
+
end
|
45
|
+
|
46
|
+
def create_ca_pair_signed_by_self(cert_path, private_key_path, passphrase)
|
47
|
+
cert, key, _ = CertUtil.cert_option_generate_ca_pair_self_signed(CA_OPTION)
|
48
|
+
write_cert_and_key(cert_path, cert, private_key_path, key, passphrase)
|
49
|
+
cert
|
50
|
+
end
|
51
|
+
|
52
|
+
def create_server_pair_signed_by_ca(ca_cert_path, ca_key_path, ca_key_passphrase, cert_path, private_key_path, passphrase)
|
53
|
+
cert, key, _ = CertUtil.cert_option_generate_server_pair_by_ca(ca_cert_path, ca_key_path, ca_key_passphrase, SERVER_OPTION)
|
54
|
+
write_cert_and_key(cert_path, cert, private_key_path, key, passphrase)
|
55
|
+
cert
|
56
|
+
end
|
57
|
+
|
58
|
+
def create_without_ca
|
59
|
+
FileUtils.mkdir_p(WITHOUT_CA_DIR)
|
60
|
+
cert_path = File.join(WITHOUT_CA_DIR, 'cert.pem')
|
61
|
+
cert_key_path = File.join(WITHOUT_CA_DIR, 'cert-key.pem')
|
62
|
+
cert_pass_path = File.join(WITHOUT_CA_DIR, 'cert-pass.pem')
|
63
|
+
cert_key_pass_path = File.join(WITHOUT_CA_DIR, 'cert-key-pass.pem')
|
64
|
+
|
65
|
+
create_server_pair_signed_by_self(cert_path, cert_key_path, nil)
|
66
|
+
create_server_pair_signed_by_self(cert_pass_path, cert_key_pass_path, 'apple') # with passphrase
|
67
|
+
end
|
68
|
+
|
69
|
+
def create_with_ca
|
70
|
+
FileUtils.mkdir_p(WITH_CA_DIR)
|
71
|
+
cert_path = File.join(WITH_CA_DIR, 'cert.pem')
|
72
|
+
cert_key_path = File.join(WITH_CA_DIR, 'cert-key.pem')
|
73
|
+
ca_cert_path = File.join(WITH_CA_DIR, 'ca-cert.pem')
|
74
|
+
ca_key_path = File.join(WITH_CA_DIR, 'ca-cert-key.pem')
|
75
|
+
create_ca_pair_signed_by_self(ca_cert_path, ca_key_path, nil)
|
76
|
+
create_server_pair_signed_by_ca(ca_cert_path, ca_key_path, nil, cert_path, cert_key_path, nil)
|
77
|
+
|
78
|
+
cert_pass_path = File.join(WITH_CA_DIR, 'cert-pass.pem')
|
79
|
+
cert_key_pass_path = File.join(WITH_CA_DIR, 'cert-key-pass.pem')
|
80
|
+
ca_cert_pass_path = File.join(WITH_CA_DIR, 'ca-cert-pass.pem')
|
81
|
+
ca_key_pass_path = File.join(WITH_CA_DIR, 'ca-cert-key-pass.pem')
|
82
|
+
create_ca_pair_signed_by_self(ca_cert_pass_path, ca_key_pass_path, 'orange') # with passphrase
|
83
|
+
create_server_pair_signed_by_ca(ca_cert_pass_path, ca_key_pass_path, 'orange', cert_pass_path, cert_key_pass_path, 'apple')
|
84
|
+
end
|
85
|
+
|
86
|
+
create_without_ca
|
87
|
+
create_with_ca
|