0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

SERVER-44266 Add IAM client code to shell and clients with mock ECS endpoint

This commit is contained in:
Mark Benvenuto 2019-12-26 20:03:14 +00:00 committed by evergreen
parent 8f3a768c61
commit 62f35e9e7b
5 changed files with 56 additions and 8 deletions

View File

@ -47,10 +47,14 @@ namespace iam {
SASLIamClientGlobalParams saslIamClientGlobalParams;
} // namespace iam
std::string getDefaultHost() {
std::string getDefaultEC2Host() {
return iam::saslIamClientGlobalParams.awsEC2InstanceMetadataUrl;
}
std::string getDefaultECSHost() {
return iam::saslIamClientGlobalParams.awsECSInstanceMetadataUrl;
}
SaslIAMClientConversation::SaslIAMClientConversation(SaslClientSession* saslClientSession)
: SaslClientConversation(saslClientSession) {}
@ -79,7 +83,11 @@ iam::AWSCredentials SaslIAMClientConversation::_getUserCredentials() const {
}
iam::AWSCredentials SaslIAMClientConversation::_getLocalAWSCredentials() const {
// T O D O - branch on the environment variable that ECS tasks set
StringData ecsMetadata = getenv("AWS_CONTAINER_CREDENTIALS_RELATIVE_URI");
if (!ecsMetadata.empty()) {
return _getEcsCredentials(ecsMetadata);
}
return _getEc2Credentials();
}
@ -93,7 +101,7 @@ iam::AWSCredentials SaslIAMClientConversation::_getEc2Credentials() const {
// Retrieve the role attached to the EC2 instance
DataBuilder getRoleResult =
httpClient->get(getDefaultHost() + "/latest/meta-data/iam/security-credentials/");
httpClient->get(getDefaultEC2Host() + "/latest/meta-data/iam/security-credentials/");
ConstDataRange cdrRole = getRoleResult.getCursor();
StringData getRoleOutput;
@ -103,7 +111,7 @@ iam::AWSCredentials SaslIAMClientConversation::_getEc2Credentials() const {
// Retrieve the temporary credentials of the EC2 instance
DataBuilder getRoleCredentialsResult = httpClient->get(
str::stream() << getDefaultHost() + "/latest/meta-data/iam/security-credentials/"
str::stream() << getDefaultEC2Host() + "/latest/meta-data/iam/security-credentials/"
<< role);
ConstDataRange cdrCredentials = getRoleCredentialsResult.getCursor();
@ -113,10 +121,33 @@ iam::AWSCredentials SaslIAMClientConversation::_getEc2Credentials() const {
return iam::parseCredentialsFromEC2IamSecurityCredentials(getRoleCredentialsOutput);
} catch (const DBException& e) {
// Wrap exceptions from HTTP to make them clearer
uassertStatusOK(Status(e.code(),
str::stream()
<< "Failed to retrieve EC2 Instance Metadata Credentials:"
<< e.reason()));
uassertStatusOKWithContext(e.toStatus(),
"Failed to retrieve EC2 Instance Metadata Credentials");
}
MONGO_UNREACHABLE;
}
iam::AWSCredentials SaslIAMClientConversation::_getEcsCredentials(StringData relativeUri) const {
try {
std::unique_ptr<HttpClient> httpClient = HttpClient::create();
// The local web server is just a normal HTTP server
httpClient->allowInsecureHTTP(true);
// Retrieve the security token attached to the ECS task
DataBuilder getRoleResult = httpClient->get(getDefaultECSHost() + relativeUri);
ConstDataRange cdrRole = getRoleResult.getCursor();
StringData getRoleOutput;
cdrRole.readInto<StringData>(&getRoleOutput);
return iam::parseCredentialsFromECSTaskIamCredentials(getRoleOutput);
} catch (const DBException& e) {
// Wrap exceptions from HTTP to make them clearer
uassertStatusOKWithContext(e.toStatus(),
"Failed to retrieve ECS Instance Metadata Credentials");
}
MONGO_UNREACHABLE;

View File

@ -74,6 +74,11 @@ private:
*/
iam::AWSCredentials _getEc2Credentials() const;
/**
* Get AWS credentials from ECS Instance metadata HTTP server.
*/
iam::AWSCredentials _getEcsCredentials(StringData relativeUri) const;
StatusWith<bool> _firstStep(std::string* outputData);
StatusWith<bool> _secondStep(StringData inputData, std::string* outputData);

View File

@ -42,6 +42,11 @@ struct SASLIamClientGlobalParams {
*/
std::string awsEC2InstanceMetadataUrl;
/**
* ECS Instance metadata endpoint.
*/
std::string awsECSInstanceMetadataUrl;
/**
* AWS Session Token.
*/

View File

@ -20,3 +20,9 @@ server_parameters:
set_at: startup
cpp_varname: saslIamClientGlobalParams.awsEC2InstanceMetadataUrl
default: "http://169.254.169.254"
awsECSInstanceMetadataUrl:
description: "Test parameter to override the URL for AWS ECS Instance Metadata"
set_at: startup
cpp_varname: saslIamClientGlobalParams.awsECSInstanceMetadataUrl
default: "http://169.254.170.2"

View File

@ -63,6 +63,7 @@ using std::vector;
// SERVER-36807: Limit --setShellParameter to SetParameters we know we want to expose.
const std::set<std::string> kSetShellParameterWhitelist = {
"awsEC2InstanceMetadataUrl",
"awsECSInstanceMetadataUrl",
"disabledSecureAllocatorDomains",
"newLineAfterPasswordPromptForTest",
"skipShellCursorFinalize",