aws-sdk-core 3.46.0 → 3.94.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +5 -5
  2. data/VERSION +1 -1
  3. data/lib/aws-sdk-core.rb +7 -0
  4. data/lib/aws-sdk-core/arn.rb +77 -0
  5. data/lib/aws-sdk-core/arn_parser.rb +38 -0
  6. data/lib/aws-sdk-core/assume_role_web_identity_credentials.rb +102 -0
  7. data/lib/aws-sdk-core/async_client_stubs.rb +80 -0
  8. data/lib/aws-sdk-core/binary.rb +3 -0
  9. data/lib/aws-sdk-core/binary/decode_handler.rb +9 -1
  10. data/lib/aws-sdk-core/binary/encode_handler.rb +32 -0
  11. data/lib/aws-sdk-core/binary/event_builder.rb +122 -0
  12. data/lib/aws-sdk-core/binary/event_parser.rb +48 -18
  13. data/lib/aws-sdk-core/binary/event_stream_decoder.rb +5 -2
  14. data/lib/aws-sdk-core/binary/event_stream_encoder.rb +53 -0
  15. data/lib/aws-sdk-core/client_side_monitoring/publisher.rb +9 -1
  16. data/lib/aws-sdk-core/client_stubs.rb +10 -9
  17. data/lib/aws-sdk-core/credential_provider.rb +0 -31
  18. data/lib/aws-sdk-core/credential_provider_chain.rb +79 -39
  19. data/lib/aws-sdk-core/deprecations.rb +16 -10
  20. data/lib/aws-sdk-core/ecs_credentials.rb +12 -8
  21. data/lib/aws-sdk-core/endpoint_cache.rb +14 -11
  22. data/lib/aws-sdk-core/errors.rb +94 -6
  23. data/lib/aws-sdk-core/event_emitter.rb +42 -0
  24. data/lib/aws-sdk-core/instance_profile_credentials.rb +120 -38
  25. data/lib/aws-sdk-core/json.rb +13 -14
  26. data/lib/aws-sdk-core/json/error_handler.rb +19 -2
  27. data/lib/aws-sdk-core/json/handler.rb +19 -1
  28. data/lib/aws-sdk-core/log/formatter.rb +7 -1
  29. data/lib/aws-sdk-core/log/param_filter.rb +3 -3
  30. data/lib/aws-sdk-core/pageable_response.rb +34 -20
  31. data/lib/aws-sdk-core/param_validator.rb +11 -5
  32. data/lib/aws-sdk-core/plugins/client_metrics_plugin.rb +26 -1
  33. data/lib/aws-sdk-core/plugins/endpoint_discovery.rb +1 -1
  34. data/lib/aws-sdk-core/plugins/event_stream_configuration.rb +14 -0
  35. data/lib/aws-sdk-core/plugins/invocation_id.rb +33 -0
  36. data/lib/aws-sdk-core/plugins/regional_endpoint.rb +8 -1
  37. data/lib/aws-sdk-core/plugins/retries/client_rate_limiter.rb +137 -0
  38. data/lib/aws-sdk-core/plugins/retries/clock_skew.rb +98 -0
  39. data/lib/aws-sdk-core/plugins/retries/error_inspector.rb +142 -0
  40. data/lib/aws-sdk-core/plugins/retries/retry_quota.rb +57 -0
  41. data/lib/aws-sdk-core/plugins/retry_errors.rb +290 -106
  42. data/lib/aws-sdk-core/plugins/signature_v4.rb +13 -2
  43. data/lib/aws-sdk-core/plugins/stub_responses.rb +20 -7
  44. data/lib/aws-sdk-core/plugins/transfer_encoding.rb +51 -0
  45. data/lib/aws-sdk-core/plugins/user_agent.rb +4 -8
  46. data/lib/aws-sdk-core/process_credentials.rb +9 -3
  47. data/lib/aws-sdk-core/shared_config.rb +95 -125
  48. data/lib/aws-sdk-core/structure.rb +1 -2
  49. data/lib/aws-sdk-core/stubbing/protocols/rest.rb +19 -0
  50. data/lib/aws-sdk-core/stubbing/stub_data.rb +13 -4
  51. data/lib/aws-sdk-core/util.rb +4 -0
  52. data/lib/aws-sdk-core/waiters/waiter.rb +2 -2
  53. data/lib/aws-sdk-core/xml/error_handler.rb +26 -3
  54. data/lib/aws-sdk-sts.rb +7 -4
  55. data/lib/aws-sdk-sts/client.rb +1109 -459
  56. data/lib/aws-sdk-sts/client_api.rb +67 -0
  57. data/lib/aws-sdk-sts/customizations.rb +2 -0
  58. data/lib/aws-sdk-sts/errors.rb +150 -0
  59. data/lib/aws-sdk-sts/plugins/sts_regional_endpoints.rb +32 -0
  60. data/lib/aws-sdk-sts/presigner.rb +67 -0
  61. data/lib/aws-sdk-sts/resource.rb +1 -0
  62. data/lib/aws-sdk-sts/types.rb +736 -176
  63. data/lib/seahorse.rb +9 -0
  64. data/lib/seahorse/client/async_base.rb +50 -0
  65. data/lib/seahorse/client/async_response.rb +62 -0
  66. data/lib/seahorse/client/base.rb +4 -2
  67. data/lib/seahorse/client/configuration.rb +4 -2
  68. data/lib/seahorse/client/events.rb +1 -1
  69. data/lib/seahorse/client/h2/connection.rb +246 -0
  70. data/lib/seahorse/client/h2/handler.rb +151 -0
  71. data/lib/seahorse/client/handler_list_entry.rb +2 -2
  72. data/lib/seahorse/client/http/async_response.rb +42 -0
  73. data/lib/seahorse/client/http/response.rb +13 -8
  74. data/lib/seahorse/client/logging/formatter.rb +4 -2
  75. data/lib/seahorse/client/net_http/connection_pool.rb +19 -20
  76. data/lib/seahorse/client/net_http/handler.rb +7 -1
  77. data/lib/seahorse/client/net_http/patches.rb +7 -1
  78. data/lib/seahorse/client/networking_error.rb +28 -0
  79. data/lib/seahorse/client/plugin.rb +5 -4
  80. data/lib/seahorse/client/plugins/content_length.rb +5 -2
  81. data/lib/seahorse/client/plugins/h2.rb +64 -0
  82. data/lib/seahorse/client/response.rb +3 -5
  83. data/lib/seahorse/model/api.rb +4 -0
  84. data/lib/seahorse/model/operation.rb +4 -0
  85. data/lib/seahorse/model/shapes.rb +2 -2
  86. metadata +43 -10
