fluentd 0.12.40 → 1.6.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.

Files changed (428) hide show
  1. checksums.yaml +5 -5
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +39 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
  4. data/.github/ISSUE_TEMPLATE.md +17 -0
  5. data/.github/PULL_REQUEST_TEMPLATE.md +13 -0
  6. data/.gitignore +5 -0
  7. data/.gitlab/cicd-template.yaml +10 -0
  8. data/.gitlab-ci.yml +147 -0
  9. data/.travis.yml +56 -20
  10. data/ADOPTERS.md +5 -0
  11. data/CHANGELOG.md +1369 -0
  12. data/CONTRIBUTING.md +16 -5
  13. data/GOVERNANCE.md +55 -0
  14. data/Gemfile +5 -0
  15. data/GithubWorkflow.md +78 -0
  16. data/LICENSE +202 -0
  17. data/MAINTAINERS.md +7 -0
  18. data/README.md +23 -11
  19. data/Rakefile +48 -2
  20. data/Vagrantfile +17 -0
  21. data/appveyor.yml +37 -0
  22. data/bin/fluent-binlog-reader +7 -0
  23. data/bin/fluent-ca-generate +6 -0
  24. data/bin/fluent-plugin-config-format +5 -0
  25. data/bin/fluent-plugin-generate +5 -0
  26. data/bin/fluentd +3 -0
  27. data/code-of-conduct.md +3 -0
  28. data/example/copy_roundrobin.conf +39 -0
  29. data/example/counter.conf +18 -0
  30. data/example/in_dummy_blocks.conf +17 -0
  31. data/example/in_dummy_with_compression.conf +23 -0
  32. data/example/in_forward.conf +7 -0
  33. data/example/in_forward_client.conf +37 -0
  34. data/example/in_forward_shared_key.conf +15 -0
  35. data/example/in_forward_tls.conf +14 -0
  36. data/example/in_forward_users.conf +24 -0
  37. data/example/in_forward_workers.conf +21 -0
  38. data/example/in_http.conf +3 -1
  39. data/example/in_out_forward.conf +17 -0
  40. data/example/logevents.conf +25 -0
  41. data/example/multi_filters.conf +61 -0
  42. data/example/out_exec_filter.conf +42 -0
  43. data/example/out_forward.conf +13 -13
  44. data/example/out_forward_buf_file.conf +23 -0
  45. data/example/out_forward_client.conf +109 -0
  46. data/example/out_forward_heartbeat_none.conf +16 -0
  47. data/example/out_forward_shared_key.conf +36 -0
  48. data/example/out_forward_tls.conf +18 -0
  49. data/example/out_forward_users.conf +65 -0
  50. data/example/out_null.conf +36 -0
  51. data/example/secondary_file.conf +42 -0
  52. data/example/suppress_config_dump.conf +7 -0
  53. data/example/worker_section.conf +36 -0
  54. data/fluent.conf +29 -0
  55. data/fluentd.gemspec +21 -11
  56. data/lib/fluent/agent.rb +67 -90
  57. data/lib/fluent/clock.rb +62 -0
  58. data/lib/fluent/command/binlog_reader.rb +244 -0
  59. data/lib/fluent/command/ca_generate.rb +181 -0
  60. data/lib/fluent/command/cat.rb +42 -18
  61. data/lib/fluent/command/debug.rb +12 -10
  62. data/lib/fluent/command/fluentd.rb +153 -5
  63. data/lib/fluent/command/plugin_config_formatter.rb +292 -0
  64. data/lib/fluent/command/plugin_generator.rb +324 -0
  65. data/lib/fluent/compat/call_super_mixin.rb +67 -0
  66. data/lib/fluent/compat/detach_process_mixin.rb +33 -0
  67. data/lib/fluent/compat/exec_util.rb +129 -0
  68. data/lib/fluent/compat/file_util.rb +54 -0
  69. data/lib/fluent/compat/filter.rb +68 -0
  70. data/lib/fluent/compat/formatter.rb +111 -0
  71. data/lib/fluent/compat/formatter_utils.rb +85 -0
  72. data/lib/fluent/compat/handle_tag_and_time_mixin.rb +62 -0
  73. data/lib/fluent/compat/handle_tag_name_mixin.rb +53 -0
  74. data/lib/fluent/compat/input.rb +49 -0
  75. data/lib/fluent/compat/output.rb +718 -0
  76. data/lib/fluent/compat/output_chain.rb +60 -0
  77. data/lib/fluent/compat/parser.rb +310 -0
  78. data/lib/fluent/compat/parser_utils.rb +40 -0
  79. data/lib/fluent/compat/propagate_default.rb +62 -0
  80. data/lib/fluent/compat/record_filter_mixin.rb +34 -0
  81. data/lib/fluent/compat/set_tag_key_mixin.rb +50 -0
  82. data/lib/fluent/compat/set_time_key_mixin.rb +69 -0
  83. data/lib/fluent/compat/socket_util.rb +165 -0
  84. data/lib/fluent/compat/string_util.rb +34 -0
  85. data/lib/fluent/compat/structured_format_mixin.rb +26 -0
  86. data/lib/fluent/compat/type_converter.rb +90 -0
  87. data/lib/fluent/config/configure_proxy.rb +210 -62
  88. data/lib/fluent/config/dsl.rb +12 -5
  89. data/lib/fluent/config/element.rb +107 -9
  90. data/lib/fluent/config/literal_parser.rb +9 -3
  91. data/lib/fluent/config/parser.rb +4 -4
  92. data/lib/fluent/config/section.rb +51 -14
  93. data/lib/fluent/config/types.rb +28 -13
  94. data/lib/fluent/config/v1_parser.rb +3 -5
  95. data/lib/fluent/config.rb +23 -20
  96. data/lib/fluent/configurable.rb +79 -21
  97. data/lib/fluent/counter/base_socket.rb +46 -0
  98. data/lib/fluent/counter/client.rb +297 -0
  99. data/lib/fluent/counter/error.rb +86 -0
  100. data/lib/fluent/counter/mutex_hash.rb +163 -0
  101. data/lib/fluent/counter/server.rb +273 -0
  102. data/lib/fluent/counter/store.rb +205 -0
  103. data/lib/fluent/counter/validator.rb +145 -0
  104. data/lib/fluent/counter.rb +23 -0
  105. data/lib/fluent/daemon.rb +15 -0
  106. data/lib/fluent/engine.rb +102 -65
  107. data/lib/fluent/env.rb +7 -3
  108. data/lib/fluent/error.rb +30 -0
  109. data/lib/fluent/event.rb +197 -21
  110. data/lib/fluent/event_router.rb +93 -10
  111. data/lib/fluent/filter.rb +2 -50
  112. data/lib/fluent/formatter.rb +4 -293
  113. data/lib/fluent/input.rb +2 -32
  114. data/lib/fluent/label.rb +10 -2
  115. data/lib/fluent/load.rb +3 -3
  116. data/lib/fluent/log.rb +348 -81
  117. data/lib/fluent/match.rb +37 -36
  118. data/lib/fluent/mixin.rb +12 -176
  119. data/lib/fluent/msgpack_factory.rb +62 -0
  120. data/lib/fluent/output.rb +10 -612
  121. data/lib/fluent/output_chain.rb +23 -0
  122. data/lib/fluent/parser.rb +4 -800
  123. data/lib/fluent/plugin/bare_output.rb +63 -0
  124. data/lib/fluent/plugin/base.rb +192 -0
  125. data/lib/fluent/plugin/buf_file.rb +128 -174
  126. data/lib/fluent/plugin/buf_memory.rb +9 -92
  127. data/lib/fluent/plugin/buffer/chunk.rb +221 -0
  128. data/lib/fluent/plugin/buffer/file_chunk.rb +383 -0
  129. data/lib/fluent/plugin/buffer/memory_chunk.rb +90 -0
  130. data/lib/fluent/plugin/buffer.rb +779 -0
  131. data/lib/fluent/plugin/compressable.rb +92 -0
  132. data/lib/fluent/plugin/exec_util.rb +3 -108
  133. data/lib/fluent/plugin/file_util.rb +4 -34
  134. data/lib/fluent/plugin/file_wrapper.rb +120 -0
  135. data/lib/fluent/plugin/filter.rb +93 -0
  136. data/lib/fluent/plugin/filter_grep.rb +117 -34
  137. data/lib/fluent/plugin/filter_parser.rb +85 -62
  138. data/lib/fluent/plugin/filter_record_transformer.rb +27 -39
  139. data/lib/fluent/plugin/filter_stdout.rb +15 -12
  140. data/lib/fluent/plugin/formatter.rb +50 -0
  141. data/lib/fluent/plugin/formatter_csv.rb +52 -0
  142. data/lib/fluent/plugin/formatter_hash.rb +33 -0
  143. data/lib/fluent/plugin/formatter_json.rb +55 -0
  144. data/lib/fluent/plugin/formatter_ltsv.rb +42 -0
  145. data/lib/fluent/plugin/formatter_msgpack.rb +33 -0
  146. data/lib/fluent/plugin/formatter_out_file.rb +51 -0
  147. data/lib/fluent/plugin/formatter_single_value.rb +34 -0
  148. data/lib/fluent/plugin/formatter_stdout.rb +76 -0
  149. data/lib/fluent/plugin/formatter_tsv.rb +38 -0
  150. data/lib/fluent/plugin/in_debug_agent.rb +17 -6
  151. data/lib/fluent/plugin/in_dummy.rb +47 -20
  152. data/lib/fluent/plugin/in_exec.rb +55 -123
  153. data/lib/fluent/plugin/in_forward.rb +299 -216
  154. data/lib/fluent/plugin/in_gc_stat.rb +14 -36
  155. data/lib/fluent/plugin/in_http.rb +204 -91
  156. data/lib/fluent/plugin/in_monitor_agent.rb +186 -258
  157. data/lib/fluent/plugin/in_object_space.rb +13 -41
  158. data/lib/fluent/plugin/in_syslog.rb +112 -134
  159. data/lib/fluent/plugin/in_tail.rb +408 -745
  160. data/lib/fluent/plugin/in_tcp.rb +66 -9
  161. data/lib/fluent/plugin/in_udp.rb +60 -11
  162. data/lib/fluent/plugin/{in_stream.rb → in_unix.rb} +8 -4
  163. data/lib/fluent/plugin/input.rb +37 -0
  164. data/lib/fluent/plugin/multi_output.rb +158 -0
  165. data/lib/fluent/plugin/out_copy.rb +23 -35
  166. data/lib/fluent/plugin/out_exec.rb +67 -70
  167. data/lib/fluent/plugin/out_exec_filter.rb +204 -271
  168. data/lib/fluent/plugin/out_file.rb +267 -73
  169. data/lib/fluent/plugin/out_forward.rb +854 -325
  170. data/lib/fluent/plugin/out_null.rb +42 -9
  171. data/lib/fluent/plugin/out_relabel.rb +9 -5
  172. data/lib/fluent/plugin/out_roundrobin.rb +18 -37
  173. data/lib/fluent/plugin/out_secondary_file.rb +133 -0
  174. data/lib/fluent/plugin/out_stdout.rb +43 -10
  175. data/lib/fluent/plugin/out_stream.rb +7 -2
  176. data/lib/fluent/plugin/output.rb +1498 -0
  177. data/lib/fluent/plugin/owned_by_mixin.rb +42 -0
  178. data/lib/fluent/plugin/parser.rb +191 -0
  179. data/lib/fluent/plugin/parser_apache.rb +28 -0
  180. data/lib/fluent/plugin/parser_apache2.rb +88 -0
  181. data/lib/fluent/plugin/parser_apache_error.rb +26 -0
  182. data/lib/fluent/plugin/parser_csv.rb +39 -0
  183. data/lib/fluent/plugin/parser_json.rb +94 -0
  184. data/lib/fluent/plugin/parser_ltsv.rb +49 -0
  185. data/lib/fluent/plugin/parser_msgpack.rb +50 -0
  186. data/lib/fluent/plugin/parser_multiline.rb +106 -0
  187. data/lib/fluent/plugin/parser_nginx.rb +28 -0
  188. data/lib/fluent/plugin/parser_none.rb +36 -0
  189. data/lib/fluent/plugin/parser_regexp.rb +68 -0
  190. data/lib/fluent/plugin/parser_syslog.rb +142 -0
  191. data/lib/fluent/plugin/parser_tsv.rb +42 -0
  192. data/lib/fluent/plugin/socket_util.rb +3 -143
  193. data/lib/fluent/plugin/storage.rb +84 -0
  194. data/lib/fluent/plugin/storage_local.rb +164 -0
  195. data/lib/fluent/plugin/string_util.rb +3 -15
  196. data/lib/fluent/plugin.rb +122 -121
  197. data/lib/fluent/plugin_helper/cert_option.rb +178 -0
  198. data/lib/fluent/plugin_helper/child_process.rb +364 -0
  199. data/lib/fluent/plugin_helper/compat_parameters.rb +333 -0
  200. data/lib/fluent/plugin_helper/counter.rb +51 -0
  201. data/lib/fluent/plugin_helper/event_emitter.rb +93 -0
  202. data/lib/fluent/plugin_helper/event_loop.rb +170 -0
  203. data/lib/fluent/plugin_helper/extract.rb +104 -0
  204. data/lib/fluent/plugin_helper/formatter.rb +147 -0
  205. data/lib/fluent/plugin_helper/http_server/app.rb +79 -0
  206. data/lib/fluent/plugin_helper/http_server/compat/server.rb +81 -0
  207. data/lib/fluent/plugin_helper/http_server/compat/webrick_handler.rb +58 -0
  208. data/lib/fluent/plugin_helper/http_server/methods.rb +35 -0
  209. data/lib/fluent/plugin_helper/http_server/request.rb +42 -0
  210. data/lib/fluent/plugin_helper/http_server/router.rb +54 -0
  211. data/lib/fluent/plugin_helper/http_server/server.rb +87 -0
  212. data/lib/fluent/plugin_helper/http_server.rb +76 -0
  213. data/lib/fluent/plugin_helper/inject.rb +151 -0
  214. data/lib/fluent/plugin_helper/parser.rb +147 -0
  215. data/lib/fluent/plugin_helper/record_accessor.rb +210 -0
  216. data/lib/fluent/plugin_helper/retry_state.rb +205 -0
  217. data/lib/fluent/plugin_helper/server.rb +807 -0
  218. data/lib/fluent/plugin_helper/socket.rb +250 -0
  219. data/lib/fluent/plugin_helper/socket_option.rb +80 -0
  220. data/lib/fluent/plugin_helper/storage.rb +349 -0
  221. data/lib/fluent/plugin_helper/thread.rb +179 -0
  222. data/lib/fluent/plugin_helper/timer.rb +92 -0
  223. data/lib/fluent/plugin_helper.rb +73 -0
  224. data/lib/fluent/plugin_id.rb +80 -0
  225. data/lib/fluent/process.rb +3 -489
  226. data/lib/fluent/registry.rb +52 -10
  227. data/lib/fluent/root_agent.rb +204 -42
  228. data/lib/fluent/supervisor.rb +597 -359
  229. data/lib/fluent/system_config.rb +131 -42
  230. data/lib/fluent/test/base.rb +6 -54
  231. data/lib/fluent/test/driver/base.rb +224 -0
  232. data/lib/fluent/test/driver/base_owned.rb +70 -0
  233. data/lib/fluent/test/driver/base_owner.rb +135 -0
  234. data/lib/fluent/test/driver/event_feeder.rb +98 -0
  235. data/lib/fluent/test/driver/filter.rb +57 -0
  236. data/lib/fluent/test/driver/formatter.rb +30 -0
  237. data/lib/fluent/test/driver/input.rb +31 -0
  238. data/lib/fluent/test/driver/multi_output.rb +53 -0
  239. data/lib/fluent/test/driver/output.rb +102 -0
  240. data/lib/fluent/test/driver/parser.rb +30 -0
  241. data/lib/fluent/test/driver/test_event_router.rb +45 -0
  242. data/lib/fluent/test/filter_test.rb +0 -1
  243. data/lib/fluent/test/formatter_test.rb +4 -1
  244. data/lib/fluent/test/helpers.rb +58 -10
  245. data/lib/fluent/test/input_test.rb +27 -19
  246. data/lib/fluent/test/log.rb +79 -0
  247. data/lib/fluent/test/output_test.rb +28 -39
  248. data/lib/fluent/test/parser_test.rb +3 -1
  249. data/lib/fluent/test/startup_shutdown.rb +46 -0
  250. data/lib/fluent/test.rb +33 -1
  251. data/lib/fluent/time.rb +450 -1
  252. data/lib/fluent/timezone.rb +27 -3
  253. data/lib/fluent/{status.rb → unique_id.rb} +15 -24
  254. data/lib/fluent/version.rb +1 -1
  255. data/lib/fluent/winsvc.rb +85 -0
  256. data/templates/new_gem/Gemfile +3 -0
  257. data/templates/new_gem/README.md.erb +43 -0
  258. data/templates/new_gem/Rakefile +13 -0
  259. data/templates/new_gem/fluent-plugin.gemspec.erb +27 -0
  260. data/templates/new_gem/lib/fluent/plugin/filter.rb.erb +14 -0
  261. data/templates/new_gem/lib/fluent/plugin/formatter.rb.erb +14 -0
  262. data/templates/new_gem/lib/fluent/plugin/input.rb.erb +11 -0
  263. data/templates/new_gem/lib/fluent/plugin/output.rb.erb +11 -0
  264. data/templates/new_gem/lib/fluent/plugin/parser.rb.erb +15 -0
  265. data/templates/new_gem/test/helper.rb.erb +8 -0
  266. data/templates/new_gem/test/plugin/test_filter.rb.erb +18 -0
  267. data/templates/new_gem/test/plugin/test_formatter.rb.erb +18 -0
  268. data/templates/new_gem/test/plugin/test_input.rb.erb +18 -0
  269. data/templates/new_gem/test/plugin/test_output.rb.erb +18 -0
  270. data/templates/new_gem/test/plugin/test_parser.rb.erb +18 -0
  271. data/templates/plugin_config_formatter/param.md-compact.erb +25 -0
  272. data/templates/plugin_config_formatter/param.md.erb +34 -0
  273. data/templates/plugin_config_formatter/section.md.erb +12 -0
  274. data/test/command/test_binlog_reader.rb +346 -0
  275. data/test/command/test_ca_generate.rb +70 -0
  276. data/test/command/test_fluentd.rb +901 -0
  277. data/test/command/test_plugin_config_formatter.rb +276 -0
  278. data/test/command/test_plugin_generator.rb +92 -0
  279. data/test/compat/test_calls_super.rb +166 -0
  280. data/test/compat/test_parser.rb +92 -0
  281. data/test/config/test_config_parser.rb +126 -2
  282. data/test/config/test_configurable.rb +946 -187
  283. data/test/config/test_configure_proxy.rb +424 -74
  284. data/test/config/test_dsl.rb +11 -11
  285. data/test/config/test_element.rb +500 -0
  286. data/test/config/test_literal_parser.rb +8 -0
  287. data/test/config/test_plugin_configuration.rb +56 -0
  288. data/test/config/test_section.rb +79 -7
  289. data/test/config/test_system_config.rb +122 -35
  290. data/test/config/test_types.rb +38 -0
  291. data/test/counter/test_client.rb +559 -0
  292. data/test/counter/test_error.rb +44 -0
  293. data/test/counter/test_mutex_hash.rb +179 -0
  294. data/test/counter/test_server.rb +589 -0
  295. data/test/counter/test_store.rb +258 -0
  296. data/test/counter/test_validator.rb +137 -0
  297. data/test/helper.rb +89 -6
  298. data/test/helpers/fuzzy_assert.rb +89 -0
  299. data/test/plugin/test_bare_output.rb +118 -0
  300. data/test/plugin/test_base.rb +115 -0
  301. data/test/plugin/test_buf_file.rb +823 -460
  302. data/test/plugin/test_buf_memory.rb +32 -194
  303. data/test/plugin/test_buffer.rb +1233 -0
  304. data/test/plugin/test_buffer_chunk.rb +198 -0
  305. data/test/plugin/test_buffer_file_chunk.rb +844 -0
  306. data/test/plugin/test_buffer_memory_chunk.rb +338 -0
  307. data/test/plugin/test_compressable.rb +84 -0
  308. data/test/plugin/test_filter.rb +357 -0
  309. data/test/plugin/test_filter_grep.rb +540 -29
  310. data/test/plugin/test_filter_parser.rb +439 -452
  311. data/test/plugin/test_filter_record_transformer.rb +123 -166
  312. data/test/plugin/test_filter_stdout.rb +160 -72
  313. data/test/plugin/test_formatter_csv.rb +111 -0
  314. data/test/plugin/test_formatter_hash.rb +35 -0
  315. data/test/plugin/test_formatter_json.rb +51 -0
  316. data/test/plugin/test_formatter_ltsv.rb +62 -0
  317. data/test/plugin/test_formatter_msgpack.rb +28 -0
  318. data/test/plugin/test_formatter_out_file.rb +95 -0
  319. data/test/plugin/test_formatter_single_value.rb +38 -0
  320. data/test/plugin/test_formatter_tsv.rb +68 -0
  321. data/test/plugin/test_in_debug_agent.rb +24 -1
  322. data/test/plugin/test_in_dummy.rb +111 -18
  323. data/test/plugin/test_in_exec.rb +200 -113
  324. data/test/plugin/test_in_forward.rb +990 -387
  325. data/test/plugin/test_in_gc_stat.rb +10 -8
  326. data/test/plugin/test_in_http.rb +600 -224
  327. data/test/plugin/test_in_monitor_agent.rb +690 -0
  328. data/test/plugin/test_in_object_space.rb +24 -8
  329. data/test/plugin/test_in_syslog.rb +154 -215
  330. data/test/plugin/test_in_tail.rb +1006 -707
  331. data/test/plugin/test_in_tcp.rb +125 -48
  332. data/test/plugin/test_in_udp.rb +204 -63
  333. data/test/plugin/{test_in_stream.rb → test_in_unix.rb} +14 -13
  334. data/test/plugin/test_input.rb +126 -0
  335. data/test/plugin/test_metadata.rb +89 -0
  336. data/test/plugin/test_multi_output.rb +180 -0
  337. data/test/plugin/test_out_copy.rb +117 -112
  338. data/test/plugin/test_out_exec.rb +258 -53
  339. data/test/plugin/test_out_exec_filter.rb +538 -115
  340. data/test/plugin/test_out_file.rb +865 -178
  341. data/test/plugin/test_out_forward.rb +998 -210
  342. data/test/plugin/test_out_null.rb +105 -0
  343. data/test/plugin/test_out_relabel.rb +28 -0
  344. data/test/plugin/test_out_roundrobin.rb +36 -29
  345. data/test/plugin/test_out_secondary_file.rb +458 -0
  346. data/test/plugin/test_out_stdout.rb +135 -37
  347. data/test/plugin/test_out_stream.rb +18 -0
  348. data/test/plugin/test_output.rb +984 -0
  349. data/test/plugin/test_output_as_buffered.rb +2021 -0
  350. data/test/plugin/test_output_as_buffered_backup.rb +312 -0
  351. data/test/plugin/test_output_as_buffered_compress.rb +165 -0
  352. data/test/plugin/test_output_as_buffered_overflow.rb +250 -0
  353. data/test/plugin/test_output_as_buffered_retries.rb +911 -0
  354. data/test/plugin/test_output_as_buffered_secondary.rb +874 -0
  355. data/test/plugin/test_output_as_standard.rb +374 -0
  356. data/test/plugin/test_owned_by.rb +35 -0
  357. data/test/plugin/test_parser.rb +359 -0
  358. data/test/plugin/test_parser_apache.rb +42 -0
  359. data/test/plugin/test_parser_apache2.rb +47 -0
  360. data/test/plugin/test_parser_apache_error.rb +45 -0
  361. data/test/plugin/test_parser_csv.rb +103 -0
  362. data/test/plugin/test_parser_json.rb +138 -0
  363. data/test/plugin/test_parser_labeled_tsv.rb +145 -0
  364. data/test/plugin/test_parser_multiline.rb +100 -0
  365. data/test/plugin/test_parser_nginx.rb +88 -0
  366. data/test/plugin/test_parser_none.rb +52 -0
  367. data/test/plugin/test_parser_regexp.rb +289 -0
  368. data/test/plugin/test_parser_syslog.rb +441 -0
  369. data/test/plugin/test_parser_tsv.rb +122 -0
  370. data/test/plugin/test_storage.rb +167 -0
  371. data/test/plugin/test_storage_local.rb +335 -0
  372. data/test/plugin_helper/data/cert/cert-key.pem +27 -0
  373. data/test/plugin_helper/data/cert/cert-with-no-newline.pem +19 -0
  374. data/test/plugin_helper/data/cert/cert.pem +19 -0
  375. data/test/plugin_helper/http_server/test_app.rb +65 -0
  376. data/test/plugin_helper/http_server/test_route.rb +32 -0
  377. data/test/plugin_helper/test_cert_option.rb +16 -0
  378. data/test/plugin_helper/test_child_process.rb +794 -0
  379. data/test/plugin_helper/test_compat_parameters.rb +353 -0
  380. data/test/plugin_helper/test_event_emitter.rb +51 -0
  381. data/test/plugin_helper/test_event_loop.rb +52 -0
  382. data/test/plugin_helper/test_extract.rb +194 -0
  383. data/test/plugin_helper/test_formatter.rb +255 -0
  384. data/test/plugin_helper/test_http_server_helper.rb +205 -0
  385. data/test/plugin_helper/test_inject.rb +519 -0
  386. data/test/plugin_helper/test_parser.rb +264 -0
  387. data/test/plugin_helper/test_record_accessor.rb +197 -0
  388. data/test/plugin_helper/test_retry_state.rb +442 -0
  389. data/test/plugin_helper/test_server.rb +1714 -0
  390. data/test/plugin_helper/test_storage.rb +542 -0
  391. data/test/plugin_helper/test_thread.rb +164 -0
  392. data/test/plugin_helper/test_timer.rb +132 -0
  393. data/test/scripts/exec_script.rb +0 -6
  394. data/test/scripts/fluent/plugin/formatter1/formatter_test1.rb +7 -0
  395. data/test/scripts/fluent/plugin/formatter2/formatter_test2.rb +7 -0
  396. data/test/scripts/fluent/plugin/out_test.rb +23 -15
  397. data/test/scripts/fluent/plugin/out_test2.rb +80 -0
  398. data/test/test_clock.rb +164 -0
  399. data/test/test_config.rb +16 -7
  400. data/test/test_configdsl.rb +2 -2
  401. data/test/test_event.rb +360 -13
  402. data/test/test_event_router.rb +108 -11
  403. data/test/test_event_time.rb +199 -0
  404. data/test/test_filter.rb +48 -6
  405. data/test/test_formatter.rb +11 -391
  406. data/test/test_input.rb +1 -1
  407. data/test/test_log.rb +591 -31
  408. data/test/test_mixin.rb +1 -1
  409. data/test/test_output.rb +121 -185
  410. data/test/test_plugin.rb +251 -0
  411. data/test/test_plugin_classes.rb +177 -10
  412. data/test/test_plugin_helper.rb +81 -0
  413. data/test/test_plugin_id.rb +101 -0
  414. data/test/test_process.rb +8 -42
  415. data/test/test_root_agent.rb +766 -21
  416. data/test/test_supervisor.rb +481 -0
  417. data/test/test_test_drivers.rb +135 -0
  418. data/test/test_time_formatter.rb +282 -0
  419. data/test/test_time_parser.rb +231 -0
  420. data/test/test_unique_id.rb +47 -0
  421. metadata +454 -60
  422. data/COPYING +0 -14
  423. data/ChangeLog +0 -666
  424. data/lib/fluent/buffer.rb +0 -365
  425. data/lib/fluent/plugin/in_status.rb +0 -76
  426. data/test/plugin/test_in_status.rb +0 -38
  427. data/test/test_buffer.rb +0 -624
  428. data/test/test_parser.rb +0 -1305
