aws-sdk-core 3.104.3 → 3.109.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7357ce5a3cd95241ed7e567a86b6f3e9edbfd324124b0cab96116b20f41197a6
4
- data.tar.gz: 8b255e4d03b48ff6cdf80167e3a115085b09aac23323f891daf305c93d3f7fb6
3
+ metadata.gz: 9be12fd3781d8257feb49c005af422cc726da47592e55368ebc3ce4d8032e21b
4
+ data.tar.gz: 28b66904da66dc5ab09acfb20fd37dd250cc6e83c54d6735b6b3e8b15ea22f72
5
5
  SHA512:
6
- metadata.gz: 57822a88212cd847c75ed5d0bd958962a3559ec92330e46eea7ab2b7a13fcf2d8fbeea3e0dc87f4beffa6ecdf5f2e17b15985781d720caf5eff803decf53284c
7
- data.tar.gz: 674a1b2b308b44f32ea037878292c9ea621c8734559acdcfde7b7008bb48bd1be183c4c29899cbed0d9355555e2801fdaffd5d52bf3a18c7d32c83c7f6785f72
6
+ metadata.gz: fb1a6fb1b39908e6627b4fae6331fd3574d34e10c413ddc55927460af5a7d8ac11abe1b7ecb7313c6faa141ddaf81c9173b76d33588cefc9e8c563573dc96682
7
+ data.tar.gz: ca41b1a8705dd842e72d147e4c8ba0c1aa167942f5db16ca456922604cc6a6582a498329e0178fc1b8880189587d4aa204f460c0fc7edc7c8930be2d97c650d2
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.104.3
1
+ 3.109.0
@@ -18,9 +18,9 @@ require_relative 'aws-sdk-core/ecs_credentials'
18
18
  require_relative 'aws-sdk-core/instance_profile_credentials'
19
19
  require_relative 'aws-sdk-core/shared_credentials'
20
20
  require_relative 'aws-sdk-core/process_credentials'
21
+ require_relative 'aws-sdk-core/sso_credentials'
21
22
 
22
23
  # client modules
23
-
24
24
  require_relative 'aws-sdk-core/client_stubs'
25
25
  require_relative 'aws-sdk-core/async_client_stubs'
26
26
  require_relative 'aws-sdk-core/eager_loader'
@@ -86,10 +86,12 @@ require_relative 'aws-sdk-core/client_side_monitoring/publisher'
86
86
  require_relative 'aws-sdk-core/arn'
87
87
  require_relative 'aws-sdk-core/arn_parser'
88
88
 
89
- # aws-sdk-sts is vendored to support Aws::AssumeRoleCredentials
90
-
89
+ # aws-sdk-sts is included to support Aws::AssumeRoleCredentials
91
90
  require 'aws-sdk-sts'
92
91
 
92
+ # aws-sdk-sso is included to support Aws::SSOCredentials
93
+ require 'aws-sdk-sso'
94
+
93
95
  module Aws
94
96
 
95
97
  CORE_GEM_VERSION = File.read(File.expand_path('../../VERSION', __FILE__)).strip
@@ -75,5 +75,18 @@ module Aws
75
75
  def to_s
76
76
  "arn:#{partition}:#{service}:#{region}:#{account_id}:#{resource}"
77
77
  end
78
+
79
+ # Return the ARN as a hash
80
+ #
81
+ # @return [Hash]
82
+ def to_h
83
+ {
84
+ partition: @partition,
85
+ service: @service,
86
+ region: @region,
87
+ account_id: @account_id,
88
+ resource: @resource
89
+ }
90
+ end
78
91
  end
79
92
  end
