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,16 +1,22 @@
1
- require 'json'
1
+ # frozen_string_literal: true
2
+
2
3
  require 'time'
3
4
  require 'net/http'
4
5
 
5
6
  module Aws
6
7
  class InstanceProfileCredentials
7
-
8
8
  include CredentialProvider
9
9
  include RefreshingCredentials
10
10
 
11
11
  # @api private
12
12
  class Non200Response < RuntimeError; end
13
13
 
14
+ # @api private
15
+ class TokenRetrivalError < RuntimeError; end
16
+
17
+ # @api private
18
+ class TokenExpiredError < RuntimeError; end
19
+
14
20
  # These are the errors we trap when attempting to talk to the
15
21
  # instance metadata service. Any of these imply the service
16
22
  # is not present, no responding or some other non-recoverable
@@ -23,16 +29,30 @@ module Aws
23
29
  Errno::ENETUNREACH,
24
30
  SocketError,
25
31
  Timeout::Error,
26
- Non200Response,
27
- ]
32
+ Non200Response
33
+ ].freeze
34
+
35
+ # Path base for GET request for profile and credentials
36
+ # @api private
37
+ METADATA_PATH_BASE = '/latest/meta-data/iam/security-credentials/'.freeze
38
+
39
+ # Path for PUT request for token
40
+ # @api private
41
+ METADATA_TOKEN_PATH = '/latest/api/token'.freeze
28
42
 
29
43
  # @param [Hash] options
30
- # @option options [Integer] :retries (5) Number of times to retry
44
+ # @option options [Integer] :retries (1) Number of times to retry
31
45
  # when retrieving credentials.
32
- # @option options [String] :ip_address ('169.254.169.254')
46
+ # @option options [String] :endpoint ('http://169.254.169.254') The IMDS
47
+ # endpoint. This option has precedence over the :endpoint_mode.
48
+ # @option options [String] :endpoint_mode ('IPv4') The endpoint mode for
49
+ # the instance metadata service. This is either 'IPv4' ('169.254.169.254')
50
+ # or 'IPv6' ('[fd00:ec2::254]').
51
+ # @option options [String] :ip_address ('169.254.169.254') Deprecated. Use
52
+ # :endpoint instead. The IP address for the endpoint.
33
53
  # @option options [Integer] :port (80)
34
- # @option options [Float] :http_open_timeout (5)
35
- # @option options [Float] :http_read_timeout (5)
54
+ # @option options [Float] :http_open_timeout (1)
55
+ # @option options [Float] :http_read_timeout (1)
36
56
  # @option options [Numeric, Proc] :delay By default, failures are retried
37
57
  # with exponential back-off, i.e. `sleep(1.2 ** num_failures)`. You can
38
58
  # pass a number of seconds to sleep between failed attempts, or
@@ -40,28 +60,67 @@ module Aws
40
60
  # @option options [IO] :http_debug_output (nil) HTTP wire
41
61
  # traces are sent to this object. You can specify something
42
62
  # like $stdout.
43
- def initialize options = {}
44
- @retries = options[:retries] || 5
45
- @ip_address = options[:ip_address] || '169.254.169.254'
63
+ # @option options [Integer] :token_ttl Time-to-Live in seconds for EC2
64
+ # Metadata Token used for fetching Metadata Profile Credentials, defaults
65
+ # to 21600 seconds
66
+ # @option options [Callable] before_refresh Proc called before
67
+ # credentials are refreshed. `before_refresh` is called
68
+ # with an instance of this object when
69
+ # AWS credentials are required and need to be refreshed.
70
+ def initialize(options = {})
71
+ @retries = options[:retries] || 1
72
+ endpoint_mode = resolve_endpoint_mode(options)
73
+ @endpoint = resolve_endpoint(options, endpoint_mode)
46
74
  @port = options[:port] || 80
47
- @http_open_timeout = options[:http_open_timeout] || 5
48
- @http_read_timeout = options[:http_read_timeout] || 5
75
+ @http_open_timeout = options[:http_open_timeout] || 1
76
+ @http_read_timeout = options[:http_read_timeout] || 1
49
77
  @http_debug_output = options[:http_debug_output]
50
78
  @backoff = backoff(options[:backoff])
79
+ @token_ttl = options[:token_ttl] || 21_600
80
+ @token = nil
51
81
  super
52
82
  end
53
83
 
54
- # @return [Integer] The number of times to retry failed attempts to
55
- # fetch credentials from the instance metadata service. Defaults to 0.
84
+ # @return [Integer] Number of times to retry when retrieving credentials
85
+ # from the instance metadata service. Defaults to 0 when resolving from
86
+ # the default credential chain ({Aws::CredentialProviderChain}).
56
87
  attr_reader :retries
