-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for default configuration modes (#2624)
- Loading branch information
1 parent
9e917e3
commit 378dfa6
Showing
31 changed files
with
873 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# frozen_string_literal: true | ||
|
||
require_relative 'aws-defaults/default_configuration' |
153 changes: 153 additions & 0 deletions
153
gems/aws-sdk-core/lib/aws-defaults/default_configuration.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
# frozen_string_literal: true | ||
|
||
require_relative 'defaults_mode_config_resolver' | ||
|
||
module Aws | ||
|
||
# A defaults mode determines how certain default configuration options are resolved in the SDK. | ||
# | ||
# *Note*: For any mode other than `'legacy'` the vended default values might change as best practices may | ||
# evolve. As a result, it is encouraged to perform testing when upgrading the SDK if you are using a mode other than | ||
# `'legacy'`. While the `'legacy'` defaults mode is specific to Ruby, | ||
# other modes are standardized across all of the AWS SDKs. | ||
# | ||
# The defaults mode can be configured: | ||
# | ||
# * Directly on a client via `:defaults_mode` | ||
# | ||
# * On a configuration profile via the "defaults_mode" profile file property. | ||
# | ||
# * Globally via the "AWS_DEFAULTS_MODE" environment variable. | ||
# | ||
# | ||
# @code_generation START - documentation | ||
# The following `:default_mode` values are supported: | ||
# | ||
# * `'standard'` - | ||
# The STANDARD mode provides the latest recommended default values | ||
# that should be safe to run in most scenarios | ||
# | ||
# Note that the default values vended from this mode might change as | ||
# best practices may evolve. As a result, it is encouraged to perform | ||
# tests when upgrading the SDK | ||
# | ||
# * `'in-region'` - | ||
# The IN\_REGION mode builds on the standard mode and includes | ||
# optimization tailored for applications which call AWS services from | ||
# within the same AWS region | ||
# | ||
# Note that the default values vended from this mode might change as | ||
# best practices may evolve. As a result, it is encouraged to perform | ||
# tests when upgrading the SDK | ||
# | ||
# * `'cross-region'` - | ||
# The CROSS\_REGION mode builds on the standard mode and includes | ||
# optimization tailored for applications which call AWS services in a | ||
# different region | ||
# | ||
# Note that the default values vended from this mode might change as | ||
# best practices may evolve. As a result, it is encouraged to perform | ||
# tests when upgrading the SDK | ||
# | ||
# * `'mobile'` - | ||
# The MOBILE mode builds on the standard mode and includes | ||
# optimization tailored for mobile applications | ||
# | ||
# Note that the default values vended from this mode might change as | ||
# best practices may evolve. As a result, it is encouraged to perform | ||
# tests when upgrading the SDK | ||
# | ||
# * `'auto'` - | ||
# The AUTO mode is an experimental mode that builds on the standard | ||
# mode. The SDK will attempt to discover the execution environment to | ||
# determine the appropriate settings automatically. | ||
# | ||
# Note that the auto detection is heuristics-based and does not | ||
# guarantee 100% accuracy. STANDARD mode will be used if the execution | ||
# environment cannot be determined. The auto detection might query | ||
# [EC2 Instance Metadata service][1], which might introduce latency. | ||
# Therefore we recommend choosing an explicit defaults\_mode instead | ||
# if startup latency is critical to your application | ||
# | ||
# * `'legacy'` - | ||
# The LEGACY mode provides default settings that vary per SDK and were | ||
# used prior to establishment of defaults\_mode | ||
# | ||
# Based on the provided mode, the SDK will vend sensible default values | ||
# tailored to the mode for the following settings: | ||
# | ||
# * `:retry_mode` - | ||
# A retry mode specifies how the SDK attempts retries. See [Retry | ||
# Mode][2] | ||
# | ||
# * `:sts_regional_endpoints` - | ||
# Specifies how the SDK determines the AWS service endpoint that it | ||
# uses to talk to the AWS Security Token Service (AWS STS). See | ||
# [Setting STS Regional endpoints][3] | ||
# | ||
# * `:s3_us_east_1_regional_endpoint` - | ||
# Specifies how the SDK determines the AWS service endpoint that it | ||
# uses to talk to the Amazon S3 for the us-east-1 region | ||
# | ||
# * `:http_open_timeout` - | ||
# The amount of time after making an initial connection attempt on a | ||
# socket, where if the client does not receive a completion of the | ||
# connect handshake, the client gives up and fails the operation | ||
# | ||
# * `:ssl_timeout` - | ||
# The maximum amount of time that a TLS handshake is allowed to take | ||
# from the time the CLIENT HELLO message is sent to ethe time the | ||
# client and server have fully negotiated ciphers and exchanged keys | ||
# | ||
# All options above can be configured by users, and the overridden value will take precedence. | ||
# | ||
# [1]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html | ||
# [2]: https://docs.aws.amazon.com/sdkref/latest/guide/setting-global-retry_mode.html | ||
# [3]: https://docs.aws.amazon.com/sdkref/latest/guide/setting-global-sts_regional_endpoints.html | ||
# | ||
# @code_generation END - documentation | ||
module DefaultsModeConfiguration | ||
# @api private | ||
# @code_generation START - configuration | ||
SDK_DEFAULT_CONFIGURATION = | ||
{ | ||
"version" => 1, | ||
"base" => { | ||
"retryMode" => "standard", | ||
"stsRegionalEndpoints" => "regional", | ||
"s3UsEast1RegionalEndpoints" => "regional", | ||
"connectTimeoutInMillis" => 1100, | ||
"tlsNegotiationTimeoutInMillis" => 1100 | ||
}, | ||
"modes" => { | ||
"standard" => { | ||
"connectTimeoutInMillis" => { | ||
"override" => 3100 | ||
}, | ||
"tlsNegotiationTimeoutInMillis" => { | ||
"override" => 3100 | ||
} | ||
}, | ||
"in-region" => { | ||
}, | ||
"cross-region" => { | ||
"connectTimeoutInMillis" => { | ||
"override" => 3100 | ||
}, | ||
"tlsNegotiationTimeoutInMillis" => { | ||
"override" => 3100 | ||
} | ||
}, | ||
"mobile" => { | ||
"connectTimeoutInMillis" => { | ||
"override" => 30000 | ||
}, | ||
"tlsNegotiationTimeoutInMillis" => { | ||
"override" => 30000 | ||
} | ||
} | ||
} | ||
} | ||
# @code_generation END - configuration | ||
end | ||
end |
107 changes: 107 additions & 0 deletions
107
gems/aws-sdk-core/lib/aws-defaults/defaults_mode_config_resolver.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
# frozen_string_literal: true | ||
|
||
module Aws | ||
#@api private | ||
class DefaultsModeConfigResolver | ||
|
||
@@application_region = nil | ||
@@application_region_mutex = Mutex.new | ||
@@imds_client = EC2Metadata.new(retries: 0, http_open_timeout: 0.01) | ||
|
||
# mappings from Ruby SDK configuration names to the | ||
# sdk defaults option names and (optional) scale modifiers | ||
CFG_OPTIONS = { | ||
retry_mode: { name: "retryMode" }, | ||
sts_regional_endpoints: { name: "stsRegionalEndpoints" }, | ||
s3_us_east_1_regional_endpoint: { name: "s3UsEast1RegionalEndpoints" }, | ||
http_open_timeout: { name: "connectTimeoutInMillis", scale: 0.001 }, | ||
http_read_timeout: { name: "timeToFirstByteTimeoutInMillis", scale: 0.001 }, | ||
ssl_timeout: { name: "tlsNegotiationTimeoutInMillis", scale: 0.001 } | ||
}.freeze | ||
|
||
def initialize(sdk_defaults, cfg) | ||
@sdk_defaults = sdk_defaults | ||
@cfg = cfg | ||
@resolved_mode = nil | ||
@mutex = Mutex.new | ||
end | ||
|
||
# option_name should be the symbolized ruby name to resolve | ||
# returns the ruby appropriate value or nil if none are resolved | ||
def resolve(option_name) | ||
return unless (std_option = CFG_OPTIONS[option_name]) | ||
mode = resolved_mode.downcase | ||
|
||
return nil if mode == 'legacy' | ||
|
||
value = resolve_for_mode(std_option[:name], mode) | ||
value = value * std_option[:scale] if value && std_option[:scale] | ||
|
||
value | ||
end | ||
|
||
private | ||
def resolved_mode | ||
@mutex.synchronize do | ||
return @resolved_mode unless @resolved_mode.nil? | ||
|
||
@resolved_mode = @cfg.defaults_mode == 'auto' ? resolve_auto_mode : @cfg.defaults_mode | ||
end | ||
end | ||
|
||
def resolve_auto_mode | ||
return "mobile" if env_mobile? | ||
|
||
region = application_current_region | ||
|
||
if region | ||
@cfg.region == region ? "in-region": "cross-region" | ||
else | ||
# We don't seem to be mobile, and we couldn't determine whether we're running within an AWS region. Fall back to standard. | ||
'standard' | ||
end | ||
end | ||
|
||
def application_current_region | ||
resolved_region = @@application_region_mutex.synchronize do | ||
return @@application_region unless @@application_region.nil? | ||
|
||
region = nil | ||
if ENV['AWS_EXECUTION_ENV'] | ||
region = ENV['AWS_REGION'] || ENV['AWS_DEFAULT_REGION'] | ||
end | ||
|
||
if region.nil? && ENV['AWS_EC2_METADATA_DISABLED']&.downcase != "true" | ||
begin | ||
region = @@imds_client.get('/latest/meta-data/placement/region') | ||
rescue | ||
# unable to get region, leave it unset | ||
end | ||
end | ||
|
||
# required so that we cache the unknown/nil result | ||
@@application_region = region || :unknown | ||
end | ||
resolved_region == :unknown ? nil : resolved_region | ||
end | ||
|
||
def resolve_for_mode(name, mode) | ||
base_value = @sdk_defaults['base'][name] | ||
mode_value = @sdk_defaults['modes'].fetch(mode, {})[name] | ||
|
||
if mode_value.nil? | ||
return base_value | ||
end | ||
|
||
return mode_value['override'] unless mode_value['override'].nil? | ||
return base_value + mode_value['add'] unless mode_value['add'].nil? | ||
return base_value * mode_value['multiply'] unless mode_value['multiply'].nil? | ||
return base_value | ||
end | ||
|
||
def env_mobile? | ||
false | ||
end | ||
|
||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
gems/aws-sdk-core/lib/aws-sdk-core/plugins/defaults_mode.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# frozen_string_literal: true | ||
|
||
module Aws | ||
# @api private | ||
module Plugins | ||
# @api private | ||
class DefaultsMode < Seahorse::Client::Plugin | ||
|
||
option(:defaults_mode, | ||
default: 'legacy', | ||
doc_type: String, | ||
docstring: <<-DOCS | ||
See {Aws::DefaultsModeConfiguration} for a list of the | ||
accepted modes and the configuration defaults that are included. | ||
DOCS | ||
) do |cfg| | ||
resolve_defaults_mode(cfg) | ||
end | ||
|
||
option(:defaults_mode_config_resolver, | ||
doc_type: 'Aws::DefaultsModeConfigResolver') do |cfg| | ||
Aws::DefaultsModeConfigResolver.new( | ||
Aws::DefaultsModeConfiguration::SDK_DEFAULT_CONFIGURATION, cfg) | ||
end | ||
|
||
class << self | ||
private | ||
|
||
def resolve_defaults_mode(cfg) | ||
value = ENV['AWS_DEFAULTS_MODE'] | ||
value ||= Aws.shared_config.defaults_mode( | ||
profile: cfg.profile | ||
) | ||
value&.downcase || "legacy" | ||
end | ||
end | ||
|
||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.