aws-sdk-core 3.152.0 → 3.234.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (213) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +942 -1
  3. data/VERSION +1 -1
  4. data/lib/aws-defaults/default_configuration.rb +5 -6
  5. data/lib/aws-defaults.rb +4 -1
  6. data/lib/aws-sdk-core/arn.rb +14 -3
  7. data/lib/aws-sdk-core/assume_role_credentials.rb +21 -13
  8. data/lib/aws-sdk-core/assume_role_web_identity_credentials.rb +16 -9
  9. data/lib/aws-sdk-core/binary/decode_handler.rb +3 -9
  10. data/lib/aws-sdk-core/binary/encode_handler.rb +13 -2
  11. data/lib/aws-sdk-core/binary/event_builder.rb +34 -37
  12. data/lib/aws-sdk-core/binary/event_stream_decoder.rb +1 -0
  13. data/lib/aws-sdk-core/binary/event_stream_encoder.rb +4 -3
  14. data/lib/aws-sdk-core/cbor/decoder.rb +308 -0
  15. data/lib/aws-sdk-core/cbor/encoder.rb +243 -0
  16. data/lib/aws-sdk-core/cbor.rb +53 -0
  17. data/lib/aws-sdk-core/client_side_monitoring.rb +9 -0
  18. data/lib/aws-sdk-core/client_stubs.rb +33 -55
  19. data/lib/aws-sdk-core/credential_provider.rb +8 -1
  20. data/lib/aws-sdk-core/credential_provider_chain.rb +81 -29
  21. data/lib/aws-sdk-core/credentials.rb +19 -6
  22. data/lib/aws-sdk-core/ec2_metadata.rb +1 -1
  23. data/lib/aws-sdk-core/ecs_credentials.rb +186 -60
  24. data/lib/aws-sdk-core/endpoints/condition.rb +41 -0
  25. data/lib/aws-sdk-core/endpoints/endpoint.rb +19 -0
  26. data/lib/aws-sdk-core/endpoints/endpoint_rule.rb +75 -0
  27. data/lib/aws-sdk-core/endpoints/error_rule.rb +42 -0
  28. data/lib/aws-sdk-core/endpoints/function.rb +80 -0
  29. data/lib/aws-sdk-core/endpoints/matchers.rb +129 -0
  30. data/lib/aws-sdk-core/endpoints/reference.rb +31 -0
  31. data/lib/aws-sdk-core/endpoints/rule.rb +25 -0
  32. data/lib/aws-sdk-core/endpoints/rule_set.rb +52 -0
  33. data/lib/aws-sdk-core/endpoints/rules_provider.rb +37 -0
  34. data/lib/aws-sdk-core/endpoints/templater.rb +58 -0
  35. data/lib/aws-sdk-core/endpoints/tree_rule.rb +45 -0
  36. data/lib/aws-sdk-core/endpoints/url.rb +60 -0
  37. data/lib/aws-sdk-core/endpoints.rb +158 -0
  38. data/lib/aws-sdk-core/error_handler.rb +46 -0
  39. data/lib/aws-sdk-core/errors.rb +14 -5
  40. data/lib/aws-sdk-core/event_emitter.rb +1 -17
  41. data/lib/aws-sdk-core/ini_parser.rb +7 -0
  42. data/lib/aws-sdk-core/instance_profile_credentials.rb +168 -155
  43. data/lib/aws-sdk-core/json/builder.rb +8 -1
  44. data/lib/aws-sdk-core/json/error_handler.rb +46 -11
  45. data/lib/aws-sdk-core/json/handler.rb +13 -6
  46. data/lib/aws-sdk-core/json/json_engine.rb +3 -1
  47. data/lib/aws-sdk-core/json/oj_engine.rb +7 -1
  48. data/lib/aws-sdk-core/json/parser.rb +33 -3
  49. data/lib/aws-sdk-core/json.rb +43 -14
  50. data/lib/aws-sdk-core/log/formatter.rb +6 -0
  51. data/lib/aws-sdk-core/log/param_filter.rb +2 -2
  52. data/lib/aws-sdk-core/log/param_formatter.rb +7 -3
  53. data/lib/aws-sdk-core/log.rb +10 -0
  54. data/lib/aws-sdk-core/lru_cache.rb +75 -0
  55. data/lib/aws-sdk-core/pageable_response.rb +3 -1
  56. data/lib/aws-sdk-core/param_validator.rb +9 -4
  57. data/lib/aws-sdk-core/plugins/bearer_authorization.rb +2 -0
  58. data/lib/aws-sdk-core/plugins/checksum_algorithm.rb +348 -169
  59. data/lib/aws-sdk-core/plugins/client_metrics_plugin.rb +1 -1
  60. data/lib/aws-sdk-core/plugins/client_metrics_send_plugin.rb +14 -2
  61. data/lib/aws-sdk-core/plugins/credentials_configuration.rb +84 -38
  62. data/lib/aws-sdk-core/plugins/endpoint_discovery.rb +6 -2
  63. data/lib/aws-sdk-core/plugins/endpoint_pattern.rb +40 -32
  64. data/lib/aws-sdk-core/plugins/global_configuration.rb +8 -9
  65. data/lib/aws-sdk-core/plugins/http_checksum.rb +3 -8
  66. data/lib/aws-sdk-core/plugins/invocation_id.rb +1 -11
  67. data/lib/aws-sdk-core/plugins/logging.rb +2 -0
  68. data/lib/aws-sdk-core/plugins/protocols/api_gateway.rb +3 -1
  69. data/lib/aws-sdk-core/plugins/protocols/ec2.rb +2 -24
  70. data/lib/aws-sdk-core/plugins/protocols/json_rpc.rb +6 -8
  71. data/lib/aws-sdk-core/plugins/protocols/query.rb +4 -2
  72. data/lib/aws-sdk-core/plugins/protocols/rest_json.rb +3 -15
  73. data/lib/aws-sdk-core/plugins/protocols/rest_xml.rb +3 -0
  74. data/lib/aws-sdk-core/plugins/protocols/rpc_v2.rb +17 -0
  75. data/lib/aws-sdk-core/plugins/regional_endpoint.rb +164 -34
  76. data/lib/aws-sdk-core/plugins/request_compression.rb +226 -0
  77. data/lib/aws-sdk-core/plugins/retries/error_inspector.rb +2 -1
  78. data/lib/aws-sdk-core/plugins/retry_errors.rb +12 -3
  79. data/lib/aws-sdk-core/plugins/sign.rb +222 -0
  80. data/lib/aws-sdk-core/plugins/signature_v2.rb +2 -0
  81. data/lib/aws-sdk-core/plugins/signature_v4.rb +2 -0
  82. data/lib/aws-sdk-core/plugins/stub_responses.rb +59 -9
  83. data/lib/aws-sdk-core/plugins/telemetry.rb +75 -0
  84. data/lib/aws-sdk-core/plugins/transfer_encoding.rb +16 -9
  85. data/lib/aws-sdk-core/plugins/user_agent.rb +192 -14
  86. data/lib/aws-sdk-core/plugins.rb +39 -0
  87. data/lib/aws-sdk-core/process_credentials.rb +48 -29
  88. data/lib/aws-sdk-core/query/ec2_handler.rb +27 -0
  89. data/lib/aws-sdk-core/query/ec2_param_builder.rb +5 -7
  90. data/lib/aws-sdk-core/query/handler.rb +4 -4
  91. data/lib/aws-sdk-core/query/param_builder.rb +2 -2
  92. data/lib/aws-sdk-core/query.rb +2 -1
  93. data/lib/aws-sdk-core/refreshing_credentials.rb +20 -23
  94. data/lib/aws-sdk-core/resources.rb +8 -0
  95. data/lib/aws-sdk-core/rest/content_type_handler.rb +60 -0
  96. data/lib/aws-sdk-core/rest/handler.rb +3 -4
  97. data/lib/aws-sdk-core/rest/request/body.rb +32 -5
  98. data/lib/aws-sdk-core/rest/request/endpoint.rb +24 -4
  99. data/lib/aws-sdk-core/rest/request/headers.rb +14 -10
  100. data/lib/aws-sdk-core/rest/request/querystring_builder.rb +62 -36
  101. data/lib/aws-sdk-core/rest/response/body.rb +15 -1
  102. data/lib/aws-sdk-core/rest/response/header_list_parser.rb +79 -0
  103. data/lib/aws-sdk-core/rest/response/headers.rb +8 -3
  104. data/lib/aws-sdk-core/rest.rb +1 -0
  105. data/lib/aws-sdk-core/rpc_v2/builder.rb +62 -0
  106. data/lib/aws-sdk-core/rpc_v2/cbor_engine.rb +18 -0
  107. data/lib/aws-sdk-core/rpc_v2/content_type_handler.rb +47 -0
  108. data/lib/aws-sdk-core/rpc_v2/error_handler.rb +95 -0
  109. data/lib/aws-sdk-core/rpc_v2/handler.rb +79 -0
  110. data/lib/aws-sdk-core/rpc_v2/parser.rb +98 -0
  111. data/lib/aws-sdk-core/rpc_v2.rb +69 -0
  112. data/lib/aws-sdk-core/shared_config.rb +160 -36
  113. data/lib/aws-sdk-core/shared_credentials.rb +1 -7
  114. data/lib/aws-sdk-core/sso_credentials.rb +84 -46
  115. data/lib/aws-sdk-core/sso_token_provider.rb +3 -2
  116. data/lib/aws-sdk-core/static_token_provider.rb +1 -2
  117. data/lib/aws-sdk-core/stubbing/protocols/ec2.rb +12 -11
  118. data/lib/aws-sdk-core/stubbing/protocols/json.rb +11 -10
  119. data/lib/aws-sdk-core/stubbing/protocols/query.rb +7 -6
  120. data/lib/aws-sdk-core/stubbing/protocols/rest.rb +2 -1
  121. data/lib/aws-sdk-core/stubbing/protocols/rest_json.rb +9 -8
  122. data/lib/aws-sdk-core/stubbing/protocols/rest_xml.rb +6 -5
  123. data/lib/aws-sdk-core/stubbing/protocols/rpc_v2.rb +39 -0
  124. data/lib/aws-sdk-core/stubbing/stub_data.rb +11 -0
  125. data/lib/aws-sdk-core/stubbing.rb +22 -0
  126. data/lib/aws-sdk-core/telemetry/base.rb +177 -0
  127. data/lib/aws-sdk-core/telemetry/no_op.rb +70 -0
  128. data/lib/aws-sdk-core/telemetry/otel.rb +235 -0
  129. data/lib/aws-sdk-core/telemetry/span_kind.rb +22 -0
  130. data/lib/aws-sdk-core/telemetry/span_status.rb +59 -0
  131. data/lib/aws-sdk-core/telemetry.rb +78 -0
  132. data/lib/aws-sdk-core/token.rb +3 -3
  133. data/lib/aws-sdk-core/token_provider.rb +4 -0
  134. data/lib/aws-sdk-core/token_provider_chain.rb +2 -6
  135. data/lib/aws-sdk-core/util.rb +41 -1
  136. data/lib/aws-sdk-core/waiters/poller.rb +12 -5
  137. data/lib/aws-sdk-core/xml/builder.rb +17 -9
  138. data/lib/aws-sdk-core/xml/error_handler.rb +35 -43
  139. data/lib/aws-sdk-core/xml/parser/frame.rb +4 -20
  140. data/lib/aws-sdk-core/xml/parser/{engines/oga.rb → oga_engine.rb} +2 -0
  141. data/lib/aws-sdk-core/xml/parser/stack.rb +2 -0
  142. data/lib/aws-sdk-core/xml/parser.rb +2 -6
  143. data/lib/aws-sdk-core.rb +82 -103
  144. data/lib/aws-sdk-sso/client.rb +219 -89
  145. data/lib/aws-sdk-sso/client_api.rb +7 -0
  146. data/lib/aws-sdk-sso/endpoint_parameters.rb +69 -0
  147. data/lib/aws-sdk-sso/endpoint_provider.rb +53 -0
  148. data/lib/aws-sdk-sso/endpoints.rb +20 -0
  149. data/lib/aws-sdk-sso/plugins/endpoints.rb +77 -0
  150. data/lib/aws-sdk-sso/types.rb +1 -35
  151. data/lib/aws-sdk-sso.rb +15 -7
  152. data/lib/aws-sdk-ssooidc/client.rb +650 -118
  153. data/lib/aws-sdk-ssooidc/client_api.rb +94 -1
  154. data/lib/aws-sdk-ssooidc/endpoint_parameters.rb +69 -0
  155. data/lib/aws-sdk-ssooidc/endpoint_provider.rb +53 -0
  156. data/lib/aws-sdk-ssooidc/endpoints.rb +20 -0
  157. data/lib/aws-sdk-ssooidc/errors.rb +62 -0
  158. data/lib/aws-sdk-ssooidc/plugins/endpoints.rb +77 -0
  159. data/lib/aws-sdk-ssooidc/types.rb +437 -67
  160. data/lib/aws-sdk-ssooidc.rb +15 -7
  161. data/lib/aws-sdk-sts/client.rb +670 -368
  162. data/lib/aws-sdk-sts/client_api.rb +48 -9
  163. data/lib/aws-sdk-sts/customizations.rb +5 -2
  164. data/lib/aws-sdk-sts/endpoint_parameters.rb +79 -0
  165. data/lib/aws-sdk-sts/endpoint_provider.rb +107 -0
  166. data/lib/aws-sdk-sts/endpoints.rb +20 -0
  167. data/lib/aws-sdk-sts/errors.rb +15 -0
  168. data/lib/aws-sdk-sts/plugins/endpoints.rb +77 -0
  169. data/lib/aws-sdk-sts/presigner.rb +12 -18
  170. data/lib/aws-sdk-sts/types.rb +296 -222
  171. data/lib/aws-sdk-sts.rb +15 -7
  172. data/lib/seahorse/client/async_base.rb +4 -6
  173. data/lib/seahorse/client/async_response.rb +19 -0
  174. data/lib/seahorse/client/base.rb +18 -21
  175. data/lib/seahorse/client/configuration.rb +1 -5
  176. data/lib/seahorse/client/h2/connection.rb +27 -36
  177. data/lib/seahorse/client/h2/handler.rb +14 -3
  178. data/lib/seahorse/client/handler.rb +1 -1
  179. data/lib/seahorse/client/http/response.rb +1 -1
  180. data/lib/seahorse/client/net_http/connection_pool.rb +15 -12
  181. data/lib/seahorse/client/net_http/handler.rb +21 -9
  182. data/lib/seahorse/client/net_http/patches.rb +1 -4
  183. data/lib/seahorse/client/networking_error.rb +1 -1
  184. data/lib/seahorse/client/plugin.rb +9 -0
  185. data/lib/seahorse/client/plugins/endpoint.rb +0 -1
  186. data/lib/seahorse/client/plugins/h2.rb +4 -4
  187. data/lib/seahorse/client/plugins/net_http.rb +57 -16
  188. data/lib/seahorse/client/plugins/request_callback.rb +40 -9
  189. data/lib/seahorse/client/request_context.rb +9 -2
  190. data/lib/seahorse/client/response.rb +8 -0
  191. data/lib/seahorse/model/operation.rb +3 -0
  192. data/lib/seahorse/model/shapes.rb +2 -2
  193. data/lib/seahorse/util.rb +6 -1
  194. data/sig/aws-sdk-core/async_client_stubs.rbs +21 -0
  195. data/sig/aws-sdk-core/client_stubs.rbs +10 -0
  196. data/sig/aws-sdk-core/errors.rbs +22 -0
  197. data/sig/aws-sdk-core/resources/collection.rbs +21 -0
  198. data/sig/aws-sdk-core/structure.rbs +4 -0
  199. data/sig/aws-sdk-core/telemetry/base.rbs +46 -0
  200. data/sig/aws-sdk-core/telemetry/otel.rbs +22 -0
  201. data/sig/aws-sdk-core/telemetry/span_kind.rbs +15 -0
  202. data/sig/aws-sdk-core/telemetry/span_status.rbs +24 -0
  203. data/sig/aws-sdk-core/waiters/errors.rbs +20 -0
  204. data/sig/aws-sdk-core.rbs +7 -0
  205. data/sig/seahorse/client/async_base.rbs +18 -0
  206. data/sig/seahorse/client/base.rbs +25 -0
  207. data/sig/seahorse/client/handler_builder.rbs +16 -0
  208. data/sig/seahorse/client/response.rbs +61 -0
  209. metadata +133 -23
  210. /data/lib/aws-sdk-core/xml/parser/{engines/libxml.rb → libxml_engine.rb} +0 -0
  211. /data/lib/aws-sdk-core/xml/parser/{engines/nokogiri.rb → nokogiri_engine.rb} +0 -0
  212. /data/lib/aws-sdk-core/xml/parser/{engines/ox.rb → ox_engine.rb} +0 -0
  213. /data/lib/aws-sdk-core/xml/parser/{engines/rexml.rb → rexml_engine.rb} +0 -0
