Skip to content

Commit

Permalink
feat(NODE-6069): OIDC k8s machine workflow
Browse files Browse the repository at this point in the history
  • Loading branch information
durran committed Oct 24, 2024
1 parent 5c4355a commit 184e3f1
Show file tree
Hide file tree
Showing 12 changed files with 249 additions and 5 deletions.
52 changes: 52 additions & 0 deletions .evergreen/config.in.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1265,6 +1265,36 @@ tasks:
args:
- src/.evergreen/run-azure-kms-tests.sh

- name: "oidc-auth-test-k8s-latest"
commands:
- func: "install dependencies"
- command: subprocess.exec
type: test
params:
working_dir: src
binary: bash
env:
PROJECT_DIRECTORY: ${PROJECT_DIRECTORY}
ENVIRONMENT: k8s
K8S_VARIANT: eks
SCRIPT: run-oidc-prose-tests.sh
include_expansions_in_env: ["DRIVERS_TOOLS", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN"]
args:
- .evergreen/run-oidc-tests-k8s.sh
- command: subprocess.exec
type: test
params:
working_dir: src
binary: bash
env:
PROJECT_DIRECTORY: ${PROJECT_DIRECTORY}
ENVIRONMENT: k8s
K8S_VARIANT: gke
SCRIPT: run-oidc-prose-tests.sh
include_expansions_in_env: ["DRIVERS_TOOLS", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN"]
args:
- .evergreen/run-oidc-tests-k8s.sh

- name: "oidc-auth-test-azure-latest"
commands:
- func: "install dependencies"
Expand Down Expand Up @@ -1487,6 +1517,28 @@ task_groups:
tasks:
- test-azurekms-task

- name: testk8soidc_task_group
setup_group:
- func: fetch source
- command: ec2.assume_role
params:
role_arn: ${OIDC_AWS_ROLE_ARN}
- command: subprocess.exec
params:
binary: bash
args:
- ${DRIVERS_TOOLS}/.evergreen/auth_oidc/k8s/setup.sh
teardown_task:
- command: subprocess.exec
params:
binary: bash
args:
- ${DRIVERS_TOOLS}/.evergreen/auth_oidc/k8s/teardown.sh
setup_group_can_fail_task: true
setup_group_timeout_secs: 1800
tasks:
- oidc-auth-test-k8s-latest

- name: testtestoidc_task_group
setup_group:
- func: fetch source
Expand Down
59 changes: 59 additions & 0 deletions .evergreen/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1217,6 +1217,43 @@ tasks:
EXPECTED_AZUREKMS_OUTCOME: failure
args:
- src/.evergreen/run-azure-kms-tests.sh
- name: oidc-auth-test-k8s-latest
commands:
- func: install dependencies
- command: subprocess.exec
type: test
params:
working_dir: src
binary: bash
env:
PROJECT_DIRECTORY: ${PROJECT_DIRECTORY}
ENVIRONMENT: k8s
K8S_VARIANT: eks
SCRIPT: run-oidc-prose-tests.sh
include_expansions_in_env:
- DRIVERS_TOOLS
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- AWS_SESSION_TOKEN
args:
- .evergreen/run-oidc-tests-k8s.sh
- command: subprocess.exec
type: test
params:
working_dir: src
binary: bash
env:
PROJECT_DIRECTORY: ${PROJECT_DIRECTORY}
ENVIRONMENT: k8s
K8S_VARIANT: gke
SCRIPT: run-oidc-prose-tests.sh
include_expansions_in_env:
- DRIVERS_TOOLS
- AWS_ACCESS_KEY_ID
- AWS_SECRET_ACCESS_KEY
- AWS_SESSION_TOKEN
args:
- .evergreen/run-oidc-tests-k8s.sh
- name: oidc-auth-test-azure-latest
commands:
- func: install dependencies
Expand Down Expand Up @@ -4422,6 +4459,27 @@ task_groups:
- ${DRIVERS_TOOLS}/.evergreen/csfle/azurekms/teardown.sh
tasks:
- test-azurekms-task
- name: testk8soidc_task_group
setup_group:
- func: fetch source
- command: ec2.assume_role
params:
role_arn: ${OIDC_AWS_ROLE_ARN}
- command: subprocess.exec
params:
binary: bash
args:
- ${DRIVERS_TOOLS}/.evergreen/auth_oidc/k8s/setup.sh
teardown_task:
- command: subprocess.exec
params:
binary: bash
args:
- ${DRIVERS_TOOLS}/.evergreen/auth_oidc/k8s/teardown.sh
setup_group_can_fail_task: true
setup_group_timeout_secs: 1800
tasks:
- oidc-auth-test-k8s-latest
- name: testtestoidc_task_group
setup_group:
- func: fetch source
Expand Down Expand Up @@ -5114,6 +5172,7 @@ buildvariants:
- testtestoidc_task_group
- testazureoidc_task_group
- testgcpoidc_task_group
- testk8soidc_task_group
- name: rhel8-test-atlas
display_name: Atlas Cluster Tests
run_on: rhel80-large
Expand Down
3 changes: 2 additions & 1 deletion .evergreen/generate_evergreen_tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -733,7 +733,8 @@ BUILD_VARIANTS.push({
tasks: [
'testtestoidc_task_group',
'testazureoidc_task_group',
'testgcpoidc_task_group'
'testgcpoidc_task_group',
'testk8soidc_task_group'
]
});

Expand Down
8 changes: 7 additions & 1 deletion .evergreen/run-oidc-prose-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,16 @@ if [ "$ENVIRONMENT" = "azure" ]; then
npm run check:oidc-azure
elif [ "$ENVIRONMENT" = "gcp" ]; then
npm run check:oidc-gcp
else
elif [ "$ENVIRONMENT" = "test" ]; then
if [ -z "${OIDC_TOKEN_FILE}" ]; then
echo "Must specify OIDC_TOKEN_FILE"
exit 1
fi
npm run check:oidc-test
else
if [ -z "${K8S_VARIANT}" ]; then
echo "Must specify K8S_VARIANT"
exit 1
fi
npm run check:oidc-k8s
fi
12 changes: 12 additions & 0 deletions .evergreen/run-oidc-tests-k8s.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash
set -o xtrace # Write all commands first to stderr
set -o errexit # Exit the script with error if any of the commands fail

export K8S_DRIVERS_TAR_FILE=/tmp/node-mongodb-native.tgz
tar czf $K8S_DRIVERS_TAR_FILE .
bash $DRIVERS_TOOLS/.evergreen/auth_oidc/k8s/setup-pod.sh
bash $DRIVERS_TOOLS/.evergreen/auth_oidc/k8s/run-self-test.sh
export K8S_TEST_CMD="ENVIRONMENT=k8s ./.evergreen/${SCRIPT}"
source $DRIVERS_TOOLS/.evergreen/auth_oidc/k8s/secrets-export.sh
bash $DRIVERS_TOOLS/.evergreen/auth_oidc/k8s/run-driver-test.sh
bash $DRIVERS_TOOLS/.evergreen/auth_oidc/k8s/teardown-pod.sh
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@
"check:oidc-test": "mocha --config test/mocha_mongodb.json test/integration/auth/mongodb_oidc.prose.test.ts",
"check:oidc-azure": "mocha --config test/mocha_mongodb.json test/integration/auth/mongodb_oidc_azure.prose.05.test.ts",
"check:oidc-gcp": "mocha --config test/mocha_mongodb.json test/integration/auth/mongodb_oidc_gcp.prose.06.test.ts",
"check:oidc-k8s": "mocha --config test/mocha_mongodb.json test/integration/auth/mongodb_oidc_k8s.prose.07.test.ts",
"check:ocsp": "mocha --config test/manual/mocharc.json test/manual/ocsp_support.test.js",
"check:kerberos": "nyc mocha --config test/manual/mocharc.json test/manual/kerberos.test.ts",
"check:tls": "mocha --config test/manual/mocharc.json test/manual/tls_support.test.ts",
Expand Down
5 changes: 3 additions & 2 deletions src/cmap/auth/mongo_credentials.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ function getDefaultAuthMechanism(hello: Document | null): AuthMechanism {
const ALLOWED_ENVIRONMENT_NAMES: AuthMechanismProperties['ENVIRONMENT'][] = [
'test',
'azure',
'gcp'
'gcp',
'k8s'
];
const ALLOWED_HOSTS_ERROR = 'Auth mechanism property ALLOWED_HOSTS must be an array of strings.';

Expand Down Expand Up @@ -62,7 +63,7 @@ export interface AuthMechanismProperties extends Document {
/** A user provided OIDC human interacted callback function. */
OIDC_HUMAN_CALLBACK?: OIDCCallbackFunction;
/** The OIDC environment. Note that 'test' is for internal use only. */
ENVIRONMENT?: 'test' | 'azure' | 'gcp';
ENVIRONMENT?: 'test' | 'azure' | 'gcp' | 'k8s';
/** Allowed hosts that OIDC auth can connect to. */
ALLOWED_HOSTS?: string[];
/** The resource token for OIDC auth in Azure and GCP. */
Expand Down
4 changes: 3 additions & 1 deletion src/cmap/auth/mongodb_oidc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { type AuthContext, AuthProvider } from './auth_provider';
import type { MongoCredentials } from './mongo_credentials';
import { AzureMachineWorkflow } from './mongodb_oidc/azure_machine_workflow';
import { GCPMachineWorkflow } from './mongodb_oidc/gcp_machine_workflow';
import { K8SMachineWorkflow } from './mongodb_oidc/k8s_machine_workflow';
import { TokenCache } from './mongodb_oidc/token_cache';
import { TokenMachineWorkflow } from './mongodb_oidc/token_machine_workflow';

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

type EnvironmentName = 'test' | 'azure' | 'gcp' | undefined;
type EnvironmentName = 'test' | 'azure' | 'gcp' | 'k8s' | undefined;

/** @internal */
export interface Workflow {
Expand Down Expand Up @@ -118,6 +119,7 @@ export const OIDC_WORKFLOWS: Map<EnvironmentName, () => Workflow> = new Map();
OIDC_WORKFLOWS.set('test', () => new TokenMachineWorkflow(new TokenCache()));
OIDC_WORKFLOWS.set('azure', () => new AzureMachineWorkflow(new TokenCache()));
OIDC_WORKFLOWS.set('gcp', () => new GCPMachineWorkflow(new TokenCache()));
OIDC_WORKFLOWS.set('k8s', () => new K8SMachineWorkflow(new TokenCache()));

/**
* OIDC auth provider.
Expand Down
38 changes: 38 additions & 0 deletions src/cmap/auth/mongodb_oidc/k8s_machine_workflow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { readFile } from 'fs/promises';

import { type AccessToken, MachineWorkflow } from './machine_workflow';
import { type TokenCache } from './token_cache';

/** The fallback file name */
const FALLBACK_FILENAME = '/var/run/secrets/kubernetes.io/serviceaccount/token';

/** The azure environment variable for the file name. */
const AZURE_FILENAME = 'AZURE_FEDERATED_TOKEN_FILE';

/** The AWS environment variable for the file name. */
const AWS_FILENAME = 'AWS_WEB_IDENTITY_TOKEN_FILE';

export class K8SMachineWorkflow extends MachineWorkflow {
/**
* Instantiate the machine workflow.
*/
constructor(cache: TokenCache) {
super(cache);
}

/**
* Get the token from the environment.
*/
async getToken(): Promise<AccessToken> {
let filename: string;
if (process.env[AZURE_FILENAME]) {
filename = process.env[AZURE_FILENAME];
} else if (process.env[AWS_FILENAME]) {
filename = process.env[AWS_FILENAME];
} else {
filename = FALLBACK_FILENAME;
}
const token = await readFile(filename, 'utf8');
return { access_token: token };
}
}
37 changes: 37 additions & 0 deletions test/integration/auth/mongodb_oidc_k8s.prose.07.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { expect } from 'chai';

import { type Collection, MongoClient } from '../../mongodb';

const DEFAULT_URI = 'mongodb://127.0.0.1:27017';

describe('OIDC Auth Spec K8s Tests', function () {
// Note there is no spec or tests for GCP yet, these are 2 scenarios based on the
// drivers tools scripts available.
describe('6. GCP Tests', function () {
let client: MongoClient;
let collection: Collection;

beforeEach(function () {
if (!this.configuration.isOIDC(process.env.MONGODB_URI_SINGLE, 'k8s')) {
this.skipReason = 'K8s OIDC prose tests require a K8s OIDC environment.';
this.skip();
}
});

afterEach(async function () {
await client?.close();
});

describe('7.1 K8s With Environment Set', function () {
beforeEach(function () {
client = new MongoClient(process.env.MONGODB_URI_SINGLE ?? DEFAULT_URI);
collection = client.db('test').collection('test');
});

it('successfully authenticates', async function () {
const result = await collection.findOne();
expect(result).to.not.be.null;
});
});
});
});
20 changes: 20 additions & 0 deletions test/spec/auth/legacy/connection-string.json
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,26 @@
"uri": "mongodb://user:pass@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:gcp",
"valid": false,
"credential": null
},
{
"description": "should recognise the mechanism with k8s provider (MONGODB-OIDC)",
"uri": "mongodb://localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:k8s",
"valid": true,
"credential": {
"username": null,
"password": null,
"source": "$external",
"mechanism": "MONGODB-OIDC",
"mechanism_properties": {
"ENVIRONMENT": "k8s"
}
}
},
{
"description": "should throw an error for a username and password with k8s provider (MONGODB-OIDC)",
"uri": "mongodb://user:pass@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:k8s",
"valid": false,
"credential": null
}
]
}
15 changes: 15 additions & 0 deletions test/spec/auth/legacy/connection-string.yml
Original file line number Diff line number Diff line change
Expand Up @@ -454,3 +454,18 @@ tests:
uri: mongodb://user:pass@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:gcp
valid: false
credential: null
- description: should recognise the mechanism with k8s provider (MONGODB-OIDC)
uri: mongodb://localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:k8s
valid: true
credential:
username: null
password: null
source: $external
mechanism: MONGODB-OIDC
mechanism_properties:
ENVIRONMENT: k8s
- description: should throw an error for a username and password with k8s provider
(MONGODB-OIDC)
uri: mongodb://user:pass@localhost/?authMechanism=MONGODB-OIDC&authMechanismProperties=ENVIRONMENT:k8s
valid: false
credential: null

0 comments on commit 184e3f1

Please sign in to comment.