logstash-input-elasticsearch 4.23.0 → 5.0.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.
@@ -13,7 +13,9 @@ require "logstash/plugin_mixins/normalize_config_support"
13
13
  require "base64"
14
14
 
15
15
  require "elasticsearch"
16
- require "manticore"
16
+ require "elasticsearch/transport/transport/http/manticore"
17
+ require_relative "elasticsearch/patches/_elasticsearch_transport_http_manticore"
18
+ require_relative "elasticsearch/patches/_elasticsearch_transport_connections_selector"
17
19
 
18
20
  # .Compatibility Note
19
21
  # [NOTE]
@@ -73,8 +75,6 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
73
75
 
74
76
  require 'logstash/inputs/elasticsearch/paginated_search'
75
77
  require 'logstash/inputs/elasticsearch/aggregation'
76
- require 'logstash/inputs/elasticsearch/cursor_tracker'
77
- require 'logstash/inputs/elasticsearch/esql'
78
78
 
79
79
  include LogStash::PluginMixins::ECSCompatibilitySupport(:disabled, :v1, :v8 => :v1)
80
80
  include LogStash::PluginMixins::ECSCompatibilitySupport::TargetCheck
@@ -97,21 +97,15 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
97
97
  # The index or alias to search.
98
98
  config :index, :validate => :string, :default => "logstash-*"
99
99
 
100
- # A type of Elasticsearch query, provided by @query. This will validate query shape and other params.
101
- config :query_type, :validate => %w[dsl esql], :default => 'dsl'
102
-
103
- # The query to be executed. DSL or ES|QL (when `query_type => 'esql'`) query shape is accepted.
104
- # Read the following documentations for more info
105
- # Query DSL: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html
106
- # ES|QL: https://www.elastic.co/guide/en/elasticsearch/reference/current/esql.html
100
+ # The query to be executed. Read the Elasticsearch query DSL documentation
101
+ # for more info
102
+ # https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html
107
103
  config :query, :validate => :string, :default => '{ "sort": [ "_doc" ] }'
108
104
 
109
- # This allows you to specify the DSL response type: one of [hits, aggregations]
110
- # where
111
- # hits: normal search request
112
- # aggregations: aggregation request
113
- # Note that this param is invalid when `query_type => 'esql'`, ES|QL response shape is always a tabular format
114
- config :response_type, :validate => %w[hits aggregations], :default => 'hits'
105
+ # This allows you to speccify the response type: either hits or aggregations
106
+ # where hits: normal search request
107
+ # aggregations: aggregation request
108
+ config :response_type, :validate => ['hits', 'aggregations'], :default => 'hits'
115
109
 
116
110
  # This allows you to set the maximum number of hits returned per scroll.
117
111
  config :size, :validate => :number, :default => 1000
@@ -132,20 +126,6 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
132
126
  # by this pipeline input.
133
127
  config :slices, :validate => :number
134
128
 
135
- # Enable tracking the value of a given field to be used as a cursor
136
- # Main concerns:
137
- # * using anything other than _event.timestamp easily leads to data loss
138
- # * the first "synchronization run can take a long time"
139
- config :tracking_field, :validate => :string
140
-
141
- # Define the initial seed value of the tracking_field
142
- config :tracking_field_seed, :validate => :string, :default => "1970-01-01T00:00:00.000000000Z"
143
-
144
- # The location of where the tracking field value will be stored
145
- # The value is persisted after each scheduled run (and not per result)
146
- # If it's not set it defaults to '${path.data}/plugins/inputs/elasticsearch/<pipeline_id>/last_run_value'
147
- config :last_run_metadata_path, :validate => :string
148
-
149
129
  # If set, include Elasticsearch document information such as index, type, and
150
130
  # the id in the event.
151
131
  #
@@ -221,23 +201,12 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
221
201
  # Set the address of a forward HTTP proxy.
222
202
  config :proxy, :validate => :uri_or_empty
223
203
 
