aws-sdk-core 3.46.2 → 3.126.2

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.
Files changed (206) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1258 -0
  3. data/LICENSE.txt +202 -0
  4. data/VERSION +1 -1
  5. data/lib/aws-defaults/default_configuration.rb +153 -0
  6. data/lib/aws-defaults/defaults_mode_config_resolver.rb +107 -0
  7. data/lib/aws-defaults.rb +3 -0
  8. data/lib/aws-sdk-core/arn.rb +92 -0
  9. data/lib/aws-sdk-core/arn_parser.rb +40 -0
  10. data/lib/aws-sdk-core/assume_role_credentials.rb +20 -0
  11. data/lib/aws-sdk-core/assume_role_web_identity_credentials.rb +109 -0
  12. data/lib/aws-sdk-core/async_client_stubs.rb +82 -0
  13. data/lib/aws-sdk-core/binary/decode_handler.rb +11 -1
  14. data/lib/aws-sdk-core/binary/encode_handler.rb +34 -0
  15. data/lib/aws-sdk-core/binary/event_builder.rb +124 -0
  16. data/lib/aws-sdk-core/binary/event_parser.rb +50 -18
  17. data/lib/aws-sdk-core/binary/event_stream_decoder.rb +7 -2
  18. data/lib/aws-sdk-core/binary/event_stream_encoder.rb +55 -0
  19. data/lib/aws-sdk-core/binary.rb +5 -0
  20. data/lib/aws-sdk-core/client_side_monitoring/publisher.rb +11 -1
  21. data/lib/aws-sdk-core/client_side_monitoring/request_metrics.rb +2 -0
  22. data/lib/aws-sdk-core/client_stubs.rb +16 -13
  23. data/lib/aws-sdk-core/credential_provider.rb +1 -30
  24. data/lib/aws-sdk-core/credential_provider_chain.rb +102 -40
  25. data/lib/aws-sdk-core/credentials.rb +2 -0
  26. data/lib/aws-sdk-core/deprecations.rb +17 -11
  27. data/lib/aws-sdk-core/eager_loader.rb +2 -0
  28. data/lib/aws-sdk-core/ec2_metadata.rb +238 -0
  29. data/lib/aws-sdk-core/ecs_credentials.rb +18 -9
  30. data/lib/aws-sdk-core/endpoint_cache.rb +16 -11
  31. data/lib/aws-sdk-core/errors.rb +138 -15
  32. data/lib/aws-sdk-core/event_emitter.rb +44 -0
  33. data/lib/aws-sdk-core/ini_parser.rb +2 -0
  34. data/lib/aws-sdk-core/instance_profile_credentials.rb +179 -42
  35. data/lib/aws-sdk-core/json/builder.rb +2 -0
  36. data/lib/aws-sdk-core/json/error_handler.rb +21 -2
  37. data/lib/aws-sdk-core/json/handler.rb +21 -1
  38. data/lib/aws-sdk-core/json/json_engine.rb +12 -8
  39. data/lib/aws-sdk-core/json/oj_engine.rb +35 -6
  40. data/lib/aws-sdk-core/json/parser.rb +10 -0
  41. data/lib/aws-sdk-core/json.rb +11 -28
  42. data/lib/aws-sdk-core/log/formatter.rb +16 -4
  43. data/lib/aws-sdk-core/log/handler.rb +2 -0
  44. data/lib/aws-sdk-core/log/param_filter.rb +38 -13
  45. data/lib/aws-sdk-core/log/param_formatter.rb +2 -0
  46. data/lib/aws-sdk-core/pageable_response.rb +48 -24
  47. data/lib/aws-sdk-core/pager.rb +5 -0
  48. data/lib/aws-sdk-core/param_converter.rb +2 -0
  49. data/lib/aws-sdk-core/param_validator.rb +63 -7
  50. data/lib/aws-sdk-core/plugins/api_key.rb +5 -1
  51. data/lib/aws-sdk-core/plugins/apig_authorizer_token.rb +2 -0
  52. data/lib/aws-sdk-core/plugins/apig_credentials_configuration.rb +2 -0
  53. data/lib/aws-sdk-core/plugins/apig_user_agent.rb +2 -0
  54. data/lib/aws-sdk-core/plugins/client_metrics_plugin.rb +28 -1
  55. data/lib/aws-sdk-core/plugins/client_metrics_send_plugin.rb +2 -0
  56. data/lib/aws-sdk-core/plugins/credentials_configuration.rb +26 -7
  57. data/lib/aws-sdk-core/plugins/defaults_mode.rb +40 -0
  58. data/lib/aws-sdk-core/plugins/endpoint_discovery.rb +12 -4
  59. data/lib/aws-sdk-core/plugins/endpoint_pattern.rb +8 -6
  60. data/lib/aws-sdk-core/plugins/event_stream_configuration.rb +16 -0
  61. data/lib/aws-sdk-core/plugins/global_configuration.rb +2 -0
  62. data/lib/aws-sdk-core/plugins/helpful_socket_errors.rb +2 -0
  63. data/lib/aws-sdk-core/plugins/http_checksum.rb +57 -0
  64. data/lib/aws-sdk-core/plugins/idempotency_token.rb +2 -0
  65. data/lib/aws-sdk-core/plugins/invocation_id.rb +35 -0
  66. data/lib/aws-sdk-core/plugins/jsonvalue_converter.rb +2 -0
  67. data/lib/aws-sdk-core/plugins/logging.rb +2 -0
  68. data/lib/aws-sdk-core/plugins/param_converter.rb +2 -0
  69. data/lib/aws-sdk-core/plugins/param_validator.rb +2 -0
  70. data/lib/aws-sdk-core/plugins/protocols/api_gateway.rb +19 -0
  71. data/lib/aws-sdk-core/plugins/protocols/ec2.rb +2 -0
  72. data/lib/aws-sdk-core/plugins/protocols/json_rpc.rb +2 -0
  73. data/lib/aws-sdk-core/plugins/protocols/query.rb +2 -0
  74. data/lib/aws-sdk-core/plugins/protocols/rest_json.rb +18 -1
  75. data/lib/aws-sdk-core/plugins/protocols/rest_xml.rb +2 -0
  76. data/lib/aws-sdk-core/plugins/recursion_detection.rb +27 -0
  77. data/lib/aws-sdk-core/plugins/regional_endpoint.rb +74 -16
  78. data/lib/aws-sdk-core/plugins/response_paging.rb +2 -0
  79. data/lib/aws-sdk-core/plugins/retries/client_rate_limiter.rb +139 -0
  80. data/lib/aws-sdk-core/plugins/retries/clock_skew.rb +100 -0
  81. data/lib/aws-sdk-core/plugins/retries/error_inspector.rb +146 -0
  82. data/lib/aws-sdk-core/plugins/retries/retry_quota.rb +59 -0
  83. data/lib/aws-sdk-core/plugins/retry_errors.rb +295 -107
  84. data/lib/aws-sdk-core/plugins/signature_v2.rb +2 -0
  85. data/lib/aws-sdk-core/plugins/signature_v4.rb +28 -25
  86. data/lib/aws-sdk-core/plugins/stub_responses.rb +24 -7
  87. data/lib/aws-sdk-core/plugins/transfer_encoding.rb +53 -0
  88. data/lib/aws-sdk-core/plugins/user_agent.rb +6 -8
  89. data/lib/aws-sdk-core/process_credentials.rb +12 -5
  90. data/lib/aws-sdk-core/query/ec2_param_builder.rb +2 -0
  91. data/lib/aws-sdk-core/query/handler.rb +2 -0
  92. data/lib/aws-sdk-core/query/param.rb +2 -0
  93. data/lib/aws-sdk-core/query/param_builder.rb +2 -0
  94. data/lib/aws-sdk-core/query/param_list.rb +2 -0
  95. data/lib/aws-sdk-core/query.rb +2 -0
  96. data/lib/aws-sdk-core/refreshing_credentials.rb +15 -2
  97. data/lib/aws-sdk-core/resources/collection.rb +2 -0
  98. data/lib/aws-sdk-core/rest/handler.rb +2 -0
  99. data/lib/aws-sdk-core/rest/request/body.rb +21 -1
  100. data/lib/aws-sdk-core/rest/request/builder.rb +2 -0
  101. data/lib/aws-sdk-core/rest/request/endpoint.rb +10 -3
  102. data/lib/aws-sdk-core/rest/request/headers.rb +20 -6
  103. data/lib/aws-sdk-core/rest/request/querystring_builder.rb +4 -2
  104. data/lib/aws-sdk-core/rest/response/body.rb +2 -0
  105. data/lib/aws-sdk-core/rest/response/headers.rb +6 -3
  106. data/lib/aws-sdk-core/rest/response/parser.rb +2 -0
  107. data/lib/aws-sdk-core/rest/response/status_code.rb +2 -0
  108. data/lib/aws-sdk-core/rest.rb +2 -0
  109. data/lib/aws-sdk-core/shared_config.rb +153 -127
  110. data/lib/aws-sdk-core/shared_credentials.rb +9 -1
  111. data/lib/aws-sdk-core/sso_credentials.rb +136 -0
  112. data/lib/aws-sdk-core/structure.rb +14 -4
  113. data/lib/aws-sdk-core/stubbing/data_applicator.rb +2 -0
  114. data/lib/aws-sdk-core/stubbing/empty_stub.rb +2 -0
  115. data/lib/aws-sdk-core/stubbing/protocols/api_gateway.rb +2 -0
  116. data/lib/aws-sdk-core/stubbing/protocols/ec2.rb +2 -0
  117. data/lib/aws-sdk-core/stubbing/protocols/json.rb +3 -1
  118. data/lib/aws-sdk-core/stubbing/protocols/query.rb +4 -2
  119. data/lib/aws-sdk-core/stubbing/protocols/rest.rb +52 -7
  120. data/lib/aws-sdk-core/stubbing/protocols/rest_json.rb +3 -1
  121. data/lib/aws-sdk-core/stubbing/protocols/rest_xml.rb +2 -2
  122. data/lib/aws-sdk-core/stubbing/stub_data.rb +15 -4
  123. data/lib/aws-sdk-core/stubbing/xml_error.rb +2 -0
  124. data/lib/aws-sdk-core/type_builder.rb +2 -0
  125. data/lib/aws-sdk-core/util.rb +6 -0
  126. data/lib/aws-sdk-core/waiters/errors.rb +2 -0
  127. data/lib/aws-sdk-core/waiters/poller.rb +2 -0
  128. data/lib/aws-sdk-core/waiters/waiter.rb +4 -2
  129. data/lib/aws-sdk-core/waiters.rb +2 -0
  130. data/lib/aws-sdk-core/xml/builder.rb +5 -3
  131. data/lib/aws-sdk-core/xml/default_list.rb +2 -0
  132. data/lib/aws-sdk-core/xml/default_map.rb +2 -0
  133. data/lib/aws-sdk-core/xml/doc_builder.rb +15 -4
  134. data/lib/aws-sdk-core/xml/error_handler.rb +29 -4
  135. data/lib/aws-sdk-core/xml/parser/engines/libxml.rb +2 -0
  136. data/lib/aws-sdk-core/xml/parser/engines/nokogiri.rb +2 -0
  137. data/lib/aws-sdk-core/xml/parser/engines/oga.rb +2 -0
  138. data/lib/aws-sdk-core/xml/parser/engines/ox.rb +3 -1
  139. data/lib/aws-sdk-core/xml/parser/engines/rexml.rb +4 -1
  140. data/lib/aws-sdk-core/xml/parser/frame.rb +25 -0
  141. data/lib/aws-sdk-core/xml/parser/parsing_error.rb +2 -0
  142. data/lib/aws-sdk-core/xml/parser/stack.rb +2 -0
  143. data/lib/aws-sdk-core/xml/parser.rb +7 -0
  144. data/lib/aws-sdk-core/xml.rb +2 -0
  145. data/lib/aws-sdk-core.rb +23 -4
  146. data/lib/aws-sdk-sso/client.rb +568 -0
  147. data/lib/aws-sdk-sso/client_api.rb +190 -0
  148. data/lib/aws-sdk-sso/customizations.rb +1 -0
  149. data/lib/aws-sdk-sso/errors.rb +102 -0
  150. data/lib/aws-sdk-sso/resource.rb +26 -0
  151. data/lib/aws-sdk-sso/types.rb +352 -0
  152. data/lib/aws-sdk-sso.rb +55 -0
  153. data/lib/aws-sdk-sts/client.rb +1282 -531
  154. data/lib/aws-sdk-sts/client_api.rb +76 -1
  155. data/lib/aws-sdk-sts/customizations.rb +4 -0
  156. data/lib/aws-sdk-sts/errors.rb +153 -1
  157. data/lib/aws-sdk-sts/plugins/sts_regional_endpoints.rb +38 -0
  158. data/lib/aws-sdk-sts/presigner.rb +75 -0
  159. data/lib/aws-sdk-sts/resource.rb +4 -1
  160. data/lib/aws-sdk-sts/types.rb +958 -229
  161. data/lib/aws-sdk-sts.rb +16 -6
  162. data/lib/seahorse/client/async_base.rb +52 -0
  163. data/lib/seahorse/client/async_response.rb +64 -0
  164. data/lib/seahorse/client/base.rb +7 -2
  165. data/lib/seahorse/client/block_io.rb +6 -2
  166. data/lib/seahorse/client/configuration.rb +7 -1
  167. data/lib/seahorse/client/events.rb +3 -1
  168. data/lib/seahorse/client/h2/connection.rb +250 -0
  169. data/lib/seahorse/client/h2/handler.rb +152 -0
  170. data/lib/seahorse/client/handler.rb +2 -0
  171. data/lib/seahorse/client/handler_builder.rb +2 -0
  172. data/lib/seahorse/client/handler_list.rb +2 -0
  173. data/lib/seahorse/client/handler_list_entry.rb +6 -4
  174. data/lib/seahorse/client/http/async_response.rb +44 -0
  175. data/lib/seahorse/client/http/headers.rb +2 -0
  176. data/lib/seahorse/client/http/request.rb +5 -3
  177. data/lib/seahorse/client/http/response.rb +18 -11
  178. data/lib/seahorse/client/logging/formatter.rb +6 -2
  179. data/lib/seahorse/client/logging/handler.rb +2 -0
  180. data/lib/seahorse/client/managed_file.rb +2 -0
  181. data/lib/seahorse/client/net_http/connection_pool.rb +30 -23
  182. data/lib/seahorse/client/net_http/handler.rb +24 -7
  183. data/lib/seahorse/client/net_http/patches.rb +15 -84
  184. data/lib/seahorse/client/networking_error.rb +30 -0
  185. data/lib/seahorse/client/plugin.rb +10 -7
  186. data/lib/seahorse/client/plugin_list.rb +2 -0
  187. data/lib/seahorse/client/plugins/content_length.rb +14 -3
  188. data/lib/seahorse/client/plugins/endpoint.rb +4 -2
  189. data/lib/seahorse/client/plugins/h2.rb +69 -0
  190. data/lib/seahorse/client/plugins/logging.rb +2 -0
  191. data/lib/seahorse/client/plugins/net_http.rb +39 -3
  192. data/lib/seahorse/client/plugins/operation_methods.rb +2 -0
  193. data/lib/seahorse/client/plugins/raise_response_errors.rb +2 -0
  194. data/lib/seahorse/client/plugins/request_callback.rb +110 -0
  195. data/lib/seahorse/client/plugins/response_target.rb +23 -14
  196. data/lib/seahorse/client/request.rb +2 -0
  197. data/lib/seahorse/client/request_context.rb +2 -0
  198. data/lib/seahorse/client/response.rb +5 -5
  199. data/lib/seahorse/model/api.rb +10 -0
  200. data/lib/seahorse/model/authorizer.rb +2 -0
  201. data/lib/seahorse/model/operation.rb +9 -0
  202. data/lib/seahorse/model/shapes.rb +29 -2
  203. data/lib/seahorse/util.rb +8 -1
  204. data/lib/seahorse/version.rb +2 -0
  205. data/lib/seahorse.rb +12 -0
  206. metadata +64 -14
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'thread'
2
4
 