@@ -0,0 +1,164 @@
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 'fluent/plugin'
18
+ require 'fluent/plugin/storage'
19
+
20
+ require 'fileutils'
21
+ require 'yajl'
22
+
23
+ module Fluent
24
+ module Plugin
25
+ class LocalStorage < Storage
26
+ Fluent::Plugin.register_storage('local', self)
27
+
28
+ DEFAULT_DIR_MODE = 0755
29
+ DEFAULT_FILE_MODE = 0644
30
+
31
+ config_param :path, :string, default: nil
32
+ config_param :mode, default: DEFAULT_FILE_MODE do |v|
33
+ v.to_i(8)
34
+ end
35
+ config_param :dir_mode, default: DEFAULT_DIR_MODE do |v|
36
+ v.to_i(8)
37
+ end
38
+ config_param :pretty_print, :bool, default: false
39
+
40
+ attr_reader :store # for test
41
+
42
+ def initialize
43
+ super
44
+ @store = {}
45
+ @multi_workers_available = nil
46
+ end
47
+
48
+ def configure(conf)
49
+ super
50
+
51
+ @on_memory = false
52
+ if @path
53
+ if File.exist?(@path) && File.file?(@path)
54
+ @multi_workers_available = false
55
+ elsif File.exist?(@path) && File.directory?(@path)
56
+ @path = File.join(@path, "worker#{fluentd_worker_id}", "storage.json")
57
+ @multi_workers_available = true
58
+ else # path file/directory doesn't exist
59
+ if @path.end_with?('.json') # file
60
+ @multi_workers_available = false
61
+ else # directory
62
+ @path = File.join(@path, "worker#{fluentd_worker_id}", "storage.json")
63
+ @multi_workers_available = true
64
+ end
65
+ end
66
+ elsif root_dir = owner.plugin_root_dir
67
+ basename = (conf.arg && !conf.arg.empty?) ? "storage.#{conf.arg}.json" : "storage.json"
68
+ @path = File.join(root_dir, basename)
69
+ @multi_workers_available = true
70
+ else
71
+ if @persistent
72
+ raise Fluent::ConfigError, "Plugin @id or path for <storage> required when 'persistent' is true"
73
+ else
74
+ if @autosave
75
+ log.warn "both of Plugin @id and path for <storage> are not specified. Using on-memory store."
76
+ else
77
+ log.info "both of Plugin @id and path for <storage> are not specified. Using on-memory store."
78
+ end
79
+ @on_memory = true
80
+ @multi_workers_available = true
81
+ end
82
+ end
83
+
84
+ if !@on_memory
85
+ dir = File.dirname(@path)
86
+ FileUtils.mkdir_p(dir, mode: @dir_mode) unless Dir.exist?(dir)
87
+ if File.exist?(@path)
88
+ raise Fluent::ConfigError, "Plugin storage path '#{@path}' is not readable/writable" unless File.readable?(@path) && File.writable?(@path)
89
+ begin
90
+ data = open(@path, 'r:utf-8') { |io| io.read }
91
+ if data.empty?
92
+ log.warn "detect empty plugin storage file during startup. Ignored: #{@path}"
93
+ return
94
+ end
95
+ data = Yajl::Parser.parse(data)
96
+ raise Fluent::ConfigError, "Invalid contents (not object) in plugin storage file: '#{@path}'" unless data.is_a?(Hash)
97
+ rescue => e
98
+ log.error "failed to read data from plugin storage file", path: @path, error: e
99
+ raise Fluent::ConfigError, "Unexpected error: failed to read data from plugin storage file: '#{@path}'"
100
+ end
101
+ else
102
+ raise Fluent::ConfigError, "Directory is not writable for plugin storage file '#{@path}'" unless File.stat(dir).writable?
103
+ end
104
+ end
105
+ end
106
+
107
+ def multi_workers_ready?
108
+ unless @multi_workers_available
109
+ log.error "local plugin storage with multi workers should be configured to use directory 'path', or system root_dir and plugin id"
110
+ end
111
+ @multi_workers_available
112
+ end
113
+
114
+ def load
115
+ return if @on_memory
116
+ return unless File.exist?(@path)
117
+ begin
118
+ json_string = open(@path, 'r:utf-8'){ |io| io.read }
119
+ json = Yajl::Parser.parse(json_string)
120
+ unless json.is_a?(Hash)
121
+ log.error "broken content for plugin storage (Hash required: ignored)", type: json.class
122
+ log.debug "broken content", content: json_string
123
+ return
124
+ end
125
+ @store = json
126
+ rescue => e
127
+ log.error "failed to load data for plugin storage from file", path: @path, error: e
128
+ end
129
+ end
130
+
131
+ def save
132
+ return if @on_memory
133
+ tmp_path = @path + '.tmp'
134
+ begin
135
+ json_string = Yajl::Encoder.encode(@store, pretty: @pretty_print)
136
+ open(tmp_path, 'w:utf-8', @mode) { |io| io.write json_string; io.fsync }
137
+ File.rename(tmp_path, @path)
138
+ rescue => e
139
+ log.error "failed to save data for plugin storage to file", path: @path, tmp: tmp_path, error: e
140
+ end
141
+ end
142
+
143
+ def get(key)
144
+ @store[key.to_s]
145
+ end
146
+
147
+ def fetch(key, defval)
148
+ @store.fetch(key.to_s, defval)
149
+ end
150
+
151
+ def put(key, value)
152
+ @store[key.to_s] = value
153
+ end
154
+
155
+ def delete(key)
156
+ @store.delete(key.to_s)
157
+ end
158
+
159
+ def update(key, &block)
160
+ @store[key.to_s] = block.call(@store[key.to_s])
161
+ end
162
+ end
163
+ end
164
+ end
@@ -14,21 +14,9 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
- require "string-scrub" unless "".respond_to?(:scrub)
17
+ require 'fluent/compat/string_util'
18
18
 
