aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config
diff options
context:
space:
mode:
authorDevtools Arcadia <arcadia-devtools@yandex-team.ru>2022-02-07 18:08:42 +0300
committerDevtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net>2022-02-07 18:08:42 +0300
commit1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch)
treee26c9fed0de5d9873cce7e00bc214573dc2195b7 /contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config
downloadydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
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/AWSProfileConfigLoader.cpp540
1 files changed, 540 insertions, 0 deletions
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
new file mode 100644
index 0000000000..9ec2e54f55
--- /dev/null
+++ b/contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/AWSProfileConfigLoader.cpp
@@ -0,0 +1,540 @@
+/**
+ * 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 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 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