3
5
  module Aws
@@ -171,24 +173,25 @@ module Aws
171
173
  # @raise [RuntimeError] Raises a runtime error when called
172
174
  # on a client that has not enabled response stubbing via
173
175
  # `:stub_responses => true`.
174
- #
175
176
  def stub_responses(operation_name, *stubs)
176
177
  if config.stub_responses
177
178
  apply_stubs(operation_name, stubs.flatten)
178
179
  else
179
- msg = 'stubbing is not enabled; enable stubbing in the constructor '
180
- msg << 'with `:stub_responses => true`'
180
+ msg = 'stubbing is not enabled; enable stubbing in the constructor '\
181
+ 'with `:stub_responses => true`'
181
182
  raise msg
182
183
  end
183
184
  end
184
185
 
185
- # Allows you to access all of the requests that the stubbed client has made
186
- #
187
- # @params [Boolean] exclude_presign Setting to true for filtering out not sent requests from
188
- # generating presigned urls. Default to false.
189
- # @return [Array] Returns an array of the api requests made, each request object contains the
190
- # :operation_name, :params, and :context of the request.
191
- # @raise [NotImplementedError] Raises `NotImplementedError` when the client is not stubbed
186
+ # Allows you to access all of the requests that the stubbed client has made.
187
+ #
188
+ # @param [Hash] options The options for the api requests.
189
+ # @option options [Boolean] :exclude_presign (false) Set to true to filter
190
+ # out unsent requests from generated presigned urls.
191
+ # @return [Array] Returns an array of the api requests made. Each request
192
+ # object contains the :operation_name, :params, and :context.
193
+ # @raise [NotImplementedError] Raises `NotImplementedError` when the client
194
+ # is not stubbed.
192
195
  def api_requests(options = {})
