Skip to content

Commit 9205f20

Browse files
authored
feat(service-provider-core): allow replset spec in --host MONGOSH-512 (#823)
1 parent 3e2fbc1 commit 9205f20

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

packages/cli-repl/test/e2e-direct.spec.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,34 @@ describe('e2e direct connection', () => {
150150
shell.assertContainsOutput(`me: '${await rs0.hostport()}'`);
151151
shell.assertContainsOutput(`setName: '${replSetId}'`);
152152
});
153+
it('when specifying multiple seeds through --host', async() => {
154+
const hostlist = replSetId + '/' + await rs2.hostport() + ',' + await rs1.hostport() + ',' + await rs0.hostport();
155+
const shell = TestShell.start({ args: ['--host', hostlist] });
156+
await shell.waitForPrompt();
157+
await shell.executeLine('db.isMaster()');
158+
await shell.executeLine('({ dbname: db.getName() })');
159+
shell.assertContainsOutput('ismaster: true');
160+
shell.assertContainsOutput(`me: '${await rs0.hostport()}'`);
161+
shell.assertContainsOutput(`setName: '${replSetId}'`);
162+
shell.assertContainsOutput("dbname: 'test'");
163+
});
164+
it('when specifying multiple seeds through --host with a db name', async() => {
165+
const hostlist = replSetId + '/' + await rs2.hostport() + ',' + await rs1.hostport() + ',' + await rs0.hostport();
166+
const shell = TestShell.start({ args: ['--host', hostlist, 'admin'] });
167+
await shell.waitForPrompt();
168+
await shell.executeLine('db.isMaster()');
169+
await shell.executeLine('({ dbname: db.getName() })');
170+
shell.assertContainsOutput('ismaster: true');
171+
shell.assertContainsOutput(`me: '${await rs0.hostport()}'`);
172+
shell.assertContainsOutput(`setName: '${replSetId}'`);
173+
shell.assertContainsOutput("dbname: 'admin'");
174+
});
175+
it('when specifying multiple seeds through --host with a wrong replsetid', async() => {
176+
const hostlist = 'wrongreplset/' + await rs2.hostport() + ',' + await rs1.hostport() + ',' + await rs0.hostport();
177+
const shell = TestShell.start({ args: ['--host', hostlist, 'admin?serverSelectionTimeoutMS=2000'] });
178+
await shell.waitForExit();
179+
shell.assertContainsOutput('MongoServerSelectionError');
180+
});
153181

154182
it('lists collections and dbs using show by default', async() => {
155183
const shell = TestShell.start({ args: [`${await rs1.connectionString()}`] });

packages/service-provider-core/src/uri-generator.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,4 +335,16 @@ describe('uri-generator.generate-uri', () => {
335335
expect.fail('expected error');
336336
});
337337
});
338+
339+
context('when the --host option contains a replica set', () => {
340+
it('returns a URI for the hosts and ports specified in --host', () => {
341+
const options = { host: 'replsetname/host1:123,host2,host3:456,' };
342+
expect(generateUri(options)).to.equal('mongodb://host1:123,host2,host3:456/test?replicaSet=replsetname');
343+
});
344+
345+
it('returns a URI for the hosts and ports specified in --host and database name', () => {
346+
const options = { host: 'replsetname/host1:123,host2,host3:456', _: ['admin'] };
347+
expect(generateUri(options)).to.equal('mongodb://host1:123,host2,host3:456/admin?replicaSet=replsetname');
348+
});
349+
});
338350
});

packages/service-provider-core/src/uri-generator.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,18 @@ function generateUri(options: CliOptions): string {
141141
function generateUriNormalized(options: CliOptions): ConnectionString {
142142
const uri = options._?.[0];
143143

144+
// If the --host argument contains /, it has the format
145+
// <replSetName>/<hostname1><:port>,<hostname2><:port>,<...>
146+
const replSetHostMatch = (options.host ?? '').match(
147+
/^(?<replSetName>[^/]+)\/(?<hosts>([A-Za-z0-9.-]+(:\d+)?,?)+)$/);
148+
if (replSetHostMatch) {
149+
const { replSetName, hosts } = replSetHostMatch.groups as { replSetName: string, hosts: string };
150+
const connectionString = new ConnectionString(`${Scheme.Mongo}replacemeHost/${uri ?? DEFAULT_DB}`);
151+
connectionString.hosts = hosts.split(',').filter(host => host.trim());
152+
connectionString.searchParams.set('replicaSet', replSetName);
153+
return addShellConnectionStringParameters(connectionString);
154+
}
155+
144156
// There is no URI provided, use default 127.0.0.1:27017
145157
if (!uri) {
146158
return new ConnectionString(`${Scheme.Mongo}${generateHost(options)}:${generatePort(options)}/?directConnection=true`);

0 commit comments

Comments
 (0)