224
- # SSL
225
- config :ssl, :validate => :boolean, :default => false, :deprecated => "Set 'ssl_enabled' instead."
226
-
227
- # SSL Certificate Authority file in PEM encoded format, must also include any chain certificates as necessary
228
- config :ca_file, :validate => :path, :deprecated => "Set 'ssl_certificate_authorities' instead."
229
-
230
204
  # OpenSSL-style X.509 certificate certificate to authenticate the client
231
205
  config :ssl_certificate, :validate => :path
232
206
 
233
207
  # SSL Certificate Authority files in PEM encoded format, must also include any chain certificates as necessary
234
208
  config :ssl_certificate_authorities, :validate => :path, :list => true
235
209
 
236
- # Option to validate the server's certificate. Disabling this severely compromises security.
237
- # For more information on the importance of certificate verification please read
238
- # https://www.cs.utexas.edu/~shmat/shmat_ccs12.pdf
239
- config :ssl_certificate_verification, :validate => :boolean, :default => true, :deprecated => "Set 'ssl_verification_mode' instead."
240
-
241
210
  # The list of cipher suites to use, listed by priorities.
242
211
  # Supported cipher suites vary depending on which version of Java is used.
243
212
  config :ssl_cipher_suites, :validate => :string, :list => true
@@ -265,7 +234,6 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
265
234
  config :ssl_truststore_password, :validate => :password
266
235
 
267
236
  # The JKS truststore to validate the server's certificate.
268
- # Use either `:ssl_truststore_path` or `:ssl_certificate_authorities`
269
237
  config :ssl_truststore_path, :validate => :path
270
238
 
271
239
  # The format of the truststore file. It must be either jks or pkcs12
@@ -284,13 +252,14 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
284
252
  # exactly once.
285
253
  config :schedule, :validate => :string
286
254
 
287
- # Allow scheduled runs to overlap (enabled by default). Setting to false will
288
- # only start a new scheduled run after the previous one completes.
289
- config :schedule_overlap, :validate => :boolean
290
-
291
255
  # If set, the _source of each hit will be added nested under the target instead of at the top-level
292
256
  config :target, :validate => :field_reference
293
257
 
258
+ # Obsolete Settings
259
+ config :ssl, :obsolete => "Set 'ssl_enabled' instead."
260
+ config :ca_file, :obsolete => "Set 'ssl_certificate_authorities' instead."
261
+ config :ssl_certificate_verification, :obsolete => "Set 'ssl_verification_mode' instead."
262
+
294
263
  # config :ca_trusted_fingerprint, :validate => :sha_256_hex
295
264
  include LogStash::PluginMixins::CATrustedFingerprintSupport
296
265
 
@@ -300,9 +269,6 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
300
269
  DEFAULT_EAV_HEADER = { "Elastic-Api-Version" => "2023-10-31" }.freeze
301
270
  INTERNAL_ORIGIN_HEADER = { 'x-elastic-product-origin' => 'logstash-input-elasticsearch'}.freeze
302
271
 
303
- LS_ESQL_SUPPORT_VERSION = "8.17.4" # the version started using elasticsearch-ruby v8
304
- ES_ESQL_SUPPORT_VERSION = "8.11.0"
305
-
306
272
  def initialize(params={})
307
273
  super(params)
308
274
 
@@ -319,17 +285,10 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
319
285
  fill_hosts_from_cloud_id
320
286
  setup_ssl_params!
321
287
 