19
19
  module Fluent
20
- module StringUtil
21
- def match_regexp(regexp, string)
22
- begin
23
- return regexp.match(string)
24
- rescue ArgumentError => e
25
- raise e unless e.message.index("invalid byte sequence in".freeze).zero?
26
- $log.info "invalid byte sequence is replaced in `#{string}`"
27
- string = string.scrub('?')
28
- retry
29
- end
30
- return true
31
- end
32
- module_function :match_regexp
33
- end
20
+ # obsolete
21
+ StringUtil = Fluent::Compat::StringUtil
34
22
  end
data/lib/fluent/plugin.rb CHANGED
@@ -14,169 +14,170 @@
14
14
  # limitations under the License.
15
15
  #
16
16
 
17
+ require 'fluent/registry'
17
18
  require 'fluent/config/error'
18
19
 
19
20
  module Fluent
20
- class PluginClass
21
- # This class is refactored using Fluent::Registry at v0.14
21
+ module Plugin
22
+ SEARCH_PATHS = []
22
23
 
23
- def initialize
24
- @input = {}
25
- @output = {}
26
- @filter = {}
27
- @buffer = {}
28
- end
24
+ # plugins for fluentd: fluent/plugin/type_NAME.rb
25
+ # plugins for fluentd plugins: fluent/plugin/type/NAME.rb
26
+ # ex: storage, buffer chunk, ...
29
27
 
