Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
7b2c30a
PYTHON-3692 Container Test failed MONGODB-AWS on MongoDB 5.0
blink1073 May 8, 2023
67609fc
remove unused file
blink1073 May 8, 2023
9aff116
try mongosh
blink1073 May 8, 2023
5515aed
add a shim
blink1073 May 8, 2023
145ff03
work on shim
blink1073 May 8, 2023
0c6314b
fix cat
blink1073 May 8, 2023
e5cd6c1
support _isWindows
blink1073 May 8, 2023
a29e342
support _isWindows
blink1073 May 8, 2023
eef5a3b
handle running a command
blink1073 May 8, 2023
76e7a0e
fix running program
blink1073 May 8, 2023
8ba538a
assert.eq
blink1073 May 8, 2023
3f204c1
syntax
blink1073 May 9, 2023
602c4cb
try again
blink1073 May 9, 2023
0104fbc
try again
blink1073 May 9, 2023
481152f
fix handling of creds
blink1073 May 9, 2023
ed901eb
try this
blink1073 May 9, 2023
10af90c
debug
blink1073 May 9, 2023
42c9f20
try this
blink1073 May 9, 2023
2f853df
fix syntax
blink1073 May 9, 2023
644b7d6
try spawn sync
blink1073 May 9, 2023
dcb4b9e
fix return
blink1073 May 9, 2023
b617144
try this
blink1073 May 9, 2023
49c6aa7
try this
blink1073 May 9, 2023
f50d1d2
add path
blink1073 May 9, 2023
479785e
try again
blink1073 May 9, 2023
bdd1748
try again
blink1073 May 9, 2023
1a80cfa
add python tester
blink1073 May 9, 2023
8edb150
add python tester
blink1073 May 9, 2023
af4ff77
update env names
blink1073 May 9, 2023
15cd1b6
add pymongo
blink1073 May 9, 2023
f4ab6bb
fix req
blink1073 May 9, 2023
c4cfdeb
add debug print
blink1073 May 9, 2023
fd043a9
actually run
blink1073 May 9, 2023
48aefff
install aws
blink1073 May 9, 2023
e8cab4b
debug
blink1073 May 9, 2023
c4f1d41
spelling
blink1073 May 9, 2023
f7dd6b1
remove print
blink1073 May 9, 2023
2b89c45
try as a string
blink1073 May 9, 2023
d291da7
fix f-string
blink1073 May 9, 2023
edf9c92
quote the token
blink1073 May 9, 2023
0eba2d5
better handle creds
blink1073 May 9, 2023
df384fe
fix creds handling
blink1073 May 9, 2023
c56e6f8
refactor
blink1073 May 9, 2023
31afe22
debug
blink1073 May 9, 2023
878fbb9
more debug
blink1073 May 9, 2023
e37f427
more debug
blink1073 May 9, 2023
121b00e
fix handling of status code
blink1073 May 9, 2023
1d12cc2
switch to mongosh
blink1073 May 9, 2023
0e87c76
fix upload
blink1073 May 9, 2023
3cb8871
clean up ecs hosted test
blink1073 May 9, 2023
88b90cc
more cleanup
blink1073 May 9, 2023
348f47e
add logpath
blink1073 May 9, 2023
fc9ff01
cleanup
blink1073 May 9, 2023
1d76175
restore mongo legacy functionality
blink1073 May 9, 2023
42abc78
cleanup
blink1073 May 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .evergreen/auth_aws/activate-authawsvenv.sh
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ activate_authawsvenv() {
local packages=(
"boto3~=1.19.0"
"pyop~=3.4.0"
"pymongo[aws]~=4.0"
)

if [[ "$OSTYPE" == cygwin && "$HOSTTYPE" == x86_64 ]]; then
Expand Down
2 changes: 1 addition & 1 deletion .evergreen/auth_aws/aws_e2e_ecs.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ load("lib/aws_e2e_lib.js");
config['iam_auth_ecs_subnet_a'] + ' --subnets ' +
config['iam_auth_ecs_subnet_b'] + ' --security_group ' +
config['iam_auth_ecs_security_group'] +
` --files ${mongo_binaries}/mongod:/root/mongod ${mongo_binaries}/mongo:/root/mongo ` +
` --files ${mongo_binaries}/mongod:/root/mongod ${mongo_binaries}/mongosh:/root/mongosh ` +
" lib/ecs_hosted_test.js:/root/ecs_hosted_test.js " +
`${project_dir}:/root` +
" --script lib/ecs_hosted_test.sh";
Expand Down
166 changes: 166 additions & 0 deletions .evergreen/auth_aws/aws_tester.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
#!/usr/bin/env python3
"""
Script for testing MONGDOB-AWS authentication.
"""
import argparse
import os
import json
import sys
import subprocess
from pymongo import MongoClient
from urllib.parse import quote_plus


HERE = os.path.abspath(os.path.dirname(__file__))

ASSUMED_ROLE = "arn:aws:sts::557821124784:assumed-role/authtest_user_assume_role/*";
ASSUMED_WEB_ROLE = "arn:aws:sts::857654397073:assumed-role/webIdentityTestRole/*"

# This varies based on hosting EC2 as the account id and role name can vary
AWS_ACCOUNT_ARN = "arn:aws:sts::557821124784:assumed-role/evergreen_task_hosts_instance_role_production/*"


with open(os.path.join(HERE, 'aws_e2e_setup.json')) as fid:
CONFIG = json.load(fid)


def run(args, env):
"""Run a python command in a subprocess."""
return subprocess.run([sys.executable] + args, env=env).returncode


def create_user(user, kwargs):
"""Create a user and verify access."""
print('Creating user', user)
client = MongoClient(username="bob", password="pwd123")
db = client['$external']
db.command(dict(createUser=user, roles=[{"role": "read", "db": "aws"}]))
client.close()

# Verify access.
client = MongoClient(authMechanism='MONGODB-AWS', **kwargs)
client.aws.command('count', 'test')
client.close()


def handle_creds(args, env):
"""Call a python process to handle credentials."""
creds = subprocess.check_output([sys.executable] + args, env=env)
creds = json.loads(creds.decode('utf8'))
with open('creds.json', 'w') as fid:
json.dump(creds, fid)
return creds


def setup_assume_role():
# Assume the role to get temp creds.
env = dict(
AWS_ACCESS_KEY_ID=CONFIG["iam_auth_assume_aws_account"],
AWS_SECRET_ACCESS_KEY=CONFIG["iam_auth_assume_aws_secret_access_key"],
)

role_name = CONFIG["iam_auth_assume_role_name"]
creds = handle_creds(["lib/aws_assume_role.py", f"--role_name={role_name}"], env)

# Create the user.
token = quote_plus(creds['SessionToken'])
kwargs = dict(username=creds["AccessKeyId"], password=creds["SecretAccessKey"], authmechanismproperties=f"AWS_SESSION_TOKEN:{token}")
create_user(ASSUMED_ROLE, kwargs)


def setup_ec2():
# Create the user.
create_user(AWS_ACCOUNT_ARN, dict())


def setup_ecs():
# Set up commands.
mongo_binaries = os.environ['MONGODB_BINARIES']
project_dir = os.environ['PROJECT_DIRECTORY']
base_command = f"{sys.executable} -u lib/container_tester.py"
run_prune_command = f"{base_command} -v remote_gc_services --cluster {CONFIG['iam_auth_ecs_cluster']}"
run_test_command = f"{base_command} -d -v run_e2e_test --cluster {CONFIG['iam_auth_ecs_cluster']} --task_definition {CONFIG['iam_auth_ecs_task_definition']} --subnets {CONFIG['iam_auth_ecs_subnet_a']} --subnets {CONFIG['iam_auth_ecs_subnet_b']} --security_group {CONFIG['iam_auth_ecs_security_group']} --files {mongo_binaries}/mongod:/root/mongod {mongo_binaries}/mongosh:/root/mongosh lib/ecs_hosted_test.js:/root/ecs_hosted_test.js {project_dir}:/root --script lib/ecs_hosted_test.sh"

# Pass in the AWS credentials as environment variables
# AWS_SHARED_CREDENTIALS_FILE does not work in evergreen for an unknown
# reason
env = dict(AWS_ACCESS_KEY_ID=CONFIG['iam_auth_ecs_account'],
AWS_SECRET_ACCESS_KEY=CONFIG['iam_auth_ecs_secret_access_key'])

# Prune other containers
subprocess.check_call(['/bin/sh', '-c', run_prune_command], env=env)

# Run the test in a container
subprocess.check_call(['/bin/sh', '-c', run_test_command], env=env)

def setup_regular():
# Create the user.
kwargs = dict(
username=CONFIG["iam_auth_ecs_account"],
password=CONFIG["iam_auth_ecs_secret_access_key"]
)
create_user(CONFIG["iam_auth_ecs_account_arn"], kwargs)


def setup_web_identity():
# Unassign the instance profile.
env = dict(AWS_ACCESS_KEY_ID=CONFIG["iam_auth_ec2_instance_account"],
AWS_SECRET_ACCESS_KEY=CONFIG["iam_auth_ec2_instance_secret_access_key"])
ret = run(['lib/aws_unassign_instance_profile.py'], env)
if ret == 2:
raise RuntimeError("Request limit exceeded for AWS API");

if ret != 0:
print('ret was', ret)
raise RuntimeError("Failed to unassign an instance profile from the current machine")

# Handle the OIDC credentials.
env = dict(
IDP_ISSUER=CONFIG["iam_web_identity_issuer"],
IDP_JWKS_URI=CONFIG["iam_web_identity_jwks_uri"],
IDP_RSA_KEY=CONFIG["iam_web_identity_rsa_key"],
AWS_WEB_IDENTITY_TOKEN_FILE=CONFIG['iam_web_identity_token_file']
)

ret = run(['lib/aws_handle_oidc_creds.py', 'token'], env)
if ret != 0:
raise RuntimeWarning("Failed to write the web token")

# Assume the web role to get temp credentials.
env = dict(
AWS_WEB_IDENTITY_TOKEN_FILE=CONFIG['iam_web_identity_token_file'],
AWS_ROLE_ARN=CONFIG["iam_auth_assume_web_role_name"]
)
creds = handle_creds(['lib/aws_assume_web_role.py'], env)

# Create the user.
token = quote_plus(creds['SessionToken'])
kwargs = dict(username=creds["AccessKeyId"], password=creds["SecretAccessKey"], authmechanismproperties=f"AWS_SESSION_TOKEN:{token}")
create_user(ASSUMED_WEB_ROLE, kwargs)


def main():
parser = argparse.ArgumentParser(description='MONGODB-AWS tester.')
sub = parser.add_subparsers(title="Tester subcommands", help="sub-command help")

run_assume_role_cmd = sub.add_parser('assume-role', help='Assume role test')
run_assume_role_cmd.set_defaults(func=setup_assume_role)

run_ec2_cmd = sub.add_parser('ec2', help='EC2 test')
run_ec2_cmd.set_defaults(func=setup_ec2)

run_ecs_cmd = sub.add_parser('ecs', help='ECS test')
run_ecs_cmd.set_defaults(func=setup_ecs)

run_regular_cmd = sub.add_parser('regular', help='Regular credentials test')
run_regular_cmd.set_defaults(func=setup_regular)

run_web_identity_cmd = sub.add_parser('web-identity', help='Web identity test')
run_web_identity_cmd.set_defaults(func=setup_web_identity)

args = parser.parse_args()
args.func()


if __name__ == '__main__':
main()
28 changes: 6 additions & 22 deletions .evergreen/auth_aws/lib/ecs_hosted_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,16 @@
// This varies based on hosting ECS task as the account id and role name can vary
const AWS_ACCOUNT_ARN = "arn:aws:sts::557821124784:assumed-role/ecsTaskExecutionRole/*";

const conn = MongoRunner.runMongod({
setParameter: {
"authenticationMechanisms": "MONGODB-AWS,SCRAM-SHA-256",
},
auth: "",
});
const external = Mongo().getDB("$external");
const admin = Mongo().getDB("admin");

const external = conn.getDB("$external");
const admin = conn.getDB("admin");
admin.runCommand({createUser: "admin", pwd: "pwd", roles: ['root']});
admin.auth("admin", "pwd");

assert.commandWorked(admin.runCommand({createUser: "admin", pwd: "pwd", roles: ['root']}));
assert(admin.auth("admin", "pwd"));

assert.commandWorked(external.runCommand({createUser: AWS_ACCOUNT_ARN, roles:[{role: 'read', db: "aws"}]}));

const uri = "mongodb://127.0.0.1:20000/aws?authMechanism=MONGODB-AWS";
const program = "/root/src/.evergreen/run-mongodb-aws-ecs-test.sh";

// Try the command line
const smoke = runProgram(program, uri);
assert.eq(smoke, 0, "Driver .evergreen/run-mongodb-aws-ecs-test.sh script failed");
external.runCommand({createUser: AWS_ACCOUNT_ARN, roles:[{role: 'read', db: "aws"}]});

// Try the auth function
const testConn = new Mongo(conn.host);
const testConn = new Mongo();
const testExternal = testConn.getDB('$external');
assert(testExternal.auth({mechanism: 'MONGODB-AWS'}));

MongoRunner.stopMongod(conn);
}());
10 changes: 5 additions & 5 deletions .evergreen/auth_aws/lib/ecs_hosted_test.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#!/bin/bash
# A shell script to run in an ECS hosted task
set -ex

# The environment variable is always set during interactive logins
# But for non-interactive logs, ~/.bashrc does not appear to be read on Ubuntu but it works on Fedora
Expand All @@ -9,8 +10,7 @@ env

mkdir -p /data/db || true

/root/mongo --verbose --nodb ecs_hosted_test.js

RET_CODE=$?
echo RETURN CODE: $RET_CODE
exit $RET_CODE
/root/mongod --fork --logpath server.log --setParameter authenticationMechanisms="MONGODB-AWS,SCRAM-SHA-256"
sleep 1
/root/mongosh --verbose ecs_hosted_test.js
bash /root/src/.evergreen/run-mongodb-aws-ecs-test.sh "mongodb://localhost/aws?authMechanism=MONGODB-AWS"