322
- if @query_type == 'esql'
323
- validate_ls_version_for_esql_support!
324
- validate_esql_query!
325
- not_allowed_options = original_params.keys & %w(index size slices search_api docinfo docinfo_target docinfo_fields response_type tracking_field)
326
- raise(LogStash::ConfigurationError, "Configured #{not_allowed_options} params are not allowed while using ES|QL query") if not_allowed_options&.size > 1
327
- else
328
- @base_query = LogStash::Json.load(@query)
329
- if @slices
330
- @base_query.include?('slice') && fail(LogStash::ConfigurationError, "Elasticsearch Input Plugin's `query` option cannot specify specific `slice` when configured to manage parallel slices with `slices` option")
331
- @slices < 1 && fail(LogStash::ConfigurationError, "Elasticsearch Input Plugin's `slices` option must be greater than zero, got `#{@slices}`")
332
- end
288
+ @base_query = LogStash::Json.load(@query)
289
+ if @slices
290
+ @base_query.include?('slice') && fail(LogStash::ConfigurationError, "Elasticsearch Input Plugin's `query` option cannot specify specific `slice` when configured to manage parallel slices with `slices` option")
291
+ @slices < 1 && fail(LogStash::ConfigurationError, "Elasticsearch Input Plugin's `slices` option must be greater than zero, got `#{@slices}`")
333
292
  end
334
293
 
335
294
  @retries < 0 && fail(LogStash::ConfigurationError, "Elasticsearch Input Plugin's `retries` option must be equal or greater than zero, got `#{@retries}`")
@@ -357,7 +316,7 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
357
316
  @client_options = {
358
317
  :hosts => hosts,
359
318
  :transport_options => transport_options,
360
- :transport_class => get_transport_client_class,
319
+ :transport_class => ::Elasticsearch::Transport::Transport::HTTP::Manticore,
361
320
  :ssl => ssl_options
362
321
  }
363
322
 
@@ -365,27 +324,21 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
365
324
 
366
325
  test_connection!
367
326
 
368
- validate_es_for_esql_support!
369
-
370
327
  setup_serverless
371
328
 
372
329
  setup_search_api
373
330
 
374
- @query_executor = create_query_executor
375
-
376
- setup_cursor_tracker
331
+ setup_query_executor
377
332
 
378
333
  @client
379
334
  end
380
335
 
381
336
  def run(output_queue)
382
337
  if @schedule
383
- scheduler.cron(@schedule, :overlap => @schedule_overlap) do
384
- @query_executor.do_run(output_queue, get_query_object())
385
- end
338
+ scheduler.cron(@schedule) { @query_executor.do_run(output_queue) }
386
339
  scheduler.join
387
340
  else
388
- @query_executor.do_run(output_queue, get_query_object())
341
+ @query_executor.do_run(output_queue)
389
342
  end
390
343
  end
391
344
 
@@ -393,42 +346,10 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
393
346
  # This can be called externally from the query_executor
394
347
  public
395
348
  def push_hit(hit, output_queue, root_field = '_source')
396
- event = event_from_hit(hit, root_field)
397
- decorate(event)
398
- output_queue << event
399
- record_last_value(event)
400
- end
401
-
402
- def decorate_event(event)
403
- decorate(event)
404
- end
405
-
406
- private
407
-
408
- def get_query_object
409
- return @query if @query_type == 'esql'
410
- if @cursor_tracker
411
- query = @cursor_tracker.inject_cursor(@query)
412
- @logger.debug("new query is #{query}")
413
- else
414
- query = @query
415
- end
416
- LogStash::Json.load(query)
417
- end
418
-
419
- def record_last_value(event)
420
- @cursor_tracker.record_last_value(event) if @tracking_field
421
- end
422
-
423
- def event_from_hit(hit, root_field)
424
349
  event = targeted_event_factory.new_event hit[root_field]
425
350
  set_docinfo_fields(hit, event) if @docinfo
426
-
427
- event
428
- rescue => e
429
- serialized_hit = hit.to_json
430
- logger.warn("Event creation error, original data now in [event][original] field", message: e.message, exception: e.class, data: serialized_hit)
431
- return event_factory.new_event('event' => { 'original' => serialized_hit }, 'tags' => ['_elasticsearch_input_failure'])
351
+ decorate(event)
352
+ output_queue << event
432
353
  end
433
354
 
434
355
  def set_docinfo_fields(hit, event)
@@ -436,8 +357,10 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
436
357
  docinfo_target = event.get(@docinfo_target) || {}
437
358
 
438
359
  unless docinfo_target.is_a?(Hash)
