@brunwig/mup-aws-beanstalk 0.8.3 → 0.8.5

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/lib/utils.js CHANGED
@@ -3,89 +3,70 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.logStep = logStep;
7
- exports.shouldRebuild = shouldRebuild;
8
- exports.tmpBuildPath = tmpBuildPath;
9
- exports.names = names;
10
- exports.createUniqueName = createUniqueName;
11
- exports.getLogs = getLogs;
12
- exports.getNodeVersion = getNodeVersion;
13
- exports.selectPlatformArn = selectPlatformArn;
14
6
  exports.attachPolicies = attachPolicies;
15
- exports.getAccountId = getAccountId;
16
- exports.ensureRoleExists = ensureRoleExists;
17
- exports.ensureInstanceProfileExists = ensureInstanceProfileExists;
18
- exports.ensureRoleAdded = ensureRoleAdded;
19
- exports.ensurePoliciesAttached = ensurePoliciesAttached;
20
- exports.ensureInlinePolicyAttached = ensureInlinePolicyAttached;
7
+ exports.coloredStatusText = coloredStatusText;
8
+ exports.connectToInstance = connectToInstance;
9
+ exports.createUniqueName = createUniqueName;
10
+ exports.createVersionDescription = createVersionDescription;
21
11
  exports.ensureBucketExists = ensureBucketExists;
22
- exports.findBucketWithPrefix = findBucketWithPrefix;
23
12
  exports.ensureBucketPolicyAttached = ensureBucketPolicyAttached;
24
13
  exports.ensureCloudWatchRule = ensureCloudWatchRule;
14
+ exports.ensureInlinePolicyAttached = ensureInlinePolicyAttached;
15
+ exports.ensureInstanceProfileExists = ensureInstanceProfileExists;
16
+ exports.ensurePoliciesAttached = ensurePoliciesAttached;
17
+ exports.ensureRoleAdded = ensureRoleAdded;
18
+ exports.ensureRoleExists = ensureRoleExists;
25
19
  exports.ensureRuleTargetExists = ensureRuleTargetExists;
26
- exports.coloredStatusText = coloredStatusText;
27
- exports.createVersionDescription = createVersionDescription;
28
20
  exports.ensureSsmDocument = ensureSsmDocument;
29
- exports.pickInstance = pickInstance;
30
- exports.connectToInstance = connectToInstance;
31
21
  exports.executeSSHCommand = executeSSHCommand;
32
-
22
+ exports.findBucketWithPrefix = findBucketWithPrefix;
23
+ exports.getAccountId = getAccountId;
24
+ exports.getLogs = getLogs;
25
+ exports.getNodeVersion = getNodeVersion;
26
+ exports.logStep = logStep;
27
+ exports.names = names;
28
+ exports.pickInstance = pickInstance;
29
+ exports.selectPlatformArn = selectPlatformArn;
30
+ exports.shouldRebuild = shouldRebuild;
31
+ exports.tmpBuildPath = tmpBuildPath;
33
32
  var _axios = _interopRequireDefault(require("axios"));
34
-
35
33
  var _chalk = _interopRequireDefault(require("chalk"));
36
-
37
34
  var _fs = _interopRequireDefault(require("fs"));
38
-
39
35
  var _lodash = require("lodash");
40
-
41
36
  var _os = _interopRequireDefault(require("os"));
42
-
43
37
  var _randomSeed = _interopRequireDefault(require("random-seed"));
44
-
45
38
  var _uuid = _interopRequireDefault(require("uuid"));
46
-
47
39
  var _child_process = require("child_process");
48
-
49
40
  var _aws = require("./aws");
50
-
51
41
  var _recheck = require("./recheck");
52
-
53
42
  var _envReady = require("./env-ready");
54
-
55
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
56
-
57
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
58
-
59
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
60
-
61
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
43
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
44
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
45
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
46
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
47
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
48
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
49
+ const pkg = require('../package.json'); // Adjust the path as needed
62
50
 
63
51
  function logStep(message) {
64
- console.log(_chalk.default.blue(message));
52
+ console.log(`v${pkg?.version} ${_chalk.default.blue(message)}`);
65
53
  }
66
-
67
54
  function shouldRebuild(bundlePath, useCachedBuild) {
68
55
  if (_fs.default.existsSync(bundlePath) && useCachedBuild) {
69
56
  return false;
70
57
  }
71
-
72
58
  return true;
73
59
  }
