fluent-plugin-ssl-check 2.2.0 → 2.4.0

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
  SHA256:
3
- metadata.gz: 6f57a4e0f824d263cc4cde461a9b4846695309b16e7211486ba6ccd2e41365c0
4
- data.tar.gz: c93593774d277d9769bb953f0e7893bbaf7168adf514dadff415a2382b37e37b
3
+ metadata.gz: 32576d289dd8aa0e769f4e4aaa975cbc0517d3d25a70506f5ef478572ca7cf89
4
+ data.tar.gz: ac1682153f0c68ed33aec0ad1334776425d542369fa0285a6c306dc1892c72e2
5
5
  SHA512:
6
- metadata.gz: 4e4cdfd93bd663bfb08e75fc60b9cd5ec34d58957001207569932cd6696e2e6c51e5ae3392fcbf76caa624af9a1d00684e56646f2690a8d96fbdd778b7fc653c
7
- data.tar.gz: 3446b7d2cfb26a28754bafee5074725f8bff7a1381d1020128d61b01bb31ae7785b08762749c17fd83c378a78f8815e98c9809f5c5e5d9ccb874140114954be8
6
+ metadata.gz: b4702ea39635a4f00dce824ca750a5c9b507a1102234b88b3fe782bd25205c7377a40cde8e51143324af1d1f25ee574542e391b8e99f59e9c3fa1d31b15d95cc
7
+ data.tar.gz: e67001eedef2c25b144ef2f7f63b6af0824279fb84ecbe9bda90005627bd575c1558b69027ec80944804f08f1840f162f65276464e743b41c087e1515d7789fe
data/.gitlab-ci.yml ADDED
@@ -0,0 +1,10 @@
1
+ default:
2
+ image: ruby:3.3.6
3
+
4
+ before_script:
5
+ - gem install bundler -v 2.5.22
6
+ - bundle install
7
+
8
+ test_job:
9
+ script:
10
+ - bundle exec rake
data/.rubocop.yml CHANGED
@@ -22,6 +22,7 @@ Metrics/ClassLength:
22
22
  Exclude:
23
23
  - test/**/*.rb
24
24
  - lib/fluent/plugin/in_ssl_check.rb
25
+ - lib/fluent/plugin/in_ssl_file_check.rb
25
26
 
26
27
  Metrics/MethodLength:
27
28
  Max: 20
@@ -29,3 +30,6 @@ Metrics/MethodLength:
29
30
  # Naming/MethodParameterName:
30
31
  # Exclude:
31
32
  # - lib/fluent/plugin/in_ssl_check.rb
33
+
34
+ Style/Documentation:
35
+ Enabled: false
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.7.7
1
+ 3.3.6
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- fluent-plugin-ssl-check (2.2.0)
4
+ fluent-plugin-ssl-check (2.4.0)
5
5
  fluentd (>= 0.14.10, < 2)
6
6
 
7
7
  GEM
@@ -29,6 +29,8 @@ GEM
29
29
  json (2.6.3)
30
30
  kwalify (0.7.2)
31
31
  language_server-protocol (3.17.0.3)
32
+ mocha (2.6.1)
33
+ ruby2_keywords (>= 0.0.5)
32
34
  msgpack (1.7.2)
33
35
  parallel (1.23.0)
34
36
  parser (3.2.2.3)
@@ -61,6 +63,7 @@ GEM
61
63
  rubocop-rake (0.6.0)
62
64
  rubocop (~> 1.0)
63
65
  ruby-progressbar (1.13.0)
66
+ ruby2_keywords (0.0.5)
64
67
  serverengine (2.3.2)
65
68
  sigdump (~> 0.2.2)
66
69
  sigdump (0.2.5)
@@ -84,6 +87,7 @@ DEPENDENCIES
84
87
  bundler (~> 2.4)
85
88
  byebug (~> 11.1, >= 11.1.3)
86
89
  fluent-plugin-ssl-check!
90
+ mocha (~> 2.6, >= 2.6.1)
87
91
  rake (~> 13.0, >= 13.0.6)
88
92
  reek (~> 6.1, >= 6.1.4)