@@ -12,7 +12,7 @@ module Aws
12
12
  class ServiceError < RuntimeError
13
13
 
14
14
  # @param [Seahorse::Client::RequestContext] context
15
- # @param [String] message
15
+ # @param [String, nil] message
16
16
  # @param [Aws::Structure] data
17
17
  def initialize(context, message, data = Aws::EmptyStructure.new)
18
18
  @code = self.class.code
@@ -30,11 +30,11 @@ module Aws
30
30
  attr_reader :context
31
31
 
32
32
  # @return [Aws::Structure]
33
- attr_reader :data
33
+ attr_accessor :data
34
34
 
35
35
  class << self
36
36
 
37
- # @return [String]
37
+ # @return [String, nil]
38
38
  attr_accessor :code
39
39
 
40
40
  end
@@ -68,7 +68,7 @@ module Aws
68
68
  end
69
69
  end
70
70
 
71
- # Rasied when endpoint discovery failed for operations
71
+ # Raised when endpoint discovery failed for operations
72
72
  # that requires endpoints from endpoint discovery
73
73
  class EndpointDiscoveryError < RuntimeError
74
74
  def initialize(*args)
@@ -78,7 +78,7 @@ module Aws
78
78
  end
79
79
  end
80
80
 
81
- # raised when hostLabel member is not provided
81
+ # Raised when hostLabel member is not provided
82
82
  # at operation input when endpoint trait is available