30
- def register_input(type, klass)
31
- register_impl('input', @input, type, klass)
32
- end
28
+ # first class plugins (instantiated by Engine)
29
+ INPUT_REGISTRY = Registry.new(:input, 'fluent/plugin/in_', dir_search_prefix: 'in_')
30
+ OUTPUT_REGISTRY = Registry.new(:output, 'fluent/plugin/out_', dir_search_prefix: 'out_')
31
+ FILTER_REGISTRY = Registry.new(:filter, 'fluent/plugin/filter_', dir_search_prefix: 'filter_')
33
32
 
34
- def register_output(type, klass)
35
- register_impl('output', @output, type, klass)
36
- end
33
+ # feature plugin: second class plugins (instantiated by Plugins or Helpers)
34
+ BUFFER_REGISTRY = Registry.new(:buffer, 'fluent/plugin/buf_', dir_search_prefix: 'buf_')
35
+ PARSER_REGISTRY = Registry.new(:parser, 'fluent/plugin/parser_', dir_search_prefix: 'parser_')
36
+ FORMATTER_REGISTRY = Registry.new(:formatter, 'fluent/plugin/formatter_', dir_search_prefix: 'formatter_')
37
+ STORAGE_REGISTRY = Registry.new(:storage, 'fluent/plugin/storage_', dir_search_prefix: 'storage_')
37
38
 