89
93
  rubocop (~> 1.56)
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [Fluentd](https://fluentd.org/) input plugin to check ssl service.
4
4
 
5
+
5
6
  ## plugins
6
7
 
7
8
  ### in - ssl_check
@@ -35,6 +36,7 @@ Options are:
35
36
  * cert: client cert for ssl connection
36
37
  * key: client key associated to client cert for ssl connection
37
38
  * timeout: timeout for ssl check execution (5sec)
39
+ * paths: local certificate file paths
38
40
  * log_events: emit log format (true)
39
41
  * metric_events: emit metric format (false)
40
42
  * event_prefix: metric event prefix for extra dimension
@@ -42,6 +44,84 @@ Options are:
42
44
 
43
45
  If no port is specified with host, default port is 443.
44
46
 
47
+
48
+ ### in - ssl_file_check
49
+
50
+ Poll ssl local file and report status.
51
+
52
+ Example:
53
+
54
+ ``` conf
55
+ <source>
56
+ @type ssl_file_check
57
+ tag ssl_check
58
+
59
+ paths /etc/cert/host.pem,/app/application_1/cert.pem
60
+
61
+ interval 600
62
+
63
+ ca_path /my/ca_dir/
64
+ ca_file /my/ca_file
65
+ </source>
66
+ ```
67
+
68
+ Options are:
69
+ * tag: Tag to emit events on
70
+ * interval: check every X seconds
71
+ * paths: local certificate file paths
72
+ * ca_path: directory that contains CA files
73
+ * ca_file: specify a CA file directly
74
+ * log_events: emit log format (true)
75
+ * metric_events: emit metric format (false)
76
+ * event_prefix: metric event prefix for extra dimension
77
+ * timestamp_format: iso, epochmillis timestamp format (iso)
78
+
79
+
80
+ ## output examples
81
+
82
+ ### log output example
83
+
84
+ ``` json
85
+ {
86
+ "timestamp": "2023-10-03T09:59:41.580+02:00",
87
+ "status": 1,
88
+ "host": "www.google.fr",
89
+ "port": 443,
90
+ "ssl_version": "TLSv1.2",
91
+ "ssl_dn": "/CN=*.google.fr",
92
+ "ssl_not_after": "2023-11-27T08:25:08.000Z",
93
+ "expire_in_days": 55,
94
+ "serial": "4e79dbb13c6b57b309780da2d1edbda4"
95
+ }
96
+ ```
97
+
98
+ ### metric output example
99
+
100
+ ``` json
101
+ {
102
+ "timestamp": "2023-10-03T10:06:21.417+02:00",
103
+ "metric_name": "ssl_status",
104
+ "metric_value": 1,
105
+ "host": "www.google.fr",
106
+ "port": 443,
107
+ "ssl_dn": "/CN=*.google.fr",
108
+ "ssl_version": "TLSv1.2",
109
+ "ssl_not_after": "2023-11-27T08:25:08.000Z",
110
+ "serial": "4e79dbb13c6b57b309780da2d1edbda4"
111
+ }
112
+
113
+ {
114
+ "timestamp": "2023-10-03T10:06:21.417+02:00",
115
+ "metric_name": "ssl_expirency",
116
+ "metric_value": 55,
117
+ "host": "www.google.fr",
118
+ "port": 443,
119
+ "ssl_dn": "/CN=*.google.fr",
120
+ "serial": "4e79dbb13c6b57b309780da2d1edbda4"
121
+ }
122
+ ```
123
+
124
+
45
125
  ## Installation
46
126
 
47
127
  Manual install, by executing:
@@ -5,7 +5,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
 
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'fluent-plugin-ssl-check'
8
- spec.version = '2.2.0'
8
+ spec.version = '2.4.0'
9
9
  spec.authors = ['Thomas Tych']
10
10
  spec.email = ['thomas.tych@gmail.com']
11
11
 
@@ -27,6 +27,7 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency 'bump', '~> 0.10.0'
28
28
  spec.add_development_dependency 'bundler', '~> 2.4'
29
29
  spec.add_development_dependency 'byebug', '~> 11.1', '>= 11.1.3'
30
+ spec.add_development_dependency 'mocha', '~> 2.6', '>= 2.6.1'
30
31
  spec.add_development_dependency 'rake', '~> 13.0', '>= 13.0.6'
31
32
  spec.add_development_dependency 'reek', '~> 6.1', '>= 6.1.4'
32
33
  spec.add_development_dependency 'rubocop', '~> 1.56'
@@ -23,15 +23,17 @@ require 'timeout'
23
23
  require 'date'
24
24
 
25
25
  require_relative 'extensions/time'
26
+ require_relative 'ssl_check'
26
27
 
27
28
  module Fluent
28
29
  module Plugin
29
- # ssl_check input plugin
30
- # check ssl service
31
30
  class SslCheckInput < Fluent::Plugin::Input
32
31
  NAME = 'ssl_check'
33
32
  Fluent::Plugin.register_input(NAME, self)
34
33
 
34
+ include Fluent::Plugin::SslCheck::SslInputEmit
35
+ include Fluent::Plugin::SslCheck::SslCommon
36
+
35
37
  DEFAULT_TAG = NAME
36
38
  DEFAULT_PORT = 443
37
39
  DEFAULT_INTERVAL = 600
@@ -41,6 +43,7 @@ module Fluent
41
43
  DEFAULT_LOG_EVENTS = true
42
44
  DEFAULT_METRIC_EVENTS = false
43
45
  DEFAULT_EVENT_PREFIX = ''
46
+ DEFAULT_TIMESTAMP_FORMAT = :iso
44
47
 
45
48
  desc 'Tag to emit events on'
46
49
  config_param :tag, :string, default: DEFAULT_TAG
@@ -72,7 +75,7 @@ module Fluent
72
75
  desc 'Event prefix'
73
76
  config_param :event_prefix, :string, default: DEFAULT_EVENT_PREFIX
74
77
  desc 'Timestamp format'
75
- config_param :timestamp_format, :enum, list: %i[iso epochmillis], default: :iso
78
+ config_param :timestamp_format, :enum, list: %i[iso epochmillis], default: DEFAULT_TIMESTAMP_FORMAT
76
79
 
77
80
  helpers :timer
78
81
 
@@ -125,54 +128,6 @@ module Fluent
125
128
  ssl_client.ssl_info
126
129
  end
127
130
 
128
- def emit_logs(ssl_info)
129
- record = {
130
- 'timestamp' => ssl_info.time.send("to_#{timestamp_format}"),
131
- 'status' => ssl_info.status,
132
- 'host' => ssl_info.host,
133
- 'port' => ssl_info.port,
134
- 'ssl_version' => ssl_info.ssl_version,
135
- 'ssl_dn' => ssl_info.subject_s,
136
- 'ssl_not_after' => ssl_info.not_after,
137
- 'expire_in_days' => ssl_info.expire_in_days
138
- }
139
- record.update('error_class' => ssl_info.error_class) if ssl_info.error_class
140
- router.emit(tag, Fluent::EventTime.from_time(ssl_info.time), record)
141
- end
142
-
143
- def emit_metrics(ssl_info)
144
- emit_metric_status(ssl_info)
145
- emit_metric_expirency(ssl_info)
146
- end
147
-
148
- def emit_metric_status(ssl_info)
149
- record = {
150
- 'timestamp' => ssl_info.time.send("to_#{timestamp_format}"),
151
- 'metric_name' => 'ssl_status',
152
- 'metric_value' => ssl_info.status,
153
- "#{event_prefix}host" => ssl_info.host,
154
- "#{event_prefix}port" => ssl_info.port,
155
- "#{event_prefix}ssl_dn" => ssl_info.subject_s,
156
- "#{event_prefix}ssl_version" => ssl_info.ssl_version,
157
- "#{event_prefix}ssl_not_after" => ssl_info.not_after
158
- }
159
- router.emit(tag, Fluent::EventTime.from_time(ssl_info.time), record)
160
- end
161
-
162
- def emit_metric_expirency(ssl_info)
163
- return if ssl_info.error
164
-
165
- record = {
166
- 'timestamp' => ssl_info.time.send("to_#{timestamp_format}"),
167
- 'metric_name' => 'ssl_expirency',
168
- 'metric_value' => ssl_info.expire_in_days,
169
- "#{event_prefix}host" => ssl_info.host,
170
- "#{event_prefix}port" => ssl_info.port,
171
- "#{event_prefix}ssl_dn" => ssl_info.subject_s
172
- }
173
- router.emit(tag, Fluent::EventTime.from_time(ssl_info.time), record)
174
- end
175
-
176
131
  private
177
132
 
178
133
  def ssl_verify_mode
@@ -181,57 +136,6 @@ module Fluent
181
136
  OpenSSL::SSL::VERIFY_NONE
182
137
  end
183
138
 
184
- # ssl info
185
- # to encapsulate extracted ssl information
186
- class SslInfo
187
- OK = 1
188
- KO = 0
189
-
190
- attr_reader :time
191
- attr_accessor :host, :port, :cert, :cert_chain, :ssl_version, :error
192
-
193
- # rubocop:disable Metrics/ParameterLists
194
- def initialize(host: nil, port: nil, cert: nil, cert_chain: nil, ssl_version: nil, error: nil, time: Time.now)
195
- @host = host
196
- @port = port
197
- @cert = cert
198
- @cert_chain = cert_chain
199
- @ssl_version = ssl_version
200
- @error = error
201
- @time = time
202
- end
203
- # rubocop:enable Metrics/ParameterLists
204
-
205
- def subject_s
206
- cert.subject.to_s if cert&.subject
207
- end
208
-
209
- def expire_in_days
210
- return unless cert&.not_after
211
-
212
- expire_in = cert.not_after
213
- ((expire_in - time) / 3600 / 24).to_i
214
- end
215
-
216
- def not_after
217
- return unless cert
218
-
219
- cert.not_after.iso8601(3)
220
- end
221
-
222
- def status
223
- return KO if error
224
-
225
- OK
226
- end
227
-
228
- def error_class
229
- return unless error
230
-
231
- error.class.to_s
232
- end
233
- end
234
-
235
139
  # ssl client
236
140
  # to check ssl status
237
141
  class SslClient
@@ -254,7 +158,7 @@ module Fluent
254
158
  # rubocop:enable Metrics/ParameterLists
255
159
 
256
160
  def ssl_info
257
- info = SslInfo.new(host: host, port: port)
161
+ info = Fluent::Plugin::SslCheck::SslInfo.new(host: host, port: port)
258
162
  begin
259
163
  Timeout.timeout(timeout) do
260
164
  tcp_socket = TCPSocket.open(host, port)
@@ -275,18 +179,10 @@ module Fluent
275
179
  info
276
180
  end
277
181
 
278
- def store
279
- OpenSSL::X509::Store.new.tap do |store|
280
- store.set_default_paths
281
- store.add_path(ca_path) if ca_path
282
- store.add_file(ca_file) if ca_file
283
- end
284
- end
285
-
286
182
  def ssl_context
287
183
  OpenSSL::SSL::SSLContext.new.tap do |ssl_context|
288
184
  ssl_context.verify_mode = verify_mode
289
- ssl_context.cert_store = store
185
+ ssl_context.cert_store = ssl_store(ca_path: ca_path, ca_file: ca_file)
290
186
  ssl_context.min_version = nil
291
187
  ssl_context.max_version = OpenSSL::SSL::TLS1_2_VERSION
292
188
  ssl_context.cert = OpenSSL::X509::Certificate.new(File.open(cert)) if cert
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ #
4
+ # Copyright 2024- Thomas Tych
5
+ #
6
+ # Licensed under the Apache License, Version 2.0 (the "License");
7
+ # you may not use this file except in compliance with the License.
8
+ # You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing, software
13
+ # distributed under the License is distributed on an "AS IS" BASIS,
14
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ # See the License for the specific language governing permissions and
16
+ # limitations under the License.
17
+
18
+ require 'fluent/plugin/input'
19
+
20
+ require 'openssl'
21
+
22
+ require_relative 'extensions/time'
23
+ require_relative 'ssl_check'
24
+
25
+ module Fluent
26
+ module Plugin
27
+ class SslFileCheckInput < Fluent::Plugin::Input
28
+ NAME = 'ssl_file_check'
29
+ Fluent::Plugin.register_input(NAME, self)
30
+
31
+ include Fluent::Plugin::SslCheck::SslInputEmit
32
+
33
+ DEFAULT_TAG = NAME
34
+ DEFAULT_INTERVAL = 600
35
+ DEFAULT_LOG_EVENTS = true
36
+ DEFAULT_METRIC_EVENTS = false
37
+ DEFAULT_EVENT_PREFIX = ''
38
+ DEFAULT_TIMESTAMP_FORMAT = :iso
39
+
40
+ desc 'Tag to emit events on'
41
+ config_param :tag, :string, default: DEFAULT_TAG
42
+
43
+ desc 'Paths of local certificate to check'
44
+ config_param :paths, :array, default: [], value_type: :string
45
+
46
+ desc 'Interval for the check execution'
47
+ config_param :interval, :time, default: DEFAULT_INTERVAL
48
+
49
+ desc 'CA path to load'
50
+ config_param :ca_path, :string, default: nil
51
+ desc 'CA file to load'
52
+ config_param :ca_file, :string, default: nil
53
+
54
+ desc 'Emit log events'
55
+ config_param :log_events, :bool, default: DEFAULT_LOG_EVENTS
56
+ desc 'Emit metric events'
57
+ config_param :metric_events, :bool, default: DEFAULT_METRIC_EVENTS
58
+ desc 'Event prefix'
59
+ config_param :event_prefix, :string, default: DEFAULT_EVENT_PREFIX
60
+ desc 'Timestamp format'
61
+ config_param :timestamp_format, :enum, list: %i[iso epochmillis], default: DEFAULT_TIMESTAMP_FORMAT
62
+
63
+ helpers :timer
64
+
65
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
66
+ def configure(conf)
67
+ super
68
+
69
+ raise Fluent::ConfigError, 'tag can not be empty.' if !tag || tag.empty?
70
+ raise Fluent::ConfigError, 'paths can not be empty.' unless paths
71
+ raise Fluent::ConfigError, 'interval can not be < 1.' if !interval || interval < 1
72
+ raise Fluent::ConfigError, 'ca_path should be a dir.' if ca_path && !File.directory?(ca_path)
73
+ raise Fluent::ConfigError, 'ca_file should be a file.' if ca_file && !File.file?(ca_file)
74
+
75
+ log.warn("#{NAME}: paths is empty, nothing to process") if paths.empty?
76
+ end
77
+ # rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
78
+
79
+ def start
80
+ super
81
+
82
+ timer_execute(:ssl_file_check_timer, 1, repeat: false, &method(:check)) if interval > 60
83
+
84
+ timer_execute(:ssl_file_check_timer, interval, repeat: true, &method(:check))
85
+ end
86
+
87
+ # rubocop:disable Lint/SuppressedException
88
+ def check
89
+ paths.each do |cert_path|
90
+ ssl_info = fetch_ssl_info(cert_path)
91
+ emit_logs(ssl_info) if log_events
92
+ emit_metrics(ssl_info) if metric_events
93
+ rescue StandardError
94
+ end
95
+ end
96
+ # rubocop:enable Lint/SuppressedException
97
+
98
+ def fetch_ssl_info(filepath)
99
+ ssl_file = Fluent::Plugin::SslCheck::FileChecker.new(filepath, ca_path: ca_path, ca_file: ca_file)
100
+ ssl_file.ssl_info
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'socket'
4
+ require 'openssl'
5
+ require_relative 'ssl_common'
6
+ require_relative 'ssl_info'
7
+
8
+ module Fluent
9
+ module Plugin
10
+ module SslCheck
11
+ class FileChecker
12
+ attr_reader :filepath, :ca_path, :ca_file
13
+
14
+ include Fluent::Plugin::SslCheck::SslCommon
15
+
16
+ def initialize(filepath, ca_path: nil, ca_file: nil)
17
+ @filepath = filepath
18
+ @ca_path = ca_path
19
+ @ca_file = ca_file
20
+ end
21
+
22
+ def certificate
23
+ @certificate ||= OpenSSL::X509::Certificate.new(File.read(filepath_absolute))
24
+ end
25
+
26
+ def filepath_absolute
27
+ File.expand_path(filepath)
28
+ end
29
+
30
+ def ssl_info
31
+ info = Fluent::Plugin::SslCheck::SslInfo.new(host: hostname, path: filepath_absolute)
32
+ begin
33
+ ca_store = ssl_store(ca_path: ca_path, ca_file: ca_file)
34
+ ca_store.verify(certificate)
35
+
36
+ info.cert = certificate
37
+ info.cert_chain = ca_store.chain
38
+ info.error = ca_store.error_string if ca_store.error != 0
39
+ rescue StandardError => e
40
+ info.error = e
41
+ end
42
+ info
43
+ end
44
+
45
+ def hostname
46
+ Socket.gethostname
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'openssl'
4
+
5
+ module Fluent
6
+ module Plugin
7
+ module SslCheck
8
+ module SslCommon
9
+ def ssl_store(ca_path: nil, ca_file: nil)
10
+ OpenSSL::X509::Store.new.tap do |store|
11
+ store.set_default_paths
12
+ store.add_path(ca_path) if ca_path
13
+ store.add_file(ca_file) if ca_file
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'openssl'
4
+
5
+ module Fluent
6
+ module Plugin
7
+ module SslCheck
8
+ # ssl info
9
+ # to encapsulate extracted ssl information
10
+ class SslInfo
11
+ OK = 1
12
+ KO = 0
13
+
14
+ attr_accessor :host, :port, :path, :cert, :cert_chain, :ssl_version, :error
15
+
16
+ # rubocop:disable Metrics/ParameterLists
17
+ def initialize(host: nil, port: nil, path: nil, cert: nil, cert_chain: nil, ssl_version: nil,
18
+ error: nil, time: nil)
19
+ @host = host
20
+ @port = port
21
+ @path = path
22
+ @cert = cert
23
+ @cert_chain = cert_chain
24
+ @ssl_version = ssl_version
25
+ @error = error
26
+ @time = time
27
+ end
28
+ # rubocop:enable Metrics/ParameterLists
29
+
30
+ def subject_s
31
+ cert.subject.to_utf8 if cert&.subject
32
+ end
33
+
34
+ def expire_in_days
35
+ return unless cert&.not_after
36
+
37
+ expire_in = cert.not_after
38
+ ((expire_in - time) / 3600 / 24).to_i
39
+ end
40
+
41
+ def not_after
42
+ return unless cert
43
+
44
+ cert.not_after.iso8601(3)
45
+ end
46
+
47
+ def serial
48
+ cert&.serial&.to_s(16)&.downcase
49
+ end
50
+
51
+ def status
52
+ return KO if error
53
+
54
+ OK
55
+ end
56
+
57
+ def time
58
+ @time ||= Time.now.utc
59
+ end
60
+
61
+ def time_utc
62
+ time.utc
63
+ end
64
+
65
+ def error_class
66
+ return unless error
67
+
68
+ return error if error.is_a?(String)
69
+
70
+ error.class.to_s
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Fluent
4
+ module Plugin
5
+ module SslCheck
6
+ module SslInputEmit
7
+ def emit_logs(ssl_info)
8
+ record = {
9
+ 'timestamp' => ssl_info.time_utc.send("to_#{timestamp_format}"),
10
+ 'status' => ssl_info.status,
11
+ 'host' => ssl_info.host,
12
+ 'port' => ssl_info.port,
13
+ 'path' => ssl_info.path,
14
+ 'ssl_version' => ssl_info.ssl_version,
15
+ 'ssl_dn' => ssl_info.subject_s,
16
+ 'ssl_not_after' => ssl_info.not_after,
17
+ 'expire_in_days' => ssl_info.expire_in_days,
18
+ 'serial' => ssl_info.serial
19
+ }
20
+ record.update('error_class' => ssl_info.error_class) if ssl_info.error_class
21
+ router.emit(tag, Fluent::EventTime.from_time(ssl_info.time_utc), record)
22
+ end
23
+
24
+ def emit_metrics(ssl_info)
25
+ emit_metric_status(ssl_info)
26
+ emit_metric_expirency(ssl_info)
27
+ end
28
+
29
+ def emit_metric_status(ssl_info)
30
+ record = {
31
+ 'timestamp' => ssl_info.time_utc.send("to_#{timestamp_format}"),
32
+ 'metric_name' => 'ssl_status',
33
+ 'metric_value' => ssl_info.status,
34
+ "#{event_prefix}host" => ssl_info.host,
35
+ "#{event_prefix}port" => ssl_info.port,
36
+ "#{event_prefix}path" => ssl_info.path,
37
+ "#{event_prefix}ssl_dn" => ssl_info.subject_s,
38
+ "#{event_prefix}ssl_version" => ssl_info.ssl_version,
39
+ "#{event_prefix}ssl_not_after" => ssl_info.not_after,
40
+ "#{event_prefix}serial" => ssl_info.serial
41
+ }
42
+ router.emit(tag, Fluent::EventTime.from_time(ssl_info.time_utc), record)
43
+ end
44
+
45
+ def emit_metric_expirency(ssl_info)
46
+ return unless ssl_info.cert
47
+
48
+ record = {
49
+ 'timestamp' => ssl_info.time_utc.send("to_#{timestamp_format}"),
50
+ 'metric_name' => 'ssl_expirency',
51
+ 'metric_value' => ssl_info.expire_in_days,
52
+ "#{event_prefix}host" => ssl_info.host,
53
+ "#{event_prefix}port" => ssl_info.port,
54
+ "#{event_prefix}path" => ssl_info.path,
55
+ "#{event_prefix}ssl_dn" => ssl_info.subject_s,
56
+ "#{event_prefix}serial" => ssl_info.serial
57
+ }
58
+ router.emit(tag, Fluent::EventTime.from_time(ssl_info.time_utc), record)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'ssl_check/ssl_input_emit'
4
+ require_relative 'ssl_check/ssl_common'
5
+ require_relative 'ssl_check/ssl_info'
6
+ require_relative 'ssl_check/file_checker'
7
+
8
+ module Fluent
9
+ module Plugin
10
+ module SslCheck
11
+ end
12
+ end
13
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fluent-plugin-ssl-check
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas Tych
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-14 00:00:00.000000000 Z
11
+ date: 2024-12-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bump
@@ -58,6 +58,26 @@ dependencies:
58
58
  - - ">="
59
59
  - !ruby/object:Gem::Version
60
60
  version: 11.1.3
61
+ - !ruby/object:Gem::Dependency
62
+ name: mocha
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '2.6'
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: 2.6.1
71
+ type: :development
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - "~>"
76
+ - !ruby/object:Gem::Version
77
+ version: '2.6'
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: 2.6.1
61
81
  - !ruby/object:Gem::Dependency
62
82
  name: rake
63
83
  requirement: !ruby/object:Gem::Requirement
@@ -188,6 +208,7 @@ extensions: []
188
208
  extra_rdoc_files: []
189
209
  files:
190
210
  - ".gitignore"
211
+ - ".gitlab-ci.yml"
191
212
  - ".rubocop.yml"
192
213
  - ".ruby-version"
193
214
  - Gemfile
@@ -198,6 +219,12 @@ files:
198
219
  - fluent-plugin-ssl-check.gemspec
199
220
  - lib/fluent/plugin/extensions/time.rb
200
221
  - lib/fluent/plugin/in_ssl_check.rb
222
+ - lib/fluent/plugin/in_ssl_file_check.rb
223
+ - lib/fluent/plugin/ssl_check.rb
224
+ - lib/fluent/plugin/ssl_check/file_checker.rb
225
+ - lib/fluent/plugin/ssl_check/ssl_common.rb
226
+ - lib/fluent/plugin/ssl_check/ssl_info.rb
227
+ - lib/fluent/plugin/ssl_check/ssl_input_emit.rb
201
228
  homepage: https://gitlab.com/ttych/fluent-plugin-ssl-check
202
229
  licenses:
203
230
  - Apache-2.0
@@ -218,7 +245,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
218
245
  - !ruby/object:Gem::Version
219
246
  version: '0'
220
247
  requirements: []
221
- rubygems_version: 3.1.6
248
+ rubygems_version: 3.5.22
222
249
  signing_key:
223
250
  specification_version: 4
224
251
  summary: fluentd plugin to check ssl endpoint