Skip to content

Commit 55d0993

Browse files
committed
feat(NODE-6069): OIDC k8s machine workflow
1 parent 91f3035 commit 55d0993

File tree

12 files changed

+249
-5
lines changed

12 files changed

+249
-5
lines changed

.evergreen/config.in.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,36 @@ tasks:
12441244
args:
12451245
- src/.evergreen/run-azure-kms-tests.sh
12461246

1247+
- name: "oidc-auth-test-k8s-latest"
1248+
commands:
1249+
- func: "install dependencies"
1250+
- command: subprocess.exec
1251+
type: test
1252+
params:
1253+
working_dir: src
1254+
binary: bash
1255+
env:
1256+
PROJECT_DIRECTORY: ${PROJECT_DIRECTORY}
1257+
ENVIRONMENT: k8s
1258+
K8S_VARIANT: eks
1259+
SCRIPT: run-oidc-prose-tests.sh
1260+
include_expansions_in_env: ["DRIVERS_TOOLS", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN"]
1261+
args:
1262+
- .evergreen/run-oidc-tests-k8s.sh
1263+
- command: subprocess.exec
1264+
type: test
1265+
params:
1266+
working_dir: src
1267+
binary: bash
1268+
env:
1269+
PROJECT_DIRECTORY: ${PROJECT_DIRECTORY}
1270+
ENVIRONMENT: k8s
1271+
K8S_VARIANT: gke
1272+
SCRIPT: run-oidc-prose-tests.sh
1273+
include_expansions_in_env: ["DRIVERS_TOOLS", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN"]
1274+
args:
1275+
- .evergreen/run-oidc-tests-k8s.sh
1276+
12471277
- name: "oidc-auth-test-azure-latest"
12481278
commands:
12491279
- func: "install dependencies"
@@ -1466,6 +1496,28 @@ task_groups:
14661496
tasks:
14671497
- test-azurekms-task
14681498

1499+
- name: testk8soidc_task_group
1500+
setup_group:
1501+
- func: fetch source
1502+
- command: ec2.assume_role
1503+
params:
1504+
role_arn: ${OIDC_AWS_ROLE_ARN}
1505+
- command: subprocess.exec
1506+
params:
1507+
binary: bash
1508+
args:
1509+
- ${DRIVERS_TOOLS}/.evergreen/auth_oidc/k8s/setup.sh
1510+
teardown_task:
1511+
- command: subprocess.exec
1512+
params:
1513+
binary: bash
1514+
args:
1515+
- ${DRIVERS_TOOLS}/.evergreen/auth_oidc/k8s/teardown.sh
1516+
setup_group_can_fail_task: true
1517+
setup_group_timeout_secs: 1800
1518+
tasks:
1519+
- oidc-auth-test-k8s-latest
1520+
14691521
- name: testtestoidc_task_group
14701522
setup_group:
14711523
- func: fetch source

.evergreen/config.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1194,6 +1194,43 @@ tasks:
11941194
EXPECTED_AZUREKMS_OUTCOME: failure
11951195
args:
11961196
- src/.evergreen/run-azure-kms-tests.sh
1197+
- name: oidc-auth-test-k8s-latest
1198+
commands:
1199+
- func: install dependencies
1200+
- command: subprocess.exec
1201+
type: test
1202+
params:
1203+
working_dir: src
1204+
binary: bash
1205+
env:
1206+
PROJECT_DIRECTORY: ${PROJECT_DIRECTORY}
1207+
ENVIRONMENT: k8s
1208+
K8S_VARIANT: eks
1209+
SCRIPT: run-oidc-prose-tests.sh
1210+
include_expansions_in_env:
1211+
- DRIVERS_TOOLS
1212+
- AWS_ACCESS_KEY_ID
1213+
- AWS_SECRET_ACCESS_KEY
1214+
- AWS_SESSION_TOKEN
1215+
args:
1216+
- .evergreen/run-oidc-tests-k8s.sh
1217+
- command: subprocess.exec
1218+
type: test
1219+
params:
1220+
working_dir: src
1221+
binary: bash
1222+
env:
1223+
PROJECT_DIRECTORY: ${PROJECT_DIRECTORY}
1224+
ENVIRONMENT: k8s
1225+
K8S_VARIANT: gke
1226+
SCRIPT: run-oidc-prose-tests.sh
1227+
include_expansions_in_env:
1228+
- DRIVERS_TOOLS
1229+
- AWS_ACCESS_KEY_ID
1230+
- AWS_SECRET_ACCESS_KEY
1231+
- AWS_SESSION_TOKEN
1232+
args:
1233+
- .evergreen/run-oidc-tests-k8s.sh
11971234
- name: oidc-auth-test-azure-latest
11981235
commands:
11991236
- func: install dependencies
@@ -4399,6 +4436,27 @@ task_groups:
43994436
- ${DRIVERS_TOOLS}/.evergreen/csfle/azurekms/teardown.sh
44004437
tasks:
44014438
- test-azurekms-task
4439+
- name: testk8soidc_task_group
4440+
setup_group:
4441+
- func: fetch source
4442+
- command: ec2.assume_role
4443+
params:
4444+
role_arn: ${OIDC_AWS_ROLE_ARN}
4445+
- command: subprocess.exec
4446+
params:
4447+
binary: bash
4448+
args:
4449+
- ${DRIVERS_TOOLS}/.evergreen/auth_oidc/k8s/setup.sh
4450+
teardown_task:
4451+
- command: subprocess.exec
4452+
params:
4453+
binary: bash
4454+
args:
4455+
- ${DRIVERS_TOOLS}/.evergreen/auth_oidc/k8s/teardown.sh
4456+
setup_group_can_fail_task: true
4457+
setup_group_timeout_secs: 1800
4458+
tasks:
4459+
- oidc-auth-test-k8s-latest
44024460
- name: testtestoidc_task_group
44034461
setup_group:
44044462
- func: fetch source
@@ -5091,6 +5149,7 @@ buildvariants:
50915149
- testtestoidc_task_group
50925150
- testazureoidc_task_group
50935151
- testgcpoidc_task_group
5152+
- testk8soidc_task_group
50945153
- name: rhel8-test-atlas
50955154
display_name: Atlas Cluster Tests
50965155
run_on: rhel80-large

.evergreen/generate_evergreen_tasks.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,8 @@ BUILD_VARIANTS.push({
733733
tasks: [
734734
'testtestoidc_task_group',
735735
'testazureoidc_task_group',
736-
'testgcpoidc_task_group'
736+
'testgcpoidc_task_group',
737+
'testk8soidc_task_group'
737738
]
738739
});
739740

.evergreen/run-oidc-prose-tests.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,16 @@ if [ "$ENVIRONMENT" = "azure" ]; then
1515
npm run check:oidc-azure
1616
elif [ "$ENVIRONMENT" = "gcp" ]; then
1717
npm run check:oidc-gcp
18-
else
18+
elif [ "$ENVIRONMENT" = "test" ]; then
1919
if [ -z "${OIDC_TOKEN_FILE}" ]; then
2020
echo "Must specify OIDC_TOKEN_FILE"
2121
exit 1
2222
fi
2323
npm run check:oidc-test
24+
else
25+
if [ -z "${K8S_VARIANT}" ]; then
26+
echo "Must specify K8S_VARIANT"
27+
exit 1
28+
fi
29+
npm run check:oidc-k8s
2430
fi

.evergreen/run-oidc-tests-k8s.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/bash
2+
set -o xtrace # Write all commands first to stderr
3+
set -o errexit # Exit the script with error if any of the commands fail
4+
5+
export K8S_DRIVERS_TAR_FILE=/tmp/node-mongodb-native.tgz
6+
tar czf $K8S_DRIVERS_TAR_FILE .
7+
bash $DRIVERS_TOOLS/.evergreen/auth_oidc/k8s/setup-pod.sh
8+
bash $DRIVERS_TOOLS/.evergreen/auth_oidc/k8s/run-self-test.sh
9+
export K8S_TEST_CMD="ENVIRONMENT=k8s ./.evergreen/${SCRIPT}"
10+
source $DRIVERS_TOOLS/.evergreen/auth_oidc/k8s/secrets-export.sh
11+
bash $DRIVERS_TOOLS/.evergreen/auth_oidc/k8s/run-driver-test.sh
12+
bash $DRIVERS_TOOLS/.evergreen/auth_oidc/k8s/teardown-pod.sh

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@
151151
"check:oidc-test": "mocha --config test/mocha_mongodb.json test/integration/auth/mongodb_oidc.prose.test.ts",
152152
"check:oidc-azure": "mocha --config test/mocha_mongodb.json test/integration/auth/mongodb_oidc_azure.prose.05.test.ts",
153153
"check:oidc-gcp": "mocha --config test/mocha_mongodb.json test/integration/auth/mongodb_oidc_gcp.prose.06.test.ts",
154+
"check:oidc-k8s": "mocha --config test/mocha_mongodb.json test/integration/auth/mongodb_oidc_k8s.prose.07.test.ts",
154155
"check:ocsp": "mocha --config test/manual/mocharc.json test/manual/ocsp_support.test.js",
155156
"check:kerberos": "nyc mocha --config test/manual/mocharc.json test/manual/kerberos.test.ts",
156157
"check:tls": "mocha --config test/manual/mocharc.json test/manual/tls_support.test.ts",

src/cmap/auth/mongo_credentials.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ function getDefaultAuthMechanism(hello: Document | null): AuthMechanism {
2929
const ALLOWED_ENVIRONMENT_NAMES: AuthMechanismProperties['ENVIRONMENT'][] = [
3030
'test',
3131
'azure',
32-
'gcp'
32+
'gcp',
33+
'k8s'
3334
];
3435
const ALLOWED_HOSTS_ERROR = 'Auth mechanism property ALLOWED_HOSTS must be an array of strings.';
3536

@@ -60,7 +61,7 @@ export interface AuthMechanismProperties extends Document {
6061
/** A user provided OIDC human interacted callback function. */
6162
OIDC_HUMAN_CALLBACK?: OIDCCallbackFunction;
6263
/** The OIDC environment. Note that 'test' is for internal use only. */
63-
ENVIRONMENT?: 'test' | 'azure' | 'gcp';
64+
ENVIRONMENT?: 'test' | 'azure' | 'gcp' | 'k8s';
6465
/** Allowed hosts that OIDC auth can connect to. */
6566
ALLOWED_HOSTS?: string[];
6667
/** The resource token for OIDC auth in Azure and GCP. */

src/cmap/auth/mongodb_oidc.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { type AuthContext, AuthProvider } from './auth_provider';
77
import type { MongoCredentials } from './mongo_credentials';
88
import { AzureMachineWorkflow } from './mongodb_oidc/azure_machine_workflow';
99
import { GCPMachineWorkflow } from './mongodb_oidc/gcp_machine_workflow';
10+
import { K8SMachineWorkflow } from './mongodb_oidc/k8s_machine_workflow';
1011
import { TokenCache } from './mongodb_oidc/token_cache';
1112
import { TokenMachineWorkflow } from './mongodb_oidc/token_machine_workflow';
1213

@@ -89,7 +90,7 @@ export type OIDCCallbackFunction = (params: OIDCCallbackParams) => Promise<OIDCR
8990
/** The current version of OIDC implementation. */
9091
export const OIDC_VERSION = 1;
9192

92-
type EnvironmentName = 'test' | 'azure' | 'gcp' | undefined;
93+
type EnvironmentName = 'test' | 'azure' | 'gcp' | 'k8s' | undefined;
9394

9495
/** @internal */
9596
export interface Workflow {
@@ -119,6 +120,7 @@ export const OIDC_WORKFLOWS: Map<EnvironmentName, () => Workflow> = new Map();
119120
OIDC_WORKFLOWS.set('test', () => new TokenMachineWorkflow(new TokenCache()));
120121
OIDC_WORKFLOWS.set('azure', () => new AzureMachineWorkflow(new TokenCache()));
121122
OIDC_WORKFLOWS.set('gcp', () => new GCPMachineWorkflow(new TokenCache()));
123+
OIDC_WORKFLOWS.set('k8s', () => new K8SMachineWorkflow(new TokenCache()));
122124

123125
/**
124126
* OIDC auth provider.
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { readFile } from 'fs/promises';
2+
3+
import { type AccessToken, MachineWorkflow } from './machine_workflow';
4+
import { type TokenCache } from './token_cache';
5+
6+
/** The fallback file name */
7+
const FALLBACK_FILENAME = '/var/run/secrets/kubernetes.io/serviceaccount/token';
8+
9+
/** The azure environment variable for the file name. */
10+
const AZURE_FILENAME = 'AZURE_FEDERATED_TOKEN_FILE';
11+
12+
/** The AWS environment variable for the file name. */
13+
const AWS_FILENAME = 'AWS_WEB_IDENTITY_TOKEN_FILE';
14+
15+
export class K8SMachineWorkflow extends MachineWorkflow {
16+
/**
17+
* Instantiate the machine workflow.
18+
*/
19+
constructor(cache: TokenCache) {
20+
super(cache);
21+
}
22+
23+
/**
24+
* Get the token from the environment.
25+
*/
26+
async getToken(): Promise<AccessToken> {
27+
let filename: string;
28+
if (process.env[AZURE_FILENAME]) {
29+
filename = process.env[AZURE_FILENAME];
30+
} else if (process.env[AWS_FILENAME]) {
31+
filename = process.env[AWS_FILENAME];
32+
} else {
33+
filename = FALLBACK_FILENAME;
34+
}
35+
const token = await readFile(filename, 'utf8');
36+
return { access_token: token };
37+
}
38+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { expect } from 'chai';
2+
3+
import { type Collection, MongoClient } from '../../mongodb';
4+
5+
const DEFAULT_URI = 'mongodb://127.0.0.1:27017';
6+
7+
describe('OIDC Auth Spec K8s Tests', function () {
8+
// Note there is no spec or tests for GCP yet, these are 2 scenarios based on the
9+
// drivers tools scripts available.
10+
describe('6. GCP Tests', function () {
11+
let client: MongoClient;
12+
let collection: Collection;
13+
14+
beforeEach(function () {
15+
if (!this.configuration.isOIDC(process.env.MONGODB_URI_SINGLE, 'k8s')) {
16+
this.skipReason = 'K8s OIDC prose tests require a K8s OIDC environment.';
17+
this.skip();
18+
}
19+
});
20+
21+
afterEach(async function () {
22+
await client?.close();
23+
});
24+
25+
describe('7.1 K8s With Environment Set', function () {
26+
beforeEach(function () {
27+
client = new MongoClient(process.env.MONGODB_URI_SINGLE ?? DEFAULT_URI);
28+
collection = client.db('test').collection('test');
29+
});
30+
31+
it('successfully authenticates', async function () {
32+
const result = await collection.findOne();
33+
expect(result).to.not.be.null;
34+
});
35+
});
36+
});
37+
});

test/spec/auth/legacy/connection-string.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,26 @@
626626
"uri": "mongodb://user:pass@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:gcp",
627627
"valid": false,
628628
"credential": null
629+
},
630+
{
631+
"description": "should recognise the mechanism with k8s provider (MONGODB-OIDC)",
632+
"uri": "mongodb://localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:k8s",
633+
"valid": true,
634+
"credential": {
635+
"username": null,
636+
"password": null,
637+
"source": "$external",
638+
"mechanism": "MONGODB-OIDC",
639+
"mechanism_properties": {
640+
"ENVIRONMENT": "k8s"
641+
}
642+
}
643+
},
644+
{
645+
"description": "should throw an error for a username and password with k8s provider (MONGODB-OIDC)",
646+
"uri": "mongodb://user:pass@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:k8s",
647+
"valid": false,
648+
"credential": null
629649
}
630650
]
631651
}

test/spec/auth/legacy/connection-string.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,3 +454,18 @@ tests:
454454
uri: mongodb://user:pass@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:gcp
455455
valid: false
456456
credential: null
457+
- description: should recognise the mechanism with k8s provider (MONGODB-OIDC)
458+
uri: mongodb://localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:k8s
459+
valid: true
460+
credential:
461+
username: null
462+
password: null
463+
source: $external
464+
mechanism: MONGODB-OIDC
465+
mechanism_properties:
466+
ENVIRONMENT: k8s
467+
- description: should throw an error for a username and password with k8s provider
468+
(MONGODB-OIDC)
469+
uri: mongodb://user:pass@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:k8s
470+
valid: false
471+
credential: null

0 commit comments

Comments
 (0)