38
- def register_filter(type, klass)
39
- register_impl('filter', @filter, type, klass)
40
- end
39
+ REGISTRIES = [INPUT_REGISTRY, OUTPUT_REGISTRY, FILTER_REGISTRY, BUFFER_REGISTRY, PARSER_REGISTRY, FORMATTER_REGISTRY, STORAGE_REGISTRY]
41
40
 
42
- def register_buffer(type, klass)
43
- register_impl('buffer', @buffer, type, klass)
41
+ def self.register_input(type, klass)
42
+ register_impl('input', INPUT_REGISTRY, type, klass)
44
43
  end
45
44
 
46
- def register_parser(type, klass)
47
- TextParser.register_template(type, klass)
45
+ def self.register_output(type, klass)
46
+ register_impl('output', OUTPUT_REGISTRY, type, klass)
48
47
  end
49
48
 
50
- def register_formatter(type, klass)
51
- TextFormatter.register_template(type, klass)
49
+ def self.register_filter(type, klass)
50
+ register_impl('filter', FILTER_REGISTRY, type, klass)
52
51
  end
53
52
 
54
- def new_input(type)
55
- new_impl('input', @input, type)
53
+ def self.register_buffer(type, klass)
54
+ register_impl('buffer', BUFFER_REGISTRY, type, klass)
56
55
  end