@@ -15,12 +15,14 @@ require_relative 'seahorse/client/plugin_list'
15
15
  require_relative 'seahorse/client/request'
16
16
  require_relative 'seahorse/client/request_context'
17
17
  require_relative 'seahorse/client/response'
18
+ require_relative 'seahorse/client/async_response'
18
19
 
19
20
  # client http
20
21
 
21
22
  require_relative 'seahorse/client/http/headers'
22
23
  require_relative 'seahorse/client/http/request'
23
24
  require_relative 'seahorse/client/http/response'
25
+ require_relative 'seahorse/client/http/async_response'
24
26
 
25
27
  # client logging
26
28
 
@@ -32,12 +34,18 @@ require_relative 'seahorse/client/logging/formatter'
32
34
  require_relative 'seahorse/client/net_http/connection_pool'
33
35
  require_relative 'seahorse/client/net_http/handler'
34
36
 
37
+ # http2 handler
38
+
39
+ require_relative 'seahorse/client/h2/connection'
40
+ require_relative 'seahorse/client/h2/handler'
41
+
35
42
  # plugins
36
43
 
37
44
  require_relative 'seahorse/client/plugins/content_length'
38
45
  require_relative 'seahorse/client/plugins/endpoint'
39
46
  require_relative 'seahorse/client/plugins/logging'
40
47
  require_relative 'seahorse/client/plugins/net_http'
48
+ require_relative 'seahorse/client/plugins/h2'
41
49
  require_relative 'seahorse/client/plugins/raise_response_errors'
42
50
  require_relative 'seahorse/client/plugins/response_target'
43
51
 
@@ -49,3 +57,4 @@ require_relative 'seahorse/model/authorizer'
49
57
  require_relative 'seahorse/model/shapes'
50
58
 
51
59
  require_relative 'seahorse/client/base'