74
-
75
60
  function tmpBuildPath(appPath, api) {
76
61
  const rand = _randomSeed.default.create(appPath);
77
-
78
62
  const uuidNumbers = [];
79
-
80
63
  for (let i = 0; i < 16; i++) {
81
64
  uuidNumbers.push(rand(255));
82
65
  }
83
-
84
66
  return api.resolvePath(_os.default.tmpdir(), `mup-meteor-${_uuid.default.v4({
85
67
  random: uuidNumbers
86
68
  })}`);
87
69
  }
88
-
89
70
  function names(config) {
90
71
  const name = config.app.name.toLowerCase();
91
72
  return {
@@ -104,12 +85,10 @@ function names(config) {
104
85
  automationDocument: 'mup-graceful-shutdown'
105
86
  };
106
87
  }
107
-
108
88
  function createUniqueName(prefix = '') {
109
89
  const randomNumbers = Math.floor(Math.random() * 10000);
110
90
  return `${prefix}-${Date.now()}-${randomNumbers}`;
111
91
  }
112
-
113
92
  async function retrieveEnvironmentInfo(api, count) {
114
93
  const config = api.getConfig();
115
94
  const {
@@ -121,13 +100,11 @@ async function retrieveEnvironmentInfo(api, count) {
121
100
  EnvironmentName: environment,
122
101
  InfoType: 'tail'
123
102
  }).promise();
124
-
125
103
  if (EnvironmentInfo.length > 0) {
126
104
  return EnvironmentInfo;
127
105
  } else if (count > 5) {
128
106
  throw new Error('No logs');
129
107
  }
130
-
131
108
  return new Promise((resolve, reject) => {
132
109
  setTimeout(() => {
133
110
  // The logs aren't always available, so retry until they are
@@ -136,7 +113,6 @@ async function retrieveEnvironmentInfo(api, count) {
136
113
  }, (0, _recheck.getRecheckInterval)());
137
114
  });
138
115
  }
139
-
140
116
  async function getLogs(api, logNames) {
141
117
  const config = api.getConfig();
142
118
  const {
@@ -160,11 +136,9 @@ async function getLogs(api, logNames) {
160
136
  }) => {
161
137
  // The separator changed with Amazon Linux 2
162
138
  let parts = data.split('----------------------------------------\n/var/log/');
163
-
164
139
  if (parts.length === 1) {
165
140
  parts = data.split('-------------------------------------\n/var/log/');
166
141
  }
167
-
168
142
  data = logNames.map(name => parts.find(part => part.trim().startsWith(name)));
169
143
  resolve({
170
144
  data,
@@ -173,37 +147,30 @@ async function getLogs(api, logNames) {
173
147
  }).catch(reject);
174
148
  })));
175
149
  }
176
-
177
150
  function getNodeVersion(api, bundlePath) {
178
151
  let star = _fs.default.readFileSync(api.resolvePath(bundlePath, 'bundle/star.json')).toString();
179
-
180
152
  const nodeVersionTxt = _fs.default.readFileSync(api.resolvePath(bundlePath, 'bundle/.node_version.txt')).toString();
181
-
182
153
  star = JSON.parse(star);
183
-
184
154
  if (star.npmVersion) {
185
155
  return {
186
156
  nodeVersion: star.nodeVersion,
187
157
  npmVersion: star.npmVersion
188
158
  };
189
159
  }
190
-
191
160
  const nodeVersion = nodeVersionTxt.substr(1);
192
-
193
161
  if (nodeVersion.startsWith('4')) {
194
162
  return {
195
163
  nodeVersion,
196
164
  npmVersion: '4.6.1'
197
165
  };
198
166
  }
199
-
200
167
  return {
201
168
  nodeVersion,
202
169
  npmVersion: '3.10.5'
203
170
  };
204
171
  }
205
-
206
172
  async function selectPlatformArn(awsPlatformBranchName) {
173
+ console.log('----> Amazon BranchName:', awsPlatformBranchName);
207
174
  const {
208
175
  PlatformBranchSummaryList
209
176
  } = await _aws.beanstalk.listPlatformBranches({
@@ -221,11 +188,9 @@ async function selectPlatformArn(awsPlatformBranchName) {
221
188
  Values: [awsPlatformBranchName]
222
189
  }]
223
190
  }).promise();
224
-
225
191
  if (PlatformBranchSummaryList.length === 0) {
226
192
  throw new Error('Unable to find supported Node.js platform');
227
193
  }
228
-
229
194
  const branchName = PlatformBranchSummaryList[0].BranchName;
230
195
  console.log('----> Amazon Platform:', branchName);