439
- # expect error to be handled by `#event_from_hit`
440
- fail RuntimeError, "Incompatible event; unable to merge docinfo fields into docinfo_target=`#{@docinfo_target}`"
360
+ @logger.error("Incompatible Event, incompatible type for the docinfo_target=#{@docinfo_target} field in the `_source` document, expected a hash got:", :docinfo_target_type => docinfo_target.class, :event => event.to_hash_with_metadata)
361
+
362
+ # TODO: (colin) I am not sure raising is a good strategy here?
363
+ raise Exception.new("Elasticsearch input: incompatible event")
441
364
  end
442
365
 
443
366
  @docinfo_fields.each do |field|
@@ -447,6 +370,8 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
447
370
  event.set(@docinfo_target, docinfo_target)
448
371
  end
449
372
 
373
+ private
374
+
450
375
  def hosts_default?(hosts)
451
376
  hosts.nil? || ( hosts.is_a?(Array) && hosts.empty? )
452
377
  end
@@ -480,8 +405,6 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
480
405
  ssl_options[:ssl] = true if @ssl_enabled
481
406
 
482
407
  unless @ssl_enabled
483
- # Keep it backward compatible with the deprecated `ssl` option
484
- ssl_options[:trust_strategy] = trust_strategy_for_ca_trusted_fingerprint if original_params.include?('ssl')
485
408
  return ssl_options
486
409
  end
487
410
 
@@ -545,38 +468,11 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
545
468
  end
546
469
 
547
470
  def setup_ssl_params!
548
- @ssl_enabled = normalize_config(:ssl_enabled) do |normalize|
549
- normalize.with_deprecated_alias(:ssl)
471
+ # Only infer ssl_enabled if it wasn't explicitly set
472
+ unless original_params.include?('ssl_enabled')
473
+ @ssl_enabled = effectively_ssl?
474
+ params['ssl_enabled'] = @ssl_enabled
550
475
  end
551
-
552
- # Infer the value if neither the deprecate `ssl` and `ssl_enabled` were set
553
- infer_ssl_enabled_from_hosts
554
-
555
- @ssl_certificate_authorities = normalize_config(:ssl_certificate_authorities) do |normalize|
556
- normalize.with_deprecated_mapping(:ca_file) do |ca_file|
557
- [ca_file]
558
- end
559
- end
560
-
561
- @ssl_verification_mode = normalize_config(:ssl_verification_mode) do |normalize|
562
- normalize.with_deprecated_mapping(:ssl_certificate_verification) do |ssl_certificate_verification|
563
- if ssl_certificate_verification == true
564
- "full"
565
- else
566
- "none"
567
- end
568
- end
569
- end
570
-
571
- params['ssl_enabled'] = @ssl_enabled
572
- params['ssl_certificate_authorities'] = @ssl_certificate_authorities unless @ssl_certificate_authorities.nil?
573
- params['ssl_verification_mode'] = @ssl_verification_mode unless @ssl_verification_mode.nil?
574
- end
575
-
576
- def infer_ssl_enabled_from_hosts
577
- return if original_params.include?('ssl') || original_params.include?('ssl_enabled')
578
-
579
- @ssl_enabled = params['ssl_enabled'] = effectively_ssl?
580
476
  end
581
477
 
582
478
  def setup_hosts
@@ -724,72 +620,18 @@ class LogStash::Inputs::Elasticsearch < LogStash::Inputs::Base
724
620
 
725
621
  end
726
622
 
