Skip to content

Commit f04774c

Browse files
committed
MONGOSH-300 - Free monitoring methods
1 parent a8719b3 commit f04774c

File tree

4 files changed

+211
-3
lines changed

4 files changed

+211
-3
lines changed

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/i18n/src/locales/en_US.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,21 @@ const translations = {
985985
link: 'https://docs.mongodb.com/manual/reference/method/db.printCollectionStats',
986986
description: 'Prints the collection.stats for each collection in the db.',
987987
example: 'db.printCollectionStats(scale)',
988+
},
989+
getFreeMonitoringStatus: {
990+
link: 'https://docs.mongodb.com/manual/reference/method/db.getFreeMonitoringStatus',
991+
description: 'Calls the getFreeMonitoringStatus command',
992+
example: 'db.getFreeMonitoringStatus()'
993+
},
994+
enableFreeMonitoring: {
995+
link: 'https://docs.mongodb.com/manual/reference/method/db.enableFreeMonitoring',
996+
description: 'returns the db enableFreeMonitoring. uses the setFreeMonitoring command',
997+
example: 'db.enableFreeMonitoring()',
998+
},
999+
disableFreeMonitoring: {
1000+
link: 'https://docs.mongodb.com/manual/reference/method/db.disableFreeMonitoring',
1001+
description: 'returns the db disableFreeMonitoring. uses the setFreeMonitoring command',
1002+
example: 'db.disableFreeMonitoring()',
9881003
}
9891004
}
9901005
}

packages/shell-api/src/database.spec.ts

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1657,6 +1657,128 @@ describe('Database', () => {
16571657
expect(catchedError).to.equal(expectedError);
16581658
});
16591659
});
1660+
1661+
describe('getFreeMonitoringStatus', () => {
1662+
it('calls serviceProvider.runCommand on the database', async() => {
1663+
serviceProvider.runCommand.resolves({ ok: 1 });
1664+
await database.getFreeMonitoringStatus();
1665+
1666+
expect(serviceProvider.runCommand).to.have.been.calledWith(
1667+
ADMIN_DB,
1668+
{
1669+
getFreeMonitoringStatus: 1
1670+
}
1671+
);
1672+
});
1673+
1674+
it('returns whatever serviceProvider.runCommand returns', async() => {
1675+
const expectedResult = { ok: 1 };
1676+
serviceProvider.runCommand.resolves(expectedResult);
1677+
const result = await database.getFreeMonitoringStatus();
1678+
expect(result).to.deep.equal(expectedResult);
1679+
});
1680+
1681+
it('throws if serviceProvider.runCommand rejects', async() => {
1682+
const expectedError = new Error();
1683+
serviceProvider.runCommand.rejects(expectedError);
1684+
const catchedError = await database.getFreeMonitoringStatus()
1685+
.catch(e => e);
1686+
expect(catchedError).to.equal(expectedError);
1687+
});
1688+
});
1689+
1690+
describe('disableFreeMonitoring', () => {
1691+
it('calls serviceProvider.runCommand on the database with options', async() => {
1692+
serviceProvider.runCommand.resolves({ ok: 1 });
1693+
await database.disableFreeMonitoring();
1694+
1695+
expect(serviceProvider.runCommand).to.have.been.calledWith(
1696+
ADMIN_DB,
1697+
{
1698+
setFreeMonitoring: 1,
1699+
action: 'disable'
1700+
}
1701+
);
1702+
});
1703+
1704+
it('returns whatever serviceProvider.runCommand returns', async() => {
1705+
const expectedResult = { ok: 1 };
1706+
serviceProvider.runCommand.resolves(expectedResult);
1707+
const result = await database.disableFreeMonitoring();
1708+
expect(result).to.deep.equal(expectedResult);
1709+
});
1710+
1711+
it('throws if serviceProvider.runCommand rejects', async() => {
1712+
const expectedError = new Error();
1713+
serviceProvider.runCommand.rejects(expectedError);
1714+
const catchedError = await database.disableFreeMonitoring()
1715+
.catch(e => e);
1716+
expect(catchedError).to.equal(expectedError);
1717+
});
1718+
});
1719+
1720+
describe('enableFreeMonitoring', () => {
1721+
it('throws if serviceProvider isMaster is false', async() => {
1722+
serviceProvider.runCommand.resolves({ ismaster: false });
1723+
const catchedError = await database.enableFreeMonitoring()
1724+
.catch(e => e);
1725+
expect(catchedError.name).to.equal('MongoshInvalidInputError');
1726+
});
1727+
1728+
it('calls serviceProvider.runCommand on the database', async() => {
1729+
serviceProvider.runCommand.onCall(0).resolves({ ismaster: true });
1730+
serviceProvider.runCommand.onCall(1).resolves({ ok: 1, state: 'enabled' });
1731+
await database.enableFreeMonitoring();
1732+
1733+
expect(serviceProvider.runCommand).to.have.been.calledWith(
1734+
ADMIN_DB,
1735+
{
1736+
setFreeMonitoring: 1,
1737+
action: 'enable'
1738+
}
1739+
);
1740+
});
1741+
1742+
it('returns whatever serviceProvider.runCommand returns if enabled', async() => {
1743+
const expectedResult = { ok: 1, state: 'enabled' };
1744+
serviceProvider.runCommand.onCall(0).resolves({ ismaster: true });
1745+
serviceProvider.runCommand.onCall(1).resolves(expectedResult);
1746+
const result = await database.enableFreeMonitoring();
1747+
expect(result).to.deep.equal(expectedResult);
1748+
});
1749+
it('returns warning if not enabled', async() => {
1750+
serviceProvider.runCommand.onCall(0).resolves({ ismaster: true });
1751+
serviceProvider.runCommand.onCall(1).resolves({ ok: 1, enabled: false });
1752+
serviceProvider.runCommand.onCall(2).resolves({ cloudFreeMonitoringEndpointURL: 'URL' });
1753+
const result = await database.enableFreeMonitoring();
1754+
expect(result).to.include('URL');
1755+
});
1756+
1757+
it('returns warning if returns ok: 0 with auth error', async() => {
1758+
serviceProvider.runCommand.onCall(0).resolves({ ismaster: true });
1759+
serviceProvider.runCommand.onCall(1).resolves({ ok: 0, codeName: 'Unauthorized' });
1760+
const result = await database.enableFreeMonitoring();
1761+
expect(result).to.be.a('string');
1762+
expect(result).to.include('privilege');
1763+
});
1764+
it('returns warning if throws with auth error', async() => {
1765+
const expectedError = new Error();
1766+
(expectedError as any).codeName = 'Unauthorized';
1767+
serviceProvider.runCommand.onCall(0).resolves({ ismaster: true });
1768+
serviceProvider.runCommand.onCall(1).rejects(expectedError);
1769+
const result = await database.enableFreeMonitoring();
1770+
expect(result).to.be.a('string');
1771+
expect(result).to.include('privilege');
1772+
});
1773+
1774+
it('throws if serviceProvider.runCommand rejects without auth error', async() => {
1775+
const expectedError = new Error();
1776+
serviceProvider.runCommand.rejects(expectedError);
1777+
const catchedError = await database.enableFreeMonitoring()
1778+
.catch(e => e);
1779+
expect(catchedError).to.equal(expectedError);
1780+
});
1781+
});
16601782
});
16611783
});
16621784

