logstash-mixin-http_client 7.2.0 → 7.4.0

Sign up to get free protection for your applications and to get access to all the features.
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