727
- def create_query_executor
728
- return LogStash::Inputs::Elasticsearch::Esql.new(@client, self) if @query_type == 'esql'
729
-
730
- # DSL query executor
731
- return LogStash::Inputs::Elasticsearch::Aggregation.new(@client, self) if @response_type == 'aggregations'
732
- # response_type is hits, executor can be search_after or scroll type
733
- return LogStash::Inputs::Elasticsearch::SearchAfter.new(@client, self) if @resolved_search_api == "search_after"
734
-
735
- logger.warn("scroll API is no longer recommended for pagination. Consider using search_after instead.") if es_major_version >= 8
736
- LogStash::Inputs::Elasticsearch::Scroll.new(@client, self)
737
- end
738
-
739
- def setup_cursor_tracker
740
- return unless @tracking_field
741
- return unless @query_executor.is_a?(LogStash::Inputs::Elasticsearch::SearchAfter)
742
-
743
- if @resolved_search_api != "search_after" || @response_type != "hits"
744
- raise ConfigurationError.new("The `tracking_field` feature can only be used with `search_after` non-aggregation queries")
745
- end
746
-
747
- @cursor_tracker = CursorTracker.new(last_run_metadata_path: last_run_metadata_path,
748
- tracking_field: @tracking_field,
749
- tracking_field_seed: @tracking_field_seed)
750
- @query_executor.cursor_tracker = @cursor_tracker
751
- end
752
-
753
- def last_run_metadata_path
754
- return @last_run_metadata_path if @last_run_metadata_path
755
-
756
- last_run_metadata_path = ::File.join(LogStash::SETTINGS.get_value("path.data"), "plugins", "inputs", "elasticsearch", pipeline_id, "last_run_value")
757
- FileUtils.mkdir_p ::File.dirname(last_run_metadata_path)
758
- last_run_metadata_path
759
- end
760
-
761
- def get_transport_client_class
762
- # LS-core includes `elasticsearch` gem. The gem is composed of two separate gems: `elasticsearch-api` and `elasticsearch-transport`
763
- # And now `elasticsearch-transport` is old, instead we have `elastic-transport`.
764
- # LS-core updated `elasticsearch` > 8: https://github.com/elastic/logstash/pull/17161
765
- # Following source bits are for the compatibility to support both `elasticsearch-transport` and `elastic-transport` gems
766
- require "elasticsearch/transport/transport/http/manticore"
767
- require_relative "elasticsearch/patches/_elasticsearch_transport_http_manticore"
768
- require_relative "elasticsearch/patches/_elasticsearch_transport_connections_selector"
769
- ::Elasticsearch::Transport::Transport::HTTP::Manticore
770
- rescue ::LoadError
771
- require "elastic/transport/transport/http/manticore"
772
- ::Elastic::Transport::Transport::HTTP::Manticore
773
- end
774
-
775
- def validate_ls_version_for_esql_support!
776
- if Gem::Version.create(LOGSTASH_VERSION) < Gem::Version.create(LS_ESQL_SUPPORT_VERSION)
777
- fail("Current version of Logstash does not include Elasticsearch client which supports ES|QL. Please upgrade Logstash to at least #{LS_ESQL_SUPPORT_VERSION}")
778
- end
779
- end
780
-
781
- def validate_esql_query!
782
- fail(LogStash::ConfigurationError, "`query` cannot be empty") if @query.strip.empty?
783
- source_commands = %w[FROM ROW SHOW]
784
- contains_source_command = source_commands.any? { |source_command| @query.strip.start_with?(source_command) }
785
- fail(LogStash::ConfigurationError, "`query` needs to start with any of #{source_commands}") unless contains_source_command
786
- end
787
-
788
- def validate_es_for_esql_support!
789
- return unless @query_type == 'esql'
790
- # make sure connected ES supports ES|QL (8.11+)
791
- es_supports_esql = Gem::Version.create(es_version) >= Gem::Version.create(ES_ESQL_SUPPORT_VERSION)
792
- fail("Connected Elasticsearch #{es_version} version does not supports ES|QL. ES|QL feature requires at least Elasticsearch #{ES_ESQL_SUPPORT_VERSION} version.") unless es_supports_esql
623
+ def setup_query_executor
624
+ @query_executor = case @response_type
625
+ when 'hits'
626
+ if @resolved_search_api == "search_after"
627
+ LogStash::Inputs::Elasticsearch::SearchAfter.new(@client, self)
628
+ else
629
+ logger.warn("scroll API is no longer recommended for pagination. Consider using search_after instead.") if es_major_version >= 8
630
+ LogStash::Inputs::Elasticsearch::Scroll.new(@client, self)
631
+ end
632
+ when 'aggregations'
633
+ LogStash::Inputs::Elasticsearch::Aggregation.new(@client, self)
634
+ end
793
635
  end
