@qp-mongosh/shell-api 0.0.0-dev.5 → 0.0.0-dev.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +2 -2
- package/.eslintrc.js +1 -1
- package/AUTHORS +15 -15
- package/LICENSE +200 -200
- package/bin/report-missing-help.ts +24 -24
- package/bin/report-supported-api.ts +14 -14
- package/lib/abstract-cursor.d.ts +33 -33
- package/lib/abstract-cursor.js +191 -191
- package/lib/aggregation-cursor.d.ts +6 -6
- package/lib/aggregation-cursor.js +19 -19
- package/lib/bulk.d.ts +43 -43
- package/lib/bulk.js +223 -223
- package/lib/change-stream-cursor.d.ts +28 -28
- package/lib/change-stream-cursor.js +111 -111
- package/lib/collection.d.ts +95 -95
- package/lib/collection.js +964 -964
- package/lib/cursor.d.ts +32 -32
- package/lib/cursor.js +215 -215
- package/lib/database.d.ts +116 -116
- package/lib/database.js +1223 -1223
- package/lib/dbquery.d.ts +8 -8
- package/lib/dbquery.js +28 -28
- package/lib/decorators.d.ts +73 -73
- package/lib/decorators.js +395 -395
- package/lib/enums.d.ts +28 -28
- package/lib/enums.js +33 -33
- package/lib/error-codes.d.ts +12 -12
- package/lib/error-codes.js +19 -19
- package/lib/explainable-cursor.d.ts +11 -11
- package/lib/explainable-cursor.js +31 -31
- package/lib/explainable.d.ts +32 -32
- package/lib/explainable.js +166 -166
- package/lib/field-level-encryption.d.ts +50 -50
- package/lib/field-level-encryption.js +176 -176
- package/lib/help.d.ts +22 -22
- package/lib/help.js +26 -26
- package/lib/helpers.d.ts +71 -71
- package/lib/helpers.js +588 -588
- package/lib/index.d.ts +16 -16
- package/lib/index.js +45 -45
- package/lib/interruptor.d.ts +19 -19
- package/lib/interruptor.js +62 -62
- package/lib/mongo-errors.d.ts +5 -5
- package/lib/mongo-errors.js +37 -37
- package/lib/mongo.d.ts +75 -75
- package/lib/mongo.js +476 -476
- package/lib/no-db.d.ts +5 -5
- package/lib/no-db.js +28 -28
- package/lib/plan-cache.d.ts +16 -16
- package/lib/plan-cache.js +70 -70
- package/lib/replica-set.d.ts +45 -45
- package/lib/replica-set.js +314 -314
- package/lib/result.d.ts +61 -61
- package/lib/result.js +104 -104
- package/lib/session.d.ts +25 -25
- package/lib/session.js +88 -88
- package/lib/shard.d.ts +42 -42
- package/lib/shard.js +414 -414
- package/lib/shell-api.d.ts +52 -52
- package/lib/shell-api.js +298 -298
- package/lib/shell-bson.d.ts +40 -40
- package/lib/shell-bson.js +159 -159
- package/lib/shell-instance-state.d.ts +77 -77
- package/lib/shell-instance-state.js +392 -392
- package/package.json +47 -47
- package/tsconfig.lint.json +8 -8
package/lib/replica-set.js
CHANGED
|
@@ -1,315 +1,315 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
const errors_1 = require("@qp-mongosh/errors");
|
|
10
|
-
const history_1 = require("@qp-mongosh/history");
|
|
11
|
-
const decorators_1 = require("./decorators");
|
|
12
|
-
const enums_1 = require("./enums");
|
|
13
|
-
const helpers_1 = require("./helpers");
|
|
14
|
-
let ReplicaSet = class ReplicaSet extends decorators_1.ShellApiWithMongoClass {
|
|
15
|
-
constructor(database) {
|
|
16
|
-
super();
|
|
17
|
-
this._database = database;
|
|
18
|
-
}
|
|
19
|
-
get _mongo() {
|
|
20
|
-
return this._database._mongo;
|
|
21
|
-
}
|
|
22
|
-
async initiate(config = {}) {
|
|
23
|
-
this._emitReplicaSetApiCall('initiate', { config });
|
|
24
|
-
return this._database._runAdminCommand({ replSetInitiate: config });
|
|
25
|
-
}
|
|
26
|
-
async _getConfig() {
|
|
27
|
-
try {
|
|
28
|
-
const result = await this._database._runAdminCommand({ replSetGetConfig: 1 });
|
|
29
|
-
if (result.config === undefined) {
|
|
30
|
-
throw new errors_1.MongoshRuntimeError('Documented returned from command replSetGetConfig does not contain \'config\'', errors_1.CommonErrors.CommandFailed);
|
|
31
|
-
}
|
|
32
|
-
return result.config;
|
|
33
|
-
}
|
|
34
|
-
catch (error) {
|
|
35
|
-
if ((error === null || error === void 0 ? void 0 : error.codeName) === 'CommandNotFound' || (error === null || error === void 0 ? void 0 : error.codeName) === 'APIStrictError') {
|
|
36
|
-
const doc = await this._database.getSiblingDB('local').getCollection('system.replset').findOne();
|
|
37
|
-
if (doc === null) {
|
|
38
|
-
throw new errors_1.MongoshRuntimeError('No documents in local.system.replset', errors_1.CommonErrors.CommandFailed);
|
|
39
|
-
}
|
|
40
|
-
return doc;
|
|
41
|
-
}
|
|
42
|
-
throw error;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
async config() {
|
|
46
|
-
this._emitReplicaSetApiCall('config', {});
|
|
47
|
-
return this._getConfig();
|
|
48
|
-
}
|
|
49
|
-
async conf() {
|
|
50
|
-
this._emitReplicaSetApiCall('conf', {});
|
|
51
|
-
return this._getConfig();
|
|
52
|
-
}
|
|
53
|
-
async reconfig(config, options = {}) {
|
|
54
|
-
(0, helpers_1.assertArgsDefinedType)([config, options], ['object', [undefined, 'object']], 'ReplicaSet.reconfig');
|
|
55
|
-
this._emitReplicaSetApiCall('reconfig', { config, options });
|
|
56
|
-
const runReconfig = async () => {
|
|
57
|
-
var _a;
|
|
58
|
-
const conf = await this._getConfig();
|
|
59
|
-
config.version = conf.version ? conf.version + 1 : 1;
|
|
60
|
-
(_a = config.protocolVersion) !== null && _a !== void 0 ? _a : (config.protocolVersion = conf.protocolVersion);
|
|
61
|
-
const cmd = { replSetReconfig: config, ...options };
|
|
62
|
-
return await this._database._runAdminCommand(cmd);
|
|
63
|
-
};
|
|
64
|
-
let result = ['success', {}];
|
|
65
|
-
let sleepInterval = 1000;
|
|
66
|
-
for (let i = 0; i < 12; i++) {
|
|
67
|
-
try {
|
|
68
|
-
if (result[0] === 'error') {
|
|
69
|
-
await this._instanceState.shellApi.sleep(sleepInterval);
|
|
70
|
-
sleepInterval *= 1.3;
|
|
71
|
-
if (sleepInterval > 2500) {
|
|
72
|
-
await this._instanceState.shellApi.print('Reconfig did not succeed yet, starting new attempt...');
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
result = ['success', await runReconfig()];
|
|
76
|
-
break;
|
|
77
|
-
}
|
|
78
|
-
catch (err) {
|
|
79
|
-
result = ['error', err];
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
if (result[0] === 'error') {
|
|
83
|
-
throw result[1];
|
|
84
|
-
}
|
|
85
|
-
return result[1];
|
|
86
|
-
}
|
|
87
|
-
async reconfigForPSASet(newMemberIndex, config, options = {}) {
|
|
88
|
-
var _a;
|
|
89
|
-
(0, helpers_1.assertArgsDefinedType)([newMemberIndex, config, options], ['number', 'object', [undefined, 'object']], 'ReplicaSet.reconfigForPSASet');
|
|
90
|
-
this._emitReplicaSetApiCall('reconfigForPSASet', { newMemberIndex, config, options });
|
|
91
|
-
const print = (msg) => this._instanceState.shellApi.print(msg);
|
|
92
|
-
const newMemberConfig = (_a = config.members) === null || _a === void 0 ? void 0 : _a[newMemberIndex];
|
|
93
|
-
if (!newMemberConfig) {
|
|
94
|
-
throw new errors_1.MongoshInvalidInputError(`Node at index ${newMemberIndex} does not exist in the new config`, errors_1.CommonErrors.InvalidArgument);
|
|
95
|
-
}
|
|
96
|
-
if (newMemberConfig.votes !== 1) {
|
|
97
|
-
throw new errors_1.MongoshInvalidInputError(`Node at index ${newMemberIndex} must have { votes: 1 } in the new config (actual: { votes: ${newMemberConfig.votes} })`, errors_1.CommonErrors.InvalidArgument);
|
|
98
|
-
}
|
|
99
|
-
const oldConfig = await this._getConfig();
|
|
100
|
-
const oldMemberConfig = oldConfig.members.find(member => member._id === newMemberConfig._id);
|
|
101
|
-
if (!oldMemberConfig) {
|
|
102
|
-
if (oldConfig.members.find(member => member.host === newMemberConfig.host)) {
|
|
103
|
-
await print(`Warning: Node at index ${newMemberIndex} has { host: "${newMemberConfig.host}" }, ` +
|
|
104
|
-
'which is also present in the old config, but with a different _id field.');
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
else if (oldMemberConfig.votes) {
|
|
108
|
-
throw new errors_1.MongoshInvalidInputError(`Node at index ${newMemberIndex} must have { votes: 0 } in the old config (actual: { votes: ${oldMemberConfig.votes} })`, errors_1.CommonErrors.InvalidArgument);
|
|
109
|
-
}
|
|
110
|
-
const newMemberPriority = newMemberConfig.priority;
|
|
111
|
-
await print(`Running first reconfig to give member at index ${newMemberIndex} { votes: 1, priority: 0 }`);
|
|
112
|
-
newMemberConfig.votes = 1;
|
|
113
|
-
newMemberConfig.priority = 0;
|
|
114
|
-
const firstResult = await this.reconfig(config, options);
|
|
115
|
-
if (newMemberPriority === 0) {
|
|
116
|
-
await print('No second reconfig necessary because .priority = 0');
|
|
117
|
-
return firstResult;
|
|
118
|
-
}
|
|
119
|
-
await print(`Running second reconfig to give member at index ${newMemberIndex} { priority: ${newMemberPriority} }`);
|
|
120
|
-
newMemberConfig.priority = newMemberPriority;
|
|
121
|
-
try {
|
|
122
|
-
return await this.reconfig(config, options);
|
|
123
|
-
}
|
|
124
|
-
catch (e) {
|
|
125
|
-
await print('Second reconfig did not succeed, giving up');
|
|
126
|
-
await print(`Attempted command: rs.reconfig(${JSON.stringify(config, null, ' ')}, ${JSON.stringify(options)})`);
|
|
127
|
-
throw e;
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
async status() {
|
|
131
|
-
this._emitReplicaSetApiCall('status', {});
|
|
132
|
-
return this._database._runAdminCommand({
|
|
133
|
-
replSetGetStatus: 1,
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
async isMaster() {
|
|
137
|
-
this._emitReplicaSetApiCall('isMaster', {});
|
|
138
|
-
return this._database.getSiblingDB('admin').isMaster();
|
|
139
|
-
}
|
|
140
|
-
async hello() {
|
|
141
|
-
this._emitReplicaSetApiCall('hello', {});
|
|
142
|
-
return this._database.getSiblingDB('admin').hello();
|
|
143
|
-
}
|
|
144
|
-
async printSecondaryReplicationInfo() {
|
|
145
|
-
this._emitReplicaSetApiCall('printSecondaryReplicationInfo', {});
|
|
146
|
-
return this._database.printSecondaryReplicationInfo();
|
|
147
|
-
}
|
|
148
|
-
printSlaveReplicationInfo() {
|
|
149
|
-
throw new errors_1.MongoshDeprecatedError('printSlaveReplicationInfo has been deprecated. Use printSecondaryReplicationInfo instead');
|
|
150
|
-
}
|
|
151
|
-
async printReplicationInfo() {
|
|
152
|
-
this._emitReplicaSetApiCall('printReplicationInfo', {});
|
|
153
|
-
return this._database.printReplicationInfo();
|
|
154
|
-
}
|
|
155
|
-
async add(hostport, arb) {
|
|
156
|
-
(0, helpers_1.assertArgsDefinedType)([hostport, arb], [['string', 'object'], [undefined, 'boolean']], 'ReplicaSet.add');
|
|
157
|
-
this._emitReplicaSetApiCall('add', { hostport, arb });
|
|
158
|
-
const configDoc = await this._getConfig();
|
|
159
|
-
configDoc.version++;
|
|
160
|
-
const max = Math.max(...configDoc.members.map(m => m._id));
|
|
161
|
-
let cfg;
|
|
162
|
-
if (typeof hostport === 'string') {
|
|
163
|
-
cfg = { _id: max + 1, host: hostport };
|
|
164
|
-
if (arb) {
|
|
165
|
-
cfg.arbiterOnly = true;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
else if (arb === true) {
|
|
169
|
-
throw new errors_1.MongoshInvalidInputError(`Expected first parameter to be a host-and-port string of arbiter, but got ${JSON.stringify(hostport)}`, errors_1.CommonErrors.InvalidArgument);
|
|
170
|
-
}
|
|
171
|
-
else {
|
|
172
|
-
cfg = hostport;
|
|
173
|
-
if (cfg._id === null || cfg._id === undefined) {
|
|
174
|
-
cfg._id = max + 1;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
configDoc.members.push(cfg);
|
|
178
|
-
return this._database._runAdminCommand({
|
|
179
|
-
replSetReconfig: configDoc,
|
|
180
|
-
});
|
|
181
|
-
}
|
|
182
|
-
async addArb(hostname) {
|
|
183
|
-
this._emitReplicaSetApiCall('addArb', { hostname });
|
|
184
|
-
return this.add(hostname, true);
|
|
185
|
-
}
|
|
186
|
-
async remove(hostname) {
|
|
187
|
-
(0, helpers_1.assertArgsDefinedType)([hostname], ['string'], 'ReplicaSet.remove');
|
|
188
|
-
this._emitReplicaSetApiCall('remove', { hostname });
|
|
189
|
-
const configDoc = await this._getConfig();
|
|
190
|
-
configDoc.version++;
|
|
191
|
-
for (let i = 0; i < configDoc.members.length; i++) {
|
|
192
|
-
if (configDoc.members[i].host === hostname) {
|
|
193
|
-
configDoc.members.splice(i, 1);
|
|
194
|
-
return this._database._runAdminCommand({
|
|
195
|
-
replSetReconfig: configDoc,
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
throw new errors_1.MongoshInvalidInputError(`Couldn't find ${hostname} in ${JSON.stringify(configDoc.members)}. Is ${hostname} a member of this replset?`, errors_1.CommonErrors.InvalidArgument);
|
|
200
|
-
}
|
|
201
|
-
async freeze(secs) {
|
|
202
|
-
(0, helpers_1.assertArgsDefinedType)([secs], ['number'], 'ReplicaSet.freeze');
|
|
203
|
-
this._emitReplicaSetApiCall('freeze', { secs });
|
|
204
|
-
return this._database._runAdminCommand({
|
|
205
|
-
replSetFreeze: secs,
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
async stepDown(stepdownSecs, catchUpSecs) {
|
|
209
|
-
(0, helpers_1.assertArgsDefinedType)([stepdownSecs, catchUpSecs], [[undefined, 'number'], [undefined, 'number']], 'ReplicaSet.stepDown');
|
|
210
|
-
this._emitReplicaSetApiCall('stepDown', { stepdownSecs, catchUpSecs });
|
|
211
|
-
const cmd = {
|
|
212
|
-
replSetStepDown: stepdownSecs === undefined ? 60 : stepdownSecs,
|
|
213
|
-
};
|
|
214
|
-
if (catchUpSecs !== undefined) {
|
|
215
|
-
cmd.secondaryCatchUpPeriodSecs = catchUpSecs;
|
|
216
|
-
}
|
|
217
|
-
return this._database._runAdminCommand(cmd);
|
|
218
|
-
}
|
|
219
|
-
async syncFrom(host) {
|
|
220
|
-
(0, helpers_1.assertArgsDefinedType)([host], ['string'], 'ReplicaSet.syncFrom');
|
|
221
|
-
this._emitReplicaSetApiCall('syncFrom', { host });
|
|
222
|
-
return this._database._runAdminCommand({
|
|
223
|
-
replSetSyncFrom: host,
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
async secondaryOk() {
|
|
227
|
-
await this._mongo.setSecondaryOk();
|
|
228
|
-
}
|
|
229
|
-
[enums_1.asPrintable]() {
|
|
230
|
-
return `ReplicaSet class connected to ${(0, history_1.redactURICredentials)(this._database._mongo._uri)} via db ${this._database._name}`;
|
|
231
|
-
}
|
|
232
|
-
_emitReplicaSetApiCall(methodName, methodArguments = {}) {
|
|
233
|
-
this._database._mongo._instanceState.emitApiCallWithArgs({
|
|
234
|
-
method: methodName,
|
|
235
|
-
class: 'ReplicaSet',
|
|
236
|
-
arguments: methodArguments
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
};
|
|
240
|
-
__decorate([
|
|
241
|
-
decorators_1.returnsPromise
|
|
242
|
-
], ReplicaSet.prototype, "initiate", null);
|
|
243
|
-
__decorate([
|
|
244
|
-
decorators_1.returnsPromise,
|
|
245
|
-
(0, decorators_1.apiVersions)([1])
|
|
246
|
-
], ReplicaSet.prototype, "config", null);
|
|
247
|
-
__decorate([
|
|
248
|
-
decorators_1.returnsPromise,
|
|
249
|
-
(0, decorators_1.apiVersions)([1])
|
|
250
|
-
], ReplicaSet.prototype, "conf", null);
|
|
251
|
-
__decorate([
|
|
252
|
-
decorators_1.returnsPromise,
|
|
253
|
-
(0, decorators_1.apiVersions)([])
|
|
254
|
-
], ReplicaSet.prototype, "reconfig", null);
|
|
255
|
-
__decorate([
|
|
256
|
-
decorators_1.returnsPromise,
|
|
257
|
-
(0, decorators_1.apiVersions)([])
|
|
258
|
-
], ReplicaSet.prototype, "reconfigForPSASet", null);
|
|
259
|
-
__decorate([
|
|
260
|
-
decorators_1.returnsPromise,
|
|
261
|
-
(0, decorators_1.apiVersions)([])
|
|
262
|
-
], ReplicaSet.prototype, "status", null);
|
|
263
|
-
__decorate([
|
|
264
|
-
decorators_1.returnsPromise,
|
|
265
|
-
(0, decorators_1.apiVersions)([])
|
|
266
|
-
], ReplicaSet.prototype, "isMaster", null);
|
|
267
|
-
__decorate([
|
|
268
|
-
decorators_1.returnsPromise,
|
|
269
|
-
(0, decorators_1.apiVersions)([1])
|
|
270
|
-
], ReplicaSet.prototype, "hello", null);
|
|
271
|
-
__decorate([
|
|
272
|
-
decorators_1.returnsPromise,
|
|
273
|
-
(0, decorators_1.apiVersions)([])
|
|
274
|
-
], ReplicaSet.prototype, "printSecondaryReplicationInfo", null);
|
|
275
|
-
__decorate([
|
|
276
|
-
decorators_1.deprecated,
|
|
277
|
-
(0, decorators_1.apiVersions)([])
|
|
278
|
-
], ReplicaSet.prototype, "printSlaveReplicationInfo", null);
|
|
279
|
-
__decorate([
|
|
280
|
-
decorators_1.returnsPromise,
|
|
281
|
-
(0, decorators_1.apiVersions)([])
|
|
282
|
-
], ReplicaSet.prototype, "printReplicationInfo", null);
|
|
283
|
-
__decorate([
|
|
284
|
-
decorators_1.returnsPromise,
|
|
285
|
-
(0, decorators_1.apiVersions)([])
|
|
286
|
-
], ReplicaSet.prototype, "add", null);
|
|
287
|
-
__decorate([
|
|
288
|
-
decorators_1.returnsPromise,
|
|
289
|
-
(0, decorators_1.apiVersions)([])
|
|
290
|
-
], ReplicaSet.prototype, "addArb", null);
|
|
291
|
-
__decorate([
|
|
292
|
-
decorators_1.returnsPromise,
|
|
293
|
-
(0, decorators_1.apiVersions)([])
|
|
294
|
-
], ReplicaSet.prototype, "remove", null);
|
|
295
|
-
__decorate([
|
|
296
|
-
decorators_1.returnsPromise,
|
|
297
|
-
(0, decorators_1.apiVersions)([])
|
|
298
|
-
], ReplicaSet.prototype, "freeze", null);
|
|
299
|
-
__decorate([
|
|
300
|
-
decorators_1.returnsPromise,
|
|
301
|
-
(0, decorators_1.apiVersions)([])
|
|
302
|
-
], ReplicaSet.prototype, "stepDown", null);
|
|
303
|
-
__decorate([
|
|
304
|
-
decorators_1.returnsPromise,
|
|
305
|
-
(0, decorators_1.apiVersions)([])
|
|
306
|
-
], ReplicaSet.prototype, "syncFrom", null);
|
|
307
|
-
__decorate([
|
|
308
|
-
decorators_1.deprecated,
|
|
309
|
-
decorators_1.returnsPromise
|
|
310
|
-
], ReplicaSet.prototype, "secondaryOk", null);
|
|
311
|
-
ReplicaSet = __decorate([
|
|
312
|
-
decorators_1.shellApiClassDefault
|
|
313
|
-
], ReplicaSet);
|
|
314
|
-
exports.default = ReplicaSet;
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
const errors_1 = require("@qp-mongosh/errors");
|
|
10
|
+
const history_1 = require("@qp-mongosh/history");
|
|
11
|
+
const decorators_1 = require("./decorators");
|
|
12
|
+
const enums_1 = require("./enums");
|
|
13
|
+
const helpers_1 = require("./helpers");
|
|
14
|
+
let ReplicaSet = class ReplicaSet extends decorators_1.ShellApiWithMongoClass {
|
|
15
|
+
constructor(database) {
|
|
16
|
+
super();
|
|
17
|
+
this._database = database;
|
|
18
|
+
}
|
|
19
|
+
get _mongo() {
|
|
20
|
+
return this._database._mongo;
|
|
21
|
+
}
|
|
22
|
+
async initiate(config = {}) {
|
|
23
|
+
this._emitReplicaSetApiCall('initiate', { config });
|
|
24
|
+
return this._database._runAdminCommand({ replSetInitiate: config });
|
|
25
|
+
}
|
|
26
|
+
async _getConfig() {
|
|
27
|
+
try {
|
|
28
|
+
const result = await this._database._runAdminCommand({ replSetGetConfig: 1 });
|
|
29
|
+
if (result.config === undefined) {
|
|
30
|
+
throw new errors_1.MongoshRuntimeError('Documented returned from command replSetGetConfig does not contain \'config\'', errors_1.CommonErrors.CommandFailed);
|
|
31
|
+
}
|
|
32
|
+
return result.config;
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
if ((error === null || error === void 0 ? void 0 : error.codeName) === 'CommandNotFound' || (error === null || error === void 0 ? void 0 : error.codeName) === 'APIStrictError') {
|
|
36
|
+
const doc = await this._database.getSiblingDB('local').getCollection('system.replset').findOne();
|
|
37
|
+
if (doc === null) {
|
|
38
|
+
throw new errors_1.MongoshRuntimeError('No documents in local.system.replset', errors_1.CommonErrors.CommandFailed);
|
|
39
|
+
}
|
|
40
|
+
return doc;
|
|
41
|
+
}
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async config() {
|
|
46
|
+
this._emitReplicaSetApiCall('config', {});
|
|
47
|
+
return this._getConfig();
|
|
48
|
+
}
|
|
49
|
+
async conf() {
|
|
50
|
+
this._emitReplicaSetApiCall('conf', {});
|
|
51
|
+
return this._getConfig();
|
|
52
|
+
}
|
|
53
|
+
async reconfig(config, options = {}) {
|
|
54
|
+
(0, helpers_1.assertArgsDefinedType)([config, options], ['object', [undefined, 'object']], 'ReplicaSet.reconfig');
|
|
55
|
+
this._emitReplicaSetApiCall('reconfig', { config, options });
|
|
56
|
+
const runReconfig = async () => {
|
|
57
|
+
var _a;
|
|
58
|
+
const conf = await this._getConfig();
|
|
59
|
+
config.version = conf.version ? conf.version + 1 : 1;
|
|
60
|
+
(_a = config.protocolVersion) !== null && _a !== void 0 ? _a : (config.protocolVersion = conf.protocolVersion);
|
|
61
|
+
const cmd = { replSetReconfig: config, ...options };
|
|
62
|
+
return await this._database._runAdminCommand(cmd);
|
|
63
|
+
};
|
|
64
|
+
let result = ['success', {}];
|
|
65
|
+
let sleepInterval = 1000;
|
|
66
|
+
for (let i = 0; i < 12; i++) {
|
|
67
|
+
try {
|
|
68
|
+
if (result[0] === 'error') {
|
|
69
|
+
await this._instanceState.shellApi.sleep(sleepInterval);
|
|
70
|
+
sleepInterval *= 1.3;
|
|
71
|
+
if (sleepInterval > 2500) {
|
|
72
|
+
await this._instanceState.shellApi.print('Reconfig did not succeed yet, starting new attempt...');
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
result = ['success', await runReconfig()];
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
result = ['error', err];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
if (result[0] === 'error') {
|
|
83
|
+
throw result[1];
|
|
84
|
+
}
|
|
85
|
+
return result[1];
|
|
86
|
+
}
|
|
87
|
+
async reconfigForPSASet(newMemberIndex, config, options = {}) {
|
|
88
|
+
var _a;
|
|
89
|
+
(0, helpers_1.assertArgsDefinedType)([newMemberIndex, config, options], ['number', 'object', [undefined, 'object']], 'ReplicaSet.reconfigForPSASet');
|
|
90
|
+
this._emitReplicaSetApiCall('reconfigForPSASet', { newMemberIndex, config, options });
|
|
91
|
+
const print = (msg) => this._instanceState.shellApi.print(msg);
|
|
92
|
+
const newMemberConfig = (_a = config.members) === null || _a === void 0 ? void 0 : _a[newMemberIndex];
|
|
93
|
+
if (!newMemberConfig) {
|
|
94
|
+
throw new errors_1.MongoshInvalidInputError(`Node at index ${newMemberIndex} does not exist in the new config`, errors_1.CommonErrors.InvalidArgument);
|
|
95
|
+
}
|
|
96
|
+
if (newMemberConfig.votes !== 1) {
|
|
97
|
+
throw new errors_1.MongoshInvalidInputError(`Node at index ${newMemberIndex} must have { votes: 1 } in the new config (actual: { votes: ${newMemberConfig.votes} })`, errors_1.CommonErrors.InvalidArgument);
|
|
98
|
+
}
|
|
99
|
+
const oldConfig = await this._getConfig();
|
|
100
|
+
const oldMemberConfig = oldConfig.members.find(member => member._id === newMemberConfig._id);
|
|
101
|
+
if (!oldMemberConfig) {
|
|
102
|
+
if (oldConfig.members.find(member => member.host === newMemberConfig.host)) {
|
|
103
|
+
await print(`Warning: Node at index ${newMemberIndex} has { host: "${newMemberConfig.host}" }, ` +
|
|
104
|
+
'which is also present in the old config, but with a different _id field.');
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else if (oldMemberConfig.votes) {
|
|
108
|
+
throw new errors_1.MongoshInvalidInputError(`Node at index ${newMemberIndex} must have { votes: 0 } in the old config (actual: { votes: ${oldMemberConfig.votes} })`, errors_1.CommonErrors.InvalidArgument);
|
|
109
|
+
}
|
|
110
|
+
const newMemberPriority = newMemberConfig.priority;
|
|
111
|
+
await print(`Running first reconfig to give member at index ${newMemberIndex} { votes: 1, priority: 0 }`);
|
|
112
|
+
newMemberConfig.votes = 1;
|
|
113
|
+
newMemberConfig.priority = 0;
|
|
114
|
+
const firstResult = await this.reconfig(config, options);
|
|
115
|
+
if (newMemberPriority === 0) {
|
|
116
|
+
await print('No second reconfig necessary because .priority = 0');
|
|
117
|
+
return firstResult;
|
|
118
|
+
}
|
|
119
|
+
await print(`Running second reconfig to give member at index ${newMemberIndex} { priority: ${newMemberPriority} }`);
|
|
120
|
+
newMemberConfig.priority = newMemberPriority;
|
|
121
|
+
try {
|
|
122
|
+
return await this.reconfig(config, options);
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
await print('Second reconfig did not succeed, giving up');
|
|
126
|
+
await print(`Attempted command: rs.reconfig(${JSON.stringify(config, null, ' ')}, ${JSON.stringify(options)})`);
|
|
127
|
+
throw e;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async status() {
|
|
131
|
+
this._emitReplicaSetApiCall('status', {});
|
|
132
|
+
return this._database._runAdminCommand({
|
|
133
|
+
replSetGetStatus: 1,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
async isMaster() {
|
|
137
|
+
this._emitReplicaSetApiCall('isMaster', {});
|
|
138
|
+
return this._database.getSiblingDB('admin').isMaster();
|
|
139
|
+
}
|
|
140
|
+
async hello() {
|
|
141
|
+
this._emitReplicaSetApiCall('hello', {});
|
|
142
|
+
return this._database.getSiblingDB('admin').hello();
|
|
143
|
+
}
|
|
144
|
+
async printSecondaryReplicationInfo() {
|
|
145
|
+
this._emitReplicaSetApiCall('printSecondaryReplicationInfo', {});
|
|
146
|
+
return this._database.printSecondaryReplicationInfo();
|
|
147
|
+
}
|
|
148
|
+
printSlaveReplicationInfo() {
|
|
149
|
+
throw new errors_1.MongoshDeprecatedError('printSlaveReplicationInfo has been deprecated. Use printSecondaryReplicationInfo instead');
|
|
150
|
+
}
|
|
151
|
+
async printReplicationInfo() {
|
|
152
|
+
this._emitReplicaSetApiCall('printReplicationInfo', {});
|
|
153
|
+
return this._database.printReplicationInfo();
|
|
154
|
+
}
|
|
155
|
+
async add(hostport, arb) {
|
|
156
|
+
(0, helpers_1.assertArgsDefinedType)([hostport, arb], [['string', 'object'], [undefined, 'boolean']], 'ReplicaSet.add');
|
|
157
|
+
this._emitReplicaSetApiCall('add', { hostport, arb });
|
|
158
|
+
const configDoc = await this._getConfig();
|
|
159
|
+
configDoc.version++;
|
|
160
|
+
const max = Math.max(...configDoc.members.map(m => m._id));
|
|
161
|
+
let cfg;
|
|
162
|
+
if (typeof hostport === 'string') {
|
|
163
|
+
cfg = { _id: max + 1, host: hostport };
|
|
164
|
+
if (arb) {
|
|
165
|
+
cfg.arbiterOnly = true;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
else if (arb === true) {
|
|
169
|
+
throw new errors_1.MongoshInvalidInputError(`Expected first parameter to be a host-and-port string of arbiter, but got ${JSON.stringify(hostport)}`, errors_1.CommonErrors.InvalidArgument);
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
cfg = hostport;
|
|
173
|
+
if (cfg._id === null || cfg._id === undefined) {
|
|
174
|
+
cfg._id = max + 1;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
configDoc.members.push(cfg);
|
|
178
|
+
return this._database._runAdminCommand({
|
|
179
|
+
replSetReconfig: configDoc,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
async addArb(hostname) {
|
|
183
|
+
this._emitReplicaSetApiCall('addArb', { hostname });
|
|
184
|
+
return this.add(hostname, true);
|
|
185
|
+
}
|
|
186
|
+
async remove(hostname) {
|
|
187
|
+
(0, helpers_1.assertArgsDefinedType)([hostname], ['string'], 'ReplicaSet.remove');
|
|
188
|
+
this._emitReplicaSetApiCall('remove', { hostname });
|
|
189
|
+
const configDoc = await this._getConfig();
|
|
190
|
+
configDoc.version++;
|
|
191
|
+
for (let i = 0; i < configDoc.members.length; i++) {
|
|
192
|
+
if (configDoc.members[i].host === hostname) {
|
|
193
|
+
configDoc.members.splice(i, 1);
|
|
194
|
+
return this._database._runAdminCommand({
|
|
195
|
+
replSetReconfig: configDoc,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
throw new errors_1.MongoshInvalidInputError(`Couldn't find ${hostname} in ${JSON.stringify(configDoc.members)}. Is ${hostname} a member of this replset?`, errors_1.CommonErrors.InvalidArgument);
|
|
200
|
+
}
|
|
201
|
+
async freeze(secs) {
|
|
202
|
+
(0, helpers_1.assertArgsDefinedType)([secs], ['number'], 'ReplicaSet.freeze');
|
|
203
|
+
this._emitReplicaSetApiCall('freeze', { secs });
|
|
204
|
+
return this._database._runAdminCommand({
|
|
205
|
+
replSetFreeze: secs,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
async stepDown(stepdownSecs, catchUpSecs) {
|
|
209
|
+
(0, helpers_1.assertArgsDefinedType)([stepdownSecs, catchUpSecs], [[undefined, 'number'], [undefined, 'number']], 'ReplicaSet.stepDown');
|
|
210
|
+
this._emitReplicaSetApiCall('stepDown', { stepdownSecs, catchUpSecs });
|
|
211
|
+
const cmd = {
|
|
212
|
+
replSetStepDown: stepdownSecs === undefined ? 60 : stepdownSecs,
|
|
213
|
+
};
|
|
214
|
+
if (catchUpSecs !== undefined) {
|
|
215
|
+
cmd.secondaryCatchUpPeriodSecs = catchUpSecs;
|
|
216
|
+
}
|
|
217
|
+
return this._database._runAdminCommand(cmd);
|
|
218
|
+
}
|
|
219
|
+
async syncFrom(host) {
|
|
220
|
+
(0, helpers_1.assertArgsDefinedType)([host], ['string'], 'ReplicaSet.syncFrom');
|
|
221
|
+
this._emitReplicaSetApiCall('syncFrom', { host });
|
|
222
|
+
return this._database._runAdminCommand({
|
|
223
|
+
replSetSyncFrom: host,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
async secondaryOk() {
|
|
227
|
+
await this._mongo.setSecondaryOk();
|
|
228
|
+
}
|
|
229
|
+
[enums_1.asPrintable]() {
|
|
230
|
+
return `ReplicaSet class connected to ${(0, history_1.redactURICredentials)(this._database._mongo._uri)} via db ${this._database._name}`;
|
|
231
|
+
}
|
|
232
|
+
_emitReplicaSetApiCall(methodName, methodArguments = {}) {
|
|
233
|
+
this._database._mongo._instanceState.emitApiCallWithArgs({
|
|
234
|
+
method: methodName,
|
|
235
|
+
class: 'ReplicaSet',
|
|
236
|
+
arguments: methodArguments
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
__decorate([
|
|
241
|
+
decorators_1.returnsPromise
|
|
242
|
+
], ReplicaSet.prototype, "initiate", null);
|
|
243
|
+
__decorate([
|
|
244
|
+
decorators_1.returnsPromise,
|
|
245
|
+
(0, decorators_1.apiVersions)([1])
|
|
246
|
+
], ReplicaSet.prototype, "config", null);
|
|
247
|
+
__decorate([
|
|
248
|
+
decorators_1.returnsPromise,
|
|
249
|
+
(0, decorators_1.apiVersions)([1])
|
|
250
|
+
], ReplicaSet.prototype, "conf", null);
|
|
251
|
+
__decorate([
|
|
252
|
+
decorators_1.returnsPromise,
|
|
253
|
+
(0, decorators_1.apiVersions)([])
|
|
254
|
+
], ReplicaSet.prototype, "reconfig", null);
|
|
255
|
+
__decorate([
|
|
256
|
+
decorators_1.returnsPromise,
|
|
257
|
+
(0, decorators_1.apiVersions)([])
|
|
258
|
+
], ReplicaSet.prototype, "reconfigForPSASet", null);
|
|
259
|
+
__decorate([
|
|
260
|
+
decorators_1.returnsPromise,
|
|
261
|
+
(0, decorators_1.apiVersions)([])
|
|
262
|
+
], ReplicaSet.prototype, "status", null);
|
|
263
|
+
__decorate([
|
|
264
|
+
decorators_1.returnsPromise,
|
|
265
|
+
(0, decorators_1.apiVersions)([])
|
|
266
|
+
], ReplicaSet.prototype, "isMaster", null);
|
|
267
|
+
__decorate([
|
|
268
|
+
decorators_1.returnsPromise,
|
|
269
|
+
(0, decorators_1.apiVersions)([1])
|
|
270
|
+
], ReplicaSet.prototype, "hello", null);
|
|
271
|
+
__decorate([
|
|
272
|
+
decorators_1.returnsPromise,
|
|
273
|
+
(0, decorators_1.apiVersions)([])
|
|
274
|
+
], ReplicaSet.prototype, "printSecondaryReplicationInfo", null);
|
|
275
|
+
__decorate([
|
|
276
|
+
decorators_1.deprecated,
|
|
277
|
+
(0, decorators_1.apiVersions)([])
|
|
278
|
+
], ReplicaSet.prototype, "printSlaveReplicationInfo", null);
|
|
279
|
+
__decorate([
|
|
280
|
+
decorators_1.returnsPromise,
|
|
281
|
+
(0, decorators_1.apiVersions)([])
|
|
282
|
+
], ReplicaSet.prototype, "printReplicationInfo", null);
|
|
283
|
+
__decorate([
|
|
284
|
+
decorators_1.returnsPromise,
|
|
285
|
+
(0, decorators_1.apiVersions)([])
|
|
286
|
+
], ReplicaSet.prototype, "add", null);
|
|
287
|
+
__decorate([
|
|
288
|
+
decorators_1.returnsPromise,
|
|
289
|
+
(0, decorators_1.apiVersions)([])
|
|
290
|
+
], ReplicaSet.prototype, "addArb", null);
|
|
291
|
+
__decorate([
|
|
292
|
+
decorators_1.returnsPromise,
|
|
293
|
+
(0, decorators_1.apiVersions)([])
|
|
294
|
+
], ReplicaSet.prototype, "remove", null);
|
|
295
|
+
__decorate([
|
|
296
|
+
decorators_1.returnsPromise,
|
|
297
|
+
(0, decorators_1.apiVersions)([])
|
|
298
|
+
], ReplicaSet.prototype, "freeze", null);
|
|
299
|
+
__decorate([
|
|
300
|
+
decorators_1.returnsPromise,
|
|
301
|
+
(0, decorators_1.apiVersions)([])
|
|
302
|
+
], ReplicaSet.prototype, "stepDown", null);
|
|
303
|
+
__decorate([
|
|
304
|
+
decorators_1.returnsPromise,
|
|
305
|
+
(0, decorators_1.apiVersions)([])
|
|
306
|
+
], ReplicaSet.prototype, "syncFrom", null);
|
|
307
|
+
__decorate([
|
|
308
|
+
decorators_1.deprecated,
|
|
309
|
+
decorators_1.returnsPromise
|
|
310
|
+
], ReplicaSet.prototype, "secondaryOk", null);
|
|
311
|
+
ReplicaSet = __decorate([
|
|
312
|
+
decorators_1.shellApiClassDefault
|
|
313
|
+
], ReplicaSet);
|
|
314
|
+
exports.default = ReplicaSet;
|
|
315
315
|
//# sourceMappingURL=replica-set.js.map
|