57
56
 
58
- def new_output(type)
59
- new_impl('output', @output, type)
57
+ def self.register_parser(type, klass_or_proc)
58
+ if klass_or_proc.is_a?(Regexp)
59
+ # This usage is not recommended for new API
60
+ require 'fluent/parser'
61
+ register_impl('parser', PARSER_REGISTRY, type, Proc.new { Fluent::TextParser::RegexpParser.new(klass_or_proc) })
62
+ else
63
+ register_impl('parser', PARSER_REGISTRY, type, klass_or_proc)
64
+ end
60
65
  end
61
66
 
62
- def new_filter(type)
63
- new_impl('filter', @filter, type)
67
+ def self.register_formatter(type, klass_or_proc)
68
+ if klass_or_proc.respond_to?(:call) && klass_or_proc.arity == 3 # Proc.new { |tag, time, record| }
69
+ # This usage is not recommended for new API
70
+ require 'fluent/formatter'
71
+ register_impl('formatter', FORMATTER_REGISTRY, type, Proc.new { Fluent::TextFormatter::ProcWrappedFormatter.new(klass_or_proc) })
72
+ else
73
+ register_impl('formatter', FORMATTER_REGISTRY, type, klass_or_proc)
74
+ end
64
75
  end
65
76
 
66
- def new_buffer(type)
67
- new_impl('buffer', @buffer, type)
77
+ def self.register_storage(type, klass)
78
+ register_impl('storage', STORAGE_REGISTRY, type, klass)
68
79
  end
69
80
 
70
- def new_parser(type)
71
- require 'fluent/parser'
72
- TextParser.lookup(type)
81
+ def self.lookup_type_from_class(klass_or_its_name)
82
+ klass = if klass_or_its_name.is_a? Class
83
+ klass_or_its_name
84
+ elsif klass_or_its_name.is_a? String
85
+ eval(klass_or_its_name) # const_get can't handle qualified klass name (ex: A::B)
86
+ else
87
+ raise ArgumentError, "invalid argument type #{klass_or_its_name.class}: #{klass_or_its_name}"
88
+ end
89
+ REGISTRIES.reduce(nil){|a, r| a || r.reverse_lookup(klass) }
73
90
  end