57
88
 
58
89
  private
59
90
 
91
+ def resolve_endpoint_mode(options)
92
+ value = options[:endpoint_mode]
93
+ value ||= ENV['AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE']
94
+ value ||= Aws.shared_config.ec2_metadata_service_endpoint_mode(
95
+ profile: options[:profile]
96
+ )
97
+ value || 'IPv4'
98
+ end
99
+
100
+ def resolve_endpoint(options, endpoint_mode)
101
+ value = options[:endpoint] || options[:ip_address]
102
+ value ||= ENV['AWS_EC2_METADATA_SERVICE_ENDPOINT']
103
+ value ||= Aws.shared_config.ec2_metadata_service_endpoint(
104
+ profile: options[:profile]
105
+ )
106
+
107
+ return value if value
108
+
109
+ case endpoint_mode.downcase
110
+ when 'ipv4' then 'http://169.254.169.254'
111
+ when 'ipv6' then 'http://[fd00:ec2::254]'
112
+ else
113
+ raise ArgumentError,
114
+ ':endpoint_mode is not valid, expected IPv4 or IPv6, '\
115
+ "got: #{endpoint_mode}"
116
+ end
117
+ end
118
+
60
119
  def backoff(backoff)
61
120
  case backoff
62
121
  when Proc then backoff
63
- when Numeric then lambda { |_| sleep(backoff) }
64
- else lambda { |num_failures| Kernel.sleep(1.2 ** num_failures) }
122
+ when Numeric then ->(_) { sleep(backoff) }
123
+ else ->(num_failures) { Kernel.sleep(1.2**num_failures) }
65
124
  end
66
125
  end
67
126
 
@@ -69,14 +128,18 @@ module Aws
69
128
  # Retry loading credentials up to 3 times is the instance metadata
70
129
  # service is responding but is returning invalid JSON documents
71
130
  # in response to the GET profile credentials call.
72
- retry_errors([JSON::ParserError, StandardError], max_retries: 3) do
73
- c = JSON.parse(get_credentials.to_s)
74
- @credentials = Credentials.new(
75
- c['AccessKeyId'],
76
- c['SecretAccessKey'],
77
- c['Token']
78
- )
79
- @expiration = c['Expiration'] ? Time.iso8601(c['Expiration']) : nil
131
+ begin
132
+ retry_errors([Aws::Json::ParseError, StandardError], max_retries: 3) do
133
+ c = Aws::Json.load(get_credentials.to_s)
134
+ @credentials = Credentials.new(
135
+ c['AccessKeyId'],
136
+ c['SecretAccessKey'],
137
+ c['Token']
138
+ )
139
+ @expiration = c['Expiration'] ? Time.iso8601(c['Expiration']) : nil
140
+ end
141
+ rescue Aws::Json::ParseError
142
+ raise Aws::Errors::MetadataParserError
80
143
  end
81
144
  end
82
145
 
@@ -89,9 +152,36 @@ module Aws
89
152
  begin
90
153
  retry_errors(NETWORK_ERRORS, max_retries: @retries) do
91
154
  open_connection do |conn|
92
- path = '/latest/meta-data/iam/security-credentials/'
93
- profile_name = http_get(conn, path).lines.first.strip
94
- http_get(conn, path + profile_name)
155
+ # attempt to fetch token to start secure flow first
156
+ # and rescue to failover
157
+ begin
158
+ retry_errors(NETWORK_ERRORS, max_retries: @retries) do
159
+ unless token_set?
160
+ created_time = Time.now
161
+ token_value, ttl = http_put(
162
+ conn, METADATA_TOKEN_PATH, @token_ttl
163
+ )
164
+ @token = Token.new(token_value, ttl, created_time) if token_value && ttl
165
+ end
166
+ end
167
+ rescue *NETWORK_ERRORS
168
+ # token attempt failed, reset token
169
+ # fallback to non-token mode
170
+ @token = nil
171
+ end
172
+
173
+ token = @token.value if token_set?
174
+
175
+ begin
176
+ metadata = http_get(conn, METADATA_PATH_BASE, token)
177
+ profile_name = metadata.lines.first.strip
178
+ http_get(conn, METADATA_PATH_BASE + profile_name, token)
179
+ rescue TokenExpiredError
180
+ # Token has expired, reset it
181
+ # The next retry should fetch it
182
+ @token = nil
183
+ raise Non200Response
184
+ end
95
185
  end