794
636
 
795
637
  module URIOrEmptyValidator
@@ -1,13 +1,13 @@
1
1
  Gem::Specification.new do |s|
2
2
 
3
3
  s.name = 'logstash-input-elasticsearch'
4
- s.version = '4.23.0'
4
+ s.version = '5.0.0'
5
5
  s.licenses = ['Apache License (2.0)']
6
6
  s.summary = "Reads query results from an Elasticsearch cluster"
7
7
  s.description = "This gem is a Logstash plugin required to be installed on top of the Logstash core pipeline using $LS_HOME/bin/logstash-plugin install gemname. This gem is not a stand-alone program"
8
8
  s.authors = ["Elastic"]
9
9
  s.email = 'info@elastic.co'
10
- s.homepage = "https://elastic.co/logstash"
10
+ s.homepage = "http://www.elastic.co/guide/en/logstash/current/index.html"
11
11
  s.require_paths = ["lib"]
12
12
 
13
13
  # Files
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
26
26
  s.add_runtime_dependency "logstash-mixin-validator_support", '~> 1.0'
27
27
  s.add_runtime_dependency "logstash-mixin-scheduler", '~> 1.0'
28
28
 
29
- s.add_runtime_dependency 'elasticsearch', '>= 7.17.9', '< 9'
29
+ s.add_runtime_dependency 'elasticsearch', '>= 7.17.9'
30
30
  s.add_runtime_dependency 'logstash-mixin-ca_trusted_fingerprint_support', '~> 1.0'
31
31
  s.add_runtime_dependency 'logstash-mixin-normalize_config_support', '~>1.0'
32
32
 
@@ -1,19 +1,20 @@
1
1
  -----BEGIN CERTIFICATE-----
