Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changelog/bugfix-fix-dualstack-fips-env-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"type": "bugfix",
"category": "aws-cpp-sdk-core",
"contributor": "sbaluja",
"description": "Use environment variables for dualstack and FIPS endpoints"
}
16 changes: 16 additions & 0 deletions src/aws-cpp-sdk-core/source/client/ClientConfiguration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ static const char* DISABLE_IMDSV1_CONFIG_VAR = "AWS_EC2_METADATA_V1_DISABLED";
static const char* DISABLE_IMDSV1_ENV_VAR = "ec2_metadata_v1_disabled";
static const char* DISABLE_CLOCK_SKEW_CORRECTION_ENV_VAR = "AWS_DISABLE_CLOCK_SKEW_CORRECTION";
static const char* DISABLE_CLOCK_SKEW_CORRECTION_CONFIG_VAR = "disable_clock_skew_correction";
static const char* AWS_USE_DUALSTACK_ENDPOINT_ENV_VAR = "AWS_USE_DUALSTACK_ENDPOINT";
static const char* AWS_USE_DUALSTACK_ENDPOINT_CONFIG_VAR = "use_dualstack_endpoint";
static const char* AWS_USE_FIPS_ENDPOINT_ENV_VAR = "AWS_USE_FIPS_ENDPOINT";
static const char* AWS_USE_FIPS_ENDPOINT_CONFIG_VAR = "use_fips_endpoint";
static const char* AWS_ACCOUNT_ID_ENDPOINT_MODE_ENVIRONMENT_VARIABLE = "AWS_ACCOUNT_ID_ENDPOINT_MODE";
static const char* AWS_ACCOUNT_ID_ENDPOINT_MODE_CONFIG_FILE_OPTION = "account_id_endpoint_mode";
static const char* AWS_METADATA_SERVICE_TIMEOUT_ENV_VAR = "AWS_METADATA_SERVICE_TIMEOUT";
Expand Down Expand Up @@ -348,6 +352,18 @@ void setConfigFromEnvOrProfile(ClientConfiguration &config)
config.enableClockSkewAdjustment = false;
}

config.useDualStack = ClientConfiguration::LoadConfigFromEnvOrProfile(AWS_USE_DUALSTACK_ENDPOINT_ENV_VAR,
config.profileName,
AWS_USE_DUALSTACK_ENDPOINT_CONFIG_VAR,
{"true", "false"},
"false") == "true";

config.useFIPS = ClientConfiguration::LoadConfigFromEnvOrProfile(AWS_USE_FIPS_ENDPOINT_ENV_VAR,
config.profileName,
AWS_USE_FIPS_ENDPOINT_CONFIG_VAR,
{"true", "false"},
"false") == "true";

