admin.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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] The write concern.
  144. * @param {number} [options.wtimeout] The write concern timeout.
  145. * @param {boolean} [options.j=false] Specify a journal write concern.
  146. * @param {boolean} [options.fsync=false] Specify a file sync write concern.
  147. * @param {object} [options.customData] Custom data associated with the user (only Mongodb 2.6 or higher)
  148. * @param {object[]} [options.roles] Roles associated with the created user (only Mongodb 2.6 or higher)
  149. * @param {ClientSession} [options.session] optional session to use for this operation
  150. * @param {Admin~resultCallback} [callback] The command result callback
  151. * @return {Promise} returns Promise if no callback passed
  152. */
  153. Admin.prototype.addUser = function(username, password, options, callback) {
  154. const args = Array.prototype.slice.call(arguments, 2);
  155. callback = typeof args[args.length - 1] === 'function' ? args.pop() : undefined;
  156. // Special case where there is no password ($external users)
  157. if (typeof username === 'string' && password != null && typeof password === 'object') {
  158. options = password;
  159. password = null;
  160. }
  161. options = args.length ? args.shift() : {};
  162. options = Object.assign({}, options);
  163. // Get the options
  164. options = applyWriteConcern(options, { db: this.s.db });
  165. // Set the db name to admin
  166. options.dbName = 'admin';
  167. const addUserOperation = new AddUserOperation(this.s.db, username, password, options);
  168. return executeOperation(this.s.db.s.topology, addUserOperation, callback);
  169. };
  170. /**
  171. * Remove a user from a database
  172. * @method
  173. * @param {string} username The username.
  174. * @param {object} [options] Optional settings.
  175. * @param {(number|string)} [options.w] The write concern.
  176. * @param {number} [options.wtimeout] The write concern timeout.
  177. * @param {boolean} [options.j=false] Specify a journal write concern.
  178. * @param {boolean} [options.fsync=false] Specify a file sync write concern.
  179. * @param {ClientSession} [options.session] optional session to use for this operation
  180. * @param {Admin~resultCallback} [callback] The command result callback
  181. * @return {Promise} returns Promise if no callback passed
  182. */
  183. Admin.prototype.removeUser = function(username, options, callback) {
  184. const args = Array.prototype.slice.call(arguments, 1);
  185. callback = typeof args[args.length - 1] === 'function' ? args.pop() : undefined;
  186. options = args.length ? args.shift() : {};
  187. options = Object.assign({}, options);
  188. // Get the options
  189. options = applyWriteConcern(options, { db: this.s.db });
  190. // Set the db name
  191. options.dbName = 'admin';
  192. const removeUserOperation = new RemoveUserOperation(this.s.db, username, options);
  193. return executeOperation(this.s.db.s.topology, removeUserOperation, callback);
  194. };
  195. /**
  196. * Validate an existing collection
  197. *
  198. * @param {string} collectionName The name of the collection to validate.
  199. * @param {object} [options] Optional settings.
  200. * @param {ClientSession} [options.session] optional session to use for this operation
  201. * @param {Admin~resultCallback} [callback] The command result callback.
  202. * @return {Promise} returns Promise if no callback passed
  203. */
  204. Admin.prototype.validateCollection = function(collectionName, options, callback) {
  205. if (typeof options === 'function') (callback = options), (options = {});
  206. options = options || {};
  207. const validateCollectionOperation = new ValidateCollectionOperation(
  208. this,
  209. collectionName,
  210. options
  211. );
  212. return executeOperation(this.s.db.s.topology, validateCollectionOperation, callback);
  213. };
  214. /**
  215. * List the available databases
  216. *
  217. * @param {object} [options] Optional settings.
  218. * @param {boolean} [options.nameOnly=false] Whether the command should return only db names, or names and size info.
  219. * @param {ClientSession} [options.session] optional session to use for this operation
  220. * @param {Admin~resultCallback} [callback] The command result callback.
  221. * @return {Promise} returns Promise if no callback passed
  222. */
  223. Admin.prototype.listDatabases = function(options, callback) {
  224. if (typeof options === 'function') (callback = options), (options = {});
  225. options = options || {};
  226. return executeOperation(
  227. this.s.db.s.topology,
  228. new ListDatabasesOperation(this.s.db, options),
  229. callback
  230. );
  231. };
  232. /**
  233. * Get ReplicaSet status
  234. *
  235. * @param {Object} [options] optional parameters for this operation
  236. * @param {ClientSession} [options.session] optional session to use for this operation
  237. * @param {Admin~resultCallback} [callback] The command result callback.
  238. * @return {Promise} returns Promise if no callback passed
  239. */
  240. Admin.prototype.replSetGetStatus = function(options, callback) {
  241. if (typeof options === 'function') (callback = options), (options = {});
  242. options = options || {};
  243. const replSetGetStatusOperation = new ExecuteDbAdminCommandOperation(
  244. this.s.db,
  245. { replSetGetStatus: 1 },
  246. options
  247. );
  248. return executeOperation(this.s.db.s.topology, replSetGetStatusOperation, callback);
  249. };
  250. module.exports = Admin;