aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config
diff options
context:
space:
mode:
authordakovalkov <dakovalkov@yandex-team.com>2023-12-03 13:33:55 +0300
committerdakovalkov <dakovalkov@yandex-team.com>2023-12-03 14:04:39 +0300
commit2a718325637e5302334b6d0a6430f63168f8dbb3 (patch)
tree64be81080b7df9ec1d86d053a0c394ae53fcf1fe /contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config
parente0d94a470142d95c3007e9c5d80380994940664a (diff)
downloadydb-2a718325637e5302334b6d0a6430f63168f8dbb3.tar.gz
Update contrib/libs/aws-sdk-cpp to 1.11.37
Diffstat (limited to 'contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config')
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSConfigFileProfileConfigLoader.cpp629
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp571
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoaderBase.cpp50
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/ConfigAndCredentialsCacheManager.cpp206
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/EC2InstanceProfileConfigLoader.cpp112
-rw-r--r--contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/defaults/ClientConfigurationDefaults.cpp197
6 files changed, 1194 insertions, 571 deletions
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSConfigFileProfileConfigLoader.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSConfigFileProfileConfigLoader.cpp
new file mode 100644
index 0000000000..ba0079bb5e
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSConfigFileProfileConfigLoader.cpp
@@ -0,0 +1,629 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/config/AWSProfileConfigLoader.h>
+#include <aws/core/utils/memory/stl/AWSSet.h>
+#include <aws/core/utils/memory/stl/AWSStreamFwd.h>
+#include <aws/core/utils/StringUtils.h>
+#include <aws/core/utils/logging/LogMacros.h>
+#include <fstream>
+
+namespace Aws
+{
+ namespace Config
+ {
+ using namespace Aws::Utils;
+ using namespace Aws::Auth;
+
+ static const char REGION_KEY[] = "region";
+ static const char ACCESS_KEY_ID_KEY[] = "aws_access_key_id";
+ static const char SECRET_KEY_KEY[] = "aws_secret_access_key";
+ static const char SESSION_TOKEN_KEY[] = "aws_session_token";
+ static const char SSO_START_URL_KEY[] = "sso_start_url";
+ static const char SSO_REGION_KEY[] = "sso_region";
+ static const char SSO_ACCOUNT_ID_KEY[] = "sso_account_id";
+ static const char SSO_ROLE_NAME_KEY[] = "sso_role_name";
+ static const char SSO_SESSION_KEY[] = "sso_session";
+ static const char ROLE_ARN_KEY[] = "role_arn";
+ static const char EXTERNAL_ID_KEY[] = "external_id";
+ static const char CREDENTIAL_PROCESS_COMMAND[] = "credential_process";
+ static const char SOURCE_PROFILE_KEY[] = "source_profile";
+ static const char PROFILE_SECTION[] = "profile";
+ static const char DEFAULT[] = "default";
+ static const char SSO_SESSION_SECTION[] = "sso-session";
+ static const char DEFAULTS_MODE_KEY[] = "defaults_mode";
+ static const char EQ = '=';
+ static const char LEFT_BRACKET = '[';
+ static const char RIGHT_BRACKET = ']';
+ static const char PARSER_TAG[] = "Aws::Config::ConfigFileProfileFSM";
+
+ // generated by python from identifier regex pattern from the spec: R"([A-Za-z0-9_\-/.%@:\+]+)":
+ // #py: ''.join(chr(i) for i in range(128) if re.match("[A-Za-z0-9_\-\/.%@:\+]", chr(i)))
+ const char IDENTIFIER_ALLOWED_CHARACTERS[] = R"(%+-./0123456789:@ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz)";
+ static const size_t IDENTIFIER_ALLOWED_CHARACTERS_SZ = sizeof(IDENTIFIER_ALLOWED_CHARACTERS) - 1;
+ const char WHITESPACE_CHARACTERS[] = "\t ";
+ static const size_t WHITESPACE_CHARACTERS_SZ = sizeof(WHITESPACE_CHARACTERS) - 1;
+ const char COMMENT_START[] = "#;";
+ static const size_t COMMENT_START_SZ = sizeof(COMMENT_START) - 1;
+
+ struct ProfilePropertyAccessFunctions
+ {
+ const char* PropertyKey;
+ std::function<void(Profile&, const Aws::String&)> Setter;
+ std::function<const Aws::String&(const Profile&)> Getter;
+ };
+
+ static const ProfilePropertyAccessFunctions PROFILE_PROPERTY_FUNCS[] =
+ {{REGION_KEY, &Profile::SetRegion, &Profile::GetRegion},
+ //ACCESS_KEY_ID_KEY, - AwsCredentials require special handling
+ //SECRET_KEY_KEY,
+ //SESSION_TOKEN_KEY,
+ {SSO_START_URL_KEY, &Profile::SetSsoStartUrl, &Profile::GetSsoStartUrl},
+ {SSO_REGION_KEY, &Profile::SetSsoRegion, &Profile::GetSsoRegion},
+ {SSO_ACCOUNT_ID_KEY, &Profile::SetSsoAccountId, &Profile::GetSsoAccountId},
+ {SSO_ROLE_NAME_KEY, &Profile::SetSsoRoleName, &Profile::GetSsoRoleName},
+ //SSO_SESSION_KEY - SsoSession requires special handling
+ {ROLE_ARN_KEY, &Profile::SetRoleArn, &Profile::GetRoleArn},
+ {EXTERNAL_ID_KEY, &Profile::SetExternalId, &Profile::GetExternalId},
+ {CREDENTIAL_PROCESS_COMMAND, &Profile::SetCredentialProcess, &Profile::GetCredentialProcess},
+ {SOURCE_PROFILE_KEY, &Profile::SetSourceProfile, &Profile::GetSourceProfile},
+ {DEFAULTS_MODE_KEY, &Profile::SetDefaultsMode, &Profile::GetDefaultsMode}};
+
+ template<typename EntryT, size_t N>
+ const EntryT* FindInStaticArray(const EntryT (&array)[N], const Aws::String& searchKey)
+ {
+ const EntryT* found = std::find_if(array, array + N,
+ [&searchKey](const EntryT& entry)
+ {
+ return searchKey == entry.PropertyKey;
+ });
+
+ if(!!found && found != array + N)
+ return found;
+
+ return nullptr;
+ }
+
+ static const char* PROFILE_KEY_SPECIAL_HANDLING[] =
+ {ACCESS_KEY_ID_KEY, SECRET_KEY_KEY, SESSION_TOKEN_KEY, SSO_SESSION_KEY};
+ static const size_t PROFILE_KEY_SPECIAL_HANDLING_SZ = sizeof(PROFILE_KEY_SPECIAL_HANDLING) / sizeof(PROFILE_KEY_SPECIAL_HANDLING[0]);
+
+ struct SsoSessionPropertyAccessFunctions
+ {
+ const char* PropertyKey;
+ std::function<void(Profile::SsoSession&, const Aws::String&)> Setter;
+ std::function<const Aws::String&(const Profile::SsoSession&)> Getter;
+ };
+ static const SsoSessionPropertyAccessFunctions SSO_SESSION_PROPERTY_FUNCS[] =
+ {{SSO_REGION_KEY, &Profile::SsoSession::SetSsoRegion, &Profile::SsoSession::GetSsoRegion},
+ {SSO_START_URL_KEY, &Profile::SsoSession::SetSsoStartUrl, &Profile::SsoSession::GetSsoStartUrl}};
+
+ class ConfigFileProfileFSM
+ {
+ public:
+ ConfigFileProfileFSM(bool useProfilePrefix)
+ : m_useProfilePrefix(useProfilePrefix)
+ {}
+
+ const Aws::Map<String, Profile>& GetProfiles() const { return m_foundProfiles; }
+
+ void ParseStream(Aws::IStream& stream)
+ {
+ static const size_t ASSUME_EMPTY_LEN = 3;
+ State currentState = START;
+ Aws::String currentSectionName;
+ Aws::Map<Aws::String, Aws::String> currentKeyValues;
+
+ Aws::String rawLine;
+ while(std::getline(stream, rawLine) && currentState != FAILURE)
+ {
+ Aws::String line = rawLine.substr(0, rawLine.find_first_of(COMMENT_START)); // ignore comments
+ if (line.empty() || line.length() < ASSUME_EMPTY_LEN || line.find_first_not_of(WHITESPACE_CHARACTERS) == Aws::String::npos)
+ {
+ continue;
+ }
+
+ auto openPos = line.find(LEFT_BRACKET);
+ auto closePos = line.find(RIGHT_BRACKET);
+
+ if(openPos != std::string::npos && closePos != std::string::npos)
+ {
+ FlushSection(currentState, currentSectionName, currentKeyValues);
+ currentKeyValues.clear();
+ ParseSectionDeclaration(line, currentSectionName, currentState);
+ continue;
+ }
+
+ if(PROFILE_FOUND == currentState || SSO_SESSION_FOUND == currentState)
+ {
+ auto equalsPos = line.find(EQ);
+ if (equalsPos != std::string::npos)
+ {
+ auto key = StringUtils::Trim(line.substr(0, equalsPos).c_str());
+ auto value = StringUtils::Trim(line.substr(equalsPos + 1).c_str());
+ currentKeyValues[key] = value;
+ continue;
+ }
+ }
+
+ if(UNKNOWN_SECTION_FOUND == currentState)
+ {
+ // skip any unknown sections
+ continue;
+ }
+
+ AWS_LOGSTREAM_ERROR(PARSER_TAG, "Unexpected line in the aws shared profile: " << rawLine);
+ currentState = FAILURE;
+ break;
+ }
+
+ FlushSection(currentState, currentSectionName, currentKeyValues);
+
+ // Put sso-sessions into profiles
+ for(auto& profile : m_foundProfiles)
+ {
+ const Aws::String& profileSsoSessionName = profile.second.GetValue(SSO_SESSION_KEY);
+ if(!profileSsoSessionName.empty())
+ {
+ auto ssoSessionIt = m_foundSsoSessions.find(profileSsoSessionName);
+ if(ssoSessionIt == m_foundSsoSessions.end())
+ {
+ AWS_LOGSTREAM_ERROR(PARSER_TAG, "AWS profile has reference to a missing sso_session: " << profileSsoSessionName);
+ currentState = FAILURE;
+ continue;
+ }
+ auto ssoSession = ssoSessionIt->second;
+ auto prof = profile.second;
+ // If sso session and profile have conflicting start url or region, fail to parse
+ // the session/sso specific profile properties
+ auto hasConflictingStartUrls = !ssoSession.GetSsoStartUrl().empty()
+ && !prof.GetSsoStartUrl().empty()
+ && ssoSession.GetSsoStartUrl() != prof.GetSsoStartUrl();
+ auto hasConflictingRegions = !ssoSession.GetSsoRegion().empty()
+ && !prof.GetSsoRegion().empty()
+ && ssoSession.GetSsoRegion() != prof.GetSsoRegion();
+ if (hasConflictingStartUrls || hasConflictingRegions) {
+ AWS_LOGSTREAM_ERROR(PARSER_TAG,
+ "SSO profile has a start url or region conflict with sso session");
+ prof.SetSsoStartUrl("");
+ prof.SetSsoRegion("");
+ prof.SetSsoAccountId("");
+ prof.SetSsoRoleName("");
+ continue;
+ }
+ profile.second.SetSsoSession(ssoSessionIt->second);
+ }
+ }
+
+ if(FAILURE == currentState)
+ {
+ AWS_LOGSTREAM_ERROR(PARSER_TAG, "AWS shared profile config parsing failed");
+ }
+ }
+
+ private:
+ // true means Shared Config parsing, false means Shared Credentials parsing
+ bool m_useProfilePrefix = false;
+
+ enum State
+ {
+ START = 0,
+ PROFILE_FOUND,
+ SSO_SESSION_FOUND,
+ UNKNOWN_SECTION_FOUND,
+ FAILURE
+ };
+
+ /**
+ * Helper function to parse a single word (aka section identifier) containing allowed characters from a line and a pos
+ * i.e. line="[ profile default ]";identifierBegin=10 will return "default"
+ * @param line, a section definition line being parsed
+ * @param identifierBegin, an Aws::String position to start parsing
+ * @param oErrorMsg, a reference to Aws::String to store error message in case of a parsing error.
+ * @return Aws::String, e.g. "default"
+ */
+ Aws::String ParseIdentifier(const Aws::String& line, Aws::String::size_type identifierBegin, Aws::String& oErrorMsg)
+ {
+ // pos at the beginning of section Identifier (or sso_session section keyword)
+ Aws::String::size_type identifierLength = 0;
+ Aws::String::size_type pos = identifierBegin;
+ while(pos < line.length())
+ {
+ if(std::find(IDENTIFIER_ALLOWED_CHARACTERS,
+ IDENTIFIER_ALLOWED_CHARACTERS + IDENTIFIER_ALLOWED_CHARACTERS_SZ,
+ line[pos]) != IDENTIFIER_ALLOWED_CHARACTERS + IDENTIFIER_ALLOWED_CHARACTERS_SZ)
+ {
+ identifierLength++;
+ pos++;
+ }
+ else
+ {
+ break;
+ }
+ }
+ const Aws::String SECTION_END_CHARS_TO_SKIP = Aws::String(WHITESPACE_CHARACTERS) + RIGHT_BRACKET;
+
+ if(identifierLength == 0)
+ {
+ oErrorMsg = "identifier is missing";
+ return "";
+ }
+ if(pos >= line.size() || SECTION_END_CHARS_TO_SKIP.find(line[pos]) == Aws::String::npos) {
+ oErrorMsg = "a blank space character or closing bracket is expected after Identifier";
+ return "";
+ }
+ Aws::String sectionIdentifier = line.substr(identifierBegin, identifierLength);
+
+ return sectionIdentifier;
+ }
+
+ /**
+ * A helper function to parse config section declaration line
+ * @param line, an input line, e.g. "[profile default]"
+ * @param ioSectionName, a return argument representing parsed section Identifier, e.g. "default"
+ * @param ioState, a return argument representing parser state, e.g. PROFILE_FOUND
+ */
+ void ParseSectionDeclaration(const Aws::String& line,
+ Aws::String& ioSectionName,
+ State& ioState)
+ {
+ do { // goto in a form of "do { break; } while(0);"
+ Aws::String::size_type pos = 0;
+ pos = line.find_first_not_of(WHITESPACE_CHARACTERS, pos);
+ if(pos != Aws::String::npos && LEFT_BRACKET != line[pos])
+ {
+ AWS_LOGSTREAM_ERROR(PARSER_TAG, "First non-blank space character of a section definition must be [, line:" << line);
+ break;
+ }
+ pos++;
+ pos = line.find_first_not_of(WHITESPACE_CHARACTERS, pos);
+ if(pos == Aws::String::npos || pos >= line.size())
+ {
+ AWS_LOGSTREAM_ERROR(PARSER_TAG, "Unknown section found in the aws config file: " << line);
+ break;
+ }
+ bool defaultProfileOrSsoSectionRequired = false;
+ if (m_useProfilePrefix)
+ {
+ // in configuration files, the profile name must start with profile. (eg. [profile profile-name]),
+ // except where the profile name is default. When the profile name is default it may start with profile
+ static const size_t PROFILE_KEYWORD_LENGTH = 7;
+ if(line.rfind(PROFILE_SECTION, pos + PROFILE_KEYWORD_LENGTH) != Aws::String::npos)
+ {
+ // skipping required (optional for default) profile keyword
+ pos += PROFILE_KEYWORD_LENGTH;
+ if(pos >= line.size() ||
+ std::find(WHITESPACE_CHARACTERS,
+ WHITESPACE_CHARACTERS + WHITESPACE_CHARACTERS_SZ,
+ line[pos]) == WHITESPACE_CHARACTERS + WHITESPACE_CHARACTERS_SZ)
+ {
+ AWS_LOGSTREAM_ERROR(PARSER_TAG, "Expected a blank space after \"profile\" keyword: " << line);
+ break;
+ }
+ pos = line.find_first_not_of(WHITESPACE_CHARACTERS, pos);
+ }
+ else
+ {
+ defaultProfileOrSsoSectionRequired = true;
+ }
+ }
+
+ Aws::String errorMsg;
+ Aws::String sectionIdentifier = ParseIdentifier(line, pos, errorMsg);
+ if (!errorMsg.empty())
+ {
+ AWS_LOGSTREAM_ERROR(PARSER_TAG, "Failed to parse section identifier: " << errorMsg << " " << line);
+ break;
+ }
+ pos += sectionIdentifier.length();
+
+ if(defaultProfileOrSsoSectionRequired)
+ {
+ if (sectionIdentifier != DEFAULT && sectionIdentifier != SSO_SESSION_SECTION)
+ {
+ AWS_LOGSTREAM_ERROR(PARSER_TAG, "In configuration files, the profile name must start with "
+ "profile keyword (except default profile): " << line);
+ break;
+ }
+ if (sectionIdentifier != SSO_SESSION_SECTION)
+ {
+ // profile found, still pending check for closing bracket
+ ioState = PROFILE_FOUND;
+ ioSectionName = sectionIdentifier;
+ }
+ }
+
+ if(!m_useProfilePrefix || sectionIdentifier != SSO_SESSION_SECTION)
+ {
+ // profile found, still pending check for closing bracket
+ ioState = PROFILE_FOUND;
+ ioSectionName = sectionIdentifier;
+ }
+
+ if(m_useProfilePrefix && sectionIdentifier == SSO_SESSION_SECTION)
+ {
+ // "[sso_session..." found, continue parsing for sso_session identifier
+ pos = line.find_first_not_of(WHITESPACE_CHARACTERS, pos);
+ if(pos == Aws::String::npos)
+ {
+ AWS_LOGSTREAM_ERROR(PARSER_TAG, "Expected a blank space after \"sso_session\" keyword: " << line);
+ break;
+ }
+
+ sectionIdentifier = ParseIdentifier(line, pos, errorMsg);
+ if (!errorMsg.empty())
+ {
+ AWS_LOGSTREAM_ERROR(PARSER_TAG, "Failed to parse section identifier: " << errorMsg << " " << line);
+ break;
+ }
+ pos += sectionIdentifier.length();
+ // sso_session found, still pending check for closing bracket
+ ioState = SSO_SESSION_FOUND;
+ ioSectionName = sectionIdentifier;
+ }
+
+ pos = line.find_first_not_of(WHITESPACE_CHARACTERS, pos);
+ if(pos == Aws::String::npos)
+ {
+ AWS_LOGSTREAM_ERROR(PARSER_TAG, "Expected a non-blank space after section identifier (i.e. missing \"]\"): " << line);
+ break;
+ }
+ if(line[pos] != RIGHT_BRACKET)
+ {
+ AWS_LOGSTREAM_ERROR(PARSER_TAG, "Missing closing bracket after Section Identifier "
+ "(i.e. missing \"]\" or extra non-blank characters before \"]\"): " << line);
+ break;
+ }
+ pos++;
+ pos = line.find_first_not_of(WHITESPACE_CHARACTERS, pos);
+ if(pos != Aws::String::npos &&
+ std::find(COMMENT_START, COMMENT_START + COMMENT_START_SZ, line[pos]) == COMMENT_START + COMMENT_START_SZ)
+ {
+ AWS_LOGSTREAM_ERROR(PARSER_TAG, "Found unexpected characters after closing bracket of Section Identifier " << line);
+ break;
+ }
+ // the rest is a comment, and we don't care about it.
+ if ((ioState != SSO_SESSION_FOUND && ioState != PROFILE_FOUND) || ioSectionName.empty())
+ {
+ AWS_LOGSTREAM_FATAL(PARSER_TAG, "Unexpected parser state after attempting to parse section " << line);
+ break;
+ }
+ return;
+ } while(0); // end of goto in a form of "do { break; } while(0);"
+
+ ioSectionName.erase();
+ ioState = UNKNOWN_SECTION_FOUND;
+ return;
+ }
+
+ /**
+ * A helper function to store currently being parsed section along with its properties
+ * (i.e. [profile default] and its key1=val1 under).
+ * @param currentState, a current parser State, e.g. PROFILE_FOUND
+ * @param currentSectionName, a current section identifier, e.g. "default"
+ * @param currentKeyValues, a map of parsed key-value properties of a section definition being recorded
+ */
+ void FlushSection(const State currentState, const Aws::String& currentSectionName, Aws::Map<Aws::String, Aws::String>& currentKeyValues)
+ {
+ if(START == currentState || currentSectionName.empty())
+ {
+ return; //nothing to flush
+ }
+
+ if(PROFILE_FOUND == currentState)
+ {
+ Profile& profile = m_foundProfiles[currentSectionName];
+
+ for(const auto& keyVal : currentKeyValues)
+ {
+ auto setterFuncPtr = FindInStaticArray(PROFILE_PROPERTY_FUNCS, keyVal.first);
+ if(setterFuncPtr)
+ {
+ AWS_LOGSTREAM_DEBUG(PARSER_TAG, "Found " << setterFuncPtr->PropertyKey << " " << keyVal.second);
+ setterFuncPtr->Setter(profile, keyVal.second);
+ }
+ else
+ {
+ auto specialPropertyKey = std::find_if(PROFILE_KEY_SPECIAL_HANDLING, PROFILE_KEY_SPECIAL_HANDLING + PROFILE_KEY_SPECIAL_HANDLING_SZ,
+ [&keyVal](const char* entry)
+ {
+ return !!entry && keyVal.first == entry;
+ });
+
+ if (specialPropertyKey && specialPropertyKey != PROFILE_KEY_SPECIAL_HANDLING + PROFILE_KEY_SPECIAL_HANDLING_SZ)
+ {
+ AWS_LOGSTREAM_INFO(PARSER_TAG, "Unknown property: " << keyVal.first << " in the profile: " << currentSectionName);
+ }
+ }
+ }
+
+ auto accessKeyIdIter = currentKeyValues.find(ACCESS_KEY_ID_KEY);
+ Aws::String accessKey, secretKey, sessionToken;
+ if (accessKeyIdIter != currentKeyValues.end())
+ {
+ accessKey = accessKeyIdIter->second;
+ AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found access key " << accessKey);
+
+ auto secretAccessKeyIter = currentKeyValues.find(SECRET_KEY_KEY);
+ auto sessionTokenIter = currentKeyValues.find(SESSION_TOKEN_KEY);
+ if (secretAccessKeyIter != currentKeyValues.end())
+ {
+ secretKey = secretAccessKeyIter->second;
+ }
+ else
+ {
+ AWS_LOGSTREAM_ERROR(PARSER_TAG, "No secret access key found even though an access key was specified. This will cause all signed AWS calls to fail.");
+ }
+
+ if (sessionTokenIter != currentKeyValues.end())
+ {
+ sessionToken = sessionTokenIter->second;
+ }
+
+ profile.SetCredentials(Aws::Auth::AWSCredentials(accessKey, secretKey, sessionToken));
+ }
+
+ if (!profile.GetSsoStartUrl().empty() || !profile.GetSsoRegion().empty()
+ || !profile.GetSsoAccountId().empty() || !profile.GetSsoRoleName().empty())
+ {
+ // If there is no sso session, all fields are required. If an SSO session is present,
+ // then only account id and sso role name are required.
+ auto hasSession = currentKeyValues.find(SSO_SESSION_KEY) != currentKeyValues.end();
+ auto hasInvalidProfileWithoutSession = !hasSession &&
+ (profile.GetSsoStartUrl().empty()
+ || profile.GetSsoRegion().empty()
+ || profile.GetSsoAccountId().empty()
+ || profile.GetSsoRoleName().empty());
+ auto hasInvalidProfileWithSession = hasSession &&
+ (profile.GetSsoAccountId().empty()
+ || profile.GetSsoRoleName().empty());
+ if (hasInvalidProfileWithoutSession || hasInvalidProfileWithSession) {
+ profile.SetSsoStartUrl("");
+ profile.SetSsoRegion("");
+ profile.SetSsoAccountId("");
+ profile.SetSsoRoleName("");
+ AWS_LOGSTREAM_ERROR(PARSER_TAG, "invalid SSO configuration for aws profile " << currentSectionName);
+ }
+ }
+
+ profile.SetName(currentSectionName);
+ profile.SetAllKeyValPairs(std::move(currentKeyValues));
+ }
+ else if (SSO_SESSION_FOUND == currentState) {
+ Profile::SsoSession& ssoSession = m_foundSsoSessions[currentSectionName];
+ for(const auto& keyVal : currentKeyValues)
+ {
+ auto setterFuncPtr = FindInStaticArray(SSO_SESSION_PROPERTY_FUNCS, keyVal.first);
+ if(setterFuncPtr)
+ {
+ AWS_LOGSTREAM_DEBUG(PARSER_TAG, "Found sso-session property " << setterFuncPtr->PropertyKey << " " << keyVal.second);
+ setterFuncPtr->Setter(ssoSession, keyVal.second);
+ }
+ else
+ {
+ AWS_LOGSTREAM_INFO(PARSER_TAG, "Unknown property: " << keyVal.first << " in the sso-session: " << currentSectionName);
+ }
+ }
+ ssoSession.SetName(currentSectionName);
+ ssoSession.SetAllKeyValPairs(std::move(currentKeyValues));
+ }
+ else
+ {
+ AWS_LOGSTREAM_FATAL(PARSER_TAG, "Unknown parser error: unexpected state " << currentState);
+ }
+ }
+
+ Aws::Map<String, Profile> m_foundProfiles;
+ Aws::Map<String, Profile::SsoSession> m_foundSsoSessions;
+ };
+
+ static const char* const CONFIG_FILE_LOADER = "Aws::Config::AWSConfigFileProfileConfigLoader";
+
+ AWSConfigFileProfileConfigLoader::AWSConfigFileProfileConfigLoader(const Aws::String& fileName, bool useProfilePrefix) :
+ m_fileName(fileName), m_useProfilePrefix(useProfilePrefix)
+ {
+ AWS_LOGSTREAM_INFO(CONFIG_FILE_LOADER, "Initializing config loader against fileName "
+ << fileName << " and using profilePrefix = " << useProfilePrefix);
+ }
+
+ bool AWSConfigFileProfileConfigLoader::LoadInternal()
+ {
+ m_profiles.clear();
+
+ Aws::IFStream inputFile(m_fileName.c_str());
+ if(inputFile)
+ {
+ ConfigFileProfileFSM parser(m_useProfilePrefix);
+ parser.ParseStream(inputFile);
+ m_profiles = parser.GetProfiles();
+ return m_profiles.size() > 0;
+ }
+
+ AWS_LOGSTREAM_INFO(CONFIG_FILE_LOADER, "Unable to open config file " << m_fileName << " for reading.");
+
+ return false;
+ }
+
+ bool AWSConfigFileProfileConfigLoader::PersistInternal(const Aws::Map<Aws::String, Profile>& profiles)
+ {
+ Aws::OFStream outputFile(m_fileName.c_str(), std::ios_base::out | std::ios_base::trunc);
+ if(outputFile)
+ {
+ Aws::UnorderedMap<Aws::String, std::reference_wrapper<const Profile::SsoSession>> ssoSessionsToDump;
+
+ for(const auto& profile : profiles)
+ {
+ Aws::String prefix = m_useProfilePrefix ? PROFILE_SECTION : "";
+
+ AWS_LOGSTREAM_DEBUG(CONFIG_FILE_LOADER, "Writing profile " << profile.first << " to disk.");
+
+ outputFile << LEFT_BRACKET << prefix << " " << profile.second.GetName() << RIGHT_BRACKET << std::endl;
+ const Aws::Auth::AWSCredentials& credentials = profile.second.GetCredentials();
+ if (!credentials.GetAWSAccessKeyId().empty()) {
+ outputFile << ACCESS_KEY_ID_KEY << EQ << credentials.GetAWSAccessKeyId() << std::endl;
+ }
+ if (!credentials.GetAWSSecretKey().empty()) {
+ outputFile << SECRET_KEY_KEY << EQ << credentials.GetAWSSecretKey() << std::endl;
+ }
+ if(!credentials.GetSessionToken().empty()) {
+ outputFile << SESSION_TOKEN_KEY << EQ << credentials.GetSessionToken() << std::endl;
+ }
+ // credentials.GetExpiration().Millis() <- is not present in a config.
+
+ for(const auto& profilePropertyPair : PROFILE_PROPERTY_FUNCS)
+ {
+ const auto& profilePropertyValue = profilePropertyPair.Getter(profile.second);
+ if(!profilePropertyValue.empty())
+ {
+ outputFile << profilePropertyPair.PropertyKey << EQ << profilePropertyValue << std::endl;
+ }
+ }
+
+ if(profile.second.IsSsoSessionSet())
+ {
+ const auto& ssoSession = profile.second.GetSsoSession();
+ const auto alreadyScheduledForDumpIt = ssoSessionsToDump.find(ssoSession.GetName());
+ if (alreadyScheduledForDumpIt != ssoSessionsToDump.end() &&
+ alreadyScheduledForDumpIt->second.get() != ssoSession)
+ {
+ AWS_LOGSTREAM_WARN(CONFIG_FILE_LOADER, "2 or more profiles reference 'sso-session' section "
+ "with the same name but different properties: " << ssoSession.GetName());
+ }
+ else
+ {
+ ssoSessionsToDump.insert({ssoSession.GetName(), std::cref(ssoSession)});
+ }
+ outputFile << SSO_SESSION_KEY << EQ << ssoSession.GetName() << std::endl;
+ }
+ outputFile << std::endl;
+ }
+
+ for(const auto& ssoSessionPair : ssoSessionsToDump)
+ {
+ AWS_LOGSTREAM_DEBUG(CONFIG_FILE_LOADER, "Writing sso-session " << ssoSessionPair.first << " to disk.");
+ const Profile::SsoSession& ssoSession = ssoSessionPair.second.get();
+ outputFile << LEFT_BRACKET << SSO_SESSION_SECTION << " " << ssoSession.GetName() << RIGHT_BRACKET << std::endl;
+ for(const auto& ssoSessionPropertyPair : SSO_SESSION_PROPERTY_FUNCS)
+ {
+ const auto& profilePropertyValue = ssoSessionPropertyPair.Getter(ssoSession);
+ if(!profilePropertyValue.empty())
+ {
+ outputFile << ssoSessionPropertyPair.PropertyKey << EQ << profilePropertyValue << std::endl;
+ }
+ }
+ outputFile << std::endl;
+ }
+
+ AWS_LOGSTREAM_INFO(CONFIG_FILE_LOADER, "Profiles written to config file " << m_fileName);
+
+ return true;
+ }
+
+ AWS_LOGSTREAM_WARN(CONFIG_FILE_LOADER, "Unable to open config file " << m_fileName << " for writing.");
+
+ return false;
+ }
+ } // Config namespace
+} // Aws namespace
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp
deleted file mode 100644
index bb6acd0b3a..0000000000
--- a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp
+++ /dev/null
@@ -1,571 +0,0 @@
-/**
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- * SPDX-License-Identifier: Apache-2.0.
- */
-
-#include <aws/core/config/AWSProfileConfigLoader.h>
-#include <aws/core/internal/AWSHttpResourceClient.h>
-#include <aws/core/auth/AWSCredentialsProvider.h>
-#include <aws/core/utils/memory/stl/AWSList.h>
-#include <aws/core/utils/memory/stl/AWSStreamFwd.h>
-#include <aws/core/utils/StringUtils.h>
-#include <aws/core/utils/logging/LogMacros.h>
-#include <aws/core/utils/json/JsonSerializer.h>
-#include <fstream>
-
-namespace Aws
-{
- namespace Config
- {
- using namespace Aws::Utils;
- using namespace Aws::Auth;
-
- static const char* const CONFIG_LOADER_TAG = "Aws::Config::AWSProfileConfigLoader";
- #ifdef _MSC_VER
- // VS2015 compiler's bug, warning s_CoreErrorsMapper: symbol will be dynamically initialized (implementation limitation)
- AWS_SUPPRESS_WARNING(4592,
- static Aws::UniquePtr<ConfigAndCredentialsCacheManager> s_configManager(nullptr);
- )
- #else
- static Aws::UniquePtr<ConfigAndCredentialsCacheManager> s_configManager(nullptr);
- #endif
-
- static const char CONFIG_CREDENTIALS_CACHE_MANAGER_TAG[] = "ConfigAndCredentialsCacheManager";
-
- bool AWSProfileConfigLoader::Load()
- {
- if(LoadInternal())
- {
- AWS_LOGSTREAM_INFO(CONFIG_LOADER_TAG, "Successfully reloaded configuration.");
- m_lastLoadTime = DateTime::Now();
- AWS_LOGSTREAM_TRACE(CONFIG_LOADER_TAG, "reloaded config at "
- << m_lastLoadTime.ToGmtString(DateFormat::ISO_8601));
- return true;
- }
-
- AWS_LOGSTREAM_INFO(CONFIG_LOADER_TAG, "Failed to reload configuration.");
- return false;
- }
-
- bool AWSProfileConfigLoader::PersistProfiles(const Aws::Map<Aws::String, Profile>& profiles)
- {
- if(PersistInternal(profiles))
- {
- AWS_LOGSTREAM_INFO(CONFIG_LOADER_TAG, "Successfully persisted configuration.");
- m_profiles = profiles;
- m_lastLoadTime = DateTime::Now();
- AWS_LOGSTREAM_TRACE(CONFIG_LOADER_TAG, "persisted config at "
- << m_lastLoadTime.ToGmtString(DateFormat::ISO_8601));
- return true;
- }
-
- AWS_LOGSTREAM_WARN(CONFIG_LOADER_TAG, "Failed to persist configuration.");
- return false;
- }
-
- static const char REGION_KEY[] = "region";
- static const char ACCESS_KEY_ID_KEY[] = "aws_access_key_id";
- static const char SECRET_KEY_KEY[] = "aws_secret_access_key";
- static const char SESSION_TOKEN_KEY[] = "aws_session_token";
- static const char SSO_START_URL_KEY[] = "sso_start_url";
- static const char SSO_REGION_KEY[] = "sso_region";
- static const char SSO_ACCOUNT_ID_KEY[] = "sso_account_id";
- static const char SSO_ROLE_NAME_KEY[] = "sso_role_name";
- static const char ROLE_ARN_KEY[] = "role_arn";
- static const char EXTERNAL_ID_KEY[] = "external_id";
- static const char CREDENTIAL_PROCESS_COMMAND[] = "credential_process";
- static const char SOURCE_PROFILE_KEY[] = "source_profile";
- static const char PROFILE_PREFIX[] = "profile ";
- static const char EQ = '=';
- static const char LEFT_BRACKET = '[';
- static const char RIGHT_BRACKET = ']';
- static const char PARSER_TAG[] = "Aws::Config::ConfigFileProfileFSM";
-
- class ConfigFileProfileFSM
- {
- public:
- ConfigFileProfileFSM() : m_parserState(START) {}
-
- const Aws::Map<String, Profile>& GetProfiles() const { return m_foundProfiles; }
-
- void ParseStream(Aws::IStream& stream)
- {
- static const size_t ASSUME_EMPTY_LEN = 3;
-
- Aws::String line;
- while(std::getline(stream, line) && m_parserState != FAILURE)
- {
- if (line.empty() || line.length() < ASSUME_EMPTY_LEN)
- {
- continue;
- }
-
- auto openPos = line.find(LEFT_BRACKET);
- auto closePos = line.find(RIGHT_BRACKET);
-
- switch(m_parserState)
- {
-
- case START:
- if(openPos != std::string::npos && closePos != std::string::npos)
- {
- FlushProfileAndReset(line, openPos, closePos);
- m_parserState = PROFILE_FOUND;
- }
- break;
-
- //fallthrough here is intentional to reduce duplicate logic
- case PROFILE_KEY_VALUE_FOUND:
- if(openPos != std::string::npos && closePos != std::string::npos)
- {
- m_parserState = PROFILE_FOUND;
- FlushProfileAndReset(line, openPos, closePos);
- break;
- }
- // fall through
- case PROFILE_FOUND:
- {
- auto equalsPos = line.find(EQ);
- if (equalsPos != std::string::npos)
- {
- auto key = line.substr(0, equalsPos);
- auto value = line.substr(equalsPos + 1);
- m_profileKeyValuePairs[StringUtils::Trim(key.c_str())] =
- StringUtils::Trim(value.c_str());
- m_parserState = PROFILE_KEY_VALUE_FOUND;
- }
-
- break;
- }
- default:
- m_parserState = FAILURE;
- break;
- }
- }
-
- FlushProfileAndReset(line, std::string::npos, std::string::npos);
- }
-
- private:
-
- void FlushProfileAndReset(Aws::String& line, size_t openPos, size_t closePos)
- {
- if(!m_currentWorkingProfile.empty() && !m_profileKeyValuePairs.empty())
- {
- Profile profile;
- profile.SetName(m_currentWorkingProfile);
-
- auto regionIter = m_profileKeyValuePairs.find(REGION_KEY);
- if (regionIter != m_profileKeyValuePairs.end())
- {
- AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found region " << regionIter->second);
- profile.SetRegion(regionIter->second);
- }
-
- auto accessKeyIdIter = m_profileKeyValuePairs.find(ACCESS_KEY_ID_KEY);
- Aws::String accessKey, secretKey, sessionToken;
- if (accessKeyIdIter != m_profileKeyValuePairs.end())
- {
- accessKey = accessKeyIdIter->second;
- AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found access key " << accessKey);
-
- auto secretAccessKeyIter = m_profileKeyValuePairs.find(SECRET_KEY_KEY);
- auto sessionTokenIter = m_profileKeyValuePairs.find(SESSION_TOKEN_KEY);
- if (secretAccessKeyIter != m_profileKeyValuePairs.end())
- {
- secretKey = secretAccessKeyIter->second;
- }
- else
- {
- AWS_LOGSTREAM_ERROR(PARSER_TAG, "No secret access key found even though an access key was specified. This will cause all signed AWS calls to fail.");
- }
-
- if (sessionTokenIter != m_profileKeyValuePairs.end())
- {
- sessionToken = sessionTokenIter->second;
- }
-
- profile.SetCredentials(Aws::Auth::AWSCredentials(accessKey, secretKey, sessionToken));
- }
-
- auto ssoStartUrlIter = m_profileKeyValuePairs.find(SSO_START_URL_KEY);
- auto ssoRegionIter = m_profileKeyValuePairs.find(SSO_REGION_KEY);
- auto ssoRoleNameIter = m_profileKeyValuePairs.find(SSO_ROLE_NAME_KEY);
- auto ssoAccountIdIter = m_profileKeyValuePairs.find(SSO_ACCOUNT_ID_KEY);
- if (ssoStartUrlIter != m_profileKeyValuePairs.end()
- || ssoRegionIter != m_profileKeyValuePairs.end()
- || ssoRoleNameIter != m_profileKeyValuePairs.end()
- || ssoAccountIdIter != m_profileKeyValuePairs.end())
- {
- if (ssoStartUrlIter != m_profileKeyValuePairs.end()
- && ssoRegionIter != m_profileKeyValuePairs.end()
- && ssoRoleNameIter != m_profileKeyValuePairs.end()
- && ssoAccountIdIter != m_profileKeyValuePairs.end())
- {
- AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found sso_start_url " << ssoStartUrlIter->second);
- profile.SetSsoStartUrl(ssoStartUrlIter->second);
- AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found sso_region " << ssoRegionIter->second);
- profile.SetSsoRegion(ssoRegionIter->second);
- AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found sso_account_id " << ssoAccountIdIter->second);
- profile.SetSsoAccountId(ssoAccountIdIter->second);
- AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found sso_role_name " << ssoRoleNameIter->second);
- profile.SetSsoRoleName(ssoRoleNameIter->second);
- } else {
- AWS_LOGSTREAM_ERROR(PARSER_TAG, "invalid configuration for sso profile " << profile.GetName());
- }
- }
-
- auto assumeRoleArnIter = m_profileKeyValuePairs.find(ROLE_ARN_KEY);
- if (assumeRoleArnIter != m_profileKeyValuePairs.end())
- {
- AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found role arn " << assumeRoleArnIter->second);
- profile.SetRoleArn(assumeRoleArnIter->second);
- }
-
- auto externalIdIter = m_profileKeyValuePairs.find(EXTERNAL_ID_KEY);
- if (externalIdIter != m_profileKeyValuePairs.end())
- {
- AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found external id " << externalIdIter->second);
- profile.SetExternalId(externalIdIter->second);
- }
-
- auto sourceProfileIter = m_profileKeyValuePairs.find(SOURCE_PROFILE_KEY);
- if (sourceProfileIter != m_profileKeyValuePairs.end())
- {
- AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found source profile " << sourceProfileIter->second);
- profile.SetSourceProfile(sourceProfileIter->second);
- }
-
- auto credentialProcessIter = m_profileKeyValuePairs.find(CREDENTIAL_PROCESS_COMMAND);
- if (credentialProcessIter != m_profileKeyValuePairs.end())
- {
- AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found credential process " << credentialProcessIter->second);
- profile.SetCredentialProcess(credentialProcessIter->second);
- }
- profile.SetAllKeyValPairs(m_profileKeyValuePairs);
-
- m_foundProfiles[profile.GetName()] = std::move(profile);
- m_currentWorkingProfile.clear();
- m_profileKeyValuePairs.clear();
- }
-
- if(!line.empty() && openPos != std::string::npos && closePos != std::string::npos)
- {
- m_currentWorkingProfile = StringUtils::Trim(line.substr(openPos + 1, closePos - openPos - 1).c_str());
- StringUtils::Replace(m_currentWorkingProfile, PROFILE_PREFIX, "");
- AWS_LOGSTREAM_DEBUG(PARSER_TAG, "found profile " << m_currentWorkingProfile);
- }
- }
-
- enum State
- {
- START = 0,
- PROFILE_FOUND,
- PROFILE_KEY_VALUE_FOUND,
- FAILURE
- };
-
- Aws::String m_currentWorkingProfile;
- Aws::Map<String, String> m_profileKeyValuePairs;
- State m_parserState;
- Aws::Map<String, Profile> m_foundProfiles;
- };
-
- static const char* const CONFIG_FILE_LOADER = "Aws::Config::AWSConfigFileProfileConfigLoader";
-
- AWSConfigFileProfileConfigLoader::AWSConfigFileProfileConfigLoader(const Aws::String& fileName, bool useProfilePrefix) :
- m_fileName(fileName), m_useProfilePrefix(useProfilePrefix)
- {
- AWS_LOGSTREAM_INFO(CONFIG_FILE_LOADER, "Initializing config loader against fileName "
- << fileName << " and using profilePrefix = " << useProfilePrefix);
- }
-
- bool AWSConfigFileProfileConfigLoader::LoadInternal()
- {
- m_profiles.clear();
-
- Aws::IFStream inputFile(m_fileName.c_str());
- if(inputFile)
- {
- ConfigFileProfileFSM parser;
- parser.ParseStream(inputFile);
- m_profiles = parser.GetProfiles();
- return m_profiles.size() > 0;
- }
-
- AWS_LOGSTREAM_INFO(CONFIG_FILE_LOADER, "Unable to open config file " << m_fileName << " for reading.");
-
- return false;
- }
-
- bool AWSConfigFileProfileConfigLoader::PersistInternal(const Aws::Map<Aws::String, Profile>& profiles)
- {
- Aws::OFStream outputFile(m_fileName.c_str(), std::ios_base::out | std::ios_base::trunc);
- if(outputFile)
- {
- for(auto& profile : profiles)
- {
- Aws::String prefix = m_useProfilePrefix ? PROFILE_PREFIX : "";
-
- AWS_LOGSTREAM_DEBUG(CONFIG_FILE_LOADER, "Writing profile " << profile.first << " to disk.");
-
- outputFile << LEFT_BRACKET << prefix << profile.second.GetName() << RIGHT_BRACKET << std::endl;
- const Aws::Auth::AWSCredentials& credentials = profile.second.GetCredentials();
- outputFile << ACCESS_KEY_ID_KEY << EQ << credentials.GetAWSAccessKeyId() << std::endl;
- outputFile << SECRET_KEY_KEY << EQ << credentials.GetAWSSecretKey() << std::endl;
-
- if(!credentials.GetSessionToken().empty())
- {
- outputFile << SESSION_TOKEN_KEY << EQ << credentials.GetSessionToken() << std::endl;
- }
-
- if(!profile.second.GetRegion().empty())
- {
- outputFile << REGION_KEY << EQ << profile.second.GetRegion() << std::endl;
- }
-
- if(!profile.second.GetRoleArn().empty())
- {
- outputFile << ROLE_ARN_KEY << EQ << profile.second.GetRoleArn() << std::endl;
- }
-
- if(!profile.second.GetSourceProfile().empty())
- {
- outputFile << SOURCE_PROFILE_KEY << EQ << profile.second.GetSourceProfile() << std::endl;
- }
-
- outputFile << std::endl;
- }
-
- AWS_LOGSTREAM_INFO(CONFIG_FILE_LOADER, "Profiles written to config file " << m_fileName);
-
- return true;
- }
-
- AWS_LOGSTREAM_WARN(CONFIG_FILE_LOADER, "Unable to open config file " << m_fileName << " for writing.");
-
- return false;
- }
-
- static const char* const EC2_INSTANCE_PROFILE_LOG_TAG = "Aws::Config::EC2InstanceProfileConfigLoader";
-
- EC2InstanceProfileConfigLoader::EC2InstanceProfileConfigLoader(const std::shared_ptr<Aws::Internal::EC2MetadataClient>& client)
- : m_ec2metadataClient(client == nullptr ? Aws::MakeShared<Aws::Internal::EC2MetadataClient>(EC2_INSTANCE_PROFILE_LOG_TAG) : client)
- {
- }
-
- bool EC2InstanceProfileConfigLoader::LoadInternal()
- {
- auto credentialsStr = m_ec2metadataClient->GetDefaultCredentialsSecurely();
- if(credentialsStr.empty()) return false;
-
- Json::JsonValue credentialsDoc(credentialsStr);
- if (!credentialsDoc.WasParseSuccessful())
- {
- AWS_LOGSTREAM_ERROR(EC2_INSTANCE_PROFILE_LOG_TAG,
- "Failed to parse output from EC2MetadataService.");
- return false;
- }
- const char* accessKeyId = "AccessKeyId";
- const char* secretAccessKey = "SecretAccessKey";
- Aws::String accessKey, secretKey, token;
-
- auto credentialsView = credentialsDoc.View();
- accessKey = credentialsView.GetString(accessKeyId);
- AWS_LOGSTREAM_INFO(EC2_INSTANCE_PROFILE_LOG_TAG,
- "Successfully pulled credentials from metadata service with access key " << accessKey);
-
- secretKey = credentialsView.GetString(secretAccessKey);
- token = credentialsView.GetString("Token");
-
- auto region = m_ec2metadataClient->GetCurrentRegion();
-
- Profile profile;
- profile.SetCredentials(AWSCredentials(accessKey, secretKey, token));
- profile.SetRegion(region);
- profile.SetName(INSTANCE_PROFILE_KEY);
-
- m_profiles[INSTANCE_PROFILE_KEY] = profile;
-
- return true;
- }
-
- ConfigAndCredentialsCacheManager::ConfigAndCredentialsCacheManager() :
- m_credentialsFileLoader(Aws::Auth::ProfileConfigFileAWSCredentialsProvider::GetCredentialsProfileFilename()),
- m_configFileLoader(Aws::Auth::GetConfigProfileFilename(), true/*use profile prefix*/)
- {
- ReloadCredentialsFile();
- ReloadConfigFile();
- }
-
- void ConfigAndCredentialsCacheManager::ReloadConfigFile()
- {
- Aws::Utils::Threading::WriterLockGuard guard(m_configLock);
- m_configFileLoader.SetFileName(Aws::Auth::GetConfigProfileFilename());
- m_configFileLoader.Load();
- }
-
- void ConfigAndCredentialsCacheManager::ReloadCredentialsFile()
- {
- Aws::Utils::Threading::WriterLockGuard guard(m_credentialsLock);
- m_credentialsFileLoader.SetFileName(Aws::Auth::ProfileConfigFileAWSCredentialsProvider::GetCredentialsProfileFilename());
- m_credentialsFileLoader.Load();
- }
-
- bool ConfigAndCredentialsCacheManager::HasConfigProfile(const Aws::String& profileName) const
- {
- Aws::Utils::Threading::ReaderLockGuard guard(m_configLock);
- return (m_configFileLoader.GetProfiles().count(profileName) == 1);
- }
-
- Aws::Config::Profile ConfigAndCredentialsCacheManager::GetConfigProfile(const Aws::String& profileName) const
- {
- Aws::Utils::Threading::ReaderLockGuard guard(m_configLock);
- const auto& profiles = m_configFileLoader.GetProfiles();
- const auto &iter = profiles.find(profileName);
- if (iter == profiles.end())
- {
- return {};
- }
- return iter->second;
- }
-
- Aws::Map<Aws::String, Aws::Config::Profile> ConfigAndCredentialsCacheManager::GetConfigProfiles() const
- {
- Aws::Utils::Threading::ReaderLockGuard guard(m_configLock);
- return m_configFileLoader.GetProfiles();
- }
-
- Aws::String ConfigAndCredentialsCacheManager::GetConfig(const Aws::String& profileName, const Aws::String& key) const
- {
- Aws::Utils::Threading::ReaderLockGuard guard(m_configLock);
- const auto& profiles = m_configFileLoader.GetProfiles();
- const auto &iter = profiles.find(profileName);
- if (iter == profiles.end())
- {
- return {};
- }
- return iter->second.GetValue(key);
- }
-
- bool ConfigAndCredentialsCacheManager::HasCredentialsProfile(const Aws::String& profileName) const
- {
- Aws::Utils::Threading::ReaderLockGuard guard(m_credentialsLock);
- return (m_credentialsFileLoader.GetProfiles().count(profileName) == 1);
- }
-
- Aws::Config::Profile ConfigAndCredentialsCacheManager::GetCredentialsProfile(const Aws::String& profileName) const
- {
- Aws::Utils::Threading::ReaderLockGuard guard(m_credentialsLock);
- const auto &profiles = m_credentialsFileLoader.GetProfiles();
- const auto &iter = profiles.find(profileName);
- if (iter == profiles.end())
- {
- return {};
- }
- return iter->second;
- }
-
- Aws::Map<Aws::String, Aws::Config::Profile> ConfigAndCredentialsCacheManager::GetCredentialsProfiles() const
- {
- Aws::Utils::Threading::ReaderLockGuard guard(m_credentialsLock);
- return m_credentialsFileLoader.GetProfiles();
- }
-
- Aws::Auth::AWSCredentials ConfigAndCredentialsCacheManager::GetCredentials(const Aws::String& profileName) const
- {
- Aws::Utils::Threading::ReaderLockGuard guard(m_credentialsLock);
- const auto& profiles = m_credentialsFileLoader.GetProfiles();
- const auto &iter = profiles.find(profileName);
- if (iter == profiles.end())
- {
- return {};
- }
- return iter->second.GetCredentials();
- }
-
- void InitConfigAndCredentialsCacheManager()
- {
- if (s_configManager)
- {
- return;
- }
- s_configManager = Aws::MakeUnique<ConfigAndCredentialsCacheManager>(CONFIG_CREDENTIALS_CACHE_MANAGER_TAG);
- }
-
- void CleanupConfigAndCredentialsCacheManager()
- {
- if (!s_configManager)
- {
- return;
- }
- s_configManager = nullptr;
- }
-
- void ReloadCachedConfigFile()
- {
- assert(s_configManager);
- s_configManager->ReloadConfigFile();
- }
-
- void ReloadCachedCredentialsFile()
- {
- assert(s_configManager);
- s_configManager->ReloadCredentialsFile();
- }
-
- bool HasCachedConfigProfile(const Aws::String& profileName)
- {
- assert(s_configManager);
- return s_configManager->HasConfigProfile(profileName);
- }
-
- Aws::Config::Profile GetCachedConfigProfile(const Aws::String& profileName)
- {
- assert(s_configManager);
- return s_configManager->GetConfigProfile(profileName);
- }
-
- Aws::Map<Aws::String, Aws::Config::Profile> GetCachedConfigProfiles()
- {
- assert(s_configManager);
- return s_configManager->GetConfigProfiles();
- }
-
- Aws::String GetCachedConfigValue(const Aws::String &profileName, const Aws::String &key)
- {
- assert(s_configManager);
- return s_configManager->GetConfig(profileName, key);
- }
-
- Aws::String GetCachedConfigValue(const Aws::String &key)
- {
- assert(s_configManager);
- return s_configManager->GetConfig(Aws::Auth::GetConfigProfileName(), key);
- }
-
- bool HasCachedCredentialsProfile(const Aws::String& profileName)
- {
- assert(s_configManager);
- return s_configManager->HasCredentialsProfile(profileName);
- }
-
- Aws::Config::Profile GetCachedCredentialsProfile(const Aws::String &profileName)
- {
- assert(s_configManager);
- return s_configManager->GetCredentialsProfile(profileName);
- }
-
- Aws::Map<Aws::String, Aws::Config::Profile> GetCachedCredentialsProfiles()
- {
- assert(s_configManager);
- return s_configManager->GetCredentialsProfiles();
- }
-
- Aws::Auth::AWSCredentials GetCachedCredentials(const Aws::String &profileName)
- {
- assert(s_configManager);
- return s_configManager->GetCredentials(profileName);
- }
- } // Config namespace
-} // Aws namespace
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoaderBase.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoaderBase.cpp
new file mode 100644
index 0000000000..cb7b19d0ce
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoaderBase.cpp
@@ -0,0 +1,50 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/config/AWSProfileConfigLoaderBase.h>
+#include <aws/core/utils/logging/LogMacros.h>
+#include <fstream>
+
+namespace Aws
+{
+ namespace Config
+ {
+ using namespace Aws::Utils;
+ using namespace Aws::Auth;
+
+ static const char* const CONFIG_LOADER_BASE_TAG = "Aws::Config::AWSProfileConfigLoaderBase";
+
+ bool AWSProfileConfigLoader::Load()
+ {
+ if(LoadInternal())
+ {
+ AWS_LOGSTREAM_INFO(CONFIG_LOADER_BASE_TAG, "Successfully reloaded configuration.");
+ m_lastLoadTime = DateTime::Now();
+ AWS_LOGSTREAM_TRACE(CONFIG_LOADER_BASE_TAG, "reloaded config at "
+ << m_lastLoadTime.ToGmtString(DateFormat::ISO_8601));
+ return true;
+ }
+
+ AWS_LOGSTREAM_INFO(CONFIG_LOADER_BASE_TAG, "Failed to reload configuration.");
+ return false;
+ }
+
+ bool AWSProfileConfigLoader::PersistProfiles(const Aws::Map<Aws::String, Profile>& profiles)
+ {
+ if(PersistInternal(profiles))
+ {
+ AWS_LOGSTREAM_INFO(CONFIG_LOADER_BASE_TAG, "Successfully persisted configuration.");
+ m_profiles = profiles;
+ m_lastLoadTime = DateTime::Now();
+ AWS_LOGSTREAM_TRACE(CONFIG_LOADER_BASE_TAG, "persisted config at "
+ << m_lastLoadTime.ToGmtString(DateFormat::ISO_8601));
+ return true;
+ }
+
+ AWS_LOGSTREAM_WARN(CONFIG_LOADER_BASE_TAG, "Failed to persist configuration.");
+ return false;
+ }
+ } // Config namespace
+} // Aws namespace
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/ConfigAndCredentialsCacheManager.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/ConfigAndCredentialsCacheManager.cpp
new file mode 100644
index 0000000000..b47fe72a0a
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/ConfigAndCredentialsCacheManager.cpp
@@ -0,0 +1,206 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/config/ConfigAndCredentialsCacheManager.h>
+#include <aws/core/auth/AWSCredentialsProvider.h>
+#include <aws/core/utils/memory/stl/AWSList.h>
+#include <aws/core/utils/json/JsonSerializer.h>
+#include <fstream>
+
+namespace Aws
+{
+ namespace Config
+ {
+ using namespace Aws::Utils;
+ using namespace Aws::Auth;
+
+ #ifdef _MSC_VER
+ // VS2015 compiler's bug, warning s_CoreErrorsMapper: symbol will be dynamically initialized (implementation limitation)
+ AWS_SUPPRESS_WARNING(4592,
+ static ConfigAndCredentialsCacheManager* s_configManager(nullptr);
+ )
+ #else
+ static ConfigAndCredentialsCacheManager* s_configManager(nullptr);
+ #endif
+
+ static const char CONFIG_CREDENTIALS_CACHE_MANAGER_TAG[] = "ConfigAndCredentialsCacheManager";
+
+
+ ConfigAndCredentialsCacheManager::ConfigAndCredentialsCacheManager() :
+ m_credentialsFileLoader(Aws::Auth::ProfileConfigFileAWSCredentialsProvider::GetCredentialsProfileFilename()),
+ m_configFileLoader(Aws::Auth::GetConfigProfileFilename(), true/*use profile prefix*/)
+ {
+ ReloadCredentialsFile();
+ ReloadConfigFile();
+ }
+
+ void ConfigAndCredentialsCacheManager::ReloadConfigFile()
+ {
+ Aws::Utils::Threading::WriterLockGuard guard(m_configLock);
+ m_configFileLoader.SetFileName(Aws::Auth::GetConfigProfileFilename());
+ m_configFileLoader.Load();
+ }
+
+ void ConfigAndCredentialsCacheManager::ReloadCredentialsFile()
+ {
+ Aws::Utils::Threading::WriterLockGuard guard(m_credentialsLock);
+ m_credentialsFileLoader.SetFileName(Aws::Auth::ProfileConfigFileAWSCredentialsProvider::GetCredentialsProfileFilename());
+ m_credentialsFileLoader.Load();
+ }
+
+ bool ConfigAndCredentialsCacheManager::HasConfigProfile(const Aws::String& profileName) const
+ {
+ Aws::Utils::Threading::ReaderLockGuard guard(m_configLock);
+ return (m_configFileLoader.GetProfiles().count(profileName) == 1);
+ }
+
+ Aws::Config::Profile ConfigAndCredentialsCacheManager::GetConfigProfile(const Aws::String& profileName) const
+ {
+ Aws::Utils::Threading::ReaderLockGuard guard(m_configLock);
+ const auto& profiles = m_configFileLoader.GetProfiles();
+ const auto &iter = profiles.find(profileName);
+ if (iter == profiles.end())
+ {
+ return {};
+ }
+ return iter->second;
+ }
+
+ Aws::Map<Aws::String, Aws::Config::Profile> ConfigAndCredentialsCacheManager::GetConfigProfiles() const
+ {
+ Aws::Utils::Threading::ReaderLockGuard guard(m_configLock);
+ return m_configFileLoader.GetProfiles();
+ }
+
+ Aws::String ConfigAndCredentialsCacheManager::GetConfig(const Aws::String& profileName, const Aws::String& key) const
+ {
+ Aws::Utils::Threading::ReaderLockGuard guard(m_configLock);
+ const auto& profiles = m_configFileLoader.GetProfiles();
+ const auto &iter = profiles.find(profileName);
+ if (iter == profiles.end())
+ {
+ return {};
+ }
+ return iter->second.GetValue(key);
+ }
+
+ bool ConfigAndCredentialsCacheManager::HasCredentialsProfile(const Aws::String& profileName) const
+ {
+ Aws::Utils::Threading::ReaderLockGuard guard(m_credentialsLock);
+ return (m_credentialsFileLoader.GetProfiles().count(profileName) == 1);
+ }
+
+ Aws::Config::Profile ConfigAndCredentialsCacheManager::GetCredentialsProfile(const Aws::String& profileName) const
+ {
+ Aws::Utils::Threading::ReaderLockGuard guard(m_credentialsLock);
+ const auto &profiles = m_credentialsFileLoader.GetProfiles();
+ const auto &iter = profiles.find(profileName);
+ if (iter == profiles.end())
+ {
+ return {};
+ }
+ return iter->second;
+ }
+
+ Aws::Map<Aws::String, Aws::Config::Profile> ConfigAndCredentialsCacheManager::GetCredentialsProfiles() const
+ {
+ Aws::Utils::Threading::ReaderLockGuard guard(m_credentialsLock);
+ return m_credentialsFileLoader.GetProfiles();
+ }
+
+ Aws::Auth::AWSCredentials ConfigAndCredentialsCacheManager::GetCredentials(const Aws::String& profileName) const
+ {
+ Aws::Utils::Threading::ReaderLockGuard guard(m_credentialsLock);
+ const auto& profiles = m_credentialsFileLoader.GetProfiles();
+ const auto &iter = profiles.find(profileName);
+ if (iter == profiles.end())
+ {
+ return {};
+ }
+ return iter->second.GetCredentials();
+ }
+
+ void InitConfigAndCredentialsCacheManager()
+ {
+ if (s_configManager)
+ {
+ return;
+ }
+ s_configManager = Aws::New<ConfigAndCredentialsCacheManager>(CONFIG_CREDENTIALS_CACHE_MANAGER_TAG);
+ }
+
+ void CleanupConfigAndCredentialsCacheManager()
+ {
+ Aws::Delete(s_configManager);
+ s_configManager = nullptr;
+ }
+
+ void ReloadCachedConfigFile()
+ {
+ assert(s_configManager);
+ s_configManager->ReloadConfigFile();
+ }
+
+ void ReloadCachedCredentialsFile()
+ {
+ assert(s_configManager);
+ s_configManager->ReloadCredentialsFile();
+ }
+
+ bool HasCachedConfigProfile(const Aws::String& profileName)
+ {
+ assert(s_configManager);
+ return s_configManager->HasConfigProfile(profileName);
+ }
+
+ Aws::Config::Profile GetCachedConfigProfile(const Aws::String& profileName)
+ {
+ assert(s_configManager);
+ return s_configManager->GetConfigProfile(profileName);
+ }
+
+ Aws::Map<Aws::String, Aws::Config::Profile> GetCachedConfigProfiles()
+ {
+ assert(s_configManager);
+ return s_configManager->GetConfigProfiles();
+ }
+
+ Aws::String GetCachedConfigValue(const Aws::String &profileName, const Aws::String &key)
+ {
+ assert(s_configManager);
+ return s_configManager->GetConfig(profileName, key);
+ }
+
+ Aws::String GetCachedConfigValue(const Aws::String &key)
+ {
+ assert(s_configManager);
+ return s_configManager->GetConfig(Aws::Auth::GetConfigProfileName(), key);
+ }
+
+ bool HasCachedCredentialsProfile(const Aws::String& profileName)
+ {
+ assert(s_configManager);
+ return s_configManager->HasCredentialsProfile(profileName);
+ }
+
+ Aws::Config::Profile GetCachedCredentialsProfile(const Aws::String &profileName)
+ {
+ assert(s_configManager);
+ return s_configManager->GetCredentialsProfile(profileName);
+ }
+
+ Aws::Map<Aws::String, Aws::Config::Profile> GetCachedCredentialsProfiles()
+ {
+ assert(s_configManager);
+ return s_configManager->GetCredentialsProfiles();
+ }
+
+ Aws::Auth::AWSCredentials GetCachedCredentials(const Aws::String &profileName)
+ {
+ assert(s_configManager);
+ return s_configManager->GetCredentials(profileName);
+ }
+ } // Config namespace
+} // Aws namespace
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/EC2InstanceProfileConfigLoader.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/EC2InstanceProfileConfigLoader.cpp
new file mode 100644
index 0000000000..0b505b2c00
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/EC2InstanceProfileConfigLoader.cpp
@@ -0,0 +1,112 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+#include <aws/core/config/AWSProfileConfigLoader.h>
+#include <aws/core/internal/AWSHttpResourceClient.h>
+#include <aws/core/auth/AWSCredentialsProvider.h>
+#include <aws/core/utils/memory/stl/AWSList.h>
+#include <aws/core/utils/logging/LogMacros.h>
+#include <aws/core/utils/json/JsonSerializer.h>
+#include <fstream>
+#include <random>
+
+namespace Aws
+{
+ namespace Config
+ {
+ using namespace Aws::Utils;
+ using namespace Aws::Auth;
+
+ static const char* const INTERNAL_EXCEPTION_PHRASE = "InternalServiceException";
+ static const int64_t FIVE_MINUTE_MILLIS = 60000 * 5;
+ static const int64_t TEN_MINUTE_MILLIS = 60000 * 10;
+
+ static const char* const EC2_INSTANCE_PROFILE_LOG_TAG = "Aws::Config::EC2InstanceProfileConfigLoader";
+
+ EC2InstanceProfileConfigLoader::EC2InstanceProfileConfigLoader(const std::shared_ptr<Aws::Internal::EC2MetadataClient>& client)
+ {
+ if(client == nullptr)
+ {
+ Aws::Internal::InitEC2MetadataClient();
+ m_ec2metadataClient = Aws::Internal::GetEC2MetadataClient();
+ }
+ else
+ {
+ m_ec2metadataClient = client;
+ }
+ }
+
+ bool EC2InstanceProfileConfigLoader::LoadInternal()
+ {
+ // re-use old credentials until we need to call IMDS again.
+ if (DateTime::Now().Millis() < this->credentialsValidUntilMillis) {
+ AWS_LOGSTREAM_ERROR(EC2_INSTANCE_PROFILE_LOG_TAG,
+ "Skipping IMDS call until " << this->credentialsValidUntilMillis);
+ return true;
+ }
+ this->credentialsValidUntilMillis = DateTime::Now().Millis();
+
+ if (!m_ec2metadataClient) {
+ AWS_LOGSTREAM_FATAL(EC2_INSTANCE_PROFILE_LOG_TAG, "EC2MetadataClient is a nullptr!")
+ return false;
+ }
+ auto credentialsStr = m_ec2metadataClient->GetDefaultCredentialsSecurely();
+ if(credentialsStr.empty()) return false;
+
+ Json::JsonValue credentialsDoc(credentialsStr);
+ if (!credentialsDoc.WasParseSuccessful())
+ {
+ AWS_LOGSTREAM_ERROR(EC2_INSTANCE_PROFILE_LOG_TAG,
+ "Failed to parse output from EC2MetadataService.");
+ return false;
+ }
+
+ const char* accessKeyId = "AccessKeyId";
+ const char* secretAccessKey = "SecretAccessKey";
+ const char* expiration = "Expiration";
+ const char* code = "Code";
+ Aws::String accessKey, secretKey, token;
+
+ auto credentialsView = credentialsDoc.View();
+ DateTime expirationTime(credentialsView.GetString(expiration), Aws::Utils::DateFormat::ISO_8601);
+ // re-use old credentials and not block if the IMDS call failed or if the latest credential is in the past
+ if (expirationTime.WasParseSuccessful() && DateTime::Now() > expirationTime) {
+ AWS_LOGSTREAM_ERROR(EC2_INSTANCE_PROFILE_LOG_TAG,
+ "Expiration Time of Credentials in the past, refusing to update credentials");
+ this->credentialsValidUntilMillis = DateTime::Now().Millis() + calculateRetryTime();
+ return true;
+ } else if (credentialsView.GetString(code) == INTERNAL_EXCEPTION_PHRASE) {
+ AWS_LOGSTREAM_ERROR(EC2_INSTANCE_PROFILE_LOG_TAG,
+ "IMDS call failed, refusing to update credentials");
+ this->credentialsValidUntilMillis = DateTime::Now().Millis() + calculateRetryTime();
+ return true;
+ }
+ accessKey = credentialsView.GetString(accessKeyId);
+ AWS_LOGSTREAM_INFO(EC2_INSTANCE_PROFILE_LOG_TAG,
+ "Successfully pulled credentials from metadata service with access key " << accessKey);
+
+ secretKey = credentialsView.GetString(secretAccessKey);
+ token = credentialsView.GetString("Token");
+
+ auto region = m_ec2metadataClient->GetCurrentRegion();
+
+ Profile profile;
+ profile.SetCredentials(AWSCredentials(accessKey, secretKey, token));
+ profile.SetRegion(region);
+ profile.SetName(INSTANCE_PROFILE_KEY);
+
+ m_profiles[INSTANCE_PROFILE_KEY] = profile;
+
+ return true;
+ }
+
+ int64_t EC2InstanceProfileConfigLoader::calculateRetryTime() const {
+ std::random_device rd;
+ std::mt19937_64 gen(rd());
+ std::uniform_int_distribution<int64_t> dist(FIVE_MINUTE_MILLIS, TEN_MINUTE_MILLIS);
+ return dist(gen);
+ }
+ } // Config namespace
+} // Aws namespace
diff --git a/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/defaults/ClientConfigurationDefaults.cpp b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/defaults/ClientConfigurationDefaults.cpp
new file mode 100644
index 0000000000..7b54066fb3
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/defaults/ClientConfigurationDefaults.cpp
@@ -0,0 +1,197 @@
+/**
+ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ * SPDX-License-Identifier: Apache-2.0.
+ */
+
+/**
+ * Please note that this file is autogenerated.
+ * The backwards compatibility of the default values provided by new client configuration defaults is not guaranteed;
+ * the values might change over time.
+ */
+
+#include <aws/common/platform.h> // for AWS_OS_IOS macro
+#include <aws/core/config/defaults/ClientConfigurationDefaults.h>
+#include <aws/core/config/AWSProfileConfigLoader.h>
+#include <aws/core/client/ClientConfiguration.h>
+#include <aws/core/internal/AWSHttpResourceClient.h>
+#include <aws/core/platform/Environment.h>
+#include <aws/core/utils/StringUtils.h>
+#include <aws/core/utils/logging/LogMacros.h>
+
+namespace Aws
+{
+ namespace Config
+ {
+ namespace Defaults
+ {
+ static const char* CLIENT_CONFIG_DEFAULTS_TAG = "ClientConfigurationDefaults";
+
+ void SetSmartDefaultsConfigurationParameters(Aws::Client::ClientConfiguration& clientConfig,
+ const Aws::String& defaultMode,
+ bool hasEc2MetadataRegion,
+ const Aws::String& ec2MetadataRegion)
+ {
+ const Aws::String caseInsensitiveMode = ResolveDefaultModeName(clientConfig,
+ defaultMode,
+ Aws::Config::GetCachedConfigValue("defaults_mode"),
+ hasEc2MetadataRegion,
+ ec2MetadataRegion);
+
+ if(caseInsensitiveMode == "legacy")
+ {
+ return SetLegacyClientConfiguration(clientConfig);
+ }
+
+ if(caseInsensitiveMode == "standard")
+ {
+ return SetStandardClientConfiguration(clientConfig);
+ }
+
+ if(caseInsensitiveMode == "in-region")
+ {
+ return SetInRegionClientConfiguration(clientConfig);
+ }
+
+ if(caseInsensitiveMode == "cross-region")
+ {
+ return SetCrossRegionClientConfiguration(clientConfig);
+ }
+
+ if(caseInsensitiveMode == "mobile")
+ {
+ return SetMobileClientConfiguration(clientConfig);
+ }
+ return SetLegacyClientConfiguration(clientConfig);
+ }
+
+ bool isMobile()
+ {
+#if defined(AWS_OS_IOS) || defined (__ANDROID__)
+ return true;
+#else
+ return false;
+#endif
+ }
+
+ const char* ResolveAutoClientConfiguration(const Aws::Client::ClientConfiguration& clientConfig,
+ const Aws::String& ec2MetadataRegion)
+ {
+ // Check if we're on mobile, CPP SDK is statically built, so we can check how we were built
+ if(isMobile())
+ {
+ return "mobile";
+ }
+ // We're not on mobile (best we can tell). See if we can determine whether we're an in-region or
+ // cross-region client.
+ Aws::String current_region;
+ Aws::String env_region = Aws::Environment::GetEnv("AWS_DEFAULT_REGION");
+ if(!Aws::Environment::GetEnv("AWS_EXECUTION_ENV").empty())
+ {
+ // We're running in an AWS service environment, so we can trust the region environment variables
+ // to be the current region, if they're set
+ current_region = Aws::Environment::GetEnv("AWS_REGION");
+ if(current_region.empty())
+ {
+ current_region = Aws::Environment::GetEnv("AWS_DEFAULT_REGION");
+ }
+ }
+ if(current_region.empty())
+ {
+ current_region = ec2MetadataRegion;
+ }
+ if(!current_region.empty() && !clientConfig.region.empty())
+ {
+ if(current_region == clientConfig.region)
+ {
+ return "in-region";
+ }
+ else
+ {
+ return "cross-region";
+ }
+ }
+ // We don't seem to be mobile, and we couldn't determine whether we're running within an AWS region.
+ // Fall back to standard.
+ return "standard";
+ }
+
+ void SetLegacyClientConfiguration(Aws::Client::ClientConfiguration& clientConfig)
+ {
+ clientConfig.retryStrategy = Aws::Client::InitRetryStrategy("default");
+ }
+
+ void SetStandardClientConfiguration(Aws::Client::ClientConfiguration& clientConfig)
+ {
+ clientConfig.connectTimeoutMs = 3100;
+ clientConfig.retryStrategy = Aws::Client::InitRetryStrategy("standard");
+ }
+
+ void SetInRegionClientConfiguration(Aws::Client::ClientConfiguration& clientConfig)
+ {
+ clientConfig.connectTimeoutMs = 1100;
+ clientConfig.retryStrategy = Aws::Client::InitRetryStrategy("standard");
+ }
+
+ void SetCrossRegionClientConfiguration(Aws::Client::ClientConfiguration& clientConfig)
+ {
+ clientConfig.connectTimeoutMs = 3100;
+ clientConfig.retryStrategy = Aws::Client::InitRetryStrategy("standard");
+ }
+
+ void SetMobileClientConfiguration(Aws::Client::ClientConfiguration& clientConfig)
+ {
+ clientConfig.connectTimeoutMs = 30000;
+ clientConfig.retryStrategy = Aws::Client::InitRetryStrategy("standard");
+ }
+
+ Aws::String ResolveDefaultModeName(const Aws::Client::ClientConfiguration& clientConfig,
+ Aws::String requestedDefaultMode,
+ const Aws::String& configFileDefaultMode,
+ bool hasEc2MetadataRegion,
+ Aws::String ec2MetadataRegion)
+ {
+ if (requestedDefaultMode.empty())
+ {
+ requestedDefaultMode = Aws::Environment::GetEnv("AWS_DEFAULTS_MODE");
+ }
+ if (requestedDefaultMode.empty())
+ {
+ requestedDefaultMode = configFileDefaultMode;
+ }
+ if (Aws::Utils::StringUtils::ToLower(requestedDefaultMode.c_str()) == "auto")
+ {
+ if (!hasEc2MetadataRegion &&
+ Aws::Utils::StringUtils::ToLower(Aws::Environment::GetEnv("AWS_EC2_METADATA_DISABLED").c_str()) != "true")
+ {
+ auto client = Aws::Internal::GetEC2MetadataClient();
+ if (client)
+ {
+ ec2MetadataRegion = client->GetCurrentRegion();
+ }
+ }
+ requestedDefaultMode = ResolveAutoClientConfiguration(clientConfig, ec2MetadataRegion);
+ return requestedDefaultMode;
+ }
+ if (requestedDefaultMode.empty())
+ {
+ requestedDefaultMode = "legacy";
+ return requestedDefaultMode;
+ }
+
+ requestedDefaultMode = Aws::Utils::StringUtils::ToLower(requestedDefaultMode.c_str());
+ if (requestedDefaultMode != "legacy" &&
+ requestedDefaultMode != "standard" &&
+ requestedDefaultMode != "in-region" &&
+ requestedDefaultMode != "cross-region" &&
+ requestedDefaultMode != "mobile")
+ {
+ AWS_LOGSTREAM_WARN(CLIENT_CONFIG_DEFAULTS_TAG, "User specified client configuration: ["
+ << requestedDefaultMode
+ << "] is not found, will use the SDK default legacy one.");
+ requestedDefaultMode = "legacy";
+ }
+ return requestedDefaultMode;
+ }
+ } //namespace Defaults
+ } //namespace Config
+} //namespace Aws