UNPKG

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