193
196
  if config.stub_responses
194
197
  if options[:exclude_presign]
@@ -197,8 +200,8 @@ module Aws
197
200
  @api_requests
198
201
  end
199
202
  else
200
- msg = 'This method is only implemented for stubbed clients, and is '
201
- msg << 'available when you enable stubbing in the constructor with `stub_responses: true`'
203
+ msg = 'This method is only implemented for stubbed clients, and is '\
204
+ 'available when you enable stubbing in the constructor with `stub_responses: true`'
202
205
  raise NotImplementedError.new(msg)
203
206
  end
204
207
  end
@@ -291,7 +294,7 @@ module Aws
291
294
  def data_to_http_resp(operation_name, data)
292
295
  api = config.api
293
296
  operation = api.operation(operation_name)
294
- ParamValidator.validate!(operation.output, data)
297
+ ParamValidator.new(operation.output, input: false).validate!(data)
295
298
  protocol_helper.stub_data(api, operation, data)
296
299
  end
297
300
 
@@ -1,10 +1,8 @@
1
- require_relative 'deprecations'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Aws
4
4
  module CredentialProvider
5
5
 
6
- extend Deprecations
7
-
8
6
  # @return [Credentials]
9
7
  attr_reader :credentials
10
8
 
@@ -13,32 +11,5 @@ module Aws
13
11
  !!credentials && credentials.set?