96
186
  end
97
187
  rescue
@@ -100,13 +190,17 @@ module Aws
100
190
  end
101
191
  end
102
192
 
193
+ def token_set?
194
+ @token && !@token.expired?
195
+ end
196
+
103
197
  def _metadata_disabled?
104
- flag = ENV["AWS_EC2_METADATA_DISABLED"]
105
- !flag.nil? && flag.downcase == "true"
198
+ ENV.fetch('AWS_EC2_METADATA_DISABLED', 'false').downcase == 'true'
106
199
  end
107
200
 
108
201
  def open_connection
109
- http = Net::HTTP.new(@ip_address, @port, nil)
202
+ uri = URI.parse(@endpoint)
203
+ http = Net::HTTP.new(uri.hostname || @endpoint, @port || uri.port)
110
204
  http.open_timeout = @http_open_timeout
111
205
  http.read_timeout = @http_read_timeout
112
206
  http.set_debug_output(@http_debug_output) if @http_debug_output
@@ -114,30 +208,73 @@ module Aws
114
208
  yield(http).tap { http.finish }
115
209
  end
116
210
 
117
- def http_get(connection, path)
118
- response = connection.request(Net::HTTP::Get.new(path, {"User-Agent" => "aws-sdk-ruby3/#{CORE_GEM_VERSION}"}))
119
- if response.code.to_i == 200
211
+ # GET request fetch profile and credentials
212
+ def http_get(connection, path, token = nil)
213
+ headers = { 'User-Agent' => "aws-sdk-ruby3/#{CORE_GEM_VERSION}" }
214
+ headers['x-aws-ec2-metadata-token'] = token if token
215
+ response = connection.request(Net::HTTP::Get.new(path, headers))
216
+
217
+ case response.code.to_i
218
+ when 200
120
219
  response.body
220
+ when 401
221
+ raise TokenExpiredError
121
222
  else
122
223
  raise Non200Response
123
224
  end
124
225
  end
125
226
 
126
- def retry_errors(error_classes, options = {}, &block)
227
+ # PUT request fetch token with ttl
228
+ def http_put(connection, path, ttl)
229
+ headers = {
230
+ 'User-Agent' => "aws-sdk-ruby3/#{CORE_GEM_VERSION}",
231
+ 'x-aws-ec2-metadata-token-ttl-seconds' => ttl.to_s
232
+ }
233
+ response = connection.request(Net::HTTP::Put.new(path, headers))
234
+ case response.code.to_i
235
+ when 200
236
+ [
237
+ response.body,
238
+ response.header['x-aws-ec2-metadata-token-ttl-seconds'].to_i
239
+ ]
240
+ when 400
241
+ raise TokenRetrivalError
242
+ when 401
243
+ raise TokenExpiredError
244
+ else
245
+ raise Non200Response
246
+ end
247
+ end
248
+
249
+ def retry_errors(error_classes, options = {}, &_block)
127
250
  max_retries = options[:max_retries]
128
251
  retries = 0
129
252
  begin
130
253
  yield
131
254
  rescue *error_classes
132
- if retries < max_retries
133
- @backoff.call(retries)
134
- retries += 1
135
- retry
136
- else
137
- raise
138
- end
255
+ raise unless retries < max_retries
256
+
257
+ @backoff.call(retries)
258
+ retries += 1
259
+ retry
139
260
  end
140
261
  end
141
262
 
263
+ # @api private
264
+ # Token used to fetch IMDS profile and credentials
265
+ class Token
266
+ def initialize(value, ttl, created_time = Time.now)
267
+ @ttl = ttl
268
+ @value = value
269
+ @created_time = created_time
270
+ end
271
+
272
+ # [String] token value
273
+ attr_reader :value
274
+
275
+ def expired?
276
+ Time.now - @created_time > @ttl
277
+ end
278
+ end
142
279
  end
143
280
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'base64'
2
4
 
3
5
  module Aws
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Aws
2
4
  module Json
3
5
  class ErrorHandler < Xml::ErrorHandler
@@ -17,9 +19,10 @@ module Aws
17
19
  json = Json.load(body)
18
20
  code = error_code(json, context)
19
21
  message = error_message(code, json)
20
- [code, message]
22
+ data = parse_error_data(context, code)
23
+ [code, message, data]
21
24
  rescue Json::ParseError
22
- [http_status_error_code(context), '']
25
+ [http_status_error_code(context), '', EmptyStructure.new]
23
26
  end
24
27
 
25
28
  def error_code(json, context)