60
+ require_relative 'seahorse/client/async_base'
@@ -0,0 +1,50 @@
1
+ module Seahorse
2
+ module Client
3
+ class AsyncBase < Seahorse::Client::Base
4
+
5
+ # default H2 plugins
6
+ @plugins = PluginList.new([
7
+ Plugins::Endpoint,
8
+ Plugins::H2,
9
+ Plugins::ResponseTarget
10
+ ])
11
+
12
+ def initialize(plugins, options)
13
+ super
14
+ @connection = H2::Connection.new(options)
15
+ @options = options
16
+ end
17
+
18
+ # @return [H2::Connection]
19
+ attr_reader :connection
20
+
21
+ # @return [Array<Symbol>] Returns a list of valid async request
22
+ # operation names.
23
+ def operation_names
24
+ self.class.api.async_operation_names
25
+ end
26
+
27
+ # Closes the underlying HTTP2 Connection for the client
28
+ # @return [Symbol] Returns the status of the connection (:closed)
29
+ def close_connection
30
+ @connection.close!
31
+ end
32
+
33
+ # Creates a new HTTP2 Connection for the client
34
+ # @return [Seahorse::Client::H2::Connection]
35
+ def new_connection
36
+ if @connection.closed?
37
+ @connection = H2::Connection.new(@options)
38
+ else
39
+ @connection
40
+ end
41
+ end
42
+
43
+ def connection_errors
44
+ @connection.errors
45
+ end
46
+
47
+ end
48
+ end
49
+ end
50
+
@@ -0,0 +1,62 @@
1
+ module Seahorse
2
+ module Client
3
+ class AsyncResponse
4
+
5
+ def initialize(options = {})
6
+ @response = Response.new(context: options[:context])
7
+ @stream = options[:stream]
8
+ @stream_mutex = options[:stream_mutex]
9
+ @close_condition = options[:close_condition]
10
+ @sync_queue = options[:sync_queue]
11
+ end
12
+
13
+ def context
14
+ @response.context
15
+ end
16
+
17
+ def error
18
+ @response.error
19
+ end
20
+
21
+ def on(range, &block)
22
+ @response.on(range, &block)
23
+ self
24
+ end
25
+
26
+ def on_complete(&block)
27
+ @response.on_complete(&block)
28
+ self
29
+ end
30
+
31
+ def wait
32
+ if error && context.config.raise_response_errors
33
+ raise error
34
+ elsif @stream
35
+ # have a sync signal that #signal can be blocked on
36
+ # else, if #signal is called before #wait
37
+ # will be waiting for a signal never arrives
38
+ @sync_queue << "sync_signal"
39
+ # now #signal is unlocked for
40
+ # signaling close condition when ready
41
+ @stream_mutex.synchronize {
42
+ @close_condition.wait(@stream_mutex)
43
+ }
44
+ @response
45
+ end
46
+ end
47
+
48
+ def join!
49
+ if error && context.config.raise_response_errors
50
+ raise error
51
+ elsif @stream
52
+ # close callback is waiting
53
+ # for the "sync_signal"
54
+ @sync_queue << "sync_signal"
55
+ @stream.close
56
+ @response
57
+ end
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -46,7 +46,7 @@ module Seahorse
46
46
  # names. These are valid arguments to {#build_request} and are also
47
47
  # valid methods.
48
48
  def operation_names
49
- self.class.api.operation_names
49
+ self.class.api.operation_names - self.class.api.async_operation_names
50
50
  end
51
51
 
52
52
  private
@@ -194,13 +194,15 @@ module Seahorse
194
194
  private
195
195
 
196
196
  def define_operation_methods
197
+ operations_module = Module.new
197
198
  @api.operation_names.each do |method_name|
198
- define_method(method_name) do |*args, &block|
199
+ operations_module.send(:define_method, method_name) do |*args, &block|
199
200
  params = args[0] || {}
200
201
  options = args[1] || {}
201
202
  build_request(method_name, params).send_request(options, &block)
202
203
  end
203
204
  end
205
+ include(operations_module)
204
206
  end
205
207
 
206
208
  def build_plugins
@@ -104,7 +104,7 @@ module Seahorse
104
104
  #
105
105
  # @return [self]
106
106
  def add_option(name, default = nil, &block)
107
- default = DynamicDefault.new(Proc.new) if block_given?
107
+ default = DynamicDefault.new(block) if block_given?
108
108
  @defaults[name.to_sym] << default
109
109
  self
110
110
  end
@@ -199,7 +199,9 @@ module Seahorse
199
199
  value = @struct[opt_name]
200
200
  if value.is_a?(Defaults)
201
201
  # this config value is used by endpoint discovery
202
- @struct[:regional_endpoint] = true if opt_name == :endpoint
202
+ if opt_name == :endpoint && @struct.members.include?(:regional_endpoint)
203
+ @struct[:regional_endpoint] = true
204
+ end
203
205
  resolve_defaults(opt_name, value)
204
206
  else