14
12
  end
15
13
 
16
- # @deprecated Deprecated in 2.1.0. This method is subject to errors
17
- # from a race condition when called against refreshable credential
18
- # objects. Will be removed in 2.2.0.
19
- # @see #credentials
20
- def access_key_id
21
- credentials ? credentials.access_key_id : nil
22
- end
23
- deprecated(:access_key_id, use: '#credentials')
24
-
25
- # @deprecated Deprecated in 2.1.0. This method is subject to errors
26
- # from a race condition when called against refreshable credential
27
- # objects. Will be removed in 2.2.0.
28
- # @see #credentials
29
- def secret_access_key
30
- credentials ? credentials.secret_access_key : nil
31
- end
32
- deprecated(:secret_access_key, use: '#credentials')
33
-
34
- # @deprecated Deprecated in 2.1.0. This method is subject to errors
35
- # from a race condition when called against refreshable credential
36
- # objects. Will be removed in 2.2.0.
37
- # @see #credentials
38
- def session_token
39
- credentials ? credentials.session_token : nil
40
- end
41
- deprecated(:session_token, use: '#credentials')
42
-
43
14
  end
44
15
  end
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Aws
2
4
  # @api private
3
5
  class CredentialProviderChain
4
-
5
6
  def initialize(config = nil)
6
7
  @config = config
7
8
  end
@@ -20,15 +21,22 @@ module Aws
20
21
  def providers
21
22
  [
22
23
  [:static_credentials, {}],
24
+ [:static_profile_assume_role_web_identity_credentials, {}],
25
+ [:static_profile_sso_credentials, {}],
26
+ [:static_profile_assume_role_credentials, {}],
27
+ [:static_profile_credentials, {}],
28
+ [:static_profile_process_credentials, {}],
23
29
  [:env_credentials, {}],
30
+ [:assume_role_web_identity_credentials, {}],
31
+ [:sso_credentials, {}],
24
32
  [:assume_role_credentials, {}],
25
33
  [:shared_credentials, {}],
26
34
  [:process_credentials, {}],
27
35
  [:instance_profile_credentials, {
28
36
  retries: @config ? @config.instance_profile_credentials_retries : 0,
29
37
  http_open_timeout: @config ? @config.instance_profile_credentials_timeout : 1,
30
- http_read_timeout: @config ? @config.instance_profile_credentials_timeout : 1,
31
- }],
38
+ http_read_timeout: @config ? @config.instance_profile_credentials_timeout : 1
39
+ }]
32
40
  ]
