1212#include " util/string_util.h"
1313
1414#ifdef USE_AWS
15-
1615#include < aws/core/utils/threading/Executor.h>
16+ #endif
1717
1818#include " cloud/aws/aws_file.h"
1919#include " cloud/aws/aws_kafka.h"
@@ -26,6 +26,149 @@ namespace rocksdb {
2626#pragma GCC diagnostic push
2727#pragma GCC diagnostic ignored "-Wunused-parameter"
2828
29+ static const std::unordered_map<std::string, AwsAccessType> AwsAccessTypeMap = {
30+ {" undefined" , AwsAccessType::kUndefined },
31+ {" simple" , AwsAccessType::kSimple },
32+ {" instance" , AwsAccessType::kInstance },
33+ {" EC2" , AwsAccessType::kInstance },
34+ {" environment" , AwsAccessType::kEnvironment },
35+ {" config" , AwsAccessType::kConfig },
36+ {" anonymous" , AwsAccessType::kAnonymous },
37+ };
38+
39+ template <typename T>
40+ bool ParseEnum (const std::unordered_map<std::string, T>& type_map,
41+ const std::string& type, T* value) {
42+ auto iter = type_map.find (type);
43+ if (iter != type_map.end ()) {
44+ *value = iter->second ;
45+ return true ;
46+ }
47+ return false ;
48+ }
49+
50+ AwsCloudAccessCredentials::AwsCloudAccessCredentials () {
51+ #ifdef USE_AWS
52+ type = AwsAccessType::kUndefined ;
53+ #else
54+ type = AwsAccessType::kSimple ;
55+ #endif
56+ }
57+
58+ AwsAccessType AwsCloudAccessCredentials::GetAccessType () const {
59+ if (type != AwsAccessType::kUndefined ) {
60+ return type;
61+ } else if (!config_file.empty ()) {
62+ return AwsAccessType::kConfig ;
63+ } else if (!access_key_id.empty () || !secret_key.empty ()) {
64+ return AwsAccessType::kSimple ;
65+ }
66+ if (getenv (" AWS_ACCESS_KEY_ID" ) || getenv (" AWS_SECRET_ACCESS_KEY" ) ||
67+ getenv (" AWS_SESSION_TOKEN" ) || getenv (" AWS_DEFAULT_PROFILE" ) ||
68+ getenv (" AWS_SHARED_CREDENTIALS_FILE" ) || getenv (" AWS_CONFIG_FILE" )) {
69+ return AwsAccessType::kEnvironment ;
70+ }
71+
72+ return AwsAccessType::kUndefined ;
73+ }
74+
75+ Status AwsCloudAccessCredentials::TEST_Initialize () {
76+ std::string type_str;
77+ if (CloudEnvOptions::GetNameFromEnvironment (
78+ " ROCKSDB_AWS_ACCESS_TYPE" , " rocksdb_aws_access_type" , &type_str)) {
79+ ParseEnum<AwsAccessType>(AwsAccessTypeMap, type_str, &type);
80+ }
81+ return HasValid ();
82+ }
83+
84+ Status AwsCloudAccessCredentials::CheckCredentials (
85+ const AwsAccessType& aws_type) const {
86+ #ifndef USE_AWS
87+ return Status::NotSupported (" AWS not supported" );
88+ #else
89+ if (aws_type == AwsAccessType::kSimple ) {
90+ if ((access_key_id.empty () && getenv (" AWS_ACCESS_KEY_ID" ) == nullptr ) ||
91+ (secret_key.empty () && getenv (" AWS_SECRET_ACCESS_KEY" ) == nullptr )) {
92+ return Status::InvalidArgument (
93+ " AWS Credentials require both access ID and secret keys" );
94+ }
95+ } else if (aws_type == AwsAccessType::kTaskRole ) {
96+ return Status::InvalidArgument (
97+ " AWS access type: Task Role access is not supported." );
98+ } else if (aws_type == AwsAccessType::kUndefined ) {
99+ return Status::InvalidArgument (" Invalid AWS Credentials configuration" );
100+ }
101+ return Status::OK ();
102+ #endif
103+ }
104+
105+ void AwsCloudAccessCredentials::InitializeSimple (
106+ const std::string& aws_access_key_id, const std::string& aws_secret_key) {
107+ type = AwsAccessType::kSimple ;
108+ access_key_id = aws_access_key_id;
109+ secret_key = aws_secret_key;
110+ }
111+
112+ void AwsCloudAccessCredentials::InitializeConfig (
113+ const std::string& aws_config_file) {
114+ type = AwsAccessType::kConfig ;
115+ config_file = aws_config_file;
116+ }
117+
118+ Status AwsCloudAccessCredentials::HasValid () const {
119+ AwsAccessType aws_type = GetAccessType ();
120+ Status status = CheckCredentials (aws_type);
121+ return status;
122+ }
123+
124+ Status AwsCloudAccessCredentials::GetCredentialsProvider (
125+ std::shared_ptr<Aws::Auth::AWSCredentialsProvider>* result) const {
126+ result->reset ();
127+
128+ AwsAccessType aws_type = GetAccessType ();
129+ Status status = CheckCredentials (aws_type);
130+ if (status.ok ()) {
131+ switch (aws_type) {
132+ #ifdef USE_AWS
133+ case AwsAccessType::kSimple : {
134+ const char * access_key =
135+ (access_key_id.empty () ? getenv (" AWS_ACCESS_KEY_ID" )
136+ : access_key_id.c_str ());
137+ const char * secret =
138+ (secret_key.empty () ? getenv (" AWS_SECRET_ACCESS_KEY" )
139+ : secret_key.c_str ());
140+ result->reset (
141+ new Aws::Auth::SimpleAWSCredentialsProvider (access_key, secret));
142+ break ;
143+ }
144+ case AwsAccessType::kConfig :
145+ if (!config_file.empty ()) {
146+ result->reset (new Aws::Auth::ProfileConfigFileAWSCredentialsProvider (
147+ config_file.c_str ()));
148+ } else {
149+ result->reset (
150+ new Aws::Auth::ProfileConfigFileAWSCredentialsProvider ());
151+ }
152+ break ;
153+ case AwsAccessType::kInstance :
154+ result->reset (new Aws::Auth::InstanceProfileCredentialsProvider ());
155+ break ;
156+ case AwsAccessType::kAnonymous :
157+ result->reset (new Aws::Auth::AnonymousAWSCredentialsProvider ());
158+ break ;
159+ case AwsAccessType::kEnvironment :
160+ result->reset (new Aws::Auth::EnvironmentAWSCredentialsProvider ());
161+ break ;
162+ #endif
163+ default :
164+ status = Status::NotSupported (" AWS credentials type not supported" );
165+ break ; // not supported
166+ }
167+ }
168+ return status;
169+ }
170+
171+ #ifdef USE_AWS
29172namespace detail {
30173
31174using ScheduledJob =
@@ -202,7 +345,7 @@ Aws::S3::Model::CreateBucketOutcome AwsS3ClientWrapper::CreateBucket(
202345Aws::S3::Model::HeadBucketOutcome AwsS3ClientWrapper::HeadBucket (
203346 const Aws::S3::Model::HeadBucketRequest& request) {
204347 CloudRequestCallbackGuard t (cloud_request_callback_.get (),
205- CloudRequestOpType::kInfoOp );
348+ CloudRequestOpType::kInfoOp );
206349 return client_->HeadBucket (request);
207350}
208351
@@ -278,12 +421,12 @@ AwsEnv::AwsEnv(Env* underlying_env, const CloudEnvOptions& _cloud_env_options,
278421 }
279422 }
280423
281- unique_ptr <Aws::Auth::AWSCredentials > creds;
282- if (!cloud_env_options. credentials . access_key_id . empty () &&
283- ! cloud_env_options.credentials .secret_key . empty ()) {
284- creds. reset ( new Aws::Auth::AWSCredentials (
285- ToAwsString (cloud_env_options. credentials . access_key_id ) ,
286- ToAwsString (cloud_env_options. credentials . secret_key )) );
424+ shared_ptr <Aws::Auth::AWSCredentialsProvider > creds;
425+ create_bucket_status_ =
426+ cloud_env_options.credentials .GetCredentialsProvider (&creds);
427+ if (!create_bucket_status_. ok ()) {
428+ Log (InfoLogLevel::INFO_LEVEL, info_log ,
429+ " [aws] NewAwsEnv - Bad AWS credentials" );
287430 }
288431
289432 Header (info_log_, " AwsEnv.src_bucket_name: %s" ,
@@ -324,8 +467,8 @@ AwsEnv::AwsEnv(Env* underlying_env, const CloudEnvOptions& _cloud_env_options,
324467 Log (InfoLogLevel::ERROR_LEVEL, info_log,
325468 " [aws] NewAwsEnv Buckets %s, %s in two different regions %s, %s "
326469 " is not supported" ,
327- cloud_env_options.src_bucket .GetBucketName ().c_str (),
328- cloud_env_options.dest_bucket .GetBucketName ().c_str (),
470+ cloud_env_options.src_bucket .GetBucketName ().c_str (),
471+ cloud_env_options.dest_bucket .GetBucketName ().c_str (),
329472 cloud_env_options.src_bucket .GetRegion ().c_str (),
330473 cloud_env_options.dest_bucket .GetRegion ().c_str ());
331474 return ;
@@ -340,10 +483,10 @@ AwsEnv::AwsEnv(Env* underlying_env, const CloudEnvOptions& _cloud_env_options,
340483 GetBucketLocationConstraintForName (config.region );
341484
342485 {
343- auto s3client = creds ? std::make_shared<Aws::S3::S3Client>(* creds, config)
486+ auto s3client = creds ? std::make_shared<Aws::S3::S3Client>(creds, config)
344487 : std::make_shared<Aws::S3::S3Client>(config);
345488
346- s3client_ = std::make_shared<AwsS3ClientWrapper>(
489+ s3client_ = std::make_shared<AwsS3ClientWrapper>(
347490 std::move (s3client), cloud_env_options.cloud_request_callback );
348491 }
349492
@@ -390,7 +533,7 @@ AwsEnv::AwsEnv(Env* underlying_env, const CloudEnvOptions& _cloud_env_options,
390533 if (cloud_env_options.log_type == kLogKinesis ) {
391534 std::unique_ptr<Aws::Kinesis::KinesisClient> kinesis_client;
392535 kinesis_client.reset (creds
393- ? new Aws::Kinesis::KinesisClient (* creds, config)
536+ ? new Aws::Kinesis::KinesisClient (creds, config)
394537 : new Aws::Kinesis::KinesisClient (config));
395538
396539 if (!kinesis_client) {
@@ -1895,47 +2038,6 @@ Status AwsEnv::NewAwsEnv(Env* base_env,
18952038 return status;
18962039}
18972040
1898- //
1899- // Retrieves the AWS credentials from two environment variables
1900- // called "aws_access_key_id" and "aws_secret_access_key".
1901- //
1902- Status AwsEnv::GetTestCredentials (std::string* aws_access_key_id,
1903- std::string* aws_secret_access_key,
1904- std::string* region) {
1905- Status st;
1906- char * id = getenv (" AWS_ACCESS_KEY_ID" );
1907- if (id == nullptr ) {
1908- id = getenv (" aws_access_key_id" );
1909- }
1910- char * secret = getenv (" AWS_SECRET_ACCESS_KEY" );
1911- if (secret == nullptr ) {
1912- secret = getenv (" aws_secret_access_key" );
1913- }
1914-
1915- if (id == nullptr || secret == nullptr ) {
1916- std::string msg =
1917- " Skipping AWS tests. "
1918- " AWS credentials should be set "
1919- " using environment varaibles AWS_ACCESS_KEY_ID and "
1920- " AWS_SECRET_ACCESS_KEY" ;
1921- return Status::IOError (msg);
1922- }
1923- aws_access_key_id->assign (id);
1924- aws_secret_access_key->assign (secret);
1925-
1926- char * reg = getenv (" AWS_DEFAULT_REGION" );
1927- if (reg == nullptr ) {
1928- reg = getenv (" aws_default_region" );
1929- }
1930-
1931- if (reg != nullptr ) {
1932- region->assign (reg);
1933- } else {
1934- region->assign (" us-west-2" );
1935- }
1936- return st;
1937- }
1938-
19392041std::string AwsEnv::GetWALCacheDir () {
19402042 return cloud_log_controller_->GetCacheDir ();
19412043}
@@ -1967,6 +2069,6 @@ Status CloudLogController::Retry(Env* env, RetryType func) {
19672069}
19682070
19692071#pragma GCC diagnostic pop
2072+ #endif // USE_AWS
19702073} // namespace rocksdb
19712074
1972- #endif
0 commit comments