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.
- checksums.yaml +5 -5
- data/CHANGELOG.md +1258 -0
- data/LICENSE.txt +202 -0
- data/VERSION +1 -1
- data/lib/aws-defaults/default_configuration.rb +153 -0
- data/lib/aws-defaults/defaults_mode_config_resolver.rb +107 -0
- data/lib/aws-defaults.rb +3 -0
- data/lib/aws-sdk-core/arn.rb +92 -0
- data/lib/aws-sdk-core/arn_parser.rb +40 -0
- data/lib/aws-sdk-core/assume_role_credentials.rb +20 -0
- data/lib/aws-sdk-core/assume_role_web_identity_credentials.rb +109 -0
- data/lib/aws-sdk-core/async_client_stubs.rb +82 -0
- data/lib/aws-sdk-core/binary/decode_handler.rb +11 -1
- data/lib/aws-sdk-core/binary/encode_handler.rb +34 -0
- data/lib/aws-sdk-core/binary/event_builder.rb +124 -0
- data/lib/aws-sdk-core/binary/event_parser.rb +50 -18
- data/lib/aws-sdk-core/binary/event_stream_decoder.rb +7 -2
- data/lib/aws-sdk-core/binary/event_stream_encoder.rb +55 -0
- data/lib/aws-sdk-core/binary.rb +5 -0
- data/lib/aws-sdk-core/client_side_monitoring/publisher.rb +11 -1
- data/lib/aws-sdk-core/client_side_monitoring/request_metrics.rb +2 -0
- data/lib/aws-sdk-core/client_stubs.rb +16 -13
- data/lib/aws-sdk-core/credential_provider.rb +1 -30
- data/lib/aws-sdk-core/credential_provider_chain.rb +102 -40
- data/lib/aws-sdk-core/credentials.rb +2 -0
- data/lib/aws-sdk-core/deprecations.rb +17 -11
- data/lib/aws-sdk-core/eager_loader.rb +2 -0
- data/lib/aws-sdk-core/ec2_metadata.rb +238 -0
- data/lib/aws-sdk-core/ecs_credentials.rb +18 -9
- data/lib/aws-sdk-core/endpoint_cache.rb +16 -11
- data/lib/aws-sdk-core/errors.rb +138 -15
- data/lib/aws-sdk-core/event_emitter.rb +44 -0
- data/lib/aws-sdk-core/ini_parser.rb +2 -0
- data/lib/aws-sdk-core/instance_profile_credentials.rb +179 -42
- data/lib/aws-sdk-core/json/builder.rb +2 -0
- data/lib/aws-sdk-core/json/error_handler.rb +21 -2
- data/lib/aws-sdk-core/json/handler.rb +21 -1
- data/lib/aws-sdk-core/json/json_engine.rb +12 -8
- data/lib/aws-sdk-core/json/oj_engine.rb +35 -6
- data/lib/aws-sdk-core/json/parser.rb +10 -0
- data/lib/aws-sdk-core/json.rb +11 -28
- data/lib/aws-sdk-core/log/formatter.rb +16 -4
- data/lib/aws-sdk-core/log/handler.rb +2 -0
- data/lib/aws-sdk-core/log/param_filter.rb +38 -13
- data/lib/aws-sdk-core/log/param_formatter.rb +2 -0
- data/lib/aws-sdk-core/pageable_response.rb +48 -24
- data/lib/aws-sdk-core/pager.rb +5 -0
- data/lib/aws-sdk-core/param_converter.rb +2 -0
- data/lib/aws-sdk-core/param_validator.rb +63 -7
- data/lib/aws-sdk-core/plugins/api_key.rb +5 -1
- data/lib/aws-sdk-core/plugins/apig_authorizer_token.rb +2 -0
- data/lib/aws-sdk-core/plugins/apig_credentials_configuration.rb +2 -0
- data/lib/aws-sdk-core/plugins/apig_user_agent.rb +2 -0
- data/lib/aws-sdk-core/plugins/client_metrics_plugin.rb +28 -1
- data/lib/aws-sdk-core/plugins/client_metrics_send_plugin.rb +2 -0
- data/lib/aws-sdk-core/plugins/credentials_configuration.rb +26 -7
- data/lib/aws-sdk-core/plugins/defaults_mode.rb +40 -0
- data/lib/aws-sdk-core/plugins/endpoint_discovery.rb +12 -4
- data/lib/aws-sdk-core/plugins/endpoint_pattern.rb +8 -6
- data/lib/aws-sdk-core/plugins/event_stream_configuration.rb +16 -0
- data/lib/aws-sdk-core/plugins/global_configuration.rb +2 -0
- data/lib/aws-sdk-core/plugins/helpful_socket_errors.rb +2 -0
- data/lib/aws-sdk-core/plugins/http_checksum.rb +57 -0
- data/lib/aws-sdk-core/plugins/idempotency_token.rb +2 -0
- data/lib/aws-sdk-core/plugins/invocation_id.rb +35 -0
- data/lib/aws-sdk-core/plugins/jsonvalue_converter.rb +2 -0
- data/lib/aws-sdk-core/plugins/logging.rb +2 -0
- data/lib/aws-sdk-core/plugins/param_converter.rb +2 -0
- data/lib/aws-sdk-core/plugins/param_validator.rb +2 -0
- data/lib/aws-sdk-core/plugins/protocols/api_gateway.rb +19 -0
- data/lib/aws-sdk-core/plugins/protocols/ec2.rb +2 -0
- data/lib/aws-sdk-core/plugins/protocols/json_rpc.rb +2 -0
- data/lib/aws-sdk-core/plugins/protocols/query.rb +2 -0
- data/lib/aws-sdk-core/plugins/protocols/rest_json.rb +18 -1
- data/lib/aws-sdk-core/plugins/protocols/rest_xml.rb +2 -0
- data/lib/aws-sdk-core/plugins/recursion_detection.rb +27 -0
- data/lib/aws-sdk-core/plugins/regional_endpoint.rb +74 -16
- data/lib/aws-sdk-core/plugins/response_paging.rb +2 -0
- data/lib/aws-sdk-core/plugins/retries/client_rate_limiter.rb +139 -0
- data/lib/aws-sdk-core/plugins/retries/clock_skew.rb +100 -0
- data/lib/aws-sdk-core/plugins/retries/error_inspector.rb +146 -0
- data/lib/aws-sdk-core/plugins/retries/retry_quota.rb +59 -0
- data/lib/aws-sdk-core/plugins/retry_errors.rb +295 -107
- data/lib/aws-sdk-core/plugins/signature_v2.rb +2 -0
- data/lib/aws-sdk-core/plugins/signature_v4.rb +28 -25
- data/lib/aws-sdk-core/plugins/stub_responses.rb +24 -7
- data/lib/aws-sdk-core/plugins/transfer_encoding.rb +53 -0
- data/lib/aws-sdk-core/plugins/user_agent.rb +6 -8
- data/lib/aws-sdk-core/process_credentials.rb +12 -5
- data/lib/aws-sdk-core/query/ec2_param_builder.rb +2 -0
- data/lib/aws-sdk-core/query/handler.rb +2 -0
- data/lib/aws-sdk-core/query/param.rb +2 -0
- data/lib/aws-sdk-core/query/param_builder.rb +2 -0
- data/lib/aws-sdk-core/query/param_list.rb +2 -0
- data/lib/aws-sdk-core/query.rb +2 -0
- data/lib/aws-sdk-core/refreshing_credentials.rb +15 -2
- data/lib/aws-sdk-core/resources/collection.rb +2 -0
- data/lib/aws-sdk-core/rest/handler.rb +2 -0
- data/lib/aws-sdk-core/rest/request/body.rb +21 -1
- data/lib/aws-sdk-core/rest/request/builder.rb +2 -0
- data/lib/aws-sdk-core/rest/request/endpoint.rb +10 -3
- data/lib/aws-sdk-core/rest/request/headers.rb +20 -6
- data/lib/aws-sdk-core/rest/request/querystring_builder.rb +4 -2
- data/lib/aws-sdk-core/rest/response/body.rb +2 -0
- data/lib/aws-sdk-core/rest/response/headers.rb +6 -3
- data/lib/aws-sdk-core/rest/response/parser.rb +2 -0
- data/lib/aws-sdk-core/rest/response/status_code.rb +2 -0
- data/lib/aws-sdk-core/rest.rb +2 -0
- data/lib/aws-sdk-core/shared_config.rb +153 -127
- data/lib/aws-sdk-core/shared_credentials.rb +9 -1
- data/lib/aws-sdk-core/sso_credentials.rb +136 -0
- data/lib/aws-sdk-core/structure.rb +14 -4
- data/lib/aws-sdk-core/stubbing/data_applicator.rb +2 -0
- data/lib/aws-sdk-core/stubbing/empty_stub.rb +2 -0
- data/lib/aws-sdk-core/stubbing/protocols/api_gateway.rb +2 -0
- data/lib/aws-sdk-core/stubbing/protocols/ec2.rb +2 -0
- data/lib/aws-sdk-core/stubbing/protocols/json.rb +3 -1
- data/lib/aws-sdk-core/stubbing/protocols/query.rb +4 -2
- data/lib/aws-sdk-core/stubbing/protocols/rest.rb +52 -7
- data/lib/aws-sdk-core/stubbing/protocols/rest_json.rb +3 -1
- data/lib/aws-sdk-core/stubbing/protocols/rest_xml.rb +2 -2
- data/lib/aws-sdk-core/stubbing/stub_data.rb +15 -4
- data/lib/aws-sdk-core/stubbing/xml_error.rb +2 -0
- data/lib/aws-sdk-core/type_builder.rb +2 -0
- data/lib/aws-sdk-core/util.rb +6 -0
- data/lib/aws-sdk-core/waiters/errors.rb +2 -0
- data/lib/aws-sdk-core/waiters/poller.rb +2 -0
- data/lib/aws-sdk-core/waiters/waiter.rb +4 -2
- data/lib/aws-sdk-core/waiters.rb +2 -0
- data/lib/aws-sdk-core/xml/builder.rb +5 -3
- data/lib/aws-sdk-core/xml/default_list.rb +2 -0
- data/lib/aws-sdk-core/xml/default_map.rb +2 -0
- data/lib/aws-sdk-core/xml/doc_builder.rb +15 -4
- data/lib/aws-sdk-core/xml/error_handler.rb +29 -4
- data/lib/aws-sdk-core/xml/parser/engines/libxml.rb +2 -0
- data/lib/aws-sdk-core/xml/parser/engines/nokogiri.rb +2 -0
- data/lib/aws-sdk-core/xml/parser/engines/oga.rb +2 -0
- data/lib/aws-sdk-core/xml/parser/engines/ox.rb +3 -1
- data/lib/aws-sdk-core/xml/parser/engines/rexml.rb +4 -1
- data/lib/aws-sdk-core/xml/parser/frame.rb +25 -0
- data/lib/aws-sdk-core/xml/parser/parsing_error.rb +2 -0
- data/lib/aws-sdk-core/xml/parser/stack.rb +2 -0
- data/lib/aws-sdk-core/xml/parser.rb +7 -0
- data/lib/aws-sdk-core/xml.rb +2 -0
- data/lib/aws-sdk-core.rb +23 -4
- data/lib/aws-sdk-sso/client.rb +568 -0
- data/lib/aws-sdk-sso/client_api.rb +190 -0
- data/lib/aws-sdk-sso/customizations.rb +1 -0
- data/lib/aws-sdk-sso/errors.rb +102 -0
- data/lib/aws-sdk-sso/resource.rb +26 -0
- data/lib/aws-sdk-sso/types.rb +352 -0
- data/lib/aws-sdk-sso.rb +55 -0
- data/lib/aws-sdk-sts/client.rb +1282 -531
- data/lib/aws-sdk-sts/client_api.rb +76 -1
- data/lib/aws-sdk-sts/customizations.rb +4 -0
- data/lib/aws-sdk-sts/errors.rb +153 -1
- data/lib/aws-sdk-sts/plugins/sts_regional_endpoints.rb +38 -0
- data/lib/aws-sdk-sts/presigner.rb +75 -0
- data/lib/aws-sdk-sts/resource.rb +4 -1
- data/lib/aws-sdk-sts/types.rb +958 -229
- data/lib/aws-sdk-sts.rb +16 -6
- data/lib/seahorse/client/async_base.rb +52 -0
- data/lib/seahorse/client/async_response.rb +64 -0
- data/lib/seahorse/client/base.rb +7 -2
- data/lib/seahorse/client/block_io.rb +6 -2
- data/lib/seahorse/client/configuration.rb +7 -1
- data/lib/seahorse/client/events.rb +3 -1
- data/lib/seahorse/client/h2/connection.rb +250 -0
- data/lib/seahorse/client/h2/handler.rb +152 -0
- data/lib/seahorse/client/handler.rb +2 -0
- data/lib/seahorse/client/handler_builder.rb +2 -0
- data/lib/seahorse/client/handler_list.rb +2 -0
- data/lib/seahorse/client/handler_list_entry.rb +6 -4
- data/lib/seahorse/client/http/async_response.rb +44 -0
- data/lib/seahorse/client/http/headers.rb +2 -0
- data/lib/seahorse/client/http/request.rb +5 -3
- data/lib/seahorse/client/http/response.rb +18 -11
- data/lib/seahorse/client/logging/formatter.rb +6 -2
- data/lib/seahorse/client/logging/handler.rb +2 -0
- data/lib/seahorse/client/managed_file.rb +2 -0
- data/lib/seahorse/client/net_http/connection_pool.rb +30 -23
- data/lib/seahorse/client/net_http/handler.rb +24 -7
- data/lib/seahorse/client/net_http/patches.rb +15 -84
- data/lib/seahorse/client/networking_error.rb +30 -0
- data/lib/seahorse/client/plugin.rb +10 -7
- data/lib/seahorse/client/plugin_list.rb +2 -0
- data/lib/seahorse/client/plugins/content_length.rb +14 -3
- data/lib/seahorse/client/plugins/endpoint.rb +4 -2
- data/lib/seahorse/client/plugins/h2.rb +69 -0
- data/lib/seahorse/client/plugins/logging.rb +2 -0
- data/lib/seahorse/client/plugins/net_http.rb +39 -3
- data/lib/seahorse/client/plugins/operation_methods.rb +2 -0
- data/lib/seahorse/client/plugins/raise_response_errors.rb +2 -0
- data/lib/seahorse/client/plugins/request_callback.rb +110 -0
- data/lib/seahorse/client/plugins/response_target.rb +23 -14
- data/lib/seahorse/client/request.rb +2 -0
- data/lib/seahorse/client/request_context.rb +2 -0
- data/lib/seahorse/client/response.rb +5 -5
- data/lib/seahorse/model/api.rb +10 -0
- data/lib/seahorse/model/authorizer.rb +2 -0
- data/lib/seahorse/model/operation.rb +9 -0
- data/lib/seahorse/model/shapes.rb +29 -2
- data/lib/seahorse/util.rb +8 -1
- data/lib/seahorse/version.rb +2 -0
- data/lib/seahorse.rb +12 -0
- metadata +64 -14
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
module Aws
|
|
3
4
|
# @api private
|
|
4
5
|
class SharedConfig
|
|
6
|
+
SSO_PROFILE_KEYS = %w[sso_start_url sso_region sso_account_id sso_role_name].freeze
|
|
5
7
|
|
|
6
8
|
# @return [String]
|
|
7
9
|
attr_reader :credentials_path
|
|
@@ -48,7 +50,7 @@ module Aws
|
|
|
48
50
|
@profile_name = determine_profile(options)
|
|
49
51
|
@config_enabled = options[:config_enabled]
|
|
50
52
|
@credentials_path = options[:credentials_path] ||
|
|
51
|
-
|
|
53
|
+
determine_credentials_path
|
|
52
54
|
@parsed_credentials = {}
|
|
53
55
|
load_credentials_file if loadable?(@credentials_path)
|
|
54
56
|
if @config_enabled
|
|
@@ -67,7 +69,7 @@ module Aws
|
|
|
67
69
|
@config_enabled = options[:config_enabled] ? true : false
|
|
68
70
|
@profile_name = determine_profile(options)
|
|
69
71
|
@credentials_path = options[:credentials_path] ||
|
|
70
|
-
|
|
72
|
+
determine_credentials_path
|
|
71
73
|
load_credentials_file if loadable?(@credentials_path)
|
|
72
74
|
if @config_enabled
|
|
73
75
|
@config_path = options[:config_path] || determine_config_path
|
|
@@ -98,13 +100,11 @@ module Aws
|
|
|
98
100
|
# or `nil` if no valid credentials were found.
|
|
99
101
|
def credentials(opts = {})
|
|
100
102
|
p = opts[:profile] || @profile_name
|
|
101
|
-
validate_profile_exists(p)
|
|
102
|
-
if credentials = credentials_from_shared(p, opts)
|
|
103
|
+
validate_profile_exists(p)
|
|
104
|
+
if (credentials = credentials_from_shared(p, opts))
|
|
103
105
|
credentials
|
|
104
|
-
elsif credentials = credentials_from_config(p, opts)
|
|
106
|
+
elsif (credentials = credentials_from_config(p, opts))
|
|
105
107
|
credentials
|
|
106
|
-
else
|
|
107
|
-
nil
|
|
108
108
|
end
|
|
109
109
|
end
|
|
110
110
|
|
|
@@ -121,110 +121,107 @@ module Aws
|
|
|
121
121
|
credentials
|
|
122
122
|
end
|
|
123
123
|
|
|
124
|
-
def
|
|
124
|
+
def assume_role_web_identity_credentials_from_config(opts = {})
|
|
125
125
|
p = opts[:profile] || @profile_name
|
|
126
|
-
if @config_enabled
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
126
|
+
if @config_enabled && @parsed_config
|
|
127
|
+
entry = @parsed_config.fetch(p, {})
|
|
128
|
+
if entry['web_identity_token_file'] && entry['role_arn']
|
|
129
|
+
cfg = {
|
|
130
|
+
role_arn: entry['role_arn'],
|
|
131
|
+
web_identity_token_file: entry['web_identity_token_file'],
|
|
132
|
+
role_session_name: entry['role_session_name']
|
|
133
|
+
}
|
|
134
|
+
cfg[:region] = opts[:region] if opts[:region]
|
|
135
|
+
AssumeRoleWebIdentityCredentials.new(cfg)
|
|
132
136
|
end
|
|
133
|
-
region
|
|
134
|
-
else
|
|
135
|
-
nil
|
|
136
137
|
end
|
|
137
138
|
end
|
|
138
139
|
|
|
139
|
-
|
|
140
|
+
# Attempts to load from shared config or shared credentials file.
|
|
141
|
+
# Will always attempt first to load from the shared credentials
|
|
142
|
+
# file, if present.
|
|
143
|
+
def sso_credentials_from_config(opts = {})
|
|
140
144
|
p = opts[:profile] || @profile_name
|
|
141
|
-
|
|
142
|
-
|
|
145
|
+
credentials = sso_credentials_from_profile(@parsed_credentials, p)
|
|
146
|
+
if @parsed_config
|
|
147
|
+
credentials ||= sso_credentials_from_profile(@parsed_config, p)
|
|
143
148
|
end
|
|
149
|
+
credentials
|
|
144
150
|
end
|
|
145
151
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
p = opts[:profile] || @profile_name
|
|
153
|
-
if @config_enabled
|
|
154
|
-
if @parsed_credentials
|
|
155
|
-
value = @parsed_credentials.fetch(p, {})["csm_enabled"]
|
|
156
|
-
end
|
|
157
|
-
if @parsed_config
|
|
158
|
-
value ||= @parsed_config.fetch(p, {})["csm_enabled"]
|
|
159
|
-
end
|
|
160
|
-
value
|
|
161
|
-
else
|
|
162
|
-
nil
|
|
152
|
+
# Add an accessor method (similar to attr_reader) to return a configuration value
|
|
153
|
+
# Uses the get_config_value below to control where
|
|
154
|
+
# values are loaded from
|
|
155
|
+
def self.config_reader(*attrs)
|
|
156
|
+
attrs.each do |attr|
|
|
157
|
+
define_method(attr) { |opts = {}| get_config_value(attr.to_s, opts) }
|
|
163
158
|
end
|
|
164
159
|
end
|
|
165
160
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
161
|
+
config_reader(
|
|
162
|
+
:region,
|
|
163
|
+
:ca_bundle,
|
|
164
|
+
:credential_process,
|
|
165
|
+
:endpoint_discovery_enabled,
|
|
166
|
+
:use_dualstack_endpoint,
|
|
167
|
+
:use_fips_endpoint,
|
|
168
|
+
:ec2_metadata_service_endpoint,
|
|
169
|
+
:ec2_metadata_service_endpoint_mode,
|
|
170
|
+
:max_attempts,
|
|
171
|
+
:retry_mode,
|
|
172
|
+
:adaptive_retry_wait_to_fill,
|
|
173
|
+
:correct_clock_skew,
|
|
174
|
+
:csm_client_id,
|
|
175
|
+
:csm_enabled,
|
|
176
|
+
:csm_host,
|
|
177
|
+
:csm_port,
|
|
178
|
+
:sts_regional_endpoints,
|
|
179
|
+
:s3_use_arn_region,
|
|
180
|
+
:s3_us_east_1_regional_endpoint,
|
|
181
|
+
:s3_disable_multiregion_access_points,
|
|
182
|
+
:defaults_mode
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
private
|
|
180
186
|
|
|
181
|
-
|
|
187
|
+
# Get a config value from from shared credential/config files.
|
|
188
|
+
# Only loads a value when config_enabled is true
|
|
189
|
+
# Return a value from credentials preferentially over config
|
|
190
|
+
def get_config_value(key, opts)
|
|
182
191
|
p = opts[:profile] || @profile_name
|
|
183
|
-
if @config_enabled
|
|
184
|
-
if @parsed_credentials
|
|
185
|
-
value = @parsed_credentials.fetch(p, {})["csm_port"]
|
|
186
|
-
end
|
|
187
|
-
if @parsed_config
|
|
188
|
-
value ||= @parsed_config.fetch(p, {})["csm_port"]
|
|
189
|
-
end
|
|
190
|
-
value
|
|
191
|
-
else
|
|
192
|
-
nil
|
|
193
|
-
end
|
|
194
|
-
end
|
|
195
192
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
(@parsed_config && !@parsed_config.empty?)
|
|
193
|
+
value = @parsed_credentials.fetch(p, {})[key] if @parsed_credentials
|
|
194
|
+
value ||= @parsed_config.fetch(p, {})[key] if @config_enabled && @parsed_config
|
|
195
|
+
value
|
|
200
196
|
end
|
|
201
197
|
|
|
202
198
|
def assume_role_from_profile(cfg, profile, opts, chain_config)
|
|
203
199
|
if cfg && prof_cfg = cfg[profile]
|
|
204
|
-
opts[:source_profile] ||= prof_cfg[
|
|
200
|
+
opts[:source_profile] ||= prof_cfg['source_profile']
|
|
205
201
|
credential_source = opts.delete(:credential_source)
|
|
206
|
-
credential_source ||= prof_cfg[
|
|
202
|
+
credential_source ||= prof_cfg['credential_source']
|
|
207
203
|
if opts[:source_profile] && credential_source
|
|
208
|
-
raise Errors::CredentialSourceConflictError
|
|
204
|
+
raise Errors::CredentialSourceConflictError,
|
|
209
205
|
"Profile #{profile} has a source_profile, and "\
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
)
|
|
206
|
+
'a credential_source. For assume role credentials, must '\
|
|
207
|
+
'provide only source_profile or credential_source, not both.'
|
|
213
208
|
elsif opts[:source_profile]
|
|
214
|
-
opts[:
|
|
209
|
+
opts[:visited_profiles] ||= Set.new
|
|
210
|
+
opts[:credentials] = resolve_source_profile(opts[:source_profile], opts)
|
|
215
211
|
if opts[:credentials]
|
|
216
|
-
opts[:role_session_name] ||= prof_cfg[
|
|
217
|
-
opts[:role_session_name] ||=
|
|
218
|
-
opts[:role_arn] ||= prof_cfg[
|
|
219
|
-
opts[:
|
|
220
|
-
opts[:
|
|
212
|
+
opts[:role_session_name] ||= prof_cfg['role_session_name']
|
|
213
|
+
opts[:role_session_name] ||= 'default_session'
|
|
214
|
+
opts[:role_arn] ||= prof_cfg['role_arn']
|
|
215
|
+
opts[:duration_seconds] ||= prof_cfg['duration_seconds']
|
|
216
|
+
opts[:external_id] ||= prof_cfg['external_id']
|
|
217
|
+
opts[:serial_number] ||= prof_cfg['mfa_serial']
|
|
221
218
|
opts[:profile] = opts.delete(:source_profile)
|
|
219
|
+
opts.delete(:visited_profiles)
|
|
222
220
|
AssumeRoleCredentials.new(opts)
|
|
223
221
|
else
|
|
224
|
-
raise Errors::NoSourceProfileError
|
|
222
|
+
raise Errors::NoSourceProfileError,
|
|
225
223
|
"Profile #{profile} has a role_arn, and source_profile, but the"\
|
|
226
|
-
|
|
227
|
-
)
|
|
224
|
+
' source_profile does not have credentials.'
|
|
228
225
|
end
|
|
229
226
|
elsif credential_source
|
|
230
227
|
opts[:credentials] = credentials_from_source(
|
|
@@ -232,61 +229,99 @@ module Aws
|
|
|
232
229
|
chain_config
|
|
233
230
|
)
|
|
234
231
|
if opts[:credentials]
|
|
235
|
-
opts[:role_session_name] ||= prof_cfg[
|
|
236
|
-
opts[:role_session_name] ||=
|
|
237
|
-
opts[:role_arn] ||= prof_cfg[
|
|
238
|
-
opts[:
|
|
239
|
-
opts[:
|
|
232
|
+
opts[:role_session_name] ||= prof_cfg['role_session_name']
|
|
233
|
+
opts[:role_session_name] ||= 'default_session'
|
|
234
|
+
opts[:role_arn] ||= prof_cfg['role_arn']
|
|
235
|
+
opts[:duration_seconds] ||= prof_cfg['duration_seconds']
|
|
236
|
+
opts[:external_id] ||= prof_cfg['external_id']
|
|
237
|
+
opts[:serial_number] ||= prof_cfg['mfa_serial']
|
|
240
238
|
opts.delete(:source_profile) # Cleanup
|
|
241
239
|
AssumeRoleCredentials.new(opts)
|
|
242
240
|
else
|
|
243
|
-
raise Errors::NoSourceCredentials
|
|
241
|
+
raise Errors::NoSourceCredentials,
|
|
244
242
|
"Profile #{profile} could not get source credentials from"\
|
|
245
|
-
|
|
246
|
-
)
|
|
243
|
+
" provider #{credential_source}"
|
|
247
244
|
end
|
|
248
|
-
elsif prof_cfg[
|
|
249
|
-
raise Errors::NoSourceProfileError.
|
|
250
|
-
"Profile #{profile} has a role_arn, but no source_profile."
|
|
251
|
-
)
|
|
252
|
-
else
|
|
253
|
-
nil
|
|
245
|
+
elsif prof_cfg['role_arn']
|
|
246
|
+
raise Errors::NoSourceProfileError, "Profile #{profile} has a role_arn, but no source_profile."
|
|
254
247
|
end
|
|
255
|
-
|
|
256
|
-
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def resolve_source_profile(profile, opts = {})
|
|
252
|
+
if opts[:visited_profiles] && opts[:visited_profiles].include?(profile)
|
|
253
|
+
raise Errors::SourceProfileCircularReferenceError
|
|
254
|
+
end
|
|
255
|
+
opts[:visited_profiles].add(profile) if opts[:visited_profiles]
|
|
256
|
+
|
|
257
|
+
profile_config = @parsed_credentials[profile]
|
|
258
|
+
if @config_enabled
|
|
259
|
+
profile_config ||= @parsed_config[profile]
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
if (creds = credentials(profile: profile))
|
|
263
|
+
creds # static credentials
|
|
264
|
+
elsif profile_config && profile_config['source_profile']
|
|
265
|
+
opts.delete(:source_profile)
|
|
266
|
+
assume_role_credentials_from_config(opts.merge(profile: profile))
|
|
267
|
+
elsif (provider = assume_role_web_identity_credentials_from_config(opts.merge(profile: profile)))
|
|
268
|
+
provider.credentials if provider.credentials.set?
|
|
269
|
+
elsif (provider = assume_role_process_credentials_from_config(profile))
|
|
270
|
+
provider.credentials if provider.credentials.set?
|
|
271
|
+
elsif (provider = sso_credentials_from_config(profile: profile))
|
|
272
|
+
provider.credentials if provider.credentials.set?
|
|
257
273
|
end
|
|
258
274
|
end
|
|
259
275
|
|
|
260
276
|
def credentials_from_source(credential_source, config)
|
|
261
277
|
case credential_source
|
|
262
|
-
when
|
|
278
|
+
when 'Ec2InstanceMetadata'
|
|
263
279
|
InstanceProfileCredentials.new(
|
|
264
280
|
retries: config ? config.instance_profile_credentials_retries : 0,
|
|
265
281
|
http_open_timeout: config ? config.instance_profile_credentials_timeout : 1,
|
|
266
282
|
http_read_timeout: config ? config.instance_profile_credentials_timeout : 1
|
|
267
283
|
)
|
|
268
|
-
when
|
|
284
|
+
when 'EcsContainer'
|
|
269
285
|
ECSCredentials.new
|
|
270
286
|
else
|
|
271
|
-
raise Errors::InvalidCredentialSourceError
|
|
272
|
-
|
|
273
|
-
|
|
287
|
+
raise Errors::InvalidCredentialSourceError, "Unsupported credential_source: #{credential_source}"
|
|
288
|
+
end
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def assume_role_process_credentials_from_config(profile)
|
|
292
|
+
validate_profile_exists(profile)
|
|
293
|
+
credential_process = @parsed_credentials.fetch(profile, {})['credential_process']
|
|
294
|
+
if @parsed_config
|
|
295
|
+
credential_process ||= @parsed_config.fetch(profile, {})['credential_process']
|
|
274
296
|
end
|
|
297
|
+
ProcessCredentials.new(credential_process) if credential_process
|
|
275
298
|
end
|
|
276
299
|
|
|
277
|
-
def credentials_from_shared(profile,
|
|
300
|
+
def credentials_from_shared(profile, _opts)
|
|
278
301
|
if @parsed_credentials && prof_config = @parsed_credentials[profile]
|
|
279
302
|
credentials_from_profile(prof_config)
|
|
280
|
-
else
|
|
281
|
-
nil
|
|
282
303
|
end
|
|
283
304
|
end
|
|
284
305
|
|
|
285
|
-
def credentials_from_config(profile,
|
|
306
|
+
def credentials_from_config(profile, _opts)
|
|
286
307
|
if @parsed_config && prof_config = @parsed_config[profile]
|
|
287
308
|
credentials_from_profile(prof_config)
|
|
288
|
-
|
|
289
|
-
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
# If any of the sso_ profile values are present, attempt to construct
|
|
313
|
+
# SSOCredentials
|
|
314
|
+
def sso_credentials_from_profile(cfg, profile)
|
|
315
|
+
if @parsed_config &&
|
|
316
|
+
(prof_config = cfg[profile]) &&
|
|
317
|
+
!(prof_config.keys & SSO_PROFILE_KEYS).empty?
|
|
318
|
+
|
|
319
|
+
SSOCredentials.new(
|
|
320
|
+
sso_start_url: prof_config['sso_start_url'],
|
|
321
|
+
sso_region: prof_config['sso_region'],
|
|
322
|
+
sso_account_id: prof_config['sso_account_id'],
|
|
323
|
+
sso_role_name: prof_config['sso_role_name']
|
|
324
|
+
)
|
|
290
325
|
end
|
|
291
326
|
end
|
|
292
327
|
|
|
@@ -296,15 +331,7 @@ module Aws
|
|
|
296
331
|
prof_config['aws_secret_access_key'],
|
|
297
332
|
prof_config['aws_session_token']
|
|
298
333
|
)
|
|
299
|
-
if
|
|
300
|
-
creds
|
|
301
|
-
else
|
|
302
|
-
nil
|
|
303
|
-
end
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
def credentials_complete(creds)
|
|
307
|
-
creds.set?
|
|
334
|
+
creds if creds.set?
|
|
308
335
|
end
|
|
309
336
|
|
|
310
337
|
def load_credentials_file
|
|
@@ -334,19 +361,18 @@ module Aws
|
|
|
334
361
|
|
|
335
362
|
def validate_profile_exists(profile)
|
|
336
363
|
unless (@parsed_credentials && @parsed_credentials[profile]) ||
|
|
337
|
-
|
|
338
|
-
msg = "Profile `#{profile}' not found in #{@credentials_path}"
|
|
339
|
-
|
|
340
|
-
raise Errors::NoSuchProfileError
|
|
364
|
+
(@parsed_config && @parsed_config[profile])
|
|
365
|
+
msg = "Profile `#{profile}' not found in #{@credentials_path}"\
|
|
366
|
+
"#{" or #{@config_path}" if @config_path}"
|
|
367
|
+
raise Errors::NoSuchProfileError, msg
|
|
341
368
|
end
|
|
342
369
|
end
|
|
343
370
|
|
|
344
371
|
def determine_profile(options)
|
|
345
372
|
ret = options[:profile_name]
|
|
346
|
-
ret ||= ENV[
|
|
347
|
-
ret ||=
|
|
373
|
+
ret ||= ENV['AWS_PROFILE']
|
|
374
|
+
ret ||= 'default'
|
|
348
375
|
ret
|
|
349
376
|
end
|
|
350
|
-
|
|
351
377
|
end
|
|
352
378
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative 'ini_parser'
|
|
2
4
|
|
|
3
5
|
module Aws
|
|
@@ -12,11 +14,17 @@ module Aws
|
|
|
12
14
|
'aws_session_token' => 'session_token',
|
|
13
15
|
}
|
|
14
16
|
|
|
15
|
-
# Constructs a new SharedCredentials object. This will load
|
|
17
|
+
# Constructs a new SharedCredentials object. This will load static
|
|
18
|
+
# (access_key_id, secret_access_key and session_token) AWS access
|
|
16
19
|
# credentials from an ini file, which supports profiles. The default
|
|
17
20
|
# profile name is 'default'. You can specify the profile name with the
|
|
18
21
|
# `ENV['AWS_PROFILE']` or with the `:profile_name` option.
|
|
19
22
|
#
|
|
23
|
+
# To use credentials from the default credential resolution chain
|
|
24
|
+
# create a client without the credential option specified.
|
|
25
|
+
# You may access the resolved credentials through
|
|
26
|
+
# `client.config.credentials`.
|
|
27
|
+
#
|
|
20
28
|
# @option [String] :path Path to the shared file. Defaults
|
|
21
29
|
# to "#{Dir.home}/.aws/credentials".
|
|
22
30
|
#
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Aws
|
|
4
|
+
# An auto-refreshing credential provider that works by assuming a
|
|
5
|
+
# role via {Aws::SSO::Client#get_role_credentials} using a cached access
|
|
6
|
+
# token. This class does NOT implement the SSO login token flow - tokens
|
|
7
|
+
# must generated and refreshed separately by running `aws login` from the
|
|
8
|
+
# AWS CLI with the correct profile.
|
|
9
|
+
#
|
|
10
|
+
# For more background on AWS SSO see the official
|
|
11
|
+
# {https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html what is SSO Userguide}
|
|
12
|
+
#
|
|
13
|
+
# ## Refreshing Credentials from SSO
|
|
14
|
+
#
|
|
15
|
+
# The `SSOCredentials` will auto-refresh the AWS credentials from SSO. In
|
|
16
|
+
# addition to AWS credentials expiring after a given amount of time, the
|
|
17
|
+
# access token generated and cached from `aws login` will also expire.
|
|
18
|
+
# Once this token expires, it will not be usable to refresh AWS credentials,
|
|
19
|
+
# and another token will be needed. The SDK does not manage refreshing of
|
|
20
|
+
# the token value, but this can be done by running `aws login` with the
|
|
21
|
+
# correct profile.
|
|
22
|
+
#
|
|
23
|
+
#
|
|
24
|
+
# # You must first run aws sso login --profile your-sso-profile
|
|
25
|
+
# sso_credentials = Aws::SSOCredentials.new(
|
|
26
|
+
# sso_account_id: '123456789',
|
|
27
|
+
# sso_role_name: "role_name",
|
|
28
|
+
# sso_region: "us-east-1",
|
|
29
|
+
# sso_start_url: 'https://your-start-url.awsapps.com/start'
|
|
30
|
+
# )
|
|
31
|
+
#
|
|
32
|
+
# ec2 = Aws::EC2::Client.new(credentials: sso_credentials)
|
|
33
|
+
#
|
|
34
|
+
# If you omit `:client` option, a new {SSO::Client} object will be
|
|
35
|
+
# constructed.
|
|
36
|
+
class SSOCredentials
|
|
37
|
+
|
|
38
|
+
include CredentialProvider
|
|
39
|
+
include RefreshingCredentials
|
|
40
|
+
|
|
41
|
+
# @api private
|
|
42
|
+
SSO_REQUIRED_OPTS = [:sso_account_id, :sso_region, :sso_role_name, :sso_start_url].freeze
|
|
43
|
+
|
|
44
|
+
# @api private
|
|
45
|
+
SSO_LOGIN_GUIDANCE = 'The SSO session associated with this profile has '\
|
|
46
|
+
'expired or is otherwise invalid. To refresh this SSO session run '\
|
|
47
|
+
'aws sso login with the corresponding profile.'.freeze
|
|
48
|
+
|
|
49
|
+
# @option options [required, String] :sso_account_id The AWS account ID
|
|
50
|
+
# that temporary AWS credentials will be resolved for
|
|
51
|
+
#
|
|
52
|
+
# @option options [required, String] :sso_region The AWS region where the
|
|
53
|
+
# SSO directory for the given sso_start_url is hosted.
|
|
54
|
+
#
|
|
55
|
+
# @option options [required, String] :sso_role_name The corresponding
|
|
56
|
+
# IAM role in the AWS account that temporary AWS credentials
|
|
57
|
+
# will be resolved for.
|
|
58
|
+
#
|
|
59
|
+
# @option options [required, String] :sso_start_url The start URL is
|
|
60
|
+
# provided by the SSO service via the console and is the URL used to
|
|
61
|
+
# login to the SSO directory. This is also sometimes referred to as
|
|
62
|
+
# the "User Portal URL"
|
|
63
|
+
#
|
|
64
|
+
# @option options [SSO::Client] :client Optional `SSO::Client`. If not
|
|
65
|
+
# provided, a client will be constructed.
|
|
66
|
+
#
|
|
67
|
+
# @option options [Callable] before_refresh Proc called before
|
|
68
|
+
# credentials are refreshed. `before_refresh` is called
|
|
69
|
+
# with an instance of this object when
|
|
70
|
+
# AWS credentials are required and need to be refreshed.
|
|
71
|
+
def initialize(options = {})
|
|
72
|
+
|
|
73
|
+
missing_keys = SSO_REQUIRED_OPTS.select { |k| options[k].nil? }
|
|
74
|
+
unless missing_keys.empty?
|
|
75
|
+
raise ArgumentError, "Missing required keys: #{missing_keys}"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
@sso_start_url = options.delete(:sso_start_url)
|
|
79
|
+
@sso_region = options.delete(:sso_region)
|
|
80
|
+
@sso_role_name = options.delete(:sso_role_name)
|
|
81
|
+
@sso_account_id = options.delete(:sso_account_id)
|
|
82
|
+
|
|
83
|
+
# validate we can read the token file
|
|
84
|
+
read_cached_token
|
|
85
|
+
|
|
86
|
+
options[:region] = @sso_region
|
|
87
|
+
options[:credentials] = nil
|
|
88
|
+
@client = options[:client] || Aws::SSO::Client.new(options)
|
|
89
|
+
super
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# @return [SSO::Client]
|
|
93
|
+
attr_reader :client
|
|
94
|
+
|
|
95
|
+
private
|
|
96
|
+
|
|
97
|
+
def read_cached_token
|
|
98
|
+
cached_token = Json.load(File.read(sso_cache_file))
|
|
99
|
+
# validation
|
|
100
|
+
unless cached_token['accessToken'] && cached_token['expiresAt']
|
|
101
|
+
raise ArgumentError, 'Missing required field(s)'
|
|
102
|
+
end
|
|
103
|
+
expires_at = DateTime.parse(cached_token['expiresAt'])
|
|
104
|
+
if expires_at < DateTime.now
|
|
105
|
+
raise ArgumentError, 'Cached SSO Token is expired.'
|
|
106
|
+
end
|
|
107
|
+
cached_token
|
|
108
|
+
rescue Errno::ENOENT, Aws::Json::ParseError, ArgumentError
|
|
109
|
+
raise Errors::InvalidSSOCredentials, SSO_LOGIN_GUIDANCE
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def refresh
|
|
113
|
+
cached_token = read_cached_token
|
|
114
|
+
c = @client.get_role_credentials(
|
|
115
|
+
account_id: @sso_account_id,
|
|
116
|
+
role_name: @sso_role_name,
|
|
117
|
+
access_token: cached_token['accessToken']
|
|
118
|
+
).role_credentials
|
|
119
|
+
|
|
120
|
+
@credentials = Credentials.new(
|
|
121
|
+
c.access_key_id,
|
|
122
|
+
c.secret_access_key,
|
|
123
|
+
c.session_token
|
|
124
|
+
)
|
|
125
|
+
@expiration = c.expiration
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def sso_cache_file
|
|
129
|
+
start_url_sha1 = OpenSSL::Digest::SHA1.hexdigest(@sso_start_url.encode('utf-8'))
|
|
130
|
+
File.join(Dir.home, '.aws', 'sso', 'cache', "#{start_url_sha1}.json")
|
|
131
|
+
rescue ArgumentError
|
|
132
|
+
# Dir.home raises ArgumentError when ENV['home'] is not set
|
|
133
|
+
raise ArgumentError, "Unable to load sso_cache_file: ENV['HOME'] is not set."
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Aws
|
|
2
4
|
# @api private
|
|
3
5
|
module Structure
|
|
@@ -29,8 +31,7 @@ module Aws
|
|
|
29
31
|
def to_h(obj = self)
|
|
30
32
|
case obj
|
|
31
33
|
when Struct
|
|
32
|
-
obj.
|
|
33
|
-
value = obj[member]
|
|
34
|
+
obj.each_pair.with_object({}) do |(member, value), hash|
|
|
34
35
|
hash[member] = to_hash(value) unless value.nil?
|
|
35
36
|
end
|
|
36
37
|
when Hash
|
|
@@ -47,7 +48,7 @@ module Aws
|
|
|
47
48
|
|
|
48
49
|
# Wraps the default #to_s logic with filtering of sensitive parameters.
|
|
49
50
|
def to_s(obj = self)
|
|
50
|
-
Aws::Log::ParamFilter.new.filter(obj).to_s
|
|
51
|
+
Aws::Log::ParamFilter.new.filter(obj, obj.class).to_s
|
|
51
52
|
end
|
|
52
53
|
|
|
53
54
|
class << self
|
|
@@ -69,11 +70,20 @@ module Aws
|
|
|
69
70
|
end
|
|
70
71
|
|
|
71
72
|
end
|
|
73
|
+
|
|
74
|
+
module Union
|
|
75
|
+
def member
|
|
76
|
+
self.members.select { |k| self[k] != nil }.first
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def value
|
|
80
|
+
self[member] if member
|
|
81
|
+
end
|
|
82
|
+
end
|
|
72
83
|
end
|
|
73
84
|
|
|
74
85
|
# @api private
|
|
75
86
|
class EmptyStructure < Struct.new('AwsEmptyStructure')
|
|
76
87
|
include(Aws::Structure)
|
|
77
88
|
end
|
|
78
|
-
|
|
79
89
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Aws
|
|
2
4
|
module Stubbing
|
|
3
5
|
module Protocols
|
|
@@ -27,7 +29,7 @@ module Aws
|
|
|
27
29
|
private
|
|
28
30
|
|
|
29
31
|
def content_type(api)
|
|
30
|
-
"application/x-amz-json-#{api.metadata['
|
|
32
|
+
"application/x-amz-json-#{api.metadata['jsonVersion']}"
|
|
31
33
|
end
|
|
32
34
|
|
|
33
35
|
def build_body(operation, data)
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Aws
|
|
2
4
|
module Stubbing
|
|
3
5
|
module Protocols
|
|
@@ -23,9 +25,9 @@ module Aws
|
|
|
23
25
|
xml = []
|
|
24
26
|
builder = Aws::Xml::DocBuilder.new(target: xml, indent: ' ')
|
|
25
27
|
builder.node(operation.name + 'Response', xmlns: xmlns(api)) do
|
|
26
|
-
if rules = operation.output
|
|
28
|
+
if (rules = operation.output)
|
|
27
29
|
rules.location_name = operation.name + 'Result'
|
|
28
|
-
Xml::Builder.new(rules, target:xml, pad:' ').to_xml(data)
|
|
30
|
+
Xml::Builder.new(rules, target: xml, pad:' ').to_xml(data)
|
|
29
31
|
end
|
|
30
32
|
builder.node('ResponseMetadata') do
|
|
31
33
|
builder.node('RequestId', 'stubbed-request-id')
|