33
41
  end
34
42
 
@@ -37,48 +45,90 @@ module Aws
37
45
  Credentials.new(
38
46
  options[:config].access_key_id,
39
47
  options[:config].secret_access_key,
40
- options[:config].session_token)
41
- else
42
- nil
48
+ options[:config].session_token
49
+ )
50
+ end
51
+ end
52
+
53
+ def static_profile_assume_role_web_identity_credentials(options)
54
+ if Aws.shared_config.config_enabled? && options[:config] && options[:config].profile
55
+ Aws.shared_config.assume_role_web_identity_credentials_from_config(
56
+ profile: options[:config].profile,
57
+ region: options[:config].region
58
+ )
43
59
  end
44
60
  end
45
61
 
46
- def env_credentials(options)
47
- key = %w(AWS_ACCESS_KEY_ID AMAZON_ACCESS_KEY_ID AWS_ACCESS_KEY)
48
- secret = %w(AWS_SECRET_ACCESS_KEY AMAZON_SECRET_ACCESS_KEY AWS_SECRET_KEY)
49
- token = %w(AWS_SESSION_TOKEN AMAZON_SESSION_TOKEN)
62
+ def static_profile_sso_credentials(options)
63
+ if Aws.shared_config.config_enabled? && options[:config] && options[:config].profile
64
+ Aws.shared_config.sso_credentials_from_config(
65
+ profile: options[:config].profile
66
+ )
67
+ end
68
+ end
69
+
70
+ def static_profile_assume_role_credentials(options)
71
+ if Aws.shared_config.config_enabled? && options[:config] && options[:config].profile
72
+ assume_role_with_profile(options, options[:config].profile)
73
+ end
74
+ end
75
+
76
+ def static_profile_credentials(options)
77
+ if options[:config] && options[:config].profile
78
+ SharedCredentials.new(profile_name: options[:config].profile)
79
+ end
80
+ rescue Errors::NoSuchProfileError
81
+ nil
82
+ end
83
+
84
+ def static_profile_process_credentials(options)
85
+ if Aws.shared_config.config_enabled? && options[:config] && options[:config].profile
86
+ process_provider = Aws.shared_config.credential_process(profile: options[:config].profile)
87
+ ProcessCredentials.new(process_provider) if process_provider
88
+ end
89
+ rescue Errors::NoSuchProfileError
90
+ nil
91
+ end
92
+
93
+ def env_credentials(_options)
94
+ key = %w[AWS_ACCESS_KEY_ID AMAZON_ACCESS_KEY_ID AWS_ACCESS_KEY]
95
+ secret = %w[AWS_SECRET_ACCESS_KEY AMAZON_SECRET_ACCESS_KEY AWS_SECRET_KEY]
96
+ token = %w[AWS_SESSION_TOKEN AMAZON_SESSION_TOKEN]
50
97
  Credentials.new(envar(key), envar(secret), envar(token))
51
98
  end
52
99
 
53
100
  def envar(keys)
54
101
  keys.each do |key|
55
- if ENV.key?(key)
56
- return ENV[key]
57
- end
102
+ return ENV[key] if ENV.key?(key)
58
103
  end
59
104
  nil
60
105
  end
61
106
 
107
+ def determine_profile_name(options)
108
+ (options[:config] && options[:config].profile) || ENV['AWS_PROFILE'] || ENV['AWS_DEFAULT_PROFILE'] || 'default'
109
+ end
110
+
62
111
  def shared_credentials(options)
63
- if options[:config]
64
- SharedCredentials.new(profile_name: options[:config].profile)
65
- else
66
- SharedCredentials.new(
67
- profile_name: ENV['AWS_PROFILE'].nil? ? 'default' : ENV['AWS_PROFILE'])
68
- end
112
+ profile_name = determine_profile_name(options)
113
+ SharedCredentials.new(profile_name: profile_name)
69
114
  rescue Errors::NoSuchProfileError
70
115
  nil
71
116
  end
72
117
 
73
118
  def process_credentials(options)
74
- profile_name = options[:config].profile if options[:config]
75
- profile_name ||= ENV['AWS_PROFILE'].nil? ? 'default' : ENV['AWS_PROFILE']
76
-
77
- config = Aws.shared_config
78
- if config.config_enabled? && process_provider = config.credentials_process(profile_name)
119
+ profile_name = determine_profile_name(options)
120
+ if Aws.shared_config.config_enabled? &&
121
+ (process_provider = Aws.shared_config.credential_process(profile: profile_name))
79
122
  ProcessCredentials.new(process_provider)
80
- else
81
- nil
123
+ end
124
+ rescue Errors::NoSuchProfileError
125
+ nil
126
+ end
127
+
128
+ def sso_credentials(options)
129
+ profile_name = determine_profile_name(options)
130
+ if Aws.shared_config.config_enabled?
131
+ Aws.shared_config.sso_credentials_from_config(profile: profile_name)
82
132
  end