205
207
  value
@@ -9,7 +9,7 @@ module Seahorse
9
9
 
10
10
  def emit(event_name, *args, &block)
11
11
  @listeners[event_name] ||= []
12
- @listeners[event_name] << Proc.new
12
+ @listeners[event_name] << block if block_given?
13
13
  end
14
14
 
15
15
  def signal(event, *args)
@@ -0,0 +1,246 @@
1
+ if RUBY_VERSION >= '2.1'
2
+ begin
3
+ require 'http/2'
4
+ rescue LoadError; end
5
+ end
6
+ require 'openssl'
7
+ require 'socket'
8
+
9
+ module Seahorse
10
+ module Client
11
+ # @api private
12
+ module H2
13
+
14
+ # H2 Connection build on top of `http/2` gem
15
+ # (requires Ruby >= 2.1)
16
+ # with TLS layer plus ALPN, requires:
17
+ # Ruby >= 2.3 and OpenSSL >= 1.0.2
18
+ class Connection
19
+
20
+ OPTIONS = {
21
+ max_concurrent_streams: 100,
22
+ connection_timeout: 60,
23
+ connection_read_timeout: 60,
24
+ http_wire_trace: false,
25
+ logger: nil,
26
+ ssl_verify_peer: true,
27
+ ssl_ca_bundle: nil,
28
+ ssl_ca_directory: nil,
29
+ ssl_ca_store: nil,
30
+ enable_alpn: false
31
+ }
32
+
33
+ # chunk read size at socket
34
+ CHUNKSIZE = 1024
35
+
36
+ SOCKET_FAMILY = ::Socket::AF_INET
37
+
38
+ def initialize(options = {})
39
+ OPTIONS.each_pair do |opt_name, default_value|
40
+ value = options[opt_name].nil? ? default_value : options[opt_name]
41
+ instance_variable_set("@#{opt_name}", value)
42
+ end
43
+ @h2_client = HTTP2::Client.new(
44
+ settings_max_concurrent_streams: max_concurrent_streams
45
+ )
46
+ @logger = options[:logger] || Logger.new($stdout) if @http_wire_trace
47
+ @chunk_size = options[:read_chunk_size] || CHUNKSIZE
48
+ @errors = []
49
+ @status = :ready
50
+ @mutex = Mutex.new # connection can be shared across requests
51
+ @socket = nil
52
+ @socket_thread = nil
53
+ end
54
+
55
+ OPTIONS.keys.each do |attr_name|
56
+ attr_reader(attr_name)
57
+ end
58
+
59
+ alias ssl_verify_peer? ssl_verify_peer
60
+
61
+ attr_reader :errors
62
+
63
+ attr_accessor :input_signal_thread
64
+
65
+ def new_stream
66
+ begin
67
+ @h2_client.new_stream
68
+ rescue => error
69
+ raise Http2StreamInitializeError.new(error)
70
+ end
71
+ end
72
+
73
+ def connect(endpoint)
74
+ @mutex.synchronize {
75
+ if @status == :ready
76
+ tcp, addr = _tcp_socket(endpoint)
77
+ debug_output("opening connection to #{endpoint.host}:#{endpoint.port} ...")
78
+ _nonblocking_connect(tcp, addr)
79
+ debug_output("opened")
80
+
81
+ @socket = OpenSSL::SSL::SSLSocket.new(tcp, _tls_context)
82
+ @socket.sync_close = true
83
+ @socket.hostname = endpoint.host
84
+
85
+ debug_output("starting TLS for #{endpoint.host}:#{endpoint.port} ...")
86
+ @socket.connect
87
+ debug_output("TLS established")
88
+ _register_h2_callbacks
89
+ @status = :active
90
+ elsif @status == :closed
91
+ msg = "Async Client HTTP2 Connection is closed, you may"\
92
+ " use #new_connection to create a new HTTP2 Connection for this client"
93
+ raise Http2ConnectionClosedError.new(msg)
94
+ end
95
+ }
96
+ end
97
+
98
+ def start(stream)
99
+ @mutex.synchronize {
100
+ return if @socket_thread
101
+ @socket_thread = Thread.new do
102
+ while !@socket.closed?
103
+ begin
104
+ data = @socket.read_nonblock(@chunk_size)
105
+ @h2_client << data
106
+ rescue IO::WaitReadable
107
+ begin
108
+ unless IO.select([@socket], nil, nil, connection_read_timeout)
109
+ self.debug_output("socket connection read time out")
110
+ self.close!
111
+ else
112
+ # available, retry to start reading
113
+ retry
114
+ end
115
+ rescue
116
+ # error can happen when closing the socket
117
+ # while it's waiting for read
118
+ self.close!
119
+ end
120
+ rescue EOFError
121
+ self.close!
122
+ rescue => error
123
+ self.debug_output(error.inspect)
124
+ @errors << error
125
+ self.close!
126
+ end
127
+ end
128
+ end
129
+ @socket_thread.abort_on_exception = true
130
+ }
131
+ end
132
+
133
+ def close!
134
+ @mutex.synchronize {
135
+ self.debug_output("closing connection ...")
136
+ if @socket
137
+ @socket.close
138
+ @socket = nil
139
+ end
140
+ if @socket_thread
141
+ Thread.kill(@socket_thread)
142
+ @socket_thread = nil
143
+ end
144
+ @status = :closed
145
+ }
146
+ end
147
+
148
+ def closed?
149
+ @status == :closed
150
+ end
151
+
152
+ def debug_output(msg, type = nil)
153
+ prefix = case type
154
+ when :send then "-> "
155
+ when :receive then "<- "
156
+ else
157
+ ""
158
+ end
159
+ return unless @logger
160
+ _debug_entry(prefix + msg)
161
+ end
162
+
163
+ private
164
+
165
+ def _debug_entry(str)
166
+ @logger << str
167
+ @logger << "\n"
168
+ end
169
+
170
+ def _register_h2_callbacks
171
+ @h2_client.on(:frame) do |bytes|
172
+ if @socket.nil?
173
+ msg = "Connection is closed due to errors, "\
174
+ "you can find errors at async_client.connection.errors"
175
+ raise Http2ConnectionClosedError.new(msg)
176
+ else
177
+ @socket.print(bytes)
178
+ @socket.flush
179
+ end
180
+ end
181
+ @h2_client.on(:frame_sent) do |frame|
182
+ debug_output("frame: #{frame.inspect}", :send)
183
+ end
184
+ @h2_client.on(:frame_received) do |frame|
185
+ debug_output("frame: #{frame.inspect}", :receive)
186
+ end
187
+ end
188
+
189
+ def _tcp_socket(endpoint)
190
+ tcp = ::Socket.new(SOCKET_FAMILY, ::Socket::SOCK_STREAM, 0)
191
+ tcp.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1)
192
+
193
+ address = ::Socket.getaddrinfo(endpoint.host, nil, SOCKET_FAMILY).first[3]
194
+ sockaddr = ::Socket.sockaddr_in(endpoint.port, address)
195
+
196
+ [tcp, sockaddr]
197
+ end
198
+
199
+ def _nonblocking_connect(tcp, addr)
200
+ begin
201
+ tcp.connect_nonblock(addr)
202
+ rescue IO::WaitWritable
203
+ unless IO.select(nil, [tcp], nil, connection_timeout)
204
+ tcp.close
205
+ raise
206
+ end
207
+ begin
208
+ tcp.connect_nonblock(addr)
209
+ rescue Errno::EISCONN
210
+ # tcp socket connected, continue
211
+ end
212
+ end
213
+ end
214
+
215
+ def _tls_context
216
+ ssl_ctx = OpenSSL::SSL::SSLContext.new(:TLSv1_2)
217
+ if ssl_verify_peer?
218
+ ssl_ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
219
+ ssl_ctx.ca_file = ssl_ca_bundle ? ssl_ca_bundle : _default_ca_bundle
220
+ ssl_ctx.ca_path = ssl_ca_directory ? ssl_ca_directory : _default_ca_directory
221
+ ssl_ctx.cert_store = ssl_ca_store if ssl_ca_store
222
+ else
223
+ ssl_ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
224
+ end
225
+ if enable_alpn
226
+ debug_output("enabling ALPN for TLS ...")
227
+ ssl_ctx.alpn_protocols = ['h2']
228
+ end
229
+ ssl_ctx
230
+ end
231
+
232
+ def _default_ca_bundle
233
+ File.exist?(OpenSSL::X509::DEFAULT_CERT_FILE) ?
234
+ OpenSSL::X509::DEFAULT_CERT_FILE : nil
235
+ end
236
+
237
+ def _default_ca_directory
238
+ Dir.exist?(OpenSSL::X509::DEFAULT_CERT_DIR) ?
239
+ OpenSSL::X509::DEFAULT_CERT_DIR : nil
240
+ end
241
+
242
+ end
243
+ end
244
+ end
245
+ end
246
+