// accountId is intentionally not set here: AWS_ACCOUNT_ID env variable may not match the provided credentials.
// it must be set by an auth provider / identity resolver or by an SDK user.
config.accountIdEndpointMode = ClientConfiguration::LoadConfigFromEnvOrProfile(AWS_ACCOUNT_ID_ENDPOINT_MODE_ENVIRONMENT_VARIABLE,
Expand Down
114 changes: 114 additions & 0 deletions tests/aws-cpp-sdk-core-tests/aws/client/AwsConfigTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <aws/core/platform/FileSystem.h>
#include <aws/core/auth/AWSCredentialsProvider.h>
#include <aws/core/platform/Environment.h>
#include <aws/core/endpoint/BuiltInParameters.h>

#include <fstream>
#include <thread>
Expand All @@ -30,6 +31,8 @@ class AWSConfigTestSuite : public Aws::Testing::AwsCppSdkGTestSuite
SaveEnvironmentVariable("AWS_REGION");
SaveEnvironmentVariable("AWS_EC2_METADATA_SERVICE_ENDPOINT");
SaveEnvironmentVariable("DISABLE_REQUEST_COMPRESSION");
SaveEnvironmentVariable("AWS_USE_DUALSTACK_ENDPOINT");
SaveEnvironmentVariable("AWS_USE_FIPS_ENDPOINT");

Aws::StringStream ss;
ss << Aws::Auth::GetConfigProfileFilename() + "_blah" << std::this_thread::get_id();
Expand All @@ -41,6 +44,8 @@ class AWSConfigTestSuite : public Aws::Testing::AwsCppSdkGTestSuite
Aws::Environment::UnSetEnv("AWS_REGION");
Aws::Environment::UnSetEnv("AWS_EC2_METADATA_SERVICE_ENDPOINT");
Aws::Environment::UnSetEnv("DISABLE_REQUEST_COMPRESSION");
Aws::Environment::UnSetEnv("AWS_USE_DUALSTACK_ENDPOINT");
Aws::Environment::UnSetEnv("AWS_USE_FIPS_ENDPOINT");

auto profileDirectory = Aws::Auth::ProfileCredentialsProvider::GetProfileDirectory();
Aws::FileSystem::CreateDirectoryIfNotExists(profileDirectory.c_str());
Expand Down Expand Up @@ -195,6 +200,115 @@ TEST_F(AWSConfigTestSuite, TestNoEnvAndConfigSetToFalseSetsUseRequestCompression
Aws::FileSystem::RemoveFileIfExists(m_configFileName.c_str());
}

TEST_F(AWSConfigTestSuite, TestNoEnvNoConfigLeavesDualStackAndFipsDisabled){
Aws::OFStream configFileNew(m_configFileName.c_str(), Aws::OFStream::out | Aws::OFStream::trunc);
configFileNew.flush();
configFileNew.close();
Aws::Config::ReloadCachedConfigFile();

Aws::Client::ClientConfiguration config;

EXPECT_FALSE(config.useDualStack);
EXPECT_FALSE(config.useFIPS);

Aws::FileSystem::RemoveFileIfExists(m_configFileName.c_str());
}

TEST_F(AWSConfigTestSuite, TestEnvEnablesDualStackAndFips){
Aws::Environment::SetEnv("AWS_USE_DUALSTACK_ENDPOINT", "true", 1/*overwrite*/);
Aws::Environment::SetEnv("AWS_USE_FIPS_ENDPOINT", "TRUE", 1/*overwrite*/);
Aws::OFStream configFileNew(m_configFileName.c_str(), Aws::OFStream::out | Aws::OFStream::trunc);
configFileNew.flush();
configFileNew.close();
Aws::Config::ReloadCachedConfigFile();

Aws::Client::ClientConfiguration config;

EXPECT_TRUE(config.useDualStack);
EXPECT_TRUE(config.useFIPS);

Aws::FileSystem::RemoveFileIfExists(m_configFileName.c_str());
}

TEST_F(AWSConfigTestSuite, TestProfileEnablesDualStackAndFips){
Aws::OFStream configFileNew(m_configFileName.c_str(), Aws::OFStream::out | Aws::OFStream::trunc);
configFileNew << "[profile Dijkstra]" << std::endl;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

love this name

configFileNew << "use_dualstack_endpoint = true" << std::endl;
configFileNew << "use_fips_endpoint = true" << std::endl;
configFileNew.flush();
configFileNew.close();
Aws::Config::ReloadCachedConfigFile();

Aws::Client::ClientConfiguration config("Dijkstra");

EXPECT_TRUE(config.useDualStack);
EXPECT_TRUE(config.useFIPS);

Aws::FileSystem::RemoveFileIfExists(m_configFileName.c_str());
}

TEST_F(AWSConfigTestSuite, TestEnvFalseOverridesProfileTrueForDualStackAndFips){
Aws::Environment::SetEnv("AWS_USE_DUALSTACK_ENDPOINT", "false", 1/*overwrite*/);
Aws::Environment::SetEnv("AWS_USE_FIPS_ENDPOINT", "false", 1/*overwrite*/);
Aws::OFStream configFileNew(m_configFileName.c_str(), Aws::OFStream::out | Aws::OFStream::trunc);
configFileNew << "[profile Dijkstra]" << std::endl;
configFileNew << "use_dualstack_endpoint = true" << std::endl;
configFileNew << "use_fips_endpoint = true" << std::endl;
configFileNew.flush();
configFileNew.close();
Aws::Config::ReloadCachedConfigFile();

Aws::Client::ClientConfiguration config("Dijkstra");

EXPECT_FALSE(config.useDualStack);
EXPECT_FALSE(config.useFIPS);

Aws::FileSystem::RemoveFileIfExists(m_configFileName.c_str());
}

TEST_F(AWSConfigTestSuite, TestInvalidValueLeavesDualStackAndFipsDisabled){
Aws::Environment::SetEnv("AWS_USE_DUALSTACK_ENDPOINT", "yes", 1/*overwrite*/);
Aws::OFStream configFileNew(m_configFileName.c_str(), Aws::OFStream::out | Aws::OFStream::trunc);
configFileNew << "[default]" << std::endl;
configFileNew << "use_fips_endpoint = 1" << std::endl;
configFileNew.flush();
configFileNew.close();
Aws::Config::ReloadCachedConfigFile();

Aws::Client::ClientConfiguration config;

EXPECT_FALSE(config.useDualStack);
EXPECT_FALSE(config.useFIPS);

Aws::FileSystem::RemoveFileIfExists(m_configFileName.c_str());
}

TEST_F(AWSConfigTestSuite, TestCodeOverridesEnvForDualStackAndFips){
Aws::Environment::SetEnv("AWS_USE_DUALSTACK_ENDPOINT", "true", 1/*overwrite*/);
Aws::Environment::SetEnv("AWS_USE_FIPS_ENDPOINT", "true", 1/*overwrite*/);
Aws::OFStream configFileNew(m_configFileName.c_str(), Aws::OFStream::out | Aws::OFStream::trunc);
configFileNew.flush();
configFileNew.close();
Aws::Config::ReloadCachedConfigFile();

Aws::Client::ClientConfiguration config;
config.useDualStack = false;
config.useFIPS = false;

Aws::Endpoint::BuiltInParameters params;
params.SetFromClientConfiguration(config);
const auto& dualStack = params.GetParameter("UseDualStack");
const auto& fips = params.GetParameter("UseFIPS");
bool dualStackValue = true;
bool fipsValue = true;
ASSERT_EQ(Aws::Endpoint::EndpointParameter::GetSetResult::SUCCESS, dualStack.GetBool(dualStackValue));
ASSERT_EQ(Aws::Endpoint::EndpointParameter::GetSetResult::SUCCESS, fips.GetBool(fipsValue));
EXPECT_FALSE(dualStackValue);
EXPECT_FALSE(fipsValue);

Aws::FileSystem::RemoveFileIfExists(m_configFileName.c_str());
}

TEST_F(AWSConfigTestSuite, TestDefaultProfileLoadingWithCLRFStyleLineEndings) {
// Create a config file with CLRF line endings
Aws::OFStream configFileNew(m_configFileName.c_str(), Aws::OFStream::out | Aws::OFStream::trunc);
Expand Down
Loading