-
Notifications
You must be signed in to change notification settings - Fork 9
feat(mongodb-runner): usability improvements for drivers DRIVERS-3335 #603
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 5 commits
fc61f7a
3a6eadf
a3904c6
f52db8f
4d776e0
892a8ba
56a3abd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,6 +20,7 @@ import { | |
| debugVerbose, | ||
| jsonClone, | ||
| makeConnectionString, | ||
| sleep, | ||
| } from './util'; | ||
|
|
||
| /** | ||
|
|
@@ -286,9 +287,11 @@ export class MongoServer extends EventEmitter<MongoServerEvents> { | |
| logEntryStream.resume(); | ||
|
|
||
| srv.port = port; | ||
| const buildInfoError = await srv._populateBuildInfo('insert-new'); | ||
| if (buildInfoError) { | ||
| debug('failed to get buildInfo', buildInfoError); | ||
| if (!options.args?.includes('--keyFile')) { | ||
| const buildInfoError = await srv._populateBuildInfo('insert-new'); | ||
| if (buildInfoError) { | ||
| debug('failed to get buildInfo', buildInfoError); | ||
| } | ||
| } | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If a keyfile is being used, wouldn't we want to use it for authentication?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, when a keyFile is present you can't do anything on the server until a user has been added to the primary. |
||
| } catch (err) { | ||
| await srv.close(); | ||
|
|
@@ -301,24 +304,77 @@ export class MongoServer extends EventEmitter<MongoServerEvents> { | |
| async updateDefaultConnectionOptions( | ||
| options: Partial<MongoClientOptions>, | ||
| ): Promise<void> { | ||
| // Assume we need these new options to connect. | ||
| this.defaultConnectionOptions = { | ||
| ...this.defaultConnectionOptions, | ||
| ...options, | ||
| }; | ||
|
|
||
| // If there is no auth in the connection options, do an immediate metadata refresh and return. | ||
| let buildInfoError: Error | null = null; | ||
| if (!options.auth) { | ||
| buildInfoError = await this._populateBuildInfo('restore-check'); | ||
| if (buildInfoError) { | ||
| debug( | ||
| 'failed to refresh buildInfo when updating connection options', | ||
| buildInfoError, | ||
| options, | ||
| ); | ||
| throw buildInfoError; | ||
| } | ||
| return; | ||
| } | ||
|
|
||
| debug('Waiting for authorization on', this.port); | ||
|
|
||
| // Wait until we can get connectionStatus. | ||
| let supportsAuth = false; | ||
| let error: unknown = null; | ||
| for (let attempts = 0; attempts < 10; attempts++) { | ||
| buildInfoError = await this._populateBuildInfo('restore-check', { | ||
| ...options, | ||
| }); | ||
| if (!buildInfoError) break; | ||
| error = null; | ||
| try { | ||
| supportsAuth = await this.withClient(async (client) => { | ||
| const status = await client | ||
| .db('admin') | ||
| .command({ connectionStatus: 1 }); | ||
| if (status.authInfo.authenticatedUsers.length > 0) { | ||
| return true; | ||
| } | ||
| // If the server does not support auth, just get the build info without | ||
| // setting the metadata. | ||
|
||
| debug('Server does not support authorization', this.port); | ||
| this.buildInfo = await client.db('admin').command({ buildInfo: 1 }); | ||
| return false; | ||
| }); | ||
| } catch (e) { | ||
| error = e; | ||
| await sleep(2 ** attempts * 10); | ||
| } | ||
| if (error === null) { | ||
| break; | ||
| } | ||
| } | ||
|
|
||
| if (error !== null) { | ||
| throw error; | ||
| } | ||
|
|
||
| if (!supportsAuth) { | ||
| return; | ||
| } | ||
|
|
||
| const mode = this.hasInsertedMetadataCollEntry | ||
| ? 'restore-check' | ||
| : 'insert-new'; | ||
| buildInfoError = await this._populateBuildInfo(mode); | ||
| if (buildInfoError) { | ||
| debug( | ||
| 'failed to get buildInfo when setting new options', | ||
| 'failed to refresh buildInfo when updating connection options', | ||
| buildInfoError, | ||
| options, | ||
| this.connectionString, | ||
| ); | ||
| throw buildInfoError; | ||
| } | ||
| if (buildInfoError) throw buildInfoError; | ||
| this.defaultConnectionOptions = { | ||
| ...this.defaultConnectionOptions, | ||
| ...options, | ||
| }; | ||
| } | ||
|
|
||
| async close(): Promise<void> { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd suggest putting this in a separate method, like we did for
addAuthIfNeeded()