83
83
  # with 'hostPrefix' requirement
84
84
  class MissingEndpointHostLabelValue < RuntimeError
@@ -236,6 +236,15 @@ module Aws
236
236
  end
237
237
  end
238
238
 
239
+ # Raised when a client is constructed and the sigv4a region set is invalid.
240
+ # It is invalid when it is empty and/or contains empty strings.
241
+ class InvalidRegionSetError < ArgumentError
242
+ def initialize(*args)
243
+ msg = 'The provided sigv4a region set was empty or invalid.'
244
+ super(msg)
245
+ end
246
+ end
247
+
239
248
  # Raised when a client is contsructed and the region is not valid.
240
249
  class InvalidRegionError < ArgumentError
241
250
  def initialize(*args)
@@ -6,7 +6,6 @@ module Aws
6
6
  def initialize
7
7
  @listeners = {}
8
8
  @validate_event = true
9
- @status = :sleep
10
9
  @signal_queue = Queue.new
11
10
  end
12
11
 
@@ -32,7 +31,7 @@ module Aws
32
31
  def emit(type, params)
33
32
  unless @stream
34
33
  raise Aws::Errors::SignalEventError.new(
35
- "Singaling events before making async request"\
34
+ "Signaling events before making async request"\
36
35
  " is not allowed."
37
36
  )