83
133
  rescue Errors::NoSuchProfileError
84
134
  nil
@@ -86,33 +136,45 @@ module Aws
86
136
 
87
137
  def assume_role_credentials(options)
88
138
  if Aws.shared_config.config_enabled?
89
- profile, region = nil, nil
90
- if options[:config]
91
- profile = options[:config].profile
92
- region = options[:config].region
93
- assume_role_with_profile(options[:config].profile, options[:config].region)
94
- end
95
- assume_role_with_profile(profile, region)
96
- else
97
- nil
139
+ assume_role_with_profile(options, determine_profile_name(options))
140
+ end
141
+ end
142
+
143
+ def assume_role_web_identity_credentials(options)
144
+ region = options[:config].region if options[:config]
145
+ if (role_arn = ENV['AWS_ROLE_ARN']) && (token_file = ENV['AWS_WEB_IDENTITY_TOKEN_FILE'])
146
+ cfg = {
147
+ role_arn: role_arn,
148
+ web_identity_token_file: token_file,
149
+ role_session_name: ENV['AWS_ROLE_SESSION_NAME']
150
+ }
151
+ cfg[:region] = region if region
152
+ AssumeRoleWebIdentityCredentials.new(cfg)
153
+ elsif Aws.shared_config.config_enabled?
154
+ profile = options[:config].profile if options[:config]
155
+ Aws.shared_config.assume_role_web_identity_credentials_from_config(
156
+ profile: profile,
157
+ region: region
158
+ )
98
159
  end
99
160
  end
100
161
 
101
162
  def instance_profile_credentials(options)
102
- if ENV["AWS_CONTAINER_CREDENTIALS_RELATIVE_URI"]
163
+ profile_name = determine_profile_name(options)
164
+ if ENV['AWS_CONTAINER_CREDENTIALS_RELATIVE_URI']
103
165
  ECSCredentials.new(options)
104
166
  else
105
- InstanceProfileCredentials.new(options)
167
+ InstanceProfileCredentials.new(options.merge(profile: profile_name))
106
168
  end
107
169
  end
108
170
 
109
- def assume_role_with_profile(prof, region)
171
+ def assume_role_with_profile(options, profile_name)
172
+ region = (options[:config] && options[:config].region)
110
173
  Aws.shared_config.assume_role_credentials_from_config(
111
- profile: prof,
174
+ profile: profile_name,
112
175
  region: region,
113
176
  chain_config: @config
114
177
  )
115
178
  end
116
-
117
179
  end
118
180
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Aws
2
4
  class Credentials
3
5
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Aws
2
4
 
3
5
  # A utility module that provides a class method that wraps
@@ -35,33 +37,37 @@ module Aws
35
37
  # @api private
36
38
  module Deprecations
37
39
 
38
- # @param [Symbol] method_name The name of the deprecated method.
40
+ # @param [Symbol] method The name of the deprecated method.
39
41
  #
40
42
  # @option options [String] :message The warning message to issue
41
43
  # when the deprecated method is called.
42
44
  #
43
- # @option options [Symbol] :use The name of an use
44
- # method that should be used.
45
+ # @option options [String] :use The name of a method that should be used.
46
+ #
47
+ # @option options [String] :version The version that will remove the
48
+ # deprecated method.
45
49
  #
46
- def deprecated(method_name, options = {})
50
+ def deprecated(method, options = {})
47
51
 
48
52
  deprecation_msg = options[:message] || begin
49
- msg = "DEPRECATION WARNING: called deprecated method `#{method_name}' "
50
- msg << "of an #{self}"
51
- msg << ", use #{options[:use]} instead" if options[:use]
52
- msg
53
+ "#################### DEPRECATION WARNING ####################\n"\
54
+ "Called deprecated method `#{method}` of #{self}."\
55
+ "#{" Use `#{options[:use]}` instead.\n" if options[:use]}"\
56
+ "#{"Method `#{method}` will be removed in #{options[:version]}."\
57
+ if options[:version]}"\
58
+ "\n#############################################################"
53
59
  end
54
60
 
55
- alias_method(:"deprecated_#{method_name}", method_name)
61
+ alias_method(:"deprecated_#{method}", method)
56
62
 
57
63
  warned = false # we only want to issue this warning once
58
64
 
59
- define_method(method_name) do |*args,&block|
65
+ define_method(method) do |*args, &block|
60
66
  unless warned
61
67
  warned = true
62
68
  warn(deprecation_msg + "\n" + caller.join("\n"))
63
69
  end
64
- send("deprecated_#{method_name}", *args, &block)
70
+ send("deprecated_#{method}", *args, &block)
65
71
  end
66
72
  end
67
73
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'set'
2
4
 
3
5
  module Aws