@@ -22,11 +22,13 @@ module Aws
22
22
  [
23
23
  [:static_credentials, {}],
24
24
  [:static_profile_assume_role_web_identity_credentials, {}],
25
+ [:static_profile_sso_credentials, {}],
25
26
  [:static_profile_assume_role_credentials, {}],
26
27
  [:static_profile_credentials, {}],
27
28
  [:static_profile_process_credentials, {}],
28
29
  [:env_credentials, {}],
29
30
  [:assume_role_web_identity_credentials, {}],
31
+ [:sso_credentials, {}],
30
32
  [:assume_role_credentials, {}],
31
33
  [:shared_credentials, {}],
32
34
  [:process_credentials, {}],
@@ -57,6 +59,14 @@ module Aws
57
59
  end
58
60
  end
59
61
 
62
+ def static_profile_sso_credentials(options)
63
+ if Aws.shared_config.config_enabled? && options[:config] && options[:config].profile
64
+ Aws.shared_config.sso_credentials_from_config(
65
+ profile: options[:config].profile
66
+ )
67
+ end
68
+ end
69
+
60
70
  def static_profile_assume_role_credentials(options)
61
71
  if Aws.shared_config.config_enabled? && options[:config] && options[:config].profile
62
72
  assume_role_with_profile(options, options[:config].profile)
@@ -115,6 +125,15 @@ module Aws
115
125
  nil
116
126
  end
117
127
 
128
+ def sso_credentials(options)
129
+ profile_name = determine_profile_name(options)
130
+ if Aws.shared_config.config_enabled?
131
+ Aws.shared_config.sso_credentials_from_config(profile: profile_name)
132
+ end
133
+ rescue Errors::NoSuchProfileError
134
+ nil
135
+ end
136
+
118
137
  def assume_role_credentials(options)
119
138
  if Aws.shared_config.config_enabled?
120
139
  assume_role_with_profile(options, determine_profile_name(options))
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
3
  require 'time'
5
4
  require 'net/http'
6
5
 
@@ -81,8 +80,8 @@ module Aws
81
80
  # service is responding but is returning invalid JSON documents
82
81
  # in response to the GET profile credentials call.
83
82
  begin
84
- retry_errors([JSON::ParserError, StandardError], max_retries: 3) do
85
- c = JSON.parse(get_credentials.to_s)
83
+ retry_errors([Aws::Json::ParseError, StandardError], max_retries: 3) do
84
+ c = Aws::Json.load(get_credentials.to_s)
86
85
  @credentials = Credentials.new(
87
86
  c['AccessKeyId'],
88
87
  c['SecretAccessKey'],
@@ -90,7 +89,7 @@ module Aws
90
89
  )
91
90
  @expiration = c['Expiration'] ? Time.iso8601(c['Expiration']) : nil
92
91
  end
93
- rescue JSON::ParserError
92
+ rescue Aws::Json::ParseError
94
93
  raise Aws::Errors::MetadataParserError.new
95
94
  end
96
95
  end
@@ -207,6 +207,9 @@ module Aws
207
207
  # payload with either invalid version number or malformed contents
208
208
  class InvalidProcessCredentialsPayload < RuntimeError; end
209
209
 
210
+ # Raised when SSO Credentials are invalid
211
+ class InvalidSSOCredentials < RuntimeError; end
212
+
210
213
  # Raised when a client is constructed and region is not specified.
211
214
  class MissingRegionError < ArgumentError
212
215
  def initialize(*args)
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'json'
4
3
  require 'time'
5
4
  require 'net/http'
6
5
 
@@ -92,8 +91,8 @@ module Aws
92
91
  # service is responding but is returning invalid JSON documents
93
92
  # in response to the GET profile credentials call.
94
93
  begin
95
- retry_errors([JSON::ParserError, StandardError], max_retries: 3) do
96
- c = JSON.parse(get_credentials.to_s)
94
+ retry_errors([Aws::Json::ParseError, StandardError], max_retries: 3) do
95
+ c = Aws::Json.load(get_credentials.to_s)
97
96
  @credentials = Credentials.new(
98
97
  c['AccessKeyId'],
99
98
  c['SecretAccessKey'],
@@ -101,7 +100,7 @@ module Aws
101
100
  )
102
101
  @expiration = c['Expiration'] ? Time.iso8601(c['Expiration']) : nil
103
102
  end
104
- rescue JSON::ParserError
103
+ rescue Aws::Json::ParseError
105
104
  raise Aws::Errors::MetadataParserError
106
105
  end
107
106
  end
@@ -39,7 +39,7 @@ module Aws
39
39
  require 'oj'
40
40
  [
41
41
  Oj,
42
- [{ mode: :compat, symbol_keys: false }],
42
+ [{ mode: :compat, symbol_keys: false, empty_string: false }],
43
43
  [{ mode: :compat }],
44
44
  oj_parse_error
45
45
  ]
@@ -30,13 +30,28 @@ following classes:
30
30
  * `Aws::Credentials` - Used for configuring static, non-refreshing
31
31
  credentials.
32
32
 
33
+ * `Aws::SharedCredentials` - Used for loading static credentials from a
34
+ shared file, such as `~/.aws/config`.
35
+
36
+ * `Aws::AssumeRoleCredentials` - Used when you need to assume a role.
37
+
38
+ * `Aws::AssumeRoleWebIdentityCredentials` - Used when you need to
39
+ assume a role after providing credentials via the web.
40
+
41
+ * `Aws::SSOCredentials` - Used for loading credentials from AWS SSO using an
42
+ access token generated from `aws login`.
43
+
44
+ * `Aws::ProcessCredentials` - Used for loading credentials from a
45
+ process that outputs to stdout.
46
+
33
47
  * `Aws::InstanceProfileCredentials` - Used for loading credentials
34
48
  from an EC2 IMDS on an EC2 instance.
35
49
 
36
- * `Aws::SharedCredentials` - Used for loading credentials from a
37
- shared file, such as `~/.aws/config`.
50
+ * `Aws::ECSCredentials` - Used for loading credentials from
51
+ instances running in ECS.
38
52
 
39
- * `Aws::AssumeRoleCredentials` - Used when you need to assume a role.
53
+ * `Aws::CognitoIdentityCredentials` - Used for loading credentials
54
+ from the Cognito Identity service.
40
55
 
41
56
  When `:credentials` are not configured directly, the following
42
57
  locations will be searched for credentials:
@@ -46,10 +61,10 @@ locations will be searched for credentials:
46
61
  * ENV['AWS_ACCESS_KEY_ID'], ENV['AWS_SECRET_ACCESS_KEY']
47
62
  * `~/.aws/credentials`
48
63
  * `~/.aws/config`
49
- * EC2 IMDS instance profile - When used by default, the timeouts are
50
- very aggressive. Construct and pass an instance of
51
- `Aws::InstanceProfileCredentails` to enable retries and extended
52
- timeouts.
64
+ * EC2/ECS IMDS instance profile - When used by default, the timeouts
65
+ are very aggressive. Construct and pass an instance of
66
+ `Aws::InstanceProfileCredentails` or `Aws::ECSCredentials` to
67
+ enable retries and extended timeouts.
53
68
  DOCS
54
69
  ) do |config|
