diff options
author | dakovalkov <dakovalkov@yandex-team.com> | 2023-12-03 13:33:55 +0300 |
---|---|---|
committer | dakovalkov <dakovalkov@yandex-team.com> | 2023-12-03 14:04:39 +0300 |
commit | 2a718325637e5302334b6d0a6430f63168f8dbb3 (patch) | |
tree | 64be81080b7df9ec1d86d053a0c394ae53fcf1fe /contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/EC2InstanceProfileConfigLoader.cpp | |
parent | e0d94a470142d95c3007e9c5d80380994940664a (diff) | |
download | ydb-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/EC2InstanceProfileConfigLoader.cpp')
-rw-r--r-- | contrib/libs/aws-sdk-cpp/aws-cpp-sdk-core/source/config/EC2InstanceProfileConfigLoader.cpp | 112 |
1 files changed, 112 insertions, 0 deletions
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 |