@@ -0,0 +1,238 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'time'
4
+ require 'net/http'
5
+
6
+ module Aws
7
+ # A client that can query version 2 of the EC2 Instance Metadata
8
+ class EC2Metadata
9
+ # Path for PUT request for token
10
+ # @api private
11
+ METADATA_TOKEN_PATH = '/latest/api/token'.freeze
12
+
13
+ # Raised when the PUT request is not valid. This would be thrown if
14
+ # `token_ttl` is not an Integer.
15
+ # @api private
16
+ class TokenRetrievalError < RuntimeError; end
17
+
18
+ # Token has expired, and the request can be retried with a new token.
19
+ # @api private
20
+ class TokenExpiredError < RuntimeError; end
21
+
22
+ # The requested metadata path does not exist.
23
+ # @api private
24
+ class MetadataNotFoundError < RuntimeError; end
25
+
26
+ # The request is not allowed or IMDS is turned off.
27
+ # @api private
28
+ class RequestForbiddenError < RuntimeError; end
29
+
30
+ # Creates a client that can query version 2 of the EC2 Instance Metadata
31
+ # service (IMDS).
32
+ #
33
+ # @note Customers using containers may need to increase their hop limit
34
+ # to access IMDSv2.
35
+ # @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html#instance-metadata-transition-to-version-2
36
+ #
37
+ # @param [Hash] options
38
+ # @option options [Integer] :token_ttl (21600) The session token's TTL,
39
+ # defaulting to 6 hours.
40
+ # @option options [Integer] :retries (3) The number of retries for failed
41
+ # requests.
42
+ # @option options [String] :endpoint ('http://169.254.169.254') The IMDS
43
+ # endpoint. This option has precedence over the :endpoint_mode.
44
+ # @option options [String] :endpoint_mode ('IPv4') The endpoint mode for
45
+ # the instance metadata service. This is either 'IPv4'
46
+ # ('http://169.254.169.254') or 'IPv6' ('http://[fd00:ec2::254]').
47
+ # @option options [Integer] :port (80) The IMDS endpoint port.
48
+ # @option options [Integer] :http_open_timeout (1) The number of seconds to
49
+ # wait for the connection to open.
50
+ # @option options [Integer] :http_read_timeout (1) The number of seconds for
51
+ # one chunk of data to be read.
52
+ # @option options [IO] :http_debug_output An output stream for debugging. Do
53
+ # not use this in production.
54
+ # @option options [Integer,Proc] :backoff A backoff used for retryable
55
+ # requests. When given an Integer, it sleeps that amount. When given a
56
+ # Proc, it is called with the current number of failed retries.
57
+ def initialize(options = {})
58
+ @token_ttl = options[:token_ttl] || 21_600
59
+ @retries = options[:retries] || 3
60
+ @backoff = backoff(options[:backoff])
61
+
62
+ endpoint_mode = options[:endpoint_mode] || 'IPv4'
63
+ @endpoint = resolve_endpoint(options[:endpoint], endpoint_mode)
64
+ @port = options[:port] || 80
65
+
66
+ @http_open_timeout = options[:http_open_timeout] || 1
67
+ @http_read_timeout = options[:http_read_timeout] || 1
68
+ @http_debug_output = options[:http_debug_output]
69
+
70
+ @token = nil
71
+ @mutex = Mutex.new
72
+ end
73
+
74
+ # Fetches a given metadata category using a String path, and returns the
75
+ # result as a String. A path starts with the API version (usually
76
+ # "/latest/"). See the instance data categories for possible paths.
77
+ #
78
+ # @example Fetching the instance ID
79
+ #
80
+ # ec2_metadata = Aws::EC2Metadata.new
81
+ # ec2_metadata.get('/latest/meta-data/instance-id')
82
+ # => "i-023a25f10a73a0f79"
83
+ #
84
+ # @note This implementation always returns a String and will not parse any
85
+ # responses. Parsable responses may include JSON objects or directory
86
+ # listings, which are strings separated by line feeds (ASCII 10).
87
+ #
88
+ # @example Fetching and parsing JSON meta-data
89
+ #
90
+ # require 'json'
91
+ # data = ec2_metadata.get('/latest/dynamic/instance-identity/document')
92
+ # JSON.parse(data)
93
+ # => {"accountId"=>"012345678912", ... }
94
+ #
95
+ # @example Fetching and parsing directory listings
96
+ #
97
+ # listing = ec2_metadata.get('/latest/meta-data')
98
+ # listing.split(10.chr)
99
+ # => ["ami-id", "ami-launch-index", ...]
100
+ #
101
+ # @note Unlike other services, IMDS does not have a service API model. This
102
+ # means that we cannot confidently generate code with methods and
103
+ # response structures. This implementation ensures that new IMDS features
104
+ # are always supported by being deployed to the instance and does not
105
+ # require code changes.
106
+ #
107
+ # @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-categories.html
108
+ # @see https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html
109
+ # @param [String] path The full path to the metadata.
110
+ def get(path)
111
+ retry_errors(max_retries: @retries) do
112
+ @mutex.synchronize do
113
+ fetch_token unless @token && !@token.expired?
114
+ end
115
+
116
+ open_connection do |conn|
117
+ http_get(conn, path, @token.value)
118
+ end
119
+ end
120
+ end
121
+
122
+ private
123
+
124
+ def resolve_endpoint(endpoint, endpoint_mode)
125
+ return endpoint if endpoint
126
+
127
+ case endpoint_mode.downcase
128
+ when 'ipv4' then 'http://169.254.169.254'
129
+ when 'ipv6' then 'http://[fd00:ec2::254]'
130
+ else
131
+ raise ArgumentError,
132
+ ':endpoint_mode is not valid, expected IPv4 or IPv6, '\
133
+ "got: #{endpoint_mode}"
134
+ end
135
+ end
136
+
137
+ def fetch_token
138
+ open_connection do |conn|
139
+ created_time = Time.now
140
+ token_value, token_ttl = http_put(conn, @token_ttl)
141
+ @token = Token.new(value: token_value, ttl: token_ttl, created_time: created_time)
142
+ end
143
+ end
144
+
145
+ def http_get(connection, path, token)
146
+ headers = {
147
+ 'User-Agent' => "aws-sdk-ruby3/#{CORE_GEM_VERSION}",
148
+ 'x-aws-ec2-metadata-token' => token
149
+ }
150
+ request = Net::HTTP::Get.new(path, headers)
151
+ response = connection.request(request)
152
+
153
+ case response.code.to_i
154
+ when 200
155
+ response.body
156
+ when 401
157
+ raise TokenExpiredError
158
+ when 404
159
+ raise MetadataNotFoundError
160
+ end
161
+ end
162
+
163
+ def http_put(connection, ttl)
164
+ headers = {
165
+ 'User-Agent' => "aws-sdk-ruby3/#{CORE_GEM_VERSION}",
166
+ 'x-aws-ec2-metadata-token-ttl-seconds' => ttl.to_s
167
+ }
168
+ request = Net::HTTP::Put.new(METADATA_TOKEN_PATH, headers)
169
+ response = connection.request(request)
170
+
171
+ case response.code.to_i
172
+ when 200
173
+ [
174
+ response.body,
175
+ response.header['x-aws-ec2-metadata-token-ttl-seconds'].to_i
176
+ ]
177
+ when 400
178
+ raise TokenRetrievalError
179
+ when 403
180
+ raise RequestForbiddenError
181
+ end
182
+ end
183
+
184
+ def open_connection
185
+ uri = URI.parse(@endpoint)
186
+ http = Net::HTTP.new(uri.hostname || @endpoint, @port || uri.port)
187
+ http.open_timeout = @http_open_timeout
188
+ http.read_timeout = @http_read_timeout
189
+ http.set_debug_output(@http_debug_output) if @http_debug_output
190
+ http.start
191
+ yield(http).tap { http.finish }
192
+ end
193
+
194
+ def retry_errors(options = {}, &_block)
195
+ max_retries = options[:max_retries]
196
+ retries = 0
197
+ begin
198
+ yield
199
+ # These errors should not be retried.
200
+ rescue TokenRetrievalError, MetadataNotFoundError, RequestForbiddenError
201
+ raise
202
+ # StandardError is not ideal but it covers Net::HTTP errors.
203
+ # https://gist.github.com/tenderlove/245188
204
+ rescue StandardError, TokenExpiredError
205
+ raise unless retries < max_retries
206
+
207
+ @backoff.call(retries)
208
+ retries += 1
209
+ retry
210
+ end
211
+ end
212
+
213
+ def backoff(backoff)
214
+ case backoff
215
+ when Proc then backoff
216
+ when Numeric then ->(_) { Kernel.sleep(backoff) }
217
+ else ->(num_failures) { Kernel.sleep(1.2**num_failures) }
218
+ end
219
+ end
220
+
221
+ # @api private
222
+ class Token
223
+ def initialize(options = {})
224
+ @ttl = options[:ttl]
225
+ @value = options[:value]
226
+ @created_time = options[:created_time] || Time.now
227
+ end
228
+
229
+ # [String] Returns the token value.
230
+ attr_reader :value
231
+
232
+ # [Boolean] Returns true if the token expired.
233
+ def expired?
234
+ Time.now - @created_time > @ttl
235
+ end
236
+ end
237
+ end
238
+ end
@@ -1,4 +1,5 @@
1
- require 'json'
1
+ # frozen_string_literal: true
2
+
2
3
  require 'time'