55
70
  CredentialProviderChain.new(config).resolve
@@ -15,17 +15,18 @@ to default service endpoint when available.
15
15
  )
16
16
 
17
17
  def add_handlers(handlers, config)
18
- if config.regional_endpoint && !config.disable_host_prefix_injection
19
- handlers.add(Handler, priority: 90)
20
- end
18
+ handlers.add(Handler, priority: 10)
21
19
  end
22
20
 
23
21
  class Handler < Seahorse::Client::Handler
24
22
 
25
23
  def call(context)
26
- endpoint_trait = context.operation.endpoint_pattern
27
- if endpoint_trait && !endpoint_trait.empty?
28
- _apply_endpoint_trait(context, endpoint_trait)
24
+ if context.config.regional_endpoint &&
25
+ !context.config.disable_host_prefix_injection
26
+ endpoint_trait = context.operation.endpoint_pattern
27
+ if endpoint_trait && !endpoint_trait.empty?
28
+ _apply_endpoint_trait(context, endpoint_trait)
29
+ end
29
30
  end
30
31
  @handler.call(context)
31
32
  end
@@ -38,7 +38,7 @@ to test or custom endpoints. This should be a valid HTTP(S) URI.
38
38
  end
39
39
 
40
40
  # check region is a valid RFC host label
41
- unless cfg.region =~ /^(?![0-9]+$)(?!-)[a-zA-Z0-9-]{,63}(?<!-)$/
41
+ unless Seahorse::Util.host_label?(cfg.region)
42
42
  raise Errors::InvalidRegionError
