logstash-mixin-http_client 7.2.0 → 7.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: 967d2306be29d709b80a1e2483e09c7eb06acdbc5079af3090ef265427377b33
4
- data.tar.gz: 6d358bd6a4b819a14cd669af4d14ea3f130b2802bec6872e6ef03f27b8c5e186
3
+ metadata.gz: 37d1b2f6c38db9be11cb37da743556d46e05f6f5e100239c18c9e0b56b8e9607
4
+ data.tar.gz: 1faae938aabfa08c0a958a5a74b4993917326caf4040beedb58dafe84af62ff4
5
5
  SHA512:
6
- metadata.gz: a0ad4d31a8e1a72d38686466b141ff16c22b24821d8c9dc9d8a0df6d2745d05b7a4e644a26b869c4c6bacac4d73e27aaa2fa065dcbbd67d1bbda2b35153e08cf
7
- data.tar.gz: b3bf2076187e018a00b19c0c2ec9eb770ae241879fc798aad60ec8b6bb02f79ce508aa23f9ff5c29ba03280288cd2cc3d5e002a87aebda51f680d2f322fe6880
6
+ metadata.gz: 283e5c0e7346f8b0051b387805ba379792a822adbf542b61c00fd2fab00de8e0e9e36121ba7234f5ba906fc7e1e6428f7343131cbaf1597e39b03004963004ee
7
+ data.tar.gz: 053f697103912ce7767f9d62797e002e9d7d6f468d34c66fffa43854cdaf7789d092563757bae1a566e4441ff11f3da468270ce16c457b17ee85b1731e727954
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## 7.4.0
2
+ - Adds new `ssl_enabled` setting for enabling/disabling the SSL configurations [#44](https://github.com/logstash-plugins/logstash-mixin-http_client/pull/44)
3
+
4
+ ## 7.3.0
5
+ - Adds standardized SSL settings and deprecates their non-standard counterparts. Deprecated settings will continue to work, and will provide pipeline maintainers with guidance toward using their standardized counterparts [#42](https://github.com/logstash-plugins/logstash-mixin-http_client/pull/42)
6
+ - Adds new `ssl_truststore_path`, `ssl_truststore_password`, and `ssl_truststore_type` settings for configuring SSL-trust using a PKCS-12 or JKS trust store, deprecating their `truststore`, `truststore_password`, and `truststore_type` counterparts.
7
+ - Adds new `ssl_certificate_authorities` setting for configuring SSL-trust using a PEM-formated list certificate authorities, deprecating its `cacert` counterpart.
8
+ - Adds new `ssl_keystore_path`, `ssl_keystore_password`, and `ssl_keystore_type` settings for configuring SSL-identity using a PKCS-12 or JKS key store, deprecating their `keystore`, `keystore_password`, and `keystore_type` counterparts.
9
+ - Adds new `ssl_certificate` and `ssl_key` settings for configuring SSL-identity using a PEM-formatted certificate/key pair, deprecating their `client_cert` and `client_key` counterparts.
10
+ - Added a way for plugin maintainers to include this mixin _without_ supporting the now-deprecated SSL options.
11
+ - Added the `ssl_cipher_suites` option
12
+
1
13
  ## 7.2.0
2
14
  - Feat: add `ssl_supported_protocols` option [#40](https://github.com/logstash-plugins/logstash-mixin-http_client/pull/40)
3
15
 
data/Gemfile CHANGED
@@ -2,3 +2,11 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in logstash-mass_effect.gemspec
4
4
  gemspec
5
+
6
+ logstash_path = ENV["LOGSTASH_PATH"] || "../../logstash"
7
+ use_logstash_source = ENV["LOGSTASH_SOURCE"] && ENV["LOGSTASH_SOURCE"].to_s == "1"
8
+
9
+ if Dir.exist?(logstash_path) && use_logstash_source
10
+ gem 'logstash-core', :path => "#{logstash_path}/logstash-core"
11
+ gem 'logstash-core-plugin-api', :path => "#{logstash_path}/logstash-core-plugin-api"
12
+ end
@@ -0,0 +1,74 @@
1
+ module LogStash::PluginMixins::HttpClient
2
+ module DeprecatedSslConfigSupport
3
+ def self.included(base)
4
+ fail ArgumentError unless base <= LogStash::PluginMixins::HttpClient::Implementation
5
+
6
+ require 'logstash/plugin_mixins/normalize_config_support'
7
+ base.include(LogStash::PluginMixins::NormalizeConfigSupport)
8
+
9
+ # If you need to use a custom X.509 CA (.pem certs) specify the path to that here
10
+ base.config :cacert, :validate => :path, :deprecated => 'Use `ssl_certificate_authorities` instead'
11
+ # If you'd like to use a client certificate (note, most people don't want this) set the path to the x509 cert here
12
+ base.config :client_cert, :validate => :path, :deprecated => 'Use `ssl_certificate` instead'
13
+ # If you're using a client certificate specify the path to the encryption key here
14
+ base.config :client_key, :validate => :path, :deprecated => 'Use `ssl_key` instead'
15
+ # If you need to use a custom keystore (`.jks`) specify that here. This does not work with .pem keys!
16
+ base.config :keystore, :validate => :path, :deprecated => 'Use `ssl_keystore_path` instead'
17
+ # Specify the keystore password here.
18
+ # Note, most .jks files created with keytool require a password!
19
+ base.config :keystore_password, :validate => :password, :deprecated => 'Use `ssl_keystore_password` instead'
20
+ # Specify the keystore type here. One of `JKS` or `PKCS12`. Default is `JKS`
21
+ base.config :keystore_type, :validate => :string, :default => 'JKS', :deprecated => 'Use `ssl_keystore_type` instead'
22
+ # If you need to use a custom truststore (`.jks`) specify that here. This does not work with .pem certs!
23
+ base.config :truststore, :validate => :path, :deprecated => 'Use `ssl_truststore_path` instead'
24
+ # Specify the truststore password here.
25
+ # Note, most .jks files created with keytool require a password!
26
+ base.config :truststore_password, :validate => :password, :deprecated => 'Use `ssl_truststore_password` instead'
27
+ # Specify the truststore type here. One of `JKS` or `PKCS12`. Default is `JKS`
28
+ base.config :truststore_type, :validate => :string, :default => 'JKS', :deprecated => 'Use `ssl_truststore_type` instead'
29
+ # NOTE: the default setting [] uses Java SSL engine defaults.
30
+ end
31
+
32
+ def initialize(*a)
33
+ super
34
+
35
+ @ssl_certificate_authorities = normalize_config(:ssl_certificate_authorities) do |normalize|
36
+ normalize.with_deprecated_mapping(:cacert) do |cacert|
37
+ [cacert]
38
+ end
39
+ end
40
+
41
+ @ssl_certificate = normalize_config(:ssl_certificate) do |normalize|
42
+ normalize.with_deprecated_alias(:client_cert)
43
+ end
44
+
45
+ @ssl_key = normalize_config(:ssl_key) do |normalize|
46
+ normalize.with_deprecated_alias(:client_key)
47
+ end
48
+
49
+ %w[keystore truststore].each do |store|
50
+ %w[path type password].each do |variable|
51
+ config_name = "ssl_#{store}_#{variable}"
52
+ normalized_value = normalize_config(config_name) do |normalize|
53
+ deprecated_config_alias = variable == 'path' ? store : "#{store}_#{variable}"
54
+ normalize.with_deprecated_alias(deprecated_config_alias.to_sym)
55
+ end
56
+ instance_variable_set("@#{config_name}", normalized_value)
57
+ end
58
+ end
59
+ end
60
+
61
+ def ssl_options
62
+ fail(InvalidHTTPConfigError, "When `client_cert` is provided, `client_key` must also be provided") if @client_cert && !@client_key
63
+ fail(InvalidHTTPConfigError, "A `client_key` is not allowed unless a `client_cert` is provided") if @client_key && !@client_cert
64
+
65
+ fail(LogStash::ConfigurationError, "When `keystore` is provided, `keystore_password` must also be provided") if @keystore && !@keystore_password
66
+ fail(LogStash::ConfigurationError, "A `keystore_password` is not allowed unless a `keystore` is provided") if @keystore_password && !@keystore
67
+
68
+ fail(LogStash::ConfigurationError, "When `truststore` is provided, `truststore_password` must also be provided") if @truststore && !@truststore_password
69
+ fail(LogStash::ConfigurationError, "A `truststore_password` is not allowed unless a `truststore` is provided") if @truststore_password && !@truststore
70
+
71
+ super
72
+ end
73
+ end
74
+ end
@@ -7,203 +7,240 @@ require "logstash/config/mixin"
7
7
  module LogStash::PluginMixins::HttpClient
8
8
  class InvalidHTTPConfigError < StandardError; end
9
9
 
10
+ def self.[](**a)
11
+ Adapter.new(**a)
12
+ end
13
+
10
14
  def self.included(base)
11
- require 'manticore'
12
- base.extend(self)
13
- base.setup_http_client_config
15
+ # TODO: deprecate the act of including this mixin directly,
16
+ # in a way that turns focus to plugin maintainers since
17
+ # an end-user cannot act to resolve the issue.
18
+ base.include(Adapter.new(with_deprecated: true))
19
+ end
20
+
21
+ class Adapter < Module
22
+ def initialize(with_deprecated: false)
23
+ @include_dep = with_deprecated
24
+ end
25
+
26
+ def included(base)
27
+ base.include(Implementation)
28
+ if @include_dep
29
+ require_relative 'http_client/deprecated_ssl_config_support'
30
+ base.include(DeprecatedSslConfigSupport)
31
+ end
32
+ nil
33
+ end
14
34
  end
35
+ private_constant :Adapter
15
36
 
16
- public
17
- def setup_http_client_config
18
- # Timeout (in seconds) for the entire request
19
- config :request_timeout, :validate => :number, :default => 60
37
+ module Implementation
38
+ def self.included(base)
39
+ require 'manticore'
20
40
 
21
- # Timeout (in seconds) to wait for data on the socket. Default is `10s`
22
- config :socket_timeout, :validate => :number, :default => 10
41
+ # Timeout (in seconds) for the entire request
42
+ base.config :request_timeout, :validate => :number, :default => 60
23
43
 
24
- # Timeout (in seconds) to wait for a connection to be established. Default is `10s`
25
- config :connect_timeout, :validate => :number, :default => 10
44
+ # Timeout (in seconds) to wait for data on the socket. Default is `10s`
45
+ base.config :socket_timeout, :validate => :number, :default => 10
26
46
 
27
- # Should redirects be followed? Defaults to `true`
28
- config :follow_redirects, :validate => :boolean, :default => true
47
+ # Timeout (in seconds) to wait for a connection to be established. Default is `10s`
48
+ base.config :connect_timeout, :validate => :number, :default => 10
29
49
 
30
- # Max number of concurrent connections. Defaults to `50`
31
- config :pool_max, :validate => :number, :default => 50
50
+ # Should redirects be followed? Defaults to `true`
51
+ base.config :follow_redirects, :validate => :boolean, :default => true
32
52
 
33
- # Max number of concurrent connections to a single host. Defaults to `25`
34
- config :pool_max_per_route, :validate => :number, :default => 25
53
+ # Max number of concurrent connections. Defaults to `50`
54
+ base.config :pool_max, :validate => :number, :default => 50
35
55
 
36
- # Turn this on to enable HTTP keepalive support. We highly recommend setting `automatic_retries` to at least
37
- # one with this to fix interactions with broken keepalive implementations.
38
- config :keepalive, :validate => :boolean, :default => true
56
+ # Max number of concurrent connections to a single host. Defaults to `25`
57
+ base.config :pool_max_per_route, :validate => :number, :default => 25
39
58
 
40
- # How many times should the client retry a failing URL. We highly recommend NOT setting this value
41
- # to zero if keepalive is enabled. Some servers incorrectly end keepalives early requiring a retry!
42
- # Note: if `retry_non_idempotent` is set only GET, HEAD, PUT, DELETE, OPTIONS, and TRACE requests will be retried.
43
- config :automatic_retries, :validate => :number, :default => 1
59
+ # Turn this on to enable HTTP keepalive support. We highly recommend setting `automatic_retries` to at least
60
+ # one with this to fix interactions with broken keepalive implementations.
61
+ base.config :keepalive, :validate => :boolean, :default => true
44
62
 
45
- # If `automatic_retries` is enabled this will cause non-idempotent HTTP verbs (such as POST) to be retried.
46
- config :retry_non_idempotent, :validate => :boolean, :default => false
63
+ # How many times should the client retry a failing URL. We highly recommend NOT setting this value
64
+ # to zero if keepalive is enabled. Some servers incorrectly end keepalives early requiring a retry!
65
+ # Note: if `retry_non_idempotent` is set only GET, HEAD, PUT, DELETE, OPTIONS, and TRACE requests will be retried.
66
+ base.config :automatic_retries, :validate => :number, :default => 1
47
67
 
48
- # How long to wait before checking if the connection is stale before executing a request on a connection using keepalive.
49
- # # You may want to set this lower, possibly to 0 if you get connection errors regularly
50
- # Quoting the Apache commons docs (this client is based Apache Commmons):
51
- # 'Defines period of inactivity in milliseconds after which persistent connections must be re-validated prior to being leased to the consumer. Non-positive value passed to this method disables connection validation. This check helps detect connections that have become stale (half-closed) while kept inactive in the pool.'
52
- # See https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/conn/PoolingHttpClientConnectionManager.html#setValidateAfterInactivity(int)[these docs for more info]
53
- config :validate_after_inactivity, :validate => :number, :default => 200
68
+ # If `automatic_retries` is enabled this will cause non-idempotent HTTP verbs (such as POST) to be retried.
69
+ base.config :retry_non_idempotent, :validate => :boolean, :default => false
54
70
 
55
- # If you need to use a custom X.509 CA (.pem certs) specify the path to that here
56
- config :cacert, :validate => :path
71
+ # How long to wait before checking if the connection is stale before executing a request on a connection using keepalive.
72
+ # # You may want to set this lower, possibly to 0 if you get connection errors regularly
73
+ # Quoting the Apache commons docs (this client is based Apache Commmons):
74
+ # 'Defines period of inactivity in milliseconds after which persistent connections must be re-validated prior to being leased to the consumer. Non-positive value passed to this method disables connection validation. This check helps detect connections that have become stale (half-closed) while kept inactive in the pool.'
75
+ # See https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/conn/PoolingHttpClientConnectionManager.html#setValidateAfterInactivity(int)[these docs for more info]
76
+ base.config :validate_after_inactivity, :validate => :number, :default => 200
57
77
 
58
- # If you'd like to use a client certificate (note, most people don't want this) set the path to the x509 cert here
59
- config :client_cert, :validate => :path
60
- # If you're using a client certificate specify the path to the encryption key here
61
- config :client_key, :validate => :path
78
+ # Enable/disable the SSL configurations
79
+ base.config :ssl_enabled, :validate => :boolean, :default => true
62
80
 
63
- # If you need to use a custom keystore (`.jks`) specify that here. This does not work with .pem keys!
64
- config :keystore, :validate => :path
81
+ # If you need to use a custom X.509 CA (.pem certs) specify the path to that here
82
+ base.config :ssl_certificate_authorities, :validate => :path, :list => :true
65
83
 
66
- # Specify the keystore password here.
67
- # Note, most .jks files created with keytool require a password!
68
- config :keystore_password, :validate => :password
84
+ # If you'd like to use a client certificate (note, most people don't want this) set the path to the x509 cert here
85
+ base.config :ssl_certificate, :validate => :path
69
86
 
70
- # Specify the keystore type here. One of `JKS` or `PKCS12`. Default is `JKS`
71
- config :keystore_type, :validate => :string, :default => "JKS"
87
+ # If you're using a client certificate specify the path to the encryption key here
88
+ base.config :ssl_key, :validate => :path
72
89
 
73
- # Naming aligned with the Elastic stack.
74
- # full: verifies that the provided certificate is signed by a trusted authority (CA) and also verifies that the
75
- # server’s hostname (or IP address) matches the names identified within the certificate
76
- # none: no verification of the server’s certificate
77
- config :ssl_verification_mode, :validate => ['full', 'none'], :default => 'full'
90
+ # If you need to use a custom keystore (`.jks`) specify that here. This does not work with .pem keys!
91
+ base.config :ssl_keystore_path, :validate => :path
78
92
 
79
- # NOTE: the default setting [] uses Java SSL engine defaults.
80
- config :ssl_supported_protocols, :validate => ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], :default => [], :list => true
93
+ # Specify the keystore password here.
94
+ # Note, most .jks files created with keytool require a password!
95
+ base.config :ssl_keystore_password, :validate => :password
81
96
 
82
- # If you need to use a custom truststore (`.jks`) specify that here. This does not work with .pem certs!
83
- config :truststore, :validate => :path
97
+ # Specify the keystore type here. One of `jks` or `pkcs12`.
98
+ # The default value is inferred from the filename.
99
+ # Note: If it's unable to determine the type based on the filename, it uses the
100
+ # `keystore.type` security property, or "jks" as default value.
101
+ base.config :ssl_keystore_type, :validate => %w(pkcs12 jks)
84
102
 
85
- # Specify the truststore password here.
86
- # Note, most .jks files created with keytool require a password!
87
- config :truststore_password, :validate => :password
103
+ # Naming aligned with the Elastic stack.
104
+ # full: verifies that the provided certificate is signed by a trusted authority (CA) and also verifies that the
105
+ # server’s hostname (or IP address) matches the names identified within the certificate
106
+ # none: no verification of the server’s certificate
107
+ base.config :ssl_verification_mode, :validate => ['full', 'none'], :default => 'full'
88
108
 
89
- # Specify the truststore type here. One of `JKS` or `PKCS12`. Default is `JKS`
90
- config :truststore_type, :validate => :string, :default => "JKS"
109
+ # The list of cipher suites to use, listed by priorities.
110
+ # Supported cipher suites vary depending on which version of Java is used.
111
+ base.config :ssl_cipher_suites, :validate => :string, :list => true
91
112
 
92
- # Enable cookie support. With this enabled the client will persist cookies
93
- # across requests as a normal web browser would. Enabled by default
94
- config :cookies, :validate => :boolean, :default => true
113
+ # NOTE: the default setting [] uses Java SSL engine defaults.
114
+ base.config :ssl_supported_protocols, :validate => ['TLSv1.1', 'TLSv1.2', 'TLSv1.3'], :default => [], :list => true
95
115
 
96
- # If you'd like to use an HTTP proxy . This supports multiple configuration syntaxes:
97
- #
98
- # 1. Proxy host in form: `http://proxy.org:1234`
99
- # 2. Proxy host in form: `{host => "proxy.org", port => 80, scheme => 'http', user => 'username@host', password => 'password'}`
100
- # 3. Proxy host in form: `{url => 'http://proxy.org:1234', user => 'username@host', password => 'password'}`
101
- config :proxy
116
+ # If you need to use a custom truststore (`.jks`) specify that here. This does not work with .pem certs!
117
+ base.config :ssl_truststore_path, :validate => :path
102
118
 
103
- # Username to use for HTTP auth.
104
- config :user, :validate => :string
119
+ # Specify the truststore password here.
120
+ # Note, most .jks files created with keytool require a password!
121
+ base.config :ssl_truststore_password, :validate => :password
105
122
 
106
- # Password to use for HTTP auth
107
- config :password, :validate => :password
108
- end
123
+ # Specify the truststore type here. One of `JKS` or `PKCS12`.
124
+ # The default value is inferred from the filename.
125
+ # Note: If it's unable to determine the type based on the filename, it uses the
126
+ # `keystore.type` security property, or "jks" as default value.
127
+ base.config :ssl_truststore_type, :validate => %w(pkcs12 jks)
128
+
129
+ # Enable cookie support. With this enabled the client will persist cookies
130
+ # across requests as a normal web browser would. Enabled by default
131
+ base.config :cookies, :validate => :boolean, :default => true
109
132
 
110
- public
111
- def client_config
112
- c = {
113
- connect_timeout: @connect_timeout,
114
- socket_timeout: @socket_timeout,
115
- request_timeout: @request_timeout,
116
- follow_redirects: @follow_redirects,
117
- automatic_retries: @automatic_retries,
118
- retry_non_idempotent: @retry_non_idempotent,
119
- check_connection_timeout: @validate_after_inactivity,
120
- pool_max: @pool_max,
121
- pool_max_per_route: @pool_max_per_route,
122
- cookies: @cookies,
123
- keepalive: @keepalive
124
- }
125
-
126
- if @proxy
127
- # Symbolize keys if necessary
128
- c[:proxy] = @proxy.is_a?(Hash) ?
129
- @proxy.reduce({}) {|memo,(k,v)| memo[k.to_sym] = v; memo} :
130
- @proxy
133
+ # If you'd like to use an HTTP proxy . This supports multiple configuration syntaxes:
134
+ #
135
+ # 1. Proxy host in form: `http://proxy.org:1234`
136
+ # 2. Proxy host in form: `{host => "proxy.org", port => 80, scheme => 'http', user => 'username@host', password => 'password'}`
137
+ # 3. Proxy host in form: `{url => 'http://proxy.org:1234', user => 'username@host', password => 'password'}`
138
+ base.config :proxy
139
+
140
+ # Username to use for HTTP auth.
141
+ base.config :user, :validate => :string
142
+
143
+ # Password to use for HTTP auth
144
+ base.config :password, :validate => :password
131
145
  end
132
146
 
133
- if @user
134
- if !@password || !@password.value
135
- raise ::LogStash::ConfigurationError, "User '#{@user}' specified without password!"
147
+ public
148
+
149
+ def client_config
150
+ c = {
151
+ connect_timeout: @connect_timeout,
152
+ socket_timeout: @socket_timeout,
153
+ request_timeout: @request_timeout,
154
+ follow_redirects: @follow_redirects,
155
+ automatic_retries: @automatic_retries,
156
+ retry_non_idempotent: @retry_non_idempotent,
157
+ check_connection_timeout: @validate_after_inactivity,
158
+ pool_max: @pool_max,
159
+ pool_max_per_route: @pool_max_per_route,
160
+ cookies: @cookies,
161
+ keepalive: @keepalive
162
+ }
163
+
164
+ if @proxy
165
+ # Symbolize keys if necessary
166
+ c[:proxy] = @proxy.is_a?(Hash) ?
167
+ @proxy.reduce({}) {|memo,(k,v)| memo[k.to_sym] = v; memo} :
168
+ @proxy
136
169
  end
137
170
 
138
- # Symbolize keys if necessary
139
- c[:auth] = {
140
- :user => @user,
141
- :password => @password.value,
142
- :eager => true
143
- }
144
- end
171
+ if @user
172
+ if !@password || !@password.value
173
+ raise ::LogStash::ConfigurationError, "User '#{@user}' specified without password!"
174
+ end
175
+
176
+ # Symbolize keys if necessary
177
+ c[:auth] = {
178
+ :user => @user,
179
+ :password => @password.value,
180
+ :eager => true
181
+ }
182
+ end
183
+
184
+ c[:ssl] = ssl_options
145
185
 
146
- c[:ssl] = {}
147
- if @cacert
148
- c[:ssl][:ca_file] = @cacert
186
+ c
149
187
  end
150
188
 
151
- if @truststore
152
- c[:ssl].merge!(
153
- :truststore => @truststore,
154
- :truststore_type => @truststore_type,
155
- :truststore_password => @truststore_password.value
156
- )
157
-
158
- if c[:ssl][:truststore_password].nil?
159
- raise LogStash::ConfigurationError, "Truststore declared without a password! This is not valid, please set the 'truststore_password' option"
189
+ private
190
+
191
+ def ssl_options
192
+
193
+ options = {}
194
+
195
+ unless @ssl_enabled
196
+ ignored_ssl_settings = original_params.select { |k| k != 'ssl_enabled' && k.start_with?('ssl_') }
197
+ self.logger.warn("Configured SSL settings are not used when `ssl_enabled` is set to `false`: #{ignored_ssl_settings.keys}") if ignored_ssl_settings.any?
198
+ return options
160
199
  end
161
- end
162
200
 
163
- if @keystore
164
- c[:ssl].merge!(
165
- :keystore => @keystore,
166
- :keystore_type => @keystore_type,
167
- :keystore_password => @keystore_password.value
168
- )
201
+ if @ssl_certificate_authorities&.any?
202
+ raise LogStash::ConfigurationError, 'Multiple values on `ssl_certificate_authorities` are not supported by this plugin' if @ssl_certificate_authorities.size > 1
169
203
 
170
- if c[:ssl][:keystore_password].nil?
171
- raise LogStash::ConfigurationError, "Keystore declared without a password! This is not valid, please set the 'keystore_password' option"
204
+ options[:ca_file] = @ssl_certificate_authorities.first
172
205
  end
173
- end
174
206
 
175
- if @client_cert && @client_key
176
- c[:ssl][:client_cert] = @client_cert
177
- c[:ssl][:client_key] = @client_key
178
- elsif !!@client_cert ^ !!@client_key
179
- raise InvalidHTTPConfigError, "You must specify both client_cert and client_key for an HTTP client, or neither!"
180
- end
207
+ if @ssl_truststore_path
208
+ options[:truststore] = @ssl_truststore_path
209
+ options[:truststore_type] = @ssl_truststore_type if @ssl_truststore_type
210
+ options[:truststore_password] = @ssl_truststore_password.value if @ssl_truststore_password
211
+ elsif @ssl_truststore_password
212
+ fail LogStash::ConfigurationError, "An `ssl_truststore_password` cannot be specified unless `ssl_truststore_path` is also provided."
213
+ end
181
214
 
182
- case @ssl_verification_mode
183
- when 'full'
184
- # NOTE: would make sense to have :browser here but historically we've used the (:strict) default
185
- #
186
- # supporting `ssl_verification_mode => strict` the same way ES does might require upstream Manticore
187
- # changes -> as in ES/Beats setting `strict` means: "if the SAN is empty return an error"
188
- c[:ssl][:verify] = :strict # :default
189
- when 'none'
190
- c[:ssl][:verify] = :disable
191
- end
215
+ if @ssl_keystore_path
216
+ options[:keystore] = @ssl_keystore_path
217
+ options[:keystore_type] = @ssl_keystore_type if @ssl_keystore_type
218
+ options[:keystore_password] = @ssl_keystore_password.value if @ssl_keystore_password
219
+ elsif @ssl_keystore_password
220
+ fail LogStash::ConfigurationError, "An `ssl_keystore_password` cannot be specified unless `ssl_keystore_path` is also provided."
221
+ end
192
222
 
193
- if @ssl_supported_protocols && @ssl_supported_protocols.any?
194
- c[:ssl][:protocols] = @ssl_supported_protocols
195
- end
223
+ if @ssl_certificate && @ssl_key
224
+ options[:client_cert] = @ssl_certificate
225
+ options[:client_key] = @ssl_key
226
+ elsif !!@ssl_certificate ^ !!@ssl_key
227
+ raise InvalidHTTPConfigError, "You must specify both `ssl_certificate` and `ssl_key` for an HTTP client, or neither!"
228
+ end
196
229
 
197
- c
198
- end
230
+ options[:verify] = @ssl_verification_mode == 'full' ? :strict : :disable
231
+ options[:protocols] = @ssl_supported_protocols if @ssl_supported_protocols&.any?
232
+ options[:cipher_suites] = @ssl_cipher_suites if @ssl_cipher_suites&.any?
199
233
 
200
- private
201
- def make_client
202
- Manticore::Client.new(client_config)
203
- end
234
+ options
235
+ end
236
+
237
+ def make_client
238
+ Manticore::Client.new(client_config)
239
+ end
204
240
 
205
- public
206
- def client
207
- @client ||= make_client
241
+ public
242
+ def client
243
+ @client ||= make_client
244
+ end
208
245
  end
209
- end
246
+ end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'logstash-mixin-http_client'
3
- s.version = '7.2.0'
3
+ s.version = '7.4.0'
4
4
  s.licenses = ['Apache License (2.0)']
5
5
  s.summary = "AWS mixins to provide a unified interface for Amazon Webservice"
6
6
  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"
@@ -19,6 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.add_runtime_dependency "logstash-core-plugin-api", ">= 1.60", "<= 2.99"
20
20
  s.add_runtime_dependency 'logstash-codec-plain'
21
21
  s.add_runtime_dependency 'manticore', '>= 0.8.0', '< 1.0.0'
22
+ s.add_runtime_dependency 'logstash-mixin-normalize_config_support', '~>1.0'
22
23
 
23
24
  s.add_development_dependency 'logstash-devutils'
24
25
  s.add_development_dependency 'stud'
@@ -5,6 +5,7 @@ require "stud/temporary"
5
5
 
6
6
  class Dummy < LogStash::Inputs::Base
7
7
  include LogStash::PluginMixins::HttpClient
8
+ config_name 'dummy'
8
9
  end
9
10
 
10
11
  describe LogStash::PluginMixins::HttpClient do
@@ -29,51 +30,6 @@ describe LogStash::PluginMixins::HttpClient do
29
30
  expect(impl.send(:client)).to eql(impl.client)
30
31
  end
31
32
 
32
- shared_examples "setting ca bundles" do |key, type|
33
- subject { Dummy.new(conf).send(:client_config) }
34
-
35
- it "should correctly set the path" do
36
- expect(subject[:ssl][key]).to eql(path), "Expected to find path for #{key}"
37
- end
38
-
39
- if type == :jks
40
- let(:store_password) { conf["#{key}_password"] }
41
- let(:store_type) { conf["#{key}_type"]}
42
-
43
- it "should set the bundle password" do
44
- expect(subject[:ssl]["#{key}_password".to_sym]).to eql(store_password)
45
- end
46
-
47
- it "should set the bundle type" do
48
- expect(subject[:ssl]["#{key}_type".to_sym]).to eql(store_type)
49
- end
50
- end
51
- end
52
-
53
- describe "with a custom ssl bundle" do
54
- let(:file) { Stud::Temporary.file }
55
- let(:path) { file.path }
56
- after { File.unlink(path)}
57
-
58
- context "with x509" do
59
- let(:conf) { basic_config.merge("cacert" => path) }
60
-
61
- include_examples("setting ca bundles", :ca_file)
62
- end
63
-
64
- context "with JKS" do
65
- let(:conf) {
66
- basic_config.merge(
67
- "truststore" => path,
68
- "truststore_password" => "foobar",
69
- "truststore_type" => "jks"
70
- )
71
- }
72
-
73
- include_examples("setting ca bundles", :truststore, :jks)
74
- end
75
- end
76
-
77
33
  describe "with a custom validate_after_activity" do
78
34
  subject { Dummy.new(client_config).send(:client_config) }
79
35
 
@@ -120,135 +76,4 @@ describe LogStash::PluginMixins::HttpClient do
120
76
  end
121
77
  end
122
78
  end
123
-
124
- ["keystore", "truststore"].each do |store|
125
- describe "with a custom #{store}" do
126
- let(:file) { Stud::Temporary.file }
127
- let(:path) { file.path }
128
- let(:password) { "foo" }
129
- after { File.unlink(path)}
130
-
131
- let(:conf) {
132
- basic_config.merge(
133
- store => path,
134
- "#{store}_password" => password,
135
- "#{store}_type" => "jks"
136
- )
137
- }
138
-
139
- include_examples("setting ca bundles", store.to_sym, :jks)
140
-
141
- context "with no password set" do
142
- let(:password) { nil }
143
-
144
- it "should raise an error" do
145
- expect do
146
- Dummy.new(conf).client_config
147
- end.to raise_error(LogStash::ConfigurationError)
148
- end
149
- end
150
- end
151
- end
152
-
153
- describe "with a client cert" do
154
- let(:file) { Stud::Temporary.file }
155
- let(:path) { file.path }
156
- after { File.unlink(path)}
157
-
158
- context "with correct client certs" do
159
- let(:conf) { basic_config.merge("client_cert" => path, "client_key" => path) }
160
-
161
- it "should create without error" do
162
- expect {
163
- Dummy.new(conf).client_config
164
- }.not_to raise_error
165
- end
166
- end
167
-
168
- shared_examples("raising a configuration error") do
169
- it "should raise an error error" do
170
- expect {
171
- Dummy.new(conf).client_config
172
- }.to raise_error(LogStash::PluginMixins::HttpClient::InvalidHTTPConfigError)
173
- end
174
- end
175
-
176
- context "without a key" do
177
- let(:conf) { basic_config.merge("client_cert" => path) }
178
-
179
- include_examples("raising a configuration error")
180
- end
181
-
182
- context "without a cert" do
183
- let(:conf) { basic_config.merge("client_key" => path) }
184
-
185
- include_examples("raising a configuration error")
186
- end
187
- end
188
-
189
- describe "with verify mode" do
190
- let(:file) { Stud::Temporary.file }
191
- let(:path) { file.path }
192
- after { File.unlink(path)}
193
-
194
- context "default" do
195
- let(:conf) { basic_config }
196
-
197
- it "sets manticore verify to :strict" do
198
- expect( Dummy.new(conf).client_config[:ssl] ).to include :verify => :strict
199
- end
200
- end
201
-
202
- context "'full'" do
203
- let(:conf) { basic_config.merge("ssl_verification_mode" => 'full') }
204
-
205
- it "sets manticore verify to :strict" do
206
- expect( Dummy.new(conf).client_config[:ssl] ).to include :verify => :strict
207
- end
208
- end
209
-
210
- context "'none'" do
211
- let(:conf) { basic_config.merge("ssl_verification_mode" => 'none') }
212
-
213
- it "sets manticore verify to :disable" do
214
- expect( Dummy.new(conf).client_config[:ssl] ).to include :verify => :disable
215
- end
216
- end
217
-
218
- end
219
-
220
- describe "with supported protocols" do
221
- context "default" do
222
- let(:conf) { basic_config }
223
-
224
- it "does not set manticore protocols option" do
225
- expect( Dummy.new(conf).client_config[:ssl] ).to_not include :protocols
226
- end
227
- end
228
-
229
- context "empty" do
230
- let(:conf) { basic_config.merge("ssl_supported_protocols" => []) }
231
-
232
- it "does not set manticore protocols option" do
233
- expect( Dummy.new(conf).client_config[:ssl] ).to_not include :protocols
234
- end
235
- end
236
-
237
- context "'TLSv1.3'" do
238
- let(:conf) { basic_config.merge("ssl_supported_protocols" => ['TLSv1.3']) }
239
-
240
- it "sets manticore protocols option" do
241
- expect( Dummy.new(conf).client_config[:ssl] ).to include :protocols => ['TLSv1.3']
242
- end
243
- end
244
-
245
- context "'TLSv1.2' and 'TLSv1.3'" do
246
- let(:conf) { basic_config.merge("ssl_supported_protocols" => ['TLSv1.3', 'TLSv1.2']) }
247
-
248
- it "sets manticore protocols option" do
249
- expect( Dummy.new(conf).client_config[:ssl] ).to include :protocols => ['TLSv1.3', 'TLSv1.2']
250
- end
251
- end
252
-
253
- end
254
79
  end
@@ -0,0 +1,464 @@
1
+ require 'logstash/devutils/rspec/spec_helper'
2
+ require 'logstash/plugin_mixins/http_client'
3
+ require 'logstash/plugin_mixins/http_client/deprecated_ssl_config_support'
4
+ require 'stud/temporary'
5
+
6
+ shared_examples 'setting ca bundles' do |key, type|
7
+ subject(:client_config) { plugin_class.new(conf).send(:client_config) }
8
+
9
+ it 'should correctly set the path' do
10
+ expect(client_config[:ssl][key]).to eql(path), "Expected to find path for #{key}"
11
+ end
12
+
13
+ if type == :jks
14
+ let(:store_password) { conf["#{use_deprecated_config ? '' : 'ssl_'}#{key}_password"] }
15
+ let(:store_type) { conf["#{use_deprecated_config ? '' : 'ssl_'}#{key}_type"]}
16
+
17
+ it 'should set the bundle password' do
18
+ expect(client_config[:ssl]["#{key}_password".to_sym]).to eql(store_password)
19
+ end
20
+
21
+ it 'should set the bundle type' do
22
+ expect(client_config[:ssl]["#{key}_type".to_sym]).to eql(store_type)
23
+ end
24
+ end
25
+ end
26
+
27
+ shared_examples 'a deprecated setting with guidance' do |deprecations_and_guidance|
28
+
29
+ let(:logger_stub) { double('Logger').as_null_object }
30
+
31
+ before(:each) do
32
+ allow(plugin_class).to receive(:logger).and_return(logger_stub)
33
+ end
34
+
35
+ deprecations_and_guidance.each do |deprecated_setting_name, canonical_setting_name|
36
+ it "emits a warning about the setting `#{deprecated_setting_name}` being deprecated and provides guidance to use `#{canonical_setting_name}`" do
37
+ plugin_class.new(conf)
38
+
39
+ deprecation_text = "deprecated config setting \"#{deprecated_setting_name}\" set"
40
+ guidance_text = "Use `#{canonical_setting_name}` instead"
41
+
42
+ expect(logger_stub).to have_received(:warn).with(a_string_including(deprecation_text).and(including(guidance_text)), anything)
43
+ end
44
+ end
45
+ end
46
+
47
+ shared_examples 'with common ssl options' do
48
+ describe 'with verify mode' do
49
+ let(:file) { Stud::Temporary.file }
50
+ let(:path) { file.path }
51
+ after { File.unlink(path)}
52
+
53
+ context 'default' do
54
+ let(:conf) { basic_config }
55
+
56
+ it 'sets manticore verify to :strict' do
57
+ expect(plugin_class.new(conf).client_config[:ssl]).to include :verify => :strict
58
+ end
59
+ end
60
+
61
+ context "'full'" do
62
+ let(:conf) { basic_config.merge('ssl_verification_mode' => 'full') }
63
+
64
+ it 'sets manticore verify to :strict' do
65
+ expect(plugin_class.new(conf).client_config[:ssl]).to include :verify => :strict
66
+ end
67
+ end
68
+
69
+ context "'none'" do
70
+ let(:conf) { basic_config.merge('ssl_verification_mode' => 'none') }
71
+
72
+ it 'sets manticore verify to :disable' do
73
+ expect(plugin_class.new(conf).client_config[:ssl]).to include :verify => :disable
74
+ end
75
+ end
76
+ end
77
+
78
+ describe 'with supported protocols' do
79
+ context 'default' do
80
+ let(:conf) { basic_config }
81
+
82
+ it 'does not set manticore protocols option' do
83
+ expect(plugin_class.new(conf).client_config[:ssl]).to_not include :protocols
84
+ end
85
+ end
86
+
87
+ context 'empty' do
88
+ let(:conf) { basic_config.merge('ssl_supported_protocols' => []) }
89
+
90
+ it 'does not set manticore protocols option' do
91
+ expect(plugin_class.new(conf).client_config[:ssl]).to_not include :protocols
92
+ end
93
+ end
94
+
95
+ context "'TLSv1.3'" do
96
+ let(:conf) { basic_config.merge('ssl_supported_protocols' => ['TLSv1.3']) }
97
+
98
+ it 'sets manticore protocols option' do
99
+ expect(plugin_class.new(conf).client_config[:ssl]).to include :protocols => ['TLSv1.3']
100
+ end
101
+ end
102
+
103
+ context "'TLSv1.2' and 'TLSv1.3'" do
104
+ let(:conf) { basic_config.merge('ssl_supported_protocols' => ['TLSv1.3', 'TLSv1.2']) }
105
+
106
+ it 'sets manticore protocols option' do
107
+ expect(plugin_class.new(conf).client_config[:ssl]).to include :protocols => ['TLSv1.3', 'TLSv1.2']
108
+ end
109
+ end
110
+ end
111
+
112
+ describe 'with ssl_cipher_suites' do
113
+ context 'default' do
114
+ let(:conf) { basic_config }
115
+
116
+ it 'does not set manticore cipher_suites option' do
117
+ expect(plugin_class.new(conf).client_config[:ssl]).to_not include :cipher_suites
118
+ end
119
+ end
120
+
121
+ context 'empty' do
122
+ let(:conf) { basic_config.merge('ssl_cipher_suites' => []) }
123
+
124
+ it 'does not set manticore cipher_suites option' do
125
+ expect(plugin_class.new(conf).client_config[:ssl]).to_not include :cipher_suites
126
+ end
127
+ end
128
+
129
+ context "set to ['TLS_AES_256_GCM_SHA384']" do
130
+ let(:conf) { basic_config.merge('ssl_cipher_suites' => ['TLS_AES_256_GCM_SHA384']) }
131
+
132
+ it 'sets manticore cipher_suites option' do
133
+ expect(plugin_class.new(conf).client_config[:ssl]).to include :cipher_suites => ['TLS_AES_256_GCM_SHA384']
134
+ end
135
+ end
136
+ end
137
+ end
138
+
139
+ shared_examples("raise an http config error") do |message|
140
+ it "should raise an error error" do
141
+ expect {
142
+ plugin_class.new(conf).client_config
143
+ }.to raise_error(LogStash::PluginMixins::HttpClient::InvalidHTTPConfigError, message)
144
+ end
145
+ end
146
+
147
+ shared_examples 'a client with deprecated ssl options' do
148
+ describe LogStash::PluginMixins::HttpClient do
149
+ let(:basic_config) { {} }
150
+ let(:impl) { plugin_class.new(basic_config) }
151
+ let(:use_deprecated_config) { true }
152
+
153
+ include_examples 'with common ssl options'
154
+
155
+ describe 'with a custom ssl bundle' do
156
+ let(:file) { Stud::Temporary.file }
157
+ let(:path) { file.path }
158
+ after { File.unlink(path)}
159
+
160
+ context 'with x509' do
161
+ let(:conf) { basic_config.merge('cacert' => path) }
162
+
163
+ include_examples('setting ca bundles', :ca_file)
164
+
165
+ it_behaves_like('a deprecated setting with guidance',
166
+ 'cacert' => 'ssl_certificate_authorities')
167
+ end
168
+
169
+ context 'with JKS' do
170
+ let(:conf) {
171
+ basic_config.merge(
172
+ 'truststore' => path,
173
+ 'truststore_password' => 'foobar',
174
+ 'truststore_type' => 'jks'
175
+ )
176
+ }
177
+
178
+ include_examples('setting ca bundles', :truststore, :jks)
179
+
180
+ it_behaves_like('a deprecated setting with guidance',
181
+ 'truststore' => 'ssl_truststore_path',
182
+ 'truststore_password' => 'ssl_truststore_password',
183
+ 'truststore_type' => 'ssl_truststore_type')
184
+ end
185
+ end
186
+
187
+ describe 'with a client cert' do
188
+ let(:file) { Stud::Temporary.file }
189
+ let(:path) { file.path }
190
+ after { File.unlink(path)}
191
+
192
+ context 'with correct client certs' do
193
+ let(:conf) { basic_config.merge('client_cert' => path, 'client_key' => path) }
194
+
195
+ it 'should create without error' do
196
+ expect {
197
+ plugin_class.new(conf).client_config
198
+ }.not_to raise_error
199
+ end
200
+
201
+ it_behaves_like('a deprecated setting with guidance',
202
+ 'client_cert' => 'ssl_certificate',
203
+ 'client_key' => 'ssl_key')
204
+ end
205
+
206
+ context 'without a key' do
207
+ let(:conf) { basic_config.merge('client_cert' => path) }
208
+
209
+ include_examples('raise an http config error', 'When `client_cert` is provided, `client_key` must also be provided')
210
+ end
211
+
212
+ context 'without a cert' do
213
+ let(:conf) { basic_config.merge('client_key' => path) }
214
+
215
+ include_examples('raise an http config error', 'A `client_key` is not allowed unless a `client_cert` is provided')
216
+ end
217
+ end
218
+
219
+ %w[keystore truststore].each do |store|
220
+ describe "with a custom #{store}" do
221
+ let(:file) { Stud::Temporary.file }
222
+ let(:path) { file.path }
223
+ let(:password) { "foo" }
224
+ after { File.unlink(path)}
225
+
226
+ let(:conf) {
227
+ basic_config.merge(
228
+ store => path,
229
+ "#{store}_password" => password,
230
+ "#{store}_type" => "jks"
231
+ ).compact
232
+ }
233
+
234
+ include_examples("setting ca bundles", store.to_sym, :jks)
235
+
236
+ it_behaves_like('a deprecated setting with guidance',
237
+ "#{store}" => "ssl_#{store}_path",
238
+ "#{store}_password" => "ssl_#{store}_password",
239
+ "#{store}_type" => "ssl_#{store}_type")
240
+
241
+ context "with no password set" do
242
+ let(:password) { nil }
243
+
244
+ it "should raise an error" do
245
+ expect do
246
+ plugin_class.new(conf).client_config
247
+ end.to raise_error(LogStash::ConfigurationError)
248
+ end
249
+ end
250
+ end
251
+ end
252
+ end
253
+ end
254
+
255
+ shared_examples 'a client with standardized ssl options' do
256
+ describe LogStash::PluginMixins::HttpClient do
257
+ let(:basic_config) { {} }
258
+ let(:impl) { plugin_class.new(basic_config) }
259
+ let(:use_deprecated_config) { false }
260
+
261
+ include_examples 'with common ssl options'
262
+
263
+ describe 'with a custom ssl bundle' do
264
+ let(:file) { Stud::Temporary.file }
265
+ let(:path) { file.path }
266
+ after { File.unlink(path)}
267
+
268
+ context 'with x509' do
269
+ let(:conf) { basic_config.merge('ssl_certificate_authorities' => path) }
270
+
271
+ include_examples('setting ca bundles', :ca_file)
272
+ end
273
+
274
+ context 'with JKS' do
275
+ let(:conf) {
276
+ basic_config.merge(
277
+ 'ssl_truststore_path' => path,
278
+ 'ssl_truststore_password' => 'foobar',
279
+ 'ssl_truststore_type' => 'jks'
280
+ )
281
+ }
282
+
283
+ include_examples('setting ca bundles', :truststore, :jks)
284
+ end
285
+ end
286
+
287
+ describe 'with a client cert' do
288
+ let(:file) { Stud::Temporary.file }
289
+ let(:path) { file.path }
290
+ after { File.unlink(path)}
291
+
292
+ context 'with correct client certs' do
293
+ let(:conf) { basic_config.merge('ssl_certificate' => path, 'ssl_key' => path) }
294
+
295
+ it 'should create without error' do
296
+ expect {
297
+ plugin_class.new(conf).client_config
298
+ }.not_to raise_error
299
+ end
300
+ end
301
+
302
+ context 'without an ssl_key' do
303
+ let(:conf) { basic_config.merge('ssl_certificate' => path) }
304
+
305
+ include_examples('raise an http config error', 'You must specify both `ssl_certificate` and `ssl_key` for an HTTP client, or neither!')
306
+ end
307
+
308
+ context 'without an ssl_certificate' do
309
+ let(:conf) { basic_config.merge('ssl_key' => path) }
310
+ include_examples('raise an http config error', 'You must specify both `ssl_certificate` and `ssl_key` for an HTTP client, or neither!')
311
+ end
312
+ end
313
+
314
+ %w[keystore truststore].each do |store|
315
+ describe "with a custom #{store}" do
316
+ let(:file) { Stud::Temporary.file }
317
+ let(:path) { file.path }
318
+ let(:password) { "foo" }
319
+ after { File.unlink(path)}
320
+
321
+ let(:conf) {
322
+ basic_config.merge(
323
+ "ssl_#{store}_path" => path,
324
+ "ssl_#{store}_password" => password,
325
+ "ssl_#{store}_type" => "jks"
326
+ ).compact
327
+ }
328
+
329
+ include_examples("setting ca bundles", store.to_sym, :jks)
330
+
331
+ context "with no password set" do
332
+ let(:password) { nil }
333
+
334
+ it "should not raise an error" do
335
+ expect do
336
+ plugin_class.new(conf).client_config
337
+ end.to_not raise_error
338
+ end
339
+ end
340
+ end
341
+ end
342
+
343
+ describe 'with ssl_enabled' do
344
+ context 'set to false' do
345
+ let(:basic_config) { super().merge('ssl_enabled' => false) }
346
+ let(:plugin) { plugin_class.new(basic_config) }
347
+
348
+ it 'should not configure the client :ssl' do
349
+ expect(plugin.client_config[:ssl]).to eq({})
350
+ end
351
+
352
+ context 'and another ssl_* config set' do
353
+ let(:basic_config) { super().merge('ssl_verification_mode' => 'none') }
354
+ let(:logger_mock) { double('logger') }
355
+
356
+ before(:each) do
357
+ allow(plugin).to receive(:logger).and_return(logger_mock)
358
+ end
359
+
360
+ it 'should log a warn message' do
361
+ allow(logger_mock).to receive(:warn)
362
+ plugin.client_config
363
+ expect(logger_mock).to have_received(:warn).with('Configured SSL settings are not used when `ssl_enabled` is set to `false`: ["ssl_verification_mode"]')
364
+ end
365
+ end
366
+ end
367
+ end
368
+ end
369
+ end
370
+
371
+ class PluginWithNoModuleConfig < LogStash::Inputs::Base
372
+ include LogStash::PluginMixins::HttpClient
373
+ config_name 'no_config'
374
+ end
375
+
376
+ class PluginWithDeprecatedTrue < LogStash::Inputs::Base
377
+ include LogStash::PluginMixins::HttpClient[:with_deprecated => true]
378
+ config_name 'with_deprecated'
379
+ end
380
+
381
+ class PluginWithDeprecatedFalse < LogStash::Inputs::Base
382
+ include LogStash::PluginMixins::HttpClient[:with_deprecated => false]
383
+ config_name 'without_deprecated'
384
+ end
385
+
386
+ describe PluginWithNoModuleConfig do
387
+ let(:plugin_class) { PluginWithNoModuleConfig }
388
+
389
+ it_behaves_like 'a client with deprecated ssl options'
390
+
391
+ it 'includes DeprecatedSslConfigSupport module' do
392
+ expect(plugin_class.ancestors).to include(LogStash::PluginMixins::HttpClient::DeprecatedSslConfigSupport)
393
+ end
394
+ end
395
+
396
+ describe PluginWithDeprecatedFalse do
397
+ let(:plugin_class) { PluginWithDeprecatedFalse }
398
+
399
+ it_behaves_like 'a client with standardized ssl options'
400
+
401
+ it 'does not include DeprecatedSslConfigSupport module' do
402
+ expect(plugin_class.ancestors).to_not include(LogStash::PluginMixins::HttpClient::DeprecatedSslConfigSupport)
403
+ end
404
+ end
405
+
406
+ describe PluginWithDeprecatedTrue do
407
+ let(:plugin_class) { PluginWithDeprecatedTrue }
408
+
409
+ it_behaves_like 'a client with deprecated ssl options'
410
+
411
+ it_behaves_like 'a client with standardized ssl options'
412
+
413
+ context 'setting deprecate configs' do
414
+ let(:cacert) { Stud::Temporary.file.path }
415
+ let(:client_cert) { Stud::Temporary.file.path }
416
+ let(:client_key) { Stud::Temporary.file.path }
417
+ let(:keystore) { Stud::Temporary.file.path }
418
+ let(:keystore_type) { 'pkcs12' }
419
+ let(:keystore_password) { 'bar' }
420
+ let(:truststore) { Stud::Temporary.file.path }
421
+ let(:truststore_type) { 'pkcs12' }
422
+ let(:truststore_password) { 'foo' }
423
+
424
+ let(:settings) do
425
+ {
426
+ 'cacert' => cacert,
427
+ 'client_cert' => client_cert,
428
+ 'client_key' => client_key,
429
+ 'keystore' => keystore,
430
+ 'keystore_password' => keystore_password,
431
+ 'keystore_type' => keystore_type,
432
+ 'truststore' => truststore,
433
+ 'truststore_password' => truststore_password,
434
+ 'truststore_type' => truststore_type
435
+ }
436
+ end
437
+
438
+ subject(:plugin_instance) { plugin_class.new(settings) }
439
+
440
+ after do
441
+ File.unlink(cacert)
442
+ File.unlink(client_cert)
443
+ File.unlink(client_key)
444
+ File.unlink(keystore)
445
+ File.unlink(truststore)
446
+ end
447
+
448
+ it 'normalizes deprecated settings' do
449
+ expect(plugin_instance.ssl_certificate_authorities).to eq([cacert])
450
+ expect(plugin_instance.ssl_certificate).to eq(client_cert)
451
+ expect(plugin_instance.ssl_key).to eq(client_key)
452
+ expect(plugin_instance.ssl_keystore_path).to eq(keystore)
453
+ expect(plugin_instance.ssl_keystore_password.value).to eq(keystore_password)
454
+ expect(plugin_instance.ssl_keystore_type).to eq(keystore_type)
455
+ expect(plugin_instance.ssl_truststore_path).to eq(truststore)
456
+ expect(plugin_instance.ssl_truststore_password.value).to eq(truststore_password)
457
+ expect(plugin_instance.ssl_truststore_type).to eq(truststore_type)
458
+ end
459
+ end
460
+
461
+ it 'includes DeprecatedSslConfigSupport module' do
462
+ expect(plugin_class.ancestors).to include(LogStash::PluginMixins::HttpClient::DeprecatedSslConfigSupport)
463
+ end
464
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: logstash-mixin-http_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.2.0
4
+ version: 7.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Elastic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-17 00:00:00.000000000 Z
11
+ date: 2024-06-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -64,6 +64,20 @@ dependencies:
64
64
  - - "<"
65
65
  - !ruby/object:Gem::Version
66
66
  version: 1.0.0
67
+ - !ruby/object:Gem::Dependency
68
+ requirement: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - "~>"
71
+ - !ruby/object:Gem::Version
72
+ version: '1.0'
73
+ name: logstash-mixin-normalize_config_support
74
+ prerelease: false
75
+ type: :runtime
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: '1.0'
67
81
  - !ruby/object:Gem::Dependency
68
82
  requirement: !ruby/object:Gem::Requirement
69
83
  requirements:
@@ -106,8 +120,10 @@ files:
106
120
  - LICENSE
107
121
  - README.md
108
122
  - lib/logstash/plugin_mixins/http_client.rb
123
+ - lib/logstash/plugin_mixins/http_client/deprecated_ssl_config_support.rb
109
124
  - logstash-mixin-http_client.gemspec
110
125
  - spec/plugin_mixin/http_client_spec.rb
126
+ - spec/plugin_mixin/http_client_ssl_spec.rb
111
127
  homepage: http://www.elastic.co/guide/en/logstash/current/index.html
112
128
  licenses:
113
129
  - Apache License (2.0)
@@ -127,9 +143,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
127
143
  - !ruby/object:Gem::Version
128
144
  version: '0'
129
145
  requirements: []
130
- rubygems_version: 3.1.6
146
+ rubygems_version: 3.2.33
131
147
  signing_key:
132
148
  specification_version: 4
133
149
  summary: AWS mixins to provide a unified interface for Amazon Webservice
134
150
  test_files:
135
151
  - spec/plugin_mixin/http_client_spec.rb
152
+ - spec/plugin_mixin/http_client_ssl_spec.rb