2
- MIIDFTCCAf2gAwIBAgIBATANBgkqhkiG9w0BAQsFADA0MTIwMAYDVQQDEylFbGFz
3
- dGljIENlcnRpZmljYXRlIFRvb2wgQXV0b2dlbmVyYXRlZCBDQTAeFw0yNDEyMjYy
4
- MjI3MTVaFw0yNTEyMjYyMjI3MTVaMDQxMjAwBgNVBAMTKUVsYXN0aWMgQ2VydGlm
5
- aWNhdGUgVG9vbCBBdXRvZ2VuZXJhdGVkIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC
6
- AQ8AMIIBCgKCAQEArUe66xG4Y2zO13gRC+rBwyvxe+c01pqV6ukw6isIbJIQWs1/
7
- QfEMhUwYwKs6/UXxK+VwardcA2zYwngXbGGEtms+mpUfH5CdJnrqW7lHz1BVK4yH
8
- 90IzGE0GU4D90OW/L4QkGX0fv3VQbL8KGFKBoF04pXIaSGMStFN4wirutHtQboYv
9
- 99X4kbLjVSIuubUpA/v9dUP1TNl8ar+HKUWRM96ijHkFTF3FR0NnZyt44gP5qC0h
10
- i4lUiR6Uo9D6WMFjeRYFF7GolCy/I1SzWBmmOnNhQLO5VxcNG4ldhBcapZeGwE98
11
- m/5lxLIwgFR9ZP8bXdxZTWLC58/LQ2NqOjA9mwIDAQABozIwMDAPBgNVHRMBAf8E
12
- BTADAQH/MB0GA1UdDgQWBBTIJMnuftpfkxNCOkbF0R4xgcKQRjANBgkqhkiG9w0B
13
- AQsFAAOCAQEAhfg/cmXc4Uh90yiXU8jOW8saQjTsq4ZMDQiLfJsNmNNYmHFN0vhv
14
- lJRI1STdy7+GpjS5QbrMjQIxWSS8X8xysE4Rt81IrWmLuao35TRFyoiE1seBQ5sz
15
- p/BxZUe57JvWi9dyzv2df4UfWFdGBhzdr80odZmz4i5VIv6qCKJKsGikcuLpepmp
16
- E/UKnKHeR/dFWsxzA9P2OzHTUNBMOOA2PyAUL49pwoChwJeOWN/zAgwMWLbuHFG0
17
- IN0u8swAmeH98QdvzbhiOatGNpqfTNvQEDc19yVjfXKpBVZQ79WtronYSqrbrUa1
18
- T2zD8bIVP7CdddD/UmpT1SSKh4PJxudy5Q==
2
+ MIIDSTCCAjGgAwIBAgIUUcAg9c8B8jiliCkOEJyqoAHrmccwDQYJKoZIhvcNAQEL
3
+ BQAwNDEyMDAGA1UEAxMpRWxhc3RpYyBDZXJ0aWZpY2F0ZSBUb29sIEF1dG9nZW5l
4
+ cmF0ZWQgQ0EwHhcNMjEwODEyMDUxNDU1WhcNMjQwODExMDUxNDU1WjA0MTIwMAYD
5
+ VQQDEylFbGFzdGljIENlcnRpZmljYXRlIFRvb2wgQXV0b2dlbmVyYXRlZCBDQTCC
6
+ ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK1HuusRuGNsztd4EQvqwcMr
7
+ 8XvnNNaalerpMOorCGySEFrNf0HxDIVMGMCrOv1F8SvlcGq3XANs2MJ4F2xhhLZr
8
+ PpqVHx+QnSZ66lu5R89QVSuMh/dCMxhNBlOA/dDlvy+EJBl9H791UGy/ChhSgaBd
9
+ OKVyGkhjErRTeMIq7rR7UG6GL/fV+JGy41UiLrm1KQP7/XVD9UzZfGq/hylFkTPe
10
+ oox5BUxdxUdDZ2creOID+agtIYuJVIkelKPQ+ljBY3kWBRexqJQsvyNUs1gZpjpz
11
+ YUCzuVcXDRuJXYQXGqWXhsBPfJv+ZcSyMIBUfWT/G13cWU1iwufPy0NjajowPZsC
12
+ AwEAAaNTMFEwHQYDVR0OBBYEFMgkye5+2l+TE0I6RsXRHjGBwpBGMB8GA1UdIwQY
13
+ MBaAFMgkye5+2l+TE0I6RsXRHjGBwpBGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZI
14
+ hvcNAQELBQADggEBAIgtJW8sy5lBpzPRHkmWSS/SCZIPsABW+cHqQ3e0udrI3CLB
15
+ G9n7yqAPWOBTbdqC2GM8dvAS/Twx4Bub/lWr84dFCu+t0mQq4l5kpJMVRS0KKXPL
16
+ DwJbUN3oPNYy4uPn5Xi+XY3BYFce5vwJUsqIxeAbIOxVTNx++k5DFnB0ESAM23QL
17
+ sgUZl7xl3/DkdO4oHj30gmTRW9bjCJ6umnHIiO3JoJatrprurUIt80vHC4Ndft36
18
+ NBQ9mZpequ4RYjpSZNLcVsxyFAYwEY4g8MvH0MoMo2RRLfehmMCzXnI/Wh2qEyYz
19
+ emHprBii/5y1HieKXlX9CZRb5qEPHckDVXW3znw=
19
20
  -----END CERTIFICATE-----
@@ -1 +1 @@
1
- b1e955819b0d14f64f863adb103c248ddacf2e17bea48d04ee4b57c64814ccc4
1
+ 195a7e7b1bc29f3d7913a918a44721704d27fa56facea0cd72a8093c7107c283
@@ -1,19 +1,20 @@
1
1
  -----BEGIN CERTIFICATE-----
2
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- UXtC1JAkvWKuujFEiBj0AannhroWlp3gvChhBwCuCAU0KXD6g8BE8tn6oT1+FW7J
18
- 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
19
+ qi02i4q6meHGcw==
19
20
  -----END CERTIFICATE-----