231
196
  const {
@@ -245,7 +210,6 @@ async function selectPlatformArn(awsPlatformBranchName) {
245
210
  console.log('----> Amazon ARN:', arn);
246
211
  return arn;
247
212
  }
248
-
249
213
  async function attachPolicies(config, roleName, policies) {
250
214
  const promises = [];
251
215
  policies.forEach(policy => {
@@ -253,39 +217,33 @@ async function attachPolicies(config, roleName, policies) {
253
217
  RoleName: roleName,
254
218
  PolicyArn: policy
255
219
  }).promise();
256
-
257
220
  promises.push(promise);
258
221
  });
259
222
  await Promise.all(promises);
260
223
  }
261
-
262
224
  function getAccountId() {
263
225
  return _aws.sts.getCallerIdentity().promise().then(({
264
226
  Account
265
227
  }) => Account);
266
228
  }
267
-
268
229
  async function ensureRoleExists(name, assumeRolePolicyDocument, ensureAssumeRolePolicy) {
269
230
  let exists = true;
270
231
  let updateAssumeRolePolicy = false;
271
-
272
232
  try {
273
233
  const {
274
234
  Role
275
235
  } = await _aws.iam.getRole({
276
236
  RoleName: name
277
237
  }).promise();
278
- const currentAssumeRolePolicy = decodeURIComponent(Role.AssumeRolePolicyDocument); // Make the whitespace consistent with the current document
279
-
238
+ const currentAssumeRolePolicy = decodeURIComponent(Role.AssumeRolePolicyDocument);
239
+ // Make the whitespace consistent with the current document
280
240
  assumeRolePolicyDocument = JSON.stringify(JSON.parse(assumeRolePolicyDocument));
281
-
282
241
  if (currentAssumeRolePolicy !== assumeRolePolicyDocument && ensureAssumeRolePolicy) {
283
242
  updateAssumeRolePolicy = true;
284
243
  }
285
244
  } catch (e) {
286
245
  exists = false;
287
246
  }
288
-
289
247
  if (!exists) {
290
248
  await _aws.iam.createRole({
291
249
  RoleName: name,
@@ -298,10 +256,8 @@ async function ensureRoleExists(name, assumeRolePolicyDocument, ensureAssumeRole
298
256
  }).promise();
299
257
  }
300
258
  }
301
-
302
259
  async function ensureInstanceProfileExists(config, name) {
303
260
  let exists = true;
304
-
305
261
  try {
306
262
  await _aws.iam.getInstanceProfile({
307
263
  InstanceProfileName: name
@@ -309,14 +265,12 @@ async function ensureInstanceProfileExists(config, name) {
309
265
  } catch (e) {
310
266
  exists = false;
311
267
  }
312
-
313
268
  if (!exists) {
314
269
  await _aws.iam.createInstanceProfile({
315
270
  InstanceProfileName: name
316
271
  }).promise();
317
272
  }
318
273
  }
319
-
320
274
  async function ensureRoleAdded(config, instanceProfile, role) {
321
275
  let added = true;
322
276
  const {
@@ -324,11 +278,9 @@ async function ensureRoleAdded(config, instanceProfile, role) {
324
278
  } = await _aws.iam.getInstanceProfile({
325
279
  InstanceProfileName: instanceProfile
326
280
  }).promise();
327
-
328
281
  if (InstanceProfile.Roles.length === 0 || InstanceProfile.Roles[0].RoleName !== role) {
329
282
  added = false;
330
283
  }
331
-
332
284
  if (!added) {
333
285
  await _aws.iam.addRoleToInstanceProfile({
334
286
  InstanceProfileName: instanceProfile,
@@ -336,7 +288,6 @@ async function ensureRoleAdded(config, instanceProfile, role) {
336
288
  }).promise();
337
289
  }
338
290
  }
339
-
340
291
  async function ensurePoliciesAttached(config, role, policies) {
341
292
  let {
342
293
  AttachedPolicies
@@ -348,33 +299,27 @@ async function ensurePoliciesAttached(config, role, policies) {
348
299
  if (AttachedPolicies.indexOf(policy) === -1) {
349
300
  result.push(policy);
350
301
  }
351
-
352
302
  return result;
353
303
  }, []);
354
-
355
304
  if (unattachedPolicies.length > 0) {
356
305
  await attachPolicies(config, role, unattachedPolicies);
357
306
  }
358
307
  }
359
-
360
308
  async function ensureInlinePolicyAttached(role, policyName, policyDocument) {
361
309
  let exists = true;
362
310
  let needsUpdating = false;
363
-
364
311
  try {
365
312
  const result = await _aws.iam.getRolePolicy({
366
313
  RoleName: role,
367
314
  PolicyName: policyName
368
315
  }).promise();
369
316
  const currentPolicyDocument = decodeURIComponent(result.PolicyDocument);
370
-
371
317
  if (currentPolicyDocument !== policyDocument) {
372
318
  needsUpdating = true;
373
319
  }
374
320
  } catch (e) {
375
321
  exists = false;
376
322
  }
377
-
378
323
  if (!exists || needsUpdating) {
379
324
  await _aws.iam.putRolePolicy({
380
325
  RoleName: role,
@@ -383,7 +328,6 @@ async function ensureInlinePolicyAttached(role, policyName, policyDocument) {
383
328
  }).promise();
384
329
  }
385
330
  }
386
-
387
331
  async function ensureBucketExists(buckets, bucketName, region) {
388
332
  if (!buckets.find(bucket => bucket.Name === bucketName)) {
389
333
  await _aws.s3.createBucket(_objectSpread({
@@ -396,15 +340,12 @@ async function ensureBucketExists(buckets, bucketName, region) {
396
340
  return true;
397
341
  }
398
342
  }
399
-
400
343
  function findBucketWithPrefix(buckets, prefix) {
401
344
  return buckets.find(bucket => bucket.Name.indexOf(prefix) === 0);
402
345
  }
403
-
404
346
  async function ensureBucketPolicyAttached(bucketName, policy) {
405
347
  let error = false;
406
348
  let currentPolicy;
407
-
408
349
  try {
409
350
  const {
410
351
  Policy
@@ -415,7 +356,6 @@ async function ensureBucketPolicyAttached(bucketName, policy) {
415
356
  } catch (e) {
416
357
  error = true;
417
358
  }
418
-
419
359
  if (error || currentPolicy !== policy) {
420
360
  const params = {
421
361
  Bucket: bucketName,
@@ -424,10 +364,8 @@ async function ensureBucketPolicyAttached(bucketName, policy) {
424
364
  await _aws.s3.putBucketPolicy(params).promise();
425
365
  }
426
366
  }
427
-
428
367
  async function ensureCloudWatchRule(name, description, eventPattern) {
429
368
  let error = false;
430
-
431
369
  try {
432
370
  await _aws.cloudWatchEvents.describeRule({
433
371
  Name: name
@@ -435,7 +373,6 @@ async function ensureCloudWatchRule(name, description, eventPattern) {
435
373
  } catch (e) {
436
374
  error = true;
437
375
  }
438
-
439
376
  if (error) {
440
377
  await _aws.cloudWatchEvents.putRule({
441
378
  Name: name,
@@ -444,17 +381,14 @@ async function ensureCloudWatchRule(name, description, eventPattern) {
444
381
  }).promise();
445
382
  return true;
446
383
  }
447
-
448
384
  return false;
449
385
  }
450
-
451
386
  async function ensureRuleTargetExists(ruleName, target) {
452
387
  const {
453
388
  Targets
454
389
  } = await _aws.cloudWatchEvents.listTargetsByRule({
455
390
  Rule: ruleName
456
391
  }).promise();
457
-
458
392
  if (!Targets.find(_target => (0, _lodash.isEqual)(_target, target))) {
459
393
  const params = {
460
394
  Rule: ruleName,
@@ -464,7 +398,6 @@ async function ensureRuleTargetExists(ruleName, target) {
464
398
  return true;
465
399
  }
466
400
  }
467
-
468
401
  function coloredStatusText(envColor, text) {
469
402
  if (envColor === 'Green') {
470
403
  return _chalk.default.green(text);
@@ -473,14 +406,11 @@ function coloredStatusText(envColor, text) {
473
406
  } else if (envColor === 'Red') {
474
407
  return _chalk.default.red(text);
475
408
  }
476
-
477
409
  return text;
478
410
  }
479
-
480
411
  function createVersionDescription(api, appConfig) {
481
412
  const appPath = api.resolvePath(api.getBasePath(), appConfig.path);
482
413
  let description = '';
483
-
484
414
  try {
485
415
  description = (0, _child_process.execSync)('git log -1 --pretty=%B', {
486
416
  cwd: appPath,
@@ -489,30 +419,25 @@ function createVersionDescription(api, appConfig) {
489
419
  } catch (e) {
490
420
  description = `Deployed by Mup on ${new Date().toUTCString()}`;
491
421
  }
492
-
493
422
  return description.split('\n')[0].slice(0, 195);
494
423
  }
495
-
496
424
  async function ensureSsmDocument(name, content) {
497
425
  let exists = true;
498
426
  let needsUpdating = false;
499
-
500
427
  try {
501
428
  const result = await _aws.ssm.getDocument({
502
429
  Name: name,
503
430
  DocumentVersion: '$DEFAULT'
504
- }).promise(); // If the document was created or edited on the AWS console, there is extra new
431
+ }).promise();
432
+ // If the document was created or edited on the AWS console, there is extra new
505
433
  // line characters and whitespace
506
-
507
434
  const currentContent = JSON.stringify(JSON.parse(result.Content.replace(/\r?\n|\r/g, '')));
508
-
509
435
  if (currentContent !== content) {
510
436
  needsUpdating = true;
511
437
  }
512
438
  } catch (e) {
513
439
  exists = false;
514
440
  }
515
-
516
441
  if (!exists) {
517
442
  await _aws.ssm.createDocument({
518
443
  Content: content,
@@ -535,7 +460,6 @@ async function ensureSsmDocument(name, content) {
535
460
  throw e;
536
461
  }
537
462
  }
538
-
539
463
  const result = await _aws.ssm.getDocument({
540
464
  Name: name,
541
465
  DocumentVersion: '$LATEST'
@@ -546,7 +470,6 @@ async function ensureSsmDocument(name, content) {
546
470
  }).promise();
547
471
  }
548
472
  }
549
-
550
473
  async function pickInstance(config, instance) {
551
474
  const {
552
475
  environment
@@ -565,18 +488,15 @@ async function pickInstance(config, instance) {
565
488
  description
566
489
  };
567
490
  }
568
-
569
491
  async function connectToInstance(api, instanceId, commandLabel) {
570
492
  const {
571
493
  sshKey
572
494
  } = api.getConfig().app;
573
-
574
495
  if (!sshKey) {
575
496
  const error = new Error('missing sshKey config');
576
497
  error.solution = 'Learn how to configure sshKey at https://github.com/zodern/mup-aws-beanstalk/blob/master/docs/index.md#meteor-shell-and-debug';
577
498
  throw error;
578
499
  }
579
-
580
500
  const {
581
501
  Reservations
582
502
  } = await _aws.ec2.describeInstances({
@@ -589,13 +509,10 @@ async function connectToInstance(api, instanceId, commandLabel) {
589
509
  data: ipAddress
590
510
  } = await _axios.default.get('https://ipv4.icanhazip.com');
591
511
  ipAddress = ipAddress.trim();
592
-
593
512
  if (securityGroups.length > 1) {
594
513
  console.warn('Instance has more than one security group. Please open a GitHub issue for mup-aws-beanstalk');
595
514
  }
596
-
597
515
  let ruleIds = [];
598
-
599
516
  try {
600
517
  const {
601
518
  SecurityGroupRules
@@ -613,14 +530,14 @@ async function connectToInstance(api, instanceId, commandLabel) {
613
530
  }).promise();
614
531
  ruleIds = SecurityGroupRules.map(rule => rule.SecurityGroupRuleId);
615
532
  } catch (e) {
616
- if (e.code === 'InvalidPermission.Duplicate') {// This rule already exists
533
+ if (e.code === 'InvalidPermission.Duplicate') {
534
+ // This rule already exists
617
535
  // TODO: should we find the rule id so we can remove it, or leave it in
618
536
  // case the user had manually added this rule?
619
537
  } else {
620
538
  throw e;
621
539
  }
622
540
  }
623
-
624
541
  await _aws.ec2InstanceConnect.sendSSHPublicKey({
625
542
  InstanceId: instanceId,
626
543
  AvailabilityZone: availabilityZone,
@@ -635,22 +552,18 @@ async function connectToInstance(api, instanceId, commandLabel) {
635
552
  };
636
553
  return {
637
554
  sshOptions,
638
-
639
555
  removeSSHAccess() {
640
556
  if (ruleIds.length === 0) {
641
557
  return;
642
558
  }
643
-
644
559
  console.log('Removing temporary security group rule for SSH');
645
560
  return _aws.ec2.revokeSecurityGroupIngress({
646
561
  GroupId: securityGroups[0],
647
562
  SecurityGroupRuleIds: ruleIds
648
563
  }).promise();
649
564
  }
650
-
651
565
  };
652
566
  }
653
-
654
567
  async function executeSSHCommand(conn, command) {
655
568
  return new Promise((resolve, reject) => {
656
569
  conn.exec(command, (err, outputStream) => {
@@ -659,7 +572,6 @@ async function executeSSHCommand(conn, command) {
659
572
  reject(err);
660
573
  return;
661
574
  }
662
-
663
575
  let output = '';
664
576
  outputStream.on('data', data => {
665
577
  output += data;