@@ -41,6 +44,22 @@ module Aws
41
44
  end
42
45
  end
43
46
 
47
+ def parse_error_data(context, code)
48
+ data = EmptyStructure.new
49
+ if error_rules = context.operation.errors
50
+ error_rules.each do |rule|
51
+ # match modeled shape name with the type(code) only
52
+ # some type(code) might contains invalid characters
53
+ # such as ':' (efs) etc
54
+ match = rule.shape.name == code.gsub(/[^^a-zA-Z0-9]/, '')
55
+ if match && rule.shape.members.any?
56
+ data = Parser.new(rule).parse(context.http_response.body_contents)
57
+ end
58
+ end
59
+ end
60
+ data
61
+ end
62
+
44
63
  end
45
64
  end
46
65
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Aws
2
4
  module Json
3
5
  class Handler < Seahorse::Client::Handler
@@ -40,7 +42,25 @@ module Aws
40
42
  Json.load(context.http_response.body_contents)
41
43
  elsif rules = context.operation.output
42
44
  json = context.http_response.body_contents
43
- Parser.new(rules).parse(json == '' ? '{}' : json)
45
+ if json.is_a?(Array)
46
+ # an array of emitted events
47
+ if json[0].respond_to?(:response)
48
+ # initial response exists
49
+ # it must be the first event arrived
50
+ resp_struct = json.shift.response
51
+ else
52
+ resp_struct = context.operation.output.shape.struct_class.new
53
+ end
54
+
55
+ rules.shape.members.each do |name, ref|
56
+ if ref.eventstream
57
+ resp_struct.send("#{name}=", json.to_enum)
58
+ end
59
+ end
60
+ resp_struct
61
+ else
62
+ Parser.new(rules).parse(json == '' ? '{}' : json)
63
+ end
44
64
  else
45
65
  EmptyStructure.new
46
66
  end
@@ -1,15 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Aws
2
4
  module Json
3
- class OjEngine
4
-
5
- def self.load(json)
6
- Oj.load(json)
7
- end
5
+ module JSONEngine
6
+ class << self
7
+ def load(json)
8
+ JSON.parse(json)
9
+ rescue JSON::ParserError => e
10
+ raise ParseError.new(e)
11
+ end
8
12
 
9
- def self.dump(value)
10
- Oj.dump(value)
13
+ def dump(value)
14
+ JSON.dump(value)
15
+ end
11
16
  end
12
-
13
17
  end
14
18
  end
15
19
  end
@@ -1,15 +1,44 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Aws
2
4
  module Json
3
- class JSONEngine
5
+ module OjEngine
6
+ # @api private
7
+ LOAD_OPTIONS = { mode: :compat, symbol_keys: false, empty_string: false }.freeze
4
8
 
5
- def self.load(json)
6
- JSON.load(json)
7
- end
9
+ # @api private
10
+ DUMP_OPTIONS = { mode: :compat }.freeze
11
+
12
+ class << self
13
+ def load(json)
14
+ Oj.load(json, LOAD_OPTIONS)
15
+ rescue *PARSE_ERRORS => e
16
+ raise ParseError.new(e)
17
+ end
18
+
19
+ def dump(value)
20
+ Oj.dump(value, DUMP_OPTIONS)
21
+ end
22
+
23
+ private
24
+
25
+ # Oj before 1.4.0 does not define Oj::ParseError and instead raises
26
+ # SyntaxError on failure
27
+ def detect_oj_parse_errors
28
+ require 'oj'
8
29
 
9
- def self.dump(value)
10
- JSON.dump(value)
30
+ if Oj.const_defined?(:ParseError)
31
+ [Oj::ParseError, EncodingError, JSON::ParserError]
32
+ else
33
+ [SyntaxError]
34
+ end
35
+ rescue LoadError
36
+ nil
37
+ end
11
38
  end
12
39
 
40
+ # @api private
41
+ PARSE_ERRORS = detect_oj_parse_errors
13
42
  end
14
43
  end
15
44
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'base64'
2
4
  require 'time'
3
5
 
@@ -26,8 +28,16 @@ module Aws
26
28
  member_name, member_ref = shape.member_by_location_name(key)
27
29
  if member_ref
28
30
  target[member_name] = parse_ref(member_ref, value)
31
+ elsif shape.union
32
+ target[:unknown] = { 'name' => key, 'value' => value }
29
33
  end
30
34
  end
35
+ if shape.union
36
+ # convert to subclass
37
+ member_subclass = shape.member_subclass(target.member).new
38
+ member_subclass[target.member] = target.value
39
+ target = member_subclass
40
+ end
31
41
  target