43
43
  end
44
44
 
@@ -42,8 +42,8 @@ module Aws
42
42
 
43
43
  if process_status.success?
44
44
  begin
45
- creds_json = JSON.parse(raw_out)
46
- rescue JSON::ParserError
45
+ creds_json = Aws::Json.load(raw_out)
46
+ rescue Aws::Json::ParseError
47
47
  raise Errors::InvalidProcessCredentialsPayload.new("Invalid JSON response")
48
48
  end
49
49
  payload_version = creds_json['Version']
@@ -2,7 +2,6 @@
2
2
 
3
3
  require 'time'
4
4
  require 'base64'
5
- require 'json'
6
5
 
7
6
  module Aws
8
7
  module Rest
@@ -68,7 +67,7 @@ module Aws
68
67
  end
69
68
 
70
69
  def extract_json_trait(value)
71
- JSON.parse(Base64.decode64(value))
70
+ Aws::Json.load(Base64.decode64(value))
72
71
  end
73
72
 
74
73
  end
@@ -3,6 +3,8 @@
3
3
  module Aws
4
4
  # @api private
5
5
  class SharedConfig
6
+ SSO_PROFILE_KEYS = %w[sso_start_url sso_region sso_account_id sso_role_name].freeze
7
+
6
8
  # @return [String]
7
9
  attr_reader :credentials_path
8
10
 
@@ -135,6 +137,18 @@ module Aws
135
137
  end
136
138
  end
137
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 = {})
144
+ p = opts[:profile] || @profile_name
145
+ credentials = sso_credentials_from_profile(@parsed_credentials, p)
146
+ if @parsed_config
147
+ credentials ||= sso_credentials_from_profile(@parsed_config, p)
148
+ end
149
+ credentials
150
+ end
151
+
138
152
  # Add an accessor method (similar to attr_reader) to return a configuration value
139
153
  # Uses the get_config_value below to control where
140
154
  # values are loaded from
@@ -146,6 +160,7 @@ module Aws
146
160
 