3
4
  require 'net/http'
4
5
 
@@ -42,6 +43,10 @@ module Aws
42
43
  # @option options [IO] :http_debug_output (nil) HTTP wire
43
44
  # traces are sent to this object. You can specify something
44
45
  # like $stdout.
46
+ # @option options [Callable] before_refresh Proc called before
47
+ # credentials are refreshed. `before_refresh` is called
48
+ # with an instance of this object when
49
+ # AWS credentials are required and need to be refreshed.
45
50
  def initialize options = {}
46
51
  @retries = options[:retries] || 5
47
52
  @ip_address = options[:ip_address] || '169.254.170.2'
@@ -78,14 +83,18 @@ module Aws
78
83
  # Retry loading credentials up to 3 times is the instance metadata
79
84
  # service is responding but is returning invalid JSON documents
80
85
  # in response to the GET profile credentials call.
81
- retry_errors([JSON::ParserError, StandardError], max_retries: 3) do
82
- c = JSON.parse(get_credentials.to_s)
83
- @credentials = Credentials.new(
84
- c['AccessKeyId'],
85
- c['SecretAccessKey'],
86
- c['Token']
87
- )
88
- @expiration = c['Expiration'] ? Time.iso8601(c['Expiration']) : nil
86
+ begin
87
+ retry_errors([Aws::Json::ParseError, StandardError], max_retries: 3) do
88
+ c = Aws::Json.load(get_credentials.to_s)
89
+ @credentials = Credentials.new(
90
+ c['AccessKeyId'],
91
+ c['SecretAccessKey'],
92
+ c['Token']
93
+ )
94
+ @expiration = c['Expiration'] ? Time.iso8601(c['Expiration']) : nil
95
+ end
96
+ rescue Aws::Json::ParseError
97
+ raise Aws::Errors::MetadataParserError.new
89
98
  end
90
99
  end
91
100