38
37
  end
@@ -40,25 +39,10 @@ module Aws
40
39
  Aws::ParamValidator.validate!(
41
40
  @encoder.rules.shape.member(type), params)
42
41
  end
43
- _ready_for_events?
44
42
  @stream.data(
45
43
  @encoder.encode(type, params),
46
44
  end_stream: type == :end_stream
47
45
  )
48
46
  end
49
-
50
- private
51
-
52
- def _ready_for_events?
53
- return true if @status == :ready
54
-
55
- # blocked until once initial 200 response is received
56
- # signal will be available in @signal_queue
57
- # and this check will no longer be blocked
58
- @signal_queue.pop
59
- @status = :ready
60
- true
61
- end
62
-
63
47
  end
64
48
  end
@@ -8,6 +8,8 @@ module Aws
8
8
  def ini_parse(raw)
9
9
  current_profile = nil
10
10
  current_prefix = nil
11
+ item = nil
12
+ previous_item = nil
11
13
  raw.lines.inject({}) do |acc, line|
12
14
  line = line.split(/^|\s;/).first # remove comments
13
15
  profile = line.match(/^\[([^\[\]]+)\]\s*(#.+)?$/) unless line.nil?
@@ -17,11 +19,16 @@ module Aws
17
19
  current_profile = named_profile[1] if named_profile
18
20
  elsif current_profile
19
21
  unless line.nil?
22
+ previous_item = item
20
23
  item = line.match(/^(.+?)\s*=\s*(.+?)\s*$/)
21
24
  prefix = line.match(/^(.+?)\s*=\s*$/)
22
25
  end
23
26
  if item && item[1].match(/^\s+/)
24
27
  # Need to add lines to a nested configuration.
28
+ if current_prefix.nil? && previous_item[2].strip.empty?
29
+ current_prefix = previous_item[1]
30
+ acc[current_profile][current_prefix] = {}
31
+ end
25
32
  inner_item = line.match(/^\s*(.+?)\s*=\s*(.+?)\s*$/)
26
33
  acc[current_profile] ||= {}
27
34
  acc[current_profile][current_prefix] ||= {}
@@ -4,11 +4,23 @@ require 'time'
4
4
  require 'net/http'
5
5
 
6
6
  module Aws
7
- # An auto-refreshing credential provider that loads credentials from
8
- # EC2 instances.
7
+ # An auto-refreshing credential provider that loads credentials from EC2 instances.
9
8
  #
10
9
  # instance_credentials = Aws::InstanceProfileCredentials.new
11
10
  # ec2 = Aws::EC2::Client.new(credentials: instance_credentials)
11
+ #
12
+ # ## Retries
13
+ # When initialized from the default credential chain, this provider defaults to `0` retries.
14
+ # Breakdown of retries is as follows:
15
+ #
16
+ # * **Configurable retries** (defaults to `1`): these retries handle errors when communicating
17
+ # with the IMDS endpoint. There are two separate retry mechanisms within the provider:
18
+ # * Entire token fetch and credential retrieval process
19
+ # * Token fetching
20
+ # * **JSON parsing retries**: Fixed at 3 attempts to handle cases when IMDS returns malformed JSON
21
+ # responses. These retries are separate from configurable retries.
22
+ #
23
+ # @see https://docs.aws.amazon.com/sdkref/latest/guide/feature-imds-credentials.html IMDS Credential Provider
12
24
  class InstanceProfileCredentials
13
25
  include CredentialProvider
14
26
  include RefreshingCredentials
@@ -22,10 +34,8 @@ module Aws
22
34
  # @api private
23
35
  class TokenExpiredError < RuntimeError; end
24
36
 
25
- # These are the errors we trap when attempting to talk to the
26
- # instance metadata service. Any of these imply the service
27
- # is not present, no responding or some other non-recoverable
28
- # error.
37
+ # These are the errors we trap when attempting to talk to the instance metadata service.
38
+ # Any of these imply the service is not present, no responding or some other non-recoverable error.
29
39
  # @api private
30
40
  NETWORK_ERRORS = [
31
41
  Errno::EHOSTUNREACH,
@@ -46,84 +56,113 @@ module Aws
46
56
  METADATA_TOKEN_PATH = '/latest/api/token'.freeze
47
57
 
48
58
  # @param [Hash] options
49
- # @option options [Integer] :retries (1) Number of times to retry
50
- # when retrieving credentials.
51
- # @option options [String] :endpoint ('http://169.254.169.254') The IMDS
52
- # endpoint. This option has precedence over the :endpoint_mode.
53
- # @option options [String] :endpoint_mode ('IPv4') The endpoint mode for
54
- # the instance metadata service. This is either 'IPv4' ('169.254.169.254')
55
- # or 'IPv6' ('[fd00:ec2::254]').
56
- # @option options [String] :ip_address ('169.254.169.254') Deprecated. Use
57
- # :endpoint instead. The IP address for the endpoint.
59
+ # @option options [Integer] :retries (1) Number of times to retry when retrieving credentials.
60
+ # @option options [String] :endpoint ('http://169.254.169.254') The IMDS endpoint. This option has precedence
61
+ # over the `:endpoint_mode`.
62
+ # @option options [String] :endpoint_mode ('IPv4') The endpoint mode for the instance metadata service. This is
63
+ # either 'IPv4' (`169.254.169.254`) or IPv6' (`[fd00:ec2::254]`).
64
+ # @option options [Boolean] :disable_imds_v1 (false) Disable the use of the legacy EC2 Metadata Service v1.
65
+ # @option options [String] :ip_address ('169.254.169.254') Deprecated. Use `:endpoint` instead.
66
+ # The IP address for the endpoint.
58
67
  # @option options [Integer] :port (80)
59
68
  # @option options [Float] :http_open_timeout (1)
60
69
  # @option options [Float] :http_read_timeout (1)
61
- # @option options [Numeric, Proc] :delay By default, failures are retried
62
- # with exponential back-off, i.e. `sleep(1.2 ** num_failures)`. You can
63
- # pass a number of seconds to sleep between failed attempts, or
64
- # a Proc that accepts the number of failures.
65
- # @option options [IO] :http_debug_output (nil) HTTP wire
66
- # traces are sent to this object. You can specify something
67
- # like $stdout.
68
- # @option options [Integer] :token_ttl Time-to-Live in seconds for EC2
69
- # Metadata Token used for fetching Metadata Profile Credentials, defaults
70
- # to 21600 seconds
71
- # @option options [Callable] before_refresh Proc called before
72
- # credentials are refreshed. `before_refresh` is called
73
- # with an instance of this object when
74
- # AWS credentials are required and need to be refreshed.
70
+ # @option options [Numeric, Proc] :delay By default, failures are retried with exponential back-off, i.e.
71
+ # `sleep(1.2 ** num_failures)`. You can pass a number of seconds to sleep between failed attempts, or a Proc
72
+ # that accepts the number of failures.
73
+ # @option options [IO] :http_debug_output (nil) HTTP wire traces are sent to this object.
74
+ # You can specify something like `$stdout`.
75
+ # @option options [Integer] :token_ttl Time-to-Live in seconds for EC2 Metadata Token used for fetching
76
+ # Metadata Profile Credentials, defaults to 21600 seconds.
77
+ # @option options [Callable] :before_refresh Proc called before credentials are refreshed. `before_refresh`
78
+ # is called with an instance of this object when AWS credentials are required and need to be refreshed.
75
79
  def initialize(options = {})
76
- @retries = options[:retries] || 1
77
- endpoint_mode = resolve_endpoint_mode(options)
78
- @endpoint = resolve_endpoint(options, endpoint_mode)
79
- @port = options[:port] || 80
80
+ @backoff = resolve_backoff(options[:backoff])
81
+ @disable_imds_v1 = resolve_disable_v1(options)
82
+ @endpoint = resolve_endpoint(options)
80
83
  @http_open_timeout = options[:http_open_timeout] || 1
81
84
  @http_read_timeout = options[:http_read_timeout] || 1
82
85
  @http_debug_output = options[:http_debug_output]
83
- @backoff = backoff(options[:backoff])
86
+ @port = options[:port] || 80
87
+ @retries = options[:retries] || 1
84
88
  @token_ttl = options[:token_ttl] || 21_600
85
- @token = nil
86
- @no_refresh_until = nil
89
+
87
90
  @async_refresh = false
91
+ @imds_v1_fallback = false
92
+ @no_refresh_until = nil
93
+ @token = nil
94
+ @metrics = ['CREDENTIALS_IMDS']
88
95
  super
89
96
  end
90
97
 
91
- # @return [Integer] Number of times to retry when retrieving credentials
92
- # from the instance metadata service. Defaults to 0 when resolving from
93
- # the default credential chain ({Aws::CredentialProviderChain}).
98
+ # @return [Boolean0
99
+ attr_reader :disable_imds_v1
100
+
101
+ # @return [Integer]
102
+ attr_reader :token_ttl
103
+
104
+ # @return [Integer]
94
105
  attr_reader :retries
95
106
 
107
+ # @return [Proc]
108
+ attr_reader :backoff
109
+
110
+ # @return [String]
111
+ attr_reader :endpoint
112
+
113
+ # @return [Integer]
114
+ attr_reader :port
115
+
116
+ # @return [Integer]
117
+ attr_reader :http_open_timeout
118
+
119
+ # @return [Integer]
120
+ attr_reader :http_read_timeout
121
+
122
+ # @return [IO, nil]
123
+ attr_reader :http_debug_output
124
+
96
125
  private
97
126
 
98
127
  def resolve_endpoint_mode(options)
99
- value = options[:endpoint_mode]
100
- value ||= ENV['AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE']
101
- value ||= Aws.shared_config.ec2_metadata_service_endpoint_mode(
102
- profile: options[:profile]
103
- )
104
- value || 'IPv4'
128
+ options[:endpoint_mode] ||
129
+ ENV['AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE'] ||
130
+ Aws.shared_config.ec2_metadata_service_endpoint_mode(profile: options[:profile]) ||
131
+ 'IPv4'
105
132
  end
106
133
 
107
- def resolve_endpoint(options, endpoint_mode)
108
- value = options[:endpoint] || options[:ip_address]
109
- value ||= ENV['AWS_EC2_METADATA_SERVICE_ENDPOINT']
110
- value ||= Aws.shared_config.ec2_metadata_service_endpoint(
111
- profile: options[:profile]
112
- )
134
+ def resolve_endpoint(options)
135
+ if (value = options[:ip_address])
136
+ warn('The `:ip_address` option is deprecated. Use `:endpoint` instead.')
137
+ return value
138
+ end
113
139
 
140
+ value =
141
+ options[:endpoint] ||
142
+ ENV['AWS_EC2_METADATA_SERVICE_ENDPOINT'] ||
143
+ Aws.shared_config.ec2_metadata_service_endpoint(profile: options[:profile]) ||
144
+ nil
114
145
  return value if value
115
146
 
147
+ endpoint_mode = resolve_endpoint_mode(options)
116
148
  case endpoint_mode.downcase
117
149
  when 'ipv4' then 'http://169.254.169.254'
118
150
  when 'ipv6' then 'http://[fd00:ec2::254]'
119
151
  else
120
- raise ArgumentError,
121
- ':endpoint_mode is not valid, expected IPv4 or IPv6, '\
122
- "got: #{endpoint_mode}"
152
+ raise ArgumentError, ":endpoint_mode is not valid, expected IPv4 or IPv6, got: #{endpoint_mode}"
123
153
  end
124
154
  end
125
155
 
126
- def backoff(backoff)
156
+ def resolve_disable_v1(options)
157
+ value =
158
+ options[:disable_imds_v1] ||
159
+ ENV['AWS_EC2_METADATA_V1_DISABLED'] ||
160
+ Aws.shared_config.ec2_metadata_v1_disabled(profile: options[:profile]) ||
161
+ 'false'
162
+ Aws::Util.str_2_bool(value.to_s.downcase)
163
+ end
164
+
165
+ def resolve_backoff(backoff)
127
166
  case backoff
128
167
  when Proc then backoff
129
168
  when Numeric then ->(_) { sleep(backoff) }
@@ -137,107 +176,89 @@ module Aws
137
176
  return
138
177
  end
139
178
 
140
- # Retry loading credentials up to 3 times is the instance metadata
141
- # service is responding but is returning invalid JSON documents
142
- # in response to the GET profile credentials call.
143
- begin
144
- retry_errors([Aws::Json::ParseError, StandardError], max_retries: 3) do
145
- c = Aws::Json.load(get_credentials.to_s)
146
- if empty_credentials?(@credentials)
147
- @credentials = Credentials.new(
148
- c['AccessKeyId'],
149
- c['SecretAccessKey'],
150
- c['Token']
151
- )
152
- @expiration = c['Expiration'] ? Time.iso8601(c['Expiration']) : nil
153
- if @expiration && @expiration < Time.now
154
- @no_refresh_until = Time.now + refresh_offset
155
- warn_expired_credentials
156
- end
157
- else
158
- # credentials are already set, update them only if the new ones are not empty
159
- if !c['AccessKeyId'] || c['AccessKeyId'].empty?
160
- # error getting new credentials
161
- @no_refresh_until = Time.now + refresh_offset
162
- warn_expired_credentials
163
- else
164
- @credentials = Credentials.new(
165
- c['AccessKeyId'],
166
- c['SecretAccessKey'],
167
- c['Token']
168
- )
169
- @expiration = c['Expiration'] ? Time.iso8601(c['Expiration']) : nil
170
- if @expiration && @expiration < Time.now
171
- @no_refresh_until = Time.now + refresh_offset
172
- warn_expired_credentials
173
- end
174
- end
179
+ new_creds =
180
+ begin
181
+ # Retry loading credentials up to 3 times is the instance metadata
182
+ # service is responding but is returning invalid JSON documents
183
+ # in response to the GET profile credentials call.
184
+ retry_errors([Aws::Json::ParseError], max_retries: 3) do
185
+ Aws::Json.load(retrieve_credentials.to_s)
175
186
  end
176
-
187
+ rescue Aws::Json::ParseError
188
+ raise Aws::Errors::MetadataParserError
177
189
  end
178
- rescue Aws::Json::ParseError
179
- raise Aws::Errors::MetadataParserError
190
+
191
+ if @credentials&.set? && empty_credentials?(new_creds)
192
+ # credentials are already set, but there was an error getting new credentials
193
+ # so don't update the credentials and use stale ones (static stability)
194
+ @no_refresh_until = Time.now + rand(300..360)
195
+ warn_expired_credentials
196
+ else
197
+ # credentials are empty or successfully retrieved, update them
198
+ update_credentials(new_creds)
180
199
  end
181
200
  end
182
201
 
183
- def get_credentials
202
+ def retrieve_credentials
184
203
  # Retry loading credentials a configurable number of times if
185
204
  # the instance metadata service is not responding.
186
- if _metadata_disabled?
187
- '{}'
188
- else
189
- begin
190
- retry_errors(NETWORK_ERRORS, max_retries: @retries) do
191
- open_connection do |conn|
192
- # attempt to fetch token to start secure flow first
193
- # and rescue to failover
194
- begin
195
- retry_errors(NETWORK_ERRORS, max_retries: @retries) do
196
- unless token_set?
197
- created_time = Time.now
198
- token_value, ttl = http_put(
199
- conn, METADATA_TOKEN_PATH, @token_ttl
200
- )
201
- @token = Token.new(token_value, ttl, created_time) if token_value && ttl
202
- end
203
- end
204
- rescue *NETWORK_ERRORS
205
- # token attempt failed, reset token
206
- # fallback to non-token mode
207
- @token = nil
208
- end
209
-
210
- token = @token.value if token_set?
211
-
212
- begin
213
- metadata = http_get(conn, METADATA_PATH_BASE, token)
214
- profile_name = metadata.lines.first.strip
215
- http_get(conn, METADATA_PATH_BASE + profile_name, token)
216
- rescue TokenExpiredError
217
- # Token has expired, reset it
218
- # The next retry should fetch it
219
- @token = nil
220
- raise Non200Response
221
- end
222
- end
205
+ begin
206
+ retry_errors(NETWORK_ERRORS, max_retries: @retries) do
207
+ open_connection do |conn|
208
+ # attempt to fetch token to start secure flow first
209
+ # and rescue to failover
210
+ fetch_token(conn) unless @imds_v1_fallback || (@token && !@token.expired?)
211
+
212
+ # disable insecure flow if we couldn't get token and imds v1 is disabled
213
+ raise TokenRetrivalError if @token.nil? && @disable_imds_v1
214
+
215
+ fetch_credentials(conn)
223
216
  end
224
- rescue
225
- '{}'
226
217
  end
218
+ rescue StandardError => e
219
+ warn("Error retrieving instance profile credentials: #{e}")
220
+ '{}'
227
221
  end
228
222
  end
229
223
 
230
- def token_set?
231
- @token && !@token.expired?
224
+ def update_credentials(creds)
225
+ @credentials = Credentials.new(creds['AccessKeyId'], creds['SecretAccessKey'], creds['Token'])
226
+ @expiration = creds['Expiration'] ? Time.iso8601(creds['Expiration']) : nil
227
+ return unless @expiration && @expiration < Time.now
228
+
229
+ @no_refresh_until = Time.now + rand(300..360)
230
+ warn_expired_credentials
232
231
  end
233
232
 
234
- def _metadata_disabled?
235
- ENV.fetch('AWS_EC2_METADATA_DISABLED', 'false').downcase == 'true'
233
+ def fetch_token(conn)
234
+ created_time = Time.now
235
+ token_value, ttl = http_put(conn)
236
+ @token = Token.new(token_value, ttl, created_time) if token_value && ttl
237
+ rescue *NETWORK_ERRORS
238
+ # token attempt failed, reset token
239
+ # fallback to non-token mode
240
+ @imds_v1_fallback = true
241
+ end
242
+
243
+ def fetch_credentials(conn)
244
+ metadata = http_get(conn, METADATA_PATH_BASE)
245
+ profile_name = metadata.lines.first.strip
246
+ http_get(conn, METADATA_PATH_BASE + profile_name)
247
+ rescue TokenExpiredError
248
+ # Token has expired, reset it
249
+ # The next retry should fetch it
250
+ @token = nil
251
+ @imds_v1_fallback = false
252
+ raise Non200Response
253
+ end
254
+
255
+ def token_set?
256
+ @token && !@token.expired?
236
257
  end
237
258
 
238
259
  def open_connection
239
260
  uri = URI.parse(@endpoint)
240
- http = Net::HTTP.new(uri.hostname || @endpoint, @port || uri.port)
261
+ http = Net::HTTP.new(uri.hostname || @endpoint, uri.port || @port)
241
262
  http.open_timeout = @http_open_timeout
242
263
  http.read_timeout = @http_read_timeout
243
264
  http.set_debug_output(@http_debug_output) if @http_debug_output
@@ -246,9 +267,9 @@ module Aws
246
267
  end
247
268
 
248
269
  # GET request fetch profile and credentials
249
- def http_get(connection, path, token = nil)
270
+ def http_get(connection, path)
250
271
  headers = { 'User-Agent' => "aws-sdk-ruby3/#{CORE_GEM_VERSION}" }
251
- headers['x-aws-ec2-metadata-token'] = token if token
272
+ headers['x-aws-ec2-metadata-token'] = @token.value if @token
252
273
  response = connection.request(Net::HTTP::Get.new(path, headers))
253
274
 
254
275
  case response.code.to_i
@@ -262,12 +283,12 @@ module Aws
262
283
  end
263
284
 
264
285
  # PUT request fetch token with ttl
265
- def http_put(connection, path, ttl)
286
+ def http_put(connection)
266
287
  headers = {
267
288
  'User-Agent' => "aws-sdk-ruby3/#{CORE_GEM_VERSION}",
268
- 'x-aws-ec2-metadata-token-ttl-seconds' => ttl.to_s
289
+ 'x-aws-ec2-metadata-token-ttl-seconds' => @token_ttl.to_s
269
290
  }
270
- response = connection.request(Net::HTTP::Put.new(path, headers))
291
+ response = connection.request(Net::HTTP::Put.new(METADATA_TOKEN_PATH, headers))
271
292
  case response.code.to_i
272
293
  when 200
273
294
  [
@@ -276,8 +297,6 @@ module Aws
276
297
  ]
277
298
  when 400
278
299
  raise TokenRetrivalError
279
- when 401
280
- raise TokenExpiredError
281
300
  else
282
301
  raise Non200Response
283
302
  end
@@ -298,18 +317,12 @@ module Aws
298
317
  end
299
318
 
300
319
  def warn_expired_credentials
301
- warn("Attempting credential expiration extension due to a credential "\
302
- "service availability issue. A refresh of these credentials "\
303
- "will be attempted again in 5 minutes.")
304
- end
305
-
306
- def empty_credentials?(creds)
307
- !creds || !creds.access_key_id || creds.access_key_id.empty?
320
+ warn('Attempting credential expiration extension due to a credential service availability issue. '\
321
+ 'A refresh of these credentials will be attempted again in 5 minutes.')
308
322
  end
309
323
 
310
- # Compute an offset for refresh with jitter
311
- def refresh_offset
312
- 300 + rand(0..60)
324
+ def empty_credentials?(creds_hash)
325
+ !creds_hash['AccessKeyId'] || creds_hash['AccessKeyId'].empty?
313
326
  end
314
327
 
315
328
  # @api private
@@ -8,7 +8,7 @@ module Aws
8
8
 
9
9
  include Seahorse::Model::Shapes
10
10
 
11
- def initialize(rules)
11
+ def initialize(rules, _options = {})
12
12
  @rules = rules
13
13
  end
14
14
 
@@ -20,6 +20,8 @@ module Aws
20
20
  private
21
21
 
22
22
  def structure(ref, values)
23
+ return nil if values.nil?
24
+
23
25
  shape = ref.shape
24
26
  values.each_pair.with_object({}) do |(key, value), data|
25
27
  if shape.member?(key) && !value.nil?
@@ -31,11 +33,15 @@ module Aws
31
33
  end
32
34
 
33
35
  def list(ref, values)
36
+ return nil if values.nil?
37
+
34
38
  member_ref = ref.shape.member
35
39
  values.collect { |value| format(member_ref, value) }
36
40
  end
37
41
 
38
42
  def map(ref, values)
43
+ return nil if values.nil?
44
+
39
45
  value_ref = ref.shape.value
40
46
  values.each.with_object({}) do |(key, value), data|
41
47
  data[key] = format(value_ref, value)
@@ -49,6 +55,7 @@ module Aws
49
55
  when MapShape then map(ref, value)
50
56
  when TimestampShape then timestamp(ref, value)
51
57
  when BlobShape then encode(value)
58
+ when FloatShape then Util.serialize_number(value)
52
59
  else value
53
60
  end
54
61
  end