admin.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. 'use strict';
  2. const applyWriteConcern = require('./utils').applyWriteConcern;
  3. const AddUserOperation = require('./operations/add_user');
  4. const ExecuteDbAdminCommandOperation = require('./operations/execute_db_admin_command');
  5. const RemoveUserOperation = require('./operations/remove_user');
  6. const ValidateCollectionOperation = require('./operations/validate_collection');
  7. const ListDatabasesOperation = require('./operations/list_databases');
  8. const executeOperation = require('./operations/execute_operation');
  9. /**
  10. * @fileOverview The **Admin** class is an internal class that allows convenient access to
  11. * the admin functionality and commands for MongoDB.
  12. *
  13. * **ADMIN Cannot directly be instantiated**
  14. * @example
  15. * const MongoClient = require('mongodb').MongoClient;
  16. * const test = require('assert');
  17. * // Connection url
  18. * const url = 'mongodb://localhost:27017';
  19. * // Database Name
  20. * const dbName = 'test';
  21. *
  22. * // Connect using MongoClient
  23. * MongoClient.connect(url, function(err, client) {
  24. * // Use the admin database for the operation
  25. * const adminDb = client.db(dbName).admin();
  26. *
  27. * // List all the available databases
  28. * adminDb.listDatabases(function(err, dbs) {
  29. * test.equal(null, err);
  30. * test.ok(dbs.databases.length > 0);
  31. * client.close();
  32. * });
  33. * });
  34. */
  35. /**
  36. * Create a new Admin instance (INTERNAL TYPE, do not instantiate directly)
  37. * @class
  38. * @return {Admin} a collection instance.
  39. */
  40. function Admin(db, topology, promiseLibrary) {
  41. if (!(this instanceof Admin)) return new Admin(db, topology);
  42. // Internal state
  43. this.s = {
  44. db: db,
  45. topology: topology,
  46. promiseLibrary: promiseLibrary
  47. };
  48. }
  49. /**
  50. * The callback format for results
  51. * @callback Admin~resultCallback
  52. * @param {MongoError} error An error instance representing the error during the execution.
  53. * @param {object} result The result object if the command was executed successfully.
  54. */
  55. /**
  56. * Execute a command
  57. * @method
  58. * @param {object} command The command hash
  59. * @param {object} [options] Optional settings.
  60. * @param {(ReadPreference|string)} [options.readPreference] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
  61. * @param {number} [options.maxTimeMS] Number of milliseconds to wait before aborting the query.
  62. * @param {Admin~resultCallback} [callback] The command result callback
  63. * @return {Promise} returns Promise if no callback passed
  64. */
  65. Admin.prototype.command = function(command, options, callback) {
  66. const args = Array.prototype.slice.call(arguments, 1);
  67. callback = typeof args[args.length - 1] === 'function' ? args.pop() : undefined;
  68. options = args.length ? args.shift() : {};
  69. const commandOperation = new ExecuteDbAdminCommandOperation(this.s.db, command, options);
  70. return executeOperation(this.s.db.s.topology, commandOperation, callback);
  71. };
  72. /**
  73. * Retrieve the server information for the current
  74. * instance of the db client
  75. *
  76. * @param {Object} [options] optional parameters for this operation
  77. * @param {ClientSession} [options.session] optional session to use for this operation
  78. * @param {Admin~resultCallback} [callback] The command result callback
  79. * @return {Promise} returns Promise if no callback passed
  80. */
  81. Admin.prototype.buildInfo = function(options, callback) {
  82. if (typeof options === 'function') (callback = options), (options = {});
  83. options = options || {};
  84. const cmd = { buildinfo: 1 };
  85. const buildInfoOperation = new ExecuteDbAdminCommandOperation(this.s.db, cmd, options);
  86. return executeOperation(this.s.db.s.topology, buildInfoOperation, callback);
  87. };
  88. /**
  89. * Retrieve the server information for the current
  90. * instance of the db client
  91. *
  92. * @param {Object} [options] optional parameters for this operation
  93. * @param {ClientSession} [options.session] optional session to use for this operation
  94. * @param {Admin~resultCallback} [callback] The command result callback
  95. * @return {Promise} returns Promise if no callback passed
  96. */
  97. Admin.prototype.serverInfo = function(options, callback) {
  98. if (typeof options === 'function') (callback = options), (options = {});
  99. options = options || {};
  100. const cmd = { buildinfo: 1 };
  101. const serverInfoOperation = new ExecuteDbAdminCommandOperation(this.s.db, cmd, options);
  102. return executeOperation(this.s.db.s.topology, serverInfoOperation, callback);
  103. };
  104. /**
  105. * Retrieve this db's server status.
  106. *
  107. * @param {Object} [options] optional parameters for this operation
  108. * @param {ClientSession} [options.session] optional session to use for this operation
  109. * @param {Admin~resultCallback} [callback] The command result callback
  110. * @return {Promise} returns Promise if no callback passed
  111. */
  112. Admin.prototype.serverStatus = function(options, callback) {
  113. if (typeof options === 'function') (callback = options), (options = {});
  114. options = options || {};
  115. const serverStatusOperation = new ExecuteDbAdminCommandOperation(
  116. this.s.db,
  117. { serverStatus: 1 },
  118. options
  119. );
  120. return executeOperation(this.s.db.s.topology, serverStatusOperation, callback);
  121. };
  122. /**
  123. * Ping the MongoDB server and retrieve results
  124. *
  125. * @param {Object} [options] optional parameters for this operation
  126. * @param {ClientSession} [options.session] optional session to use for this operation
  127. * @param {Admin~resultCallback} [callback] The command result callback
  128. * @return {Promise} returns Promise if no callback passed
  129. */
  130. Admin.prototype.ping = function(options, callback) {
  131. if (typeof options === 'function') (callback = options), (options = {});
  132. options = options || {};
  133. const cmd = { ping: 1 };
  134. const pingOperation = new ExecuteDbAdminCommandOperation(this.s.db, cmd, options);
  135. return executeOperation(this.s.db.s.topology, pingOperation, callback);
  136. };
  137. /**
  138. * Add a user to the database.
  139. * @method
  140. * @param {string} username The username.
  141. * @param {string} password The password.
  142. * @param {object} [options] Optional settings.
  143. * @param {(number|string)} [options.w] **Deprecated** The write concern. Use writeConcern instead.
  144. * @param {number} [options.wtimeout] **Deprecated** The write concern timeout. Use writeConcern instead.
  145. * @param {boolean} [options.j=false] **Deprecated** Specify a journal write concern. Use writeConcern instead.
  146. * @param {boolean} [options.fsync=false] **Deprecated** Specify a file sync write concern. Use writeConcern instead.
  147. * @param {object|WriteConcern} [options.writeConcern] Specify write concern settings.
  148. * @param {object} [options.customData] Custom data associated with the user (only Mongodb 2.6 or higher)
  149. * @param {object[]} [options.roles] Roles associated with the created user (only Mongodb 2.6 or higher)
  150. * @param {ClientSession} [options.session] optional session to use for this operation
  151. * @param {Admin~resultCallback} [callback] The command result callback
  152. * @return {Promise} returns Promise if no callback passed
  153. */
  154. Admin.prototype.addUser = function(username, password, options, callback) {
  155. const args = Array.prototype.slice.call(arguments, 2);
  156. callback = typeof args[args.length - 1] === 'function' ? args.pop() : undefined;
  157. // Special case where there is no password ($external users)
  158. if (typeof username === 'string' && password != null && typeof password === 'object') {
  159. options = password;
  160. password = null;
  161. }
  162. options = args.length ? args.shift() : {};
  163. options = Object.assign({}, options);
  164. // Get the options
  165. options = applyWriteConcern(options, { db: this.s.db });
  166. // Set the db name to admin
  167. options.dbName = 'admin';
  168. const addUserOperation = new AddUserOperation(this.s.db, username, password, options);
  169. return executeOperation(this.s.db.s.topology, addUserOperation, callback);
  170. };
  171. /**
  172. * Remove a user from a database
  173. * @method
  174. * @param {string} username The username.
  175. * @param {object} [options] Optional settings.
  176. * @param {(number|string)} [options.w] **Deprecated** The write concern. Use writeConcern instead.
  177. * @param {number} [options.wtimeout] **Deprecated** The write concern timeout. Use writeConcern instead.
  178. * @param {boolean} [options.j=false] **Deprecated** Specify a journal write concern. Use writeConcern instead.
  179. * @param {boolean} [options.fsync=false] **Deprecated** Specify a file sync write concern. Use writeConcern instead.
  180. * @param {object|WriteConcern} [options.writeConcern] Specify write concern settings.
  181. * @param {ClientSession} [options.session] optional session to use for this operation
  182. * @param {Admin~resultCallback} [callback] The command result callback
  183. * @return {Promise} returns Promise if no callback passed
  184. */
  185. Admin.prototype.removeUser = function(username, options, callback) {
  186. const args = Array.prototype.slice.call(arguments, 1);
  187. callback = typeof args[args.length - 1] === 'function' ? args.pop() : undefined;
  188. options = args.length ? args.shift() : {};
  189. options = Object.assign({}, options);
  190. // Get the options
  191. options = applyWriteConcern(options, { db: this.s.db });
  192. // Set the db name
  193. options.dbName = 'admin';
  194. const removeUserOperation = new RemoveUserOperation(this.s.db, username, options);
  195. return executeOperation(this.s.db.s.topology, removeUserOperation, callback);
  196. };
  197. /**
  198. * Validate an existing collection
  199. *
  200. * @param {string} collectionName The name of the collection to validate.
  201. * @param {object} [options] Optional settings.
  202. * @param {boolean} [options.background] Validates a collection in the background, without interrupting read or write traffic (only in MongoDB 4.4+)
  203. * @param {ClientSession} [options.session] optional session to use for this operation
  204. * @param {Admin~resultCallback} [callback] The command result callback.
  205. * @return {Promise} returns Promise if no callback passed
  206. */
  207. Admin.prototype.validateCollection = function(collectionName, options, callback) {
  208. if (typeof options === 'function') (callback = options), (options = {});
  209. options = options || {};
  210. const validateCollectionOperation = new ValidateCollectionOperation(
  211. this,
  212. collectionName,
  213. options
  214. );
  215. return executeOperation(this.s.db.s.topology, validateCollectionOperation, callback);
  216. };
  217. /**
  218. * List the available databases
  219. *
  220. * @param {object} [options] Optional settings.
  221. * @param {boolean} [options.nameOnly=false] Whether the command should return only db names, or names and size info.
  222. * @param {ClientSession} [options.session] optional session to use for this operation
  223. * @param {Admin~resultCallback} [callback] The command result callback.
  224. * @return {Promise} returns Promise if no callback passed
  225. */
  226. Admin.prototype.listDatabases = function(options, callback) {
  227. if (typeof options === 'function') (callback = options), (options = {});
  228. options = options || {};
  229. return executeOperation(
  230. this.s.db.s.topology,
  231. new ListDatabasesOperation(this.s.db, options),
  232. callback
  233. );
  234. };
  235. /**
  236. * Get ReplicaSet status
  237. *
  238. * @param {Object} [options] optional parameters for this operation
  239. * @param {ClientSession} [options.session] optional session to use for this operation
  240. * @param {Admin~resultCallback} [callback] The command result callback.
  241. * @return {Promise} returns Promise if no callback passed
  242. */
  243. Admin.prototype.replSetGetStatus = function(options, callback) {
  244. if (typeof options === 'function') (callback = options), (options = {});
  245. options = options || {};
  246. const replSetGetStatusOperation = new ExecuteDbAdminCommandOperation(
  247. this.s.db,
  248. { replSetGetStatus: 1 },
  249. options
  250. );
  251. return executeOperation(this.s.db.s.topology, replSetGetStatusOperation, callback);
  252. };
  253. module.exports = Admin;