Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add useDualstackEndpoint configuration #3957

Merged
merged 9 commits into from Nov 12, 2021
5 changes: 5 additions & 0 deletions .changes/next-release/feature-endpoint-7f7bc9fa.json
@@ -0,0 +1,5 @@
{
"type": "feature",
"category": "endpoint",
"description": "Add useDualstackEndpoint configuration"
}
4 changes: 4 additions & 0 deletions lib/config-base.d.ts
Expand Up @@ -271,4 +271,8 @@ export abstract class ConfigurationOptions {
* Enables FIPS compatible endpoints.
*/
useFipsEndpoint?: boolean;
/**
* Enables IPv6 dualstack endpoint.
*/
useDualstackEndpoint?: boolean;
}
8 changes: 7 additions & 1 deletion lib/config.js
Expand Up @@ -189,6 +189,9 @@ var PromisesDependency;
*
* @!attribute useFipsEndpoint
* @return [Boolean] Enables FIPS compatible endpoints. Defaults to `false`.
*
* @!attribute useDualstackEndpoint
* @return [Boolean] Enables IPv6 dualstack endpoint. Defaults to `false`.
*/
AWS.Config = AWS.util.inherit({
/**
Expand Down Expand Up @@ -345,6 +348,8 @@ AWS.Config = AWS.util.inherit({
* Defaults to 'legacy'.
* @option options useFipsEndpoint [Boolean] Enables FIPS compatible endpoints.
* Defaults to `false`.
* @option options useDualstackEndpoint [Boolean] Enables IPv6 dualstack endpoint.
* Defaults to `false`.
*/
constructor: function Config(options) {
if (options === undefined) options = {};
Expand Down Expand Up @@ -569,7 +574,8 @@ AWS.Config = AWS.util.inherit({
endpointCacheSize: 1000,
hostPrefixEnabled: true,
stsRegionalEndpoints: 'legacy',
useFipsEndpoint: false
useFipsEndpoint: false,
useDualstackEndpoint: false
},

/**
Expand Down
3 changes: 3 additions & 0 deletions lib/config_use_dualstack.d.ts
@@ -1,8 +1,11 @@
import {ConfigBase} from './config-base';

export interface UseDualstackConfigOptions {
/**
* Enables IPv6/IPv4 dualstack endpoint. When a DNS lookup is performed on an endpoint of this type, it returns an “A” record with an IPv4 address and an “AAAA” record with an IPv6 address.
* In most cases the network stack in the client environment will automatically prefer the AAAA record and make a connection using the IPv6 address.
* Note, however, that currently on Windows, the IPv4 address will be preferred.
* @deprecated Use {@link ConfigBase.useDualstackEndpoint}
*/
useDualstack?: boolean;
}
13 changes: 13 additions & 0 deletions lib/node_loader.js
Expand Up @@ -138,6 +138,16 @@ var USE_FIPS_ENDPOINT_CONFIG_OPTIONS = {
default: false,
};

var USE_DUALSTACK_ENDPOINT_CONFIG_OPTIONS = {
environmentVariableSelector: function(env) {
return getBooleanValue(env['AWS_USE_DUALSTACK_ENDPOINT']);
},
configFileSelector: function(profile) {
return getBooleanValue(profile['use_dualstack_endpoint']);
},
default: false,
};

// Update configuration keys
AWS.util.update(AWS.Config.prototype.keys, {
credentials: function () {
Expand Down Expand Up @@ -166,6 +176,9 @@ AWS.util.update(AWS.Config.prototype.keys, {
return isFipsRegion(region)
? true
: util.loadConfig(USE_FIPS_ENDPOINT_CONFIG_OPTIONS);
},
useDualstackEndpoint: function() {
return util.loadConfig(USE_DUALSTACK_ENDPOINT_CONFIG_OPTIONS);
}
});

Expand Down
19 changes: 9 additions & 10 deletions lib/region_config.js
Expand Up @@ -37,26 +37,25 @@ function applyConfig(service, config) {
function configureEndpoint(service) {
var keys = derivedKeys(service);
var useFipsEndpoint = service.config.useFipsEndpoint;
var useDualstackEndpoint = service.config.useDualstackEndpoint;
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (!key) continue;

var rules = useFipsEndpoint ? regionConfig.fipsRules : regionConfig.rules;
var rules = useFipsEndpoint
? useDualstackEndpoint
? regionConfig.dualstackFipsRules
: regionConfig.fipsRules
: useDualstackEndpoint
? regionConfig.dualstackRules
: regionConfig.rules;

if (Object.prototype.hasOwnProperty.call(rules, key)) {
var config = rules[key];
if (typeof config === 'string') {
config = regionConfig.patterns[config];
}

// set dualstack endpoint
if (service.config.useDualstack && util.isDualstackAvailable(service)) {
config = util.copy(config);
config.endpoint = config.endpoint.replace(
/{service}\.({region}\.)?/,
'{service}.dualstack.{region}.'
);
}

// set global endpoint
service.isGlobalEndpoint = !!config.globalEndpoint;
if (config.signingRegion) {
Expand Down
38 changes: 38 additions & 0 deletions lib/region_config_data.json
Expand Up @@ -120,6 +120,32 @@
}
},

"dualstackRules": {
"*/*": {
"endpoint": "{service}.{region}.api.aws"
},
"cn-*/*": {
"endpoint": "{service}.{region}.api.amazonwebservices.com.cn"
},
"*/s3": "dualstackLegacy",
"cn-*/s3": "dualstackLegacyCn",
"*/s3-control": "dualstackLegacy",
"cn-*/s3-control": "dualstackLegacyCn"
},

"dualstackFipsRules": {
"*/*": {
"endpoint": "{service}-fips.{region}.api.aws"
},
"cn-*/*": {
"endpoint": "{service}-fips.{region}.api.amazonwebservices.com.cn"
},
"*/s3": "dualstackFipsLegacy",
"cn-*/s3": "dualstackFipsLegacyCn",
"*/s3-control": "dualstackFipsLegacy",
"cn-*/s3-control": "dualstackFipsLegacyCn"
},

"patterns": {
"globalSSL": {
"endpoint": "https://{service}.amazonaws.com",
Expand Down Expand Up @@ -164,6 +190,18 @@
},
"fipsWithServiceOnly": {
"endpoint": "{service}.{region}.amazonaws.com"
},
"dualstackLegacy": {
"endpoint": "{service}.dualstack.{region}.amazonaws.com"
},
"dualstackLegacyCn": {
"endpoint": "{service}.dualstack.{region}.amazonaws.com.cn"
},
"dualstackFipsLegacy": {
"endpoint": "{service}-fips.dualstack.{region}.amazonaws.com"
},
"dualstackFipsLegacyCn": {
"endpoint": "{service}-fips.dualstack.{region}.amazonaws.com.cn"
}
}
}
20 changes: 13 additions & 7 deletions lib/service.js
Expand Up @@ -27,14 +27,20 @@ AWS.Service = inherit({
'Service must be constructed with `new\' operator');
}

if (config && config.region) {
var region = config.region;
if (region_utils.isFipsRegion(region)) {
config.region = region_utils.getRealRegion(region);
config.useFipsEndpoint = true;
if (config) {
if (config.region) {
var region = config.region;
if (region_utils.isFipsRegion(region)) {
config.region = region_utils.getRealRegion(region);
config.useFipsEndpoint = true;
}
if (region_utils.isGlobalRegion(region)) {
config.region = region_utils.getRealRegion(region);
}
}
if (region_utils.isGlobalRegion(region)) {
config.region = region_utils.getRealRegion(region);
if (typeof config.useDualstack === 'boolean'
&& typeof config.useDualstackEndpoint !== 'boolean') {
config.useDualstackEndpoint = config.useDualstack;
}
}

Expand Down
6 changes: 3 additions & 3 deletions scripts/region-checker/allowlist.js
Expand Up @@ -4,9 +4,9 @@ var allowlist = {
25,
85,
86,
204,
258,
259
207,
261,
262
],
'/credentials/cognito_identity_credentials.js': [
78,
Expand Down
2 changes: 2 additions & 0 deletions test/endpoint/index.spec.js
Expand Up @@ -13,6 +13,7 @@ describe('endpoints', () => {
clientName,
region,
useFipsEndpoint,
useDualstackEndpoint,
hostname,
} of testCases) {
it(`testing "${clientName}" with region: ${region}`, (done) => {
Expand All @@ -23,6 +24,7 @@ describe('endpoints', () => {
const client = new AWS[clientName]({
region,
useFipsEndpoint,
useDualstackEndpoint,
hostPrefixEnabled: false
});

Expand Down