admin.js 10 KB

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