74
91
 
75
- def new_formatter(type)
76
- require 'fluent/formatter'
77
- TextFormatter.lookup(type)
92
+ def self.add_plugin_dir(dir)
93
+ REGISTRIES.each do |r|
94
+ r.paths.push(dir)
95
+ end
96
+ nil
78
97
  end
79
98
 
80
- def load_plugins
81
- dir = File.join(File.dirname(__FILE__), "plugin")
82
- load_plugin_dir(dir)
99
+ def self.new_input(type)
100
+ new_impl('input', INPUT_REGISTRY, type)
83
101
  end
84
102
 
85
- def load_plugin_dir(dir)
86
- dir = File.expand_path(dir)
87
- Dir.entries(dir).sort.each {|fname|
88
- if fname =~ /\.rb$/
89
- require File.join(dir, fname)
90
- end
91
- }
92
- nil
103
+ def self.new_output(type)
104
+ new_impl('output', OUTPUT_REGISTRY, type)
93
105
  end
94
106
 
95
- def load_plugin(type, name)
96
- try_load_plugin(name, type)
107
+ def self.new_filter(type)
108
+ new_impl('filter', FILTER_REGISTRY, type)
97
109
  end
98
110
 
99
- def lookup_name_from_class(klass_or_str)
100
- klass = if klass_or_str.class == String
101
- eval(klass_or_str) # const_get can't handle A::B
102
- else
103
- klass_or_str
104
- end
111
+ def self.new_buffer(type, parent: nil)
112
+ new_impl('buffer', BUFFER_REGISTRY, type, parent)
113
+ end
105
114
 
106
- @input.each { |name, plugin|
107
- return name if plugin == klass
108
- }
109
- @output.each { |name, plugin|
110
- return name if plugin == klass
111
- }
112
- @filter.each { |name, plugin|
113
- return name if plugin == klass
114
- }
115
+ def self.new_parser(type, parent: nil)
116
+ if type[0] == '/' && type[-1] == '/'
117
+ # This usage is not recommended for new API... create RegexpParser directly
118
+ require 'fluent/parser'
119
+ impl = Fluent::TextParser.lookup(type)
120
+ impl.extend FeatureAvailabilityChecker
121
+ impl
122
+ else
123
+ new_impl('parser', PARSER_REGISTRY, type, parent)
124
+ end
125
+ end
115
126
 
116
- nil
127
+ def self.new_formatter(type, parent: nil)
128
+ new_impl('formatter', FORMATTER_REGISTRY, type, parent)
117
129
  end
118
130
 
119
- private
120
- def register_impl(name, map, type, klass)
121
- map[type] = klass
122
- $log.trace { "registered #{name} plugin '#{type}'" }
123
- nil
131
+ def self.new_storage(type, parent: nil)
132
+ new_impl('storage', STORAGE_REGISTRY, type, parent)
124
133
  end
125
134
 
126
- def new_impl(name, map, type)
127
- if klass = map[type]
128
- return klass.new
129
- end
130
- try_load_plugin(name, type)
131
- if klass = map[type]
132
- return klass.new
133
- end
134
- raise ConfigError, "Unknown #{name} plugin '#{type}'. Run 'gem search -rd fluent-plugin' to find plugins"
135
- end
136
-
137
- def try_load_plugin(name, type)
138
- case name
139
- when 'input'
140
- path = "fluent/plugin/in_#{type}"
141
- when 'output'
142
- path = "fluent/plugin/out_#{type}"
143
- when 'filter'
144
- path = "fluent/plugin/filter_#{type}"
145
- when 'buffer'
146
- path = "fluent/plugin/buf_#{type}"
147
- else
148
- return
135
+ def self.register_impl(kind, registry, type, value)
136
+ if !value.is_a?(Class) && !value.respond_to?(:call)
137
+ raise Fluent::ConfigError, "Invalid implementation as #{kind} plugin: '#{type}'. It must be a Class, or callable."
149
138
  end
139
+ registry.register(type, value)
140
+ $log.trace "registered #{kind} plugin '#{type}'" if defined?($log)
141
+ nil
142
+ end
150
143
 
151
- # prefer LOAD_PATH than gems
152
- files = $LOAD_PATH.map {|lp|
153
- lpath = File.join(lp, "#{path}.rb")
154
- File.exist?(lpath) ? lpath : nil
155
- }.compact
156
- unless files.empty?
157
- # prefer newer version
158
- require File.expand_path(files.sort.last)
159
- return
144
+ def self.new_impl(kind, registry, type, parent=nil)
145
+ # "'type' not found" is handled by registry
146
+ obj = registry.lookup(type)
147
+ impl = case
148
+ when obj.is_a?(Class)
149
+ obj.new
150
+ when obj.respond_to?(:call) && obj.arity == 0
151
+ obj.call
152
+ else
153
+ raise Fluent::ConfigError, "#{kind} plugin '#{type}' is not a Class nor callable (without arguments)."
154
+ end
155
+ if parent && impl.respond_to?("owner=")
156
+ impl.owner = parent
160
157
  end
161
-
162
- # search gems
163
- specs = Gem::Specification.find_all { |spec|
164
- spec.contains_requirable_file? path
165
- }
166
-
167
- # prefer newer version
168
- specs = specs.sort_by { |spec| spec.version }
169
- if spec = specs.last
170
- spec.require_paths.each { |lib|
171
- file = "#{spec.full_gem_path}/#{lib}/#{path}"
172
- if File.exist?("#{file}.rb")
173
- require file
174
- return
175
- end
176
- }
158
+ impl.extend FeatureAvailabilityChecker
159
+ impl
160
+ end
161
+
162
+ module FeatureAvailabilityChecker
163
+ def configure(conf)
164
+ super
165
+
166
+ # extend plugin instance by this module
167
+ # to run this check after all #configure methods of plugins and plugin helpers
168
+ sysconf = if self.respond_to?(:owner) && owner.respond_to?(:system_config)
169
+ owner.system_config
170
+ elsif self.respond_to?(:system_config)
171
+ self.system_config
172
+ else
173
+ nil
174
+ end
175
+
176
+ if sysconf && sysconf.workers > 1 && !self.multi_workers_ready?
177
+ type = Fluent::Plugin.lookup_type_from_class(self.class)
178
+ raise Fluent::ConfigError, "Plugin '#{type}' does not support multi workers configuration (#{self.class})"
179
+ end
177
180
  end
178
181
  end
179
182
  end
180
-
181
- Plugin = PluginClass.new
182
183
  end