32
42
  end
33
43
 
@@ -1,66 +1,49 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
  require_relative 'json/builder'
3
5
  require_relative 'json/error_handler'
4
6
  require_relative 'json/handler'
5
7
  require_relative 'json/parser'
8
+ require_relative 'json/json_engine'
9
+ require_relative 'json/oj_engine'
6
10
 
7
11
  module Aws
8
12
  # @api private
9
13
  module Json
10
-
11
14
  class ParseError < StandardError
12
-
13
15
  def initialize(error)
14
16
  @error = error
15
17
  super(error.message)
16
18
  end
17
19
 
18
20
  attr_reader :error
19
-
20
21
  end
21
22
 
22
23
  class << self
23
-
24
24
  def load(json)
25
- ENGINE.load(json, *ENGINE_LOAD_OPTIONS)
26
- rescue ENGINE_ERROR => e
27
- raise ParseError.new(e)
25
+ ENGINE.load(json)
28
26
  end
29
27
 
30
28
  def load_file(path)
31
- self.load(File.open(path, 'r', encoding: 'UTF-8') { |f| f.read })
29
+ load(File.open(path, 'r', encoding: 'UTF-8', &:read))
32
30
  end
33
31
 
34
32
  def dump(value)
35
- ENGINE.dump(value, *ENGINE_DUMP_OPTIONS)
33
+ ENGINE.dump(value)
36
34
  end
37
35
 
38
36
  private
39
37
 
40
- def oj_engine
38
+ def select_engine
41
39
  require 'oj'
42
- [Oj, [{mode: :compat, symbol_keys: false}], [{ mode: :compat }], oj_parse_error]
40
+ OjEngine
43
41
  rescue LoadError
44
- false
42
+ JSONEngine
45
43
  end
46
-
47
- def json_engine
48
- [JSON, [], [], JSON::ParserError]
49
- end
50
-
51
- def oj_parse_error
52
- if Oj.const_defined?('ParseError')
53
- Oj::ParseError
54
- else
55
- SyntaxError
56
- end
57
- end
58
-
59
44
  end
60
45
 
61
46
  # @api private
62
- ENGINE, ENGINE_LOAD_OPTIONS, ENGINE_DUMP_OPTIONS, ENGINE_ERROR =
63
- oj_engine || json_engine
64
-
47
+ ENGINE = select_engine
65
48
  end
66
49
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'pathname'
2
4
 
3
5
  module Aws
@@ -83,6 +85,9 @@ module Aws
83
85
  # The default list of filtered parameters is documented on the
84
86
  # {ParamFilter} class.
85
87
  #
88
+ # @option options [Boolean] :filter_sensitive_params (true) Set to false
89
+ # to disable the sensitive parameter filtering when logging
90
+ # `:request_params`.
86
91
  def initialize(pattern, options = {})
87
92
  @pattern = pattern
88
93
  @param_formatter = ParamFormatter.new(options)
@@ -92,12 +97,12 @@ module Aws
92
97
  # @return [String]
93
98
  attr_reader :pattern
94
99
 
95
- # Given a resopnse, this will format a log message and return it as a
100
+ # Given a response, this will format a log message and return it as a
96
101
  # string according to {#pattern}.
97
102
  # @param [Seahorse::Client::Response] response
98
103
  # @return [String]
99
104
  def format(response)
100
- pattern.gsub(/:(\w+)/) {|sym| send("_#{sym[1..-1]}", response) }
105
+ pattern.gsub(/:(\w+)/) { |sym| send("_#{sym[1..-1]}", response) }
101
106
  end
102
107
 
103
108
  # @api private
@@ -121,7 +126,8 @@ module Aws
121
126
 
122
127
  def _request_params(response)
123
128
  params = response.context.params
124
- @param_formatter.summarize(@param_filter.filter(params))
129
+ type = response.context.operation.input.shape.struct_class
130
+ @param_formatter.summarize(@param_filter.filter(params, type))
125
131
  end
126
132
 
127
133
  def _time(response)
@@ -171,7 +177,13 @@ module Aws
171
177
  end
172
178
 
173
179
  def _http_response_body(response)
174
- @param_formatter.summarize(response.context.http_response.body_contents)
180
+ if response.context.http_response.body.respond_to?(:rewind)
181
+ @param_formatter.summarize(
182
+ response.context.http_response.body_contents
183
+ )
184
+ else
185
+ ''
186
+ end
175
187
  end
176
188
 
177
189
  def _error_class(response)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Seahorse
2
4
  module Client
3
5
  module Logging