packages/shell-api/src/database.ts

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable complexity */
12
import Mongo from './mongo';
23
import Collection from './collection';
34
import {
@@ -751,4 +752,74 @@ export default class Database extends ShellApiClass {
751752
}
752753
return new CommandResult('StatsResult', result);
753754
}
755+
756+
@returnsPromise
757+
async getFreeMonitoringStatus(): Promise<any> {
758+
this._emitDatabaseApiCall('getFreeMonitoringStatus', {});
759+
const result = await this._mongo._serviceProvider.runCommand(
760+
ADMIN_DB,
761+
{
762+
getFreeMonitoringStatus: 1,
763+
}
764+
);
765+
if (!result || !result.ok) {
766+
throw new MongoshRuntimeError(`Error running command getFreeMonitoringStatus ${result ? result.errmsg || '' : ''}`);
767+
}
768+
return result;
769+
}
770+
771+
@returnsPromise
772+
async disableFreeMonitoring(): Promise<any> {
773+
this._emitDatabaseApiCall('disableFreeMonitoring', {});
774+
const result = await this._mongo._serviceProvider.runCommand(
775+
ADMIN_DB,
776+
{
777+
setFreeMonitoring: 1,
778+
action: 'disable'
779+
}
780+
);
781+
if (!result || !result.ok) {
782+
throw new MongoshRuntimeError(`Error running command setFreeMonitoring ${result ? result.errmsg || '' : ''}`);
783+
}
784+
return result;
785+
}
786+
787+
@returnsPromise
788+
async enableFreeMonitoring(): Promise<any> {
789+
this._emitDatabaseApiCall('enableFreeMonitoring', {});
790+
const isMaster = await this._mongo._serviceProvider.runCommand(this._name, { isMaster: 1 });
791+
if (!isMaster.ismaster) {
792+
throw new MongoshInvalidInputError('db.enableFreeMonitoring() may only be run on a primary');
793+
}
794+
795+
let result;
796+
let error;
797+
try {
798+
result = await this._mongo._serviceProvider.runCommand(
799+
ADMIN_DB,
800+
{
801+
setFreeMonitoring: 1,
802+
action: 'enable'
803+
}
804+
);
805+
} catch (err) {
806+
error = err;
807+
}
808+
if (error && error.codeName === 'Unauthorized' || (result && !result.ok && result.codeName === 'Unauthorized')) {
809+
return 'Unable to determine status as you lack the \'checkFreeMonitoringStatus\' privilege.';
810+
} else if (error || !result || !result.ok) {
811+
throw new MongoshRuntimeError(`Error running command setFreeMonitoring ${result ? result.errmsg : error.errmsg}`);
812+
}
813+
if (result.state !== 'enabled') {
814+
const urlResult = await this._mongo._serviceProvider.runCommand(
815+
ADMIN_DB,
816+
{
817+
getParameter: 1,
818+
cloudFreeMonitoringEndpointURL: 1
819+
}
820+
);
821+
return `Unable to get immediate response from the Cloud Monitoring service. Please check your firewall settings to ensure that mongod can communicate with '${urlResult.cloudFreeMonitoringEndpointURL || '<unknown>'}'`;
822+
}
823+
return result;
824+
}
754825
}

0 commit comments

Comments
 (0)