147
161
  config_reader(
148
162
  :region,
163
+ :ca_bundle,
149
164
  :credential_process,
150
165
  :endpoint_discovery_enabled,
151
166
  :max_attempts,
@@ -237,6 +252,8 @@ module Aws
237
252
  provider.credentials if provider.credentials.set?
238
253
  elsif (provider = assume_role_process_credentials_from_config(profile))
239
254
  provider.credentials if provider.credentials.set?
255
+ elsif (provider = sso_credentials_from_config(profile: profile))
256
+ provider.credentials if provider.credentials.set?
240
257
  end
241
258
  end
242
259
 
@@ -273,6 +290,22 @@ module Aws
273
290
  end
274
291
  end
275
292
 
293
+ # If any of the sso_ profile values are present, attempt to construct
294
+ # SSOCredentials
295
+ def sso_credentials_from_profile(cfg, profile)
296
+ if @parsed_config &&
297
+ (prof_config = cfg[profile]) &&
298
+ !(prof_config.keys & SSO_PROFILE_KEYS).empty?
299
+
300
+ SSOCredentials.new(
301
+ sso_start_url: prof_config['sso_start_url'],
302
+ sso_region: prof_config['sso_region'],
303
+ sso_account_id: prof_config['sso_account_id'],
304
+ sso_role_name: prof_config['sso_role_name']
305
+ )
306
+ end
307
+ end
308
+
276
309
  def credentials_from_profile(prof_config)
277
310
  creds = Credentials.new(
278
311
  prof_config['aws_access_key_id'],
@@ -0,0 +1,116 @@
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` with the
8
+ # correct profile.
9
+ #
10
+ # For more background on AWS SSO see the official
11
+ # [what is SSO](https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html]
12
+ # page.
13
+ #
14
+ # ## Refreshing Credentials from SSO
15
+ #
16
+ # The `SSOCredentials` will auto-refresh the AWS credentials from SSO. In
17
+ # addition to AWS credentials expiring after a given amount of time, the
18
+ # access token generated and cached from `aws login` will also expire.
19
+ # Once this token expires, it will not be usable to refresh AWS credentials,
20
+ # and another token will be needed. The SDK does not manage refreshing of
21
+ # the token value, but this can be done by running `aws login` with the
22
+ # correct profile.
23
+ class SSOCredentials
24
+
25
+ include CredentialProvider
26
+ include RefreshingCredentials
27
+
28
+ SSO_REQUIRED_OPTS = [:sso_account_id, :sso_region, :sso_role_name, :sso_start_url].freeze
29
+
30
+ SSO_LOGIN_GUIDANCE = 'The SSO session associated with this profile has '\
31
+ 'expired or is otherwise invalid. To refresh this SSO session run '\
32
+ 'aws sso login with the corresponding profile.'.freeze
33
+
34
+ # @option options [required, String] :sso_account_id The AWS account ID
35
+ # that temporary AWS credentials will be resolved for
36
+ #
37
+ # @option options [required, String] :sso_region The AWS region where the
38
+ # SSO directory for the given sso_start_url is hosted.
39
+ #
40
+ # @option options [required, String] :sso_role_name The corresponding
41
+ # IAM role in the AWS account that temporary AWS credentials
42
+ # will be resolved for.
43
+ #
44
+ # @option options [required, String] :sso_start_url The start URL is
45
+ # provided by the SSO service via the console and is the URL used to
46
+ # login to the SSO directory. This is also sometimes referred to as
47
+ # the "User Portal URL"
48
+
49
+ # @option options [SSO::Client] :client Optional `SSO::Client`. If not
50
+ # provided, a client will be constructed.
51
+ def initialize(options = {})
52
+
53
+ missing_keys = SSO_REQUIRED_OPTS.select { |k| options[k].nil? }
54
+ unless missing_keys.empty?
55
+ raise ArgumentError, "Missing required keys: #{missing_keys}"
56
+ end
57
+
58
+ @sso_start_url = options.delete(:sso_start_url)
59
+ @sso_region = options.delete(:sso_region)
60
+ @sso_role_name = options.delete(:sso_role_name)
61
+ @sso_account_id = options.delete(:sso_account_id)
62
+
63
+ # validate we can read the token file
64
+ read_cached_token
65
+
66
+ options[:region] = @sso_region
67
+ options[:credentials] = nil
68
+ @client = options[:client] || SSO::Client.new(options)
69
+ super
70
+ end
71
+
72
+ # @return [STS::Client]
73
+ attr_reader :client
74
+
75
+ private
76
+
77
+ def read_cached_token
78
+ cached_token = Json.load(File.read(sso_cache_file))
79
+ # validation
80
+ unless cached_token['accessToken'] && cached_token['expiresAt']
81
+ raise ArgumentError, 'Missing required field(s)'
82
+ end
83
+ expires_at = DateTime.parse(cached_token['expiresAt'])
84
+ if expires_at < DateTime.now
85
+ raise ArgumentError, 'Cached SSO Token is expired.'
86
+ end
87
+ cached_token
88
+ rescue Aws::Json::ParseError, ArgumentError
89
+ raise Errors::InvalidSSOCredentials, SSO_LOGIN_GUIDANCE
90
+ end
91
+
92
+ def refresh
93
+ cached_token = read_cached_token
94
+ c = @client.get_role_credentials(
95
+ account_id: @sso_account_id,
96
+ role_name: @sso_role_name,
97
+ access_token: cached_token['accessToken']
98
+ ).role_credentials
99
+
100
+ @credentials = Credentials.new(
101
+ c.access_key_id,
102
+ c.secret_access_key,
103
+ c.session_token
104
+ )
105
+ @expiration = c.expiration
106
+ end
107
+
108
+ def sso_cache_file
109
+ start_url_sha1 = OpenSSL::Digest::SHA1.hexdigest(@sso_start_url.encode('utf-8'))
110
+ File.join(Dir.home, '.aws', 'sso', 'cache', "#{start_url_sha1}.json")
111
+ rescue ArgumentError
112
+ # Dir.home raises ArgumentError when ENV['home'] is not set
113
+ raise ArgumentError, "Unable to load sso_cache_file: ENV['HOME'] is not set."
114
+ end
115
+ end
116
+ end