@@ -0,0 +1,178 @@
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 'socket'
19
+
20
+ # this module is only for Socket/Server plugin helpers
21
+ module Fluent
22
+ module PluginHelper
23
+ module CertOption
24
+ def cert_option_create_context(version, insecure, ciphers, conf)
25
+ cert, key, extra = cert_option_server_validate!(conf)
26
+
27
+ ctx = OpenSSL::SSL::SSLContext.new(version)
28
+ unless insecure
29
+ # inject OpenSSL::SSL::SSLContext::DEFAULT_PARAMS
30
+ # https://bugs.ruby-lang.org/issues/9424
31
+ ctx.set_params({})
32
+
33
+ ctx.ciphers = ciphers
34
+ end
35
+
36
+ if conf.client_cert_auth
37
+ ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT
38
+ end
39
+
40
+ ctx.ca_file = conf.ca_path
41
+ ctx.cert = cert
42
+ ctx.key = key
43
+ if extra && !extra.empty?
44
+ ctx.extra_chain_cert = extra
45
+ end
46
+
47
+ ctx
48
+ end
49
+
50
+ def cert_option_server_validate!(conf)
51
+ case
52
+ when conf.cert_path
53
+ raise Fluent::ConfigError, "private_key_path is required when cert_path is specified" unless conf.private_key_path
54
+ log.warn "For security reason, setting private_key_passphrase is recommended when cert_path is specified" unless conf.private_key_passphrase
55
+ cert_option_load(conf.cert_path, conf.private_key_path, conf.private_key_passphrase)
56
+
57
+ when conf.ca_cert_path
58
+ raise Fluent::ConfigError, "ca_private_key_path is required when ca_cert_path is specified" unless conf.ca_private_key_path
59
+ log.warn "For security reason, setting ca_private_key_passphrase is recommended when ca_cert_path is specified" unless conf.ca_private_key_passphrase
60
+ generate_opts = cert_option_cert_generation_opts_from_conf(conf)
61
+ cert_option_generate_server_pair_by_ca(
62
+ conf.ca_cert_path,
63
+ conf.ca_private_key_path,
64
+ conf.ca_private_key_passphrase,
65
+ generate_opts
66
+ )
67
+
68
+ when conf.insecure
69
+ log.warn "insecure TLS communication server is configured (using 'insecure' mode)"
70
+ generate_opts = cert_option_cert_generation_opts_from_conf(conf)
71
+ cert_option_generate_server_pair_self_signed(generate_opts)
72
+
73
+ else
74
+ raise Fluent::ConfigError, "no valid cert options configured. specify either 'cert_path', 'ca_cert_path' or 'insecure'"
75
+ end
76
+ end
77
+
78
+ def cert_option_load(cert_path, private_key_path, private_key_passphrase)
79
+ key = OpenSSL::PKey::read(File.read(private_key_path), private_key_passphrase)
80
+ certs = cert_option_certificates_from_file(cert_path)
81
+ cert = certs.shift
82
+ return cert, key, certs
83
+ end
84
+
85
+ def cert_option_cert_generation_opts_from_conf(conf)
86
+ {
87
+ private_key_length: conf.generate_private_key_length,
88
+ country: conf.generate_cert_country,
89
+ state: conf.generate_cert_state,
90
+ locality: conf.generate_cert_locality,
91
+ common_name: conf.generate_cert_common_name || ::Socket.gethostname,
92
+ expiration: conf.generate_cert_expiration,
93
+ digest: conf.generate_cert_digest,
94
+ }
95
+ end
96
+
97
+ def cert_option_generate_pair(opts, issuer = nil)
98
+ key = OpenSSL::PKey::RSA.generate(opts[:private_key_length])
99
+
100
+ subject = OpenSSL::X509::Name.new
101
+ subject.add_entry('C', opts[:country])
102
+ subject.add_entry('ST', opts[:state])
103
+ subject.add_entry('L', opts[:locality])
104
+ subject.add_entry('CN', opts[:common_name])
105
+
106
+ issuer ||= subject
107
+
108
+ cert = OpenSSL::X509::Certificate.new
109
+ cert.not_before = Time.at(0)
110
+ cert.not_after = Time.now + opts[:expiration]
111
+ cert.public_key = key
112
+ cert.version = 2
113
+ cert.serial = rand(2**(8*10))
114
+ cert.issuer = issuer
115
+ cert.subject = subject
116
+
117
+ return cert, key
118
+ end
119
+
120
+ def cert_option_add_extensions(cert, extensions)
121
+ ef = OpenSSL::X509::ExtensionFactory.new
122
+ extensions.each do |ext|
123
+ oid, value = ext
124
+ cert.add_extension ef.create_extension(oid, value)
125
+ end
126
+ end
127
+
128
+ def cert_option_generate_ca_pair_self_signed(generate_opts)
129
+ cert, key = cert_option_generate_pair(generate_opts)
130
+
131
+ cert_option_add_extensions(cert, [
132
+ ['basicConstraints', 'CA:TRUE']
133
+ ])
134
+
135
+ cert.sign(key, generate_opts[:digest].to_s)
136
+ return cert, key
137
+ end
138
+
139
+ def cert_option_generate_server_pair_by_ca(ca_cert_path, ca_key_path, ca_key_passphrase, generate_opts)
140
+ ca_key = OpenSSL::PKey::read(File.read(ca_key_path), ca_key_passphrase)
141
+ ca_cert = OpenSSL::X509::Certificate.new(File.read(ca_cert_path))
142
+ cert, key = cert_option_generate_pair(generate_opts, ca_cert.subject)
143
+ raise "BUG: certificate digest algorithm not set" unless generate_opts[:digest]
144
+
145
+ cert_option_add_extensions(cert, [
146
+ ['basicConstraints', 'CA:FALSE'],
147
+ ['nsCertType', 'server'],
148
+ ['keyUsage', 'digitalSignature,keyEncipherment'],
149
+ ['extendedKeyUsage', 'serverAuth']
150
+ ])
151
+
152
+ cert.sign(ca_key, generate_opts[:digest].to_s)
153
+ return cert, key, nil
154
+ end
155
+
156
+ def cert_option_generate_server_pair_self_signed(generate_opts)
157
+ cert, key = cert_option_generate_pair(generate_opts)
158
+ raise "BUG: certificate digest algorithm not set" unless generate_opts[:digest]
159
+
160
+ cert_option_add_extensions(cert, [
161
+ ['basicConstraints', 'CA:FALSE'],
162
+ ['nsCertType', 'server']
163
+ ])
164
+
165
+ cert.sign(key, generate_opts[:digest].to_s)
166
+ return cert, key, nil
167
+ end
168
+
169
+ def cert_option_certificates_from_file(path)
170
+ data = File.read(path)
171
+ pattern = Regexp.compile('-+BEGIN CERTIFICATE-+\n(?:[^-]*\n)+-+END CERTIFICATE-+\n?', Regexp::MULTILINE)
172
+ list = []
173
+ data.scan(pattern){|match| list << OpenSSL::X509::Certificate.new(match) }
174
+ list
175
+ end
176
+ end
177
+ end
178
+ end