@brunwig/mup-aws-beanstalk 0.8.6 → 2.0.3

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.
Files changed (57) hide show
  1. package/.babelrc +15 -4
  2. package/.eslintrc.yml +2 -2
  3. package/.yarn/install-state.gz +0 -0
  4. package/docs/getting-started.md +1 -1
  5. package/docs/index.md +22 -6
  6. package/index.js +1 -1
  7. package/lib/assets/Procfile +1 -0
  8. package/lib/assets/health-check.js +9 -1
  9. package/lib/assets/health-check.js.map +1 -1
  10. package/lib/assets/nginx-server.conf +14 -0
  11. package/lib/assets/nginx.conf +6 -0
  12. package/lib/assets/node.sh +37 -7
  13. package/lib/assets/npm.sh +14 -0
  14. package/lib/assets/prevent-npm.sh +4 -0
  15. package/lib/assets/role-start.sh +61 -0
  16. package/lib/assets/start.sh +1 -1
  17. package/lib/assets/yarn.sh +17 -0
  18. package/lib/aws.js +43 -77
  19. package/lib/aws.js.map +1 -1
  20. package/lib/certificates.js +56 -53
  21. package/lib/certificates.js.map +1 -1
  22. package/lib/command-handlers.js +615 -634
  23. package/lib/command-handlers.js.map +1 -1
  24. package/lib/commands.js +144 -106
  25. package/lib/commands.js.map +1 -1
  26. package/lib/deployment-logs.js +127 -0
  27. package/lib/deployment-logs.js.map +1 -0
  28. package/lib/download.js +11 -18
  29. package/lib/download.js.map +1 -1
  30. package/lib/eb-config.js +246 -242
  31. package/lib/eb-config.js.map +1 -1
  32. package/lib/env-ready.js +87 -88
  33. package/lib/env-ready.js.map +1 -1
  34. package/lib/env-settings.js +13 -14
  35. package/lib/env-settings.js.map +1 -1
  36. package/lib/index.js +111 -81
  37. package/lib/index.js.map +1 -1
  38. package/lib/policies.js +130 -115
  39. package/lib/policies.js.map +1 -1
  40. package/lib/prepare-bundle.js +187 -194
  41. package/lib/prepare-bundle.js.map +1 -1
  42. package/lib/recheck.js +16 -13
  43. package/lib/recheck.js.map +1 -1
  44. package/lib/tsconfig.tsbuildinfo +1 -0
  45. package/lib/types.js +3 -0
  46. package/lib/types.js.map +1 -0
  47. package/lib/upload.js +35 -49
  48. package/lib/upload.js.map +1 -1
  49. package/lib/utils.js +561 -529
  50. package/lib/utils.js.map +1 -1
  51. package/lib/validate.js +61 -59
  52. package/lib/validate.js.map +1 -1
  53. package/lib/versions.js +74 -81
  54. package/lib/versions.js.map +1 -1
  55. package/package.json +60 -26
  56. package/readme.md +2 -1
  57. package/tsconfig.json +41 -0
package/lib/utils.js CHANGED
@@ -1,592 +1,624 @@
1
1
  "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.attachPolicies = attachPolicies;
7
- exports.coloredStatusText = coloredStatusText;
8
- exports.connectToInstance = connectToInstance;
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.logStep = logStep;
7
+ exports.logStreamEvent = logStreamEvent;
8
+ exports.shouldRebuild = shouldRebuild;
9
+ exports.tmpBuildPath = tmpBuildPath;
10
+ exports.names = names;
9
11
  exports.createUniqueName = createUniqueName;
10
- exports.createVersionDescription = createVersionDescription;
12
+ exports.getLogs = getLogs;
13
+ exports.downloadFullServerLogs = downloadFullServerLogs;
14
+ exports.getNodeVersion = getNodeVersion;
15
+ exports.selectPlatformArn = selectPlatformArn;
16
+ exports.attachPolicies = attachPolicies;
17
+ exports.getAccountId = getAccountId;
18
+ exports.ensureRoleExists = ensureRoleExists;
19
+ exports.ensureInstanceProfileExists = ensureInstanceProfileExists;
20
+ exports.ensureRoleAdded = ensureRoleAdded;
21
+ exports.ensurePoliciesAttached = ensurePoliciesAttached;
22
+ exports.ensureInlinePolicyAttached = ensureInlinePolicyAttached;
11
23
  exports.ensureBucketExists = ensureBucketExists;
24
+ exports.findBucketWithPrefix = findBucketWithPrefix;
12
25
  exports.ensureBucketPolicyAttached = ensureBucketPolicyAttached;
13
26
  exports.ensureCloudWatchRule = ensureCloudWatchRule;
14
- exports.ensureInlinePolicyAttached = ensureInlinePolicyAttached;
15
- exports.ensureInstanceProfileExists = ensureInstanceProfileExists;
16
- exports.ensurePoliciesAttached = ensurePoliciesAttached;
17
- exports.ensureRoleAdded = ensureRoleAdded;
18
- exports.ensureRoleExists = ensureRoleExists;
19
27
  exports.ensureRuleTargetExists = ensureRuleTargetExists;
28
+ exports.coloredStatusText = coloredStatusText;
29
+ exports.createVersionDescription = createVersionDescription;
20
30
  exports.ensureSsmDocument = ensureSsmDocument;
21
- exports.executeSSHCommand = executeSSHCommand;
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
31
  exports.pickInstance = pickInstance;
29
- exports.selectPlatformArn = selectPlatformArn;
30
- exports.shouldRebuild = shouldRebuild;
31
- exports.tmpBuildPath = tmpBuildPath;
32
- var _axios = _interopRequireDefault(require("axios"));
33
- var _chalk = _interopRequireDefault(require("chalk"));
34
- var _fs = _interopRequireDefault(require("fs"));
35
- var _lodash = require("lodash");
36
- var _os = _interopRequireDefault(require("os"));
37
- var _randomSeed = _interopRequireDefault(require("random-seed"));
38
- var _uuid = _interopRequireDefault(require("uuid"));
39
- var _child_process = require("child_process");
40
- var _aws = require("./aws");
41
- var _recheck = require("./recheck");
42
- var _envReady = require("./env-ready");
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); }
32
+ exports.connectToInstance = connectToInstance;
33
+ exports.executeSSHCommand = executeSSHCommand;
34
+ const axios_1 = __importDefault(require("axios"));
35
+ const chalk_1 = __importDefault(require("chalk"));
36
+ const fs_1 = __importDefault(require("fs"));
37
+ const path_1 = __importDefault(require("path"));
38
+ const lodash_1 = require("lodash");
39
+ const os_1 = __importDefault(require("os"));
40
+ const random_seed_1 = __importDefault(require("random-seed"));
41
+ const uuid_1 = require("uuid");
42
+ const child_process_1 = require("child_process");
43
+ const aws_1 = require("./aws");
44
+ const recheck_1 = require("./recheck");
45
+ const env_ready_1 = require("./env-ready");
49
46
  const pkg = require('../package.json'); // Adjust the path as needed
50
-
51
47
  function logStep(message) {
52
- console.log(`v${pkg?.version} ${_chalk.default.blue(message)}`);
48
+ console.log(`v${pkg === null || pkg === void 0 ? void 0 : pkg.version} ${chalk_1.default.blue(message)}`);
49
+ }
50
+ function logStreamEvent(message) {
51
+ console.log(chalk_1.default.dim(message));
53
52
  }
54
53
  function shouldRebuild(bundlePath, useCachedBuild) {
55
- if (_fs.default.existsSync(bundlePath) && useCachedBuild) {
56
- return false;
57
- }
58
- return true;
54
+ if (fs_1.default.existsSync(bundlePath) && useCachedBuild) {
55
+ return false;
56
+ }
57
+ return true;
59
58
  }
60
59
  function tmpBuildPath(appPath, api) {
61
- const rand = _randomSeed.default.create(appPath);
62
- const uuidNumbers = [];
63
- for (let i = 0; i < 16; i++) {
64
- uuidNumbers.push(rand(255));
65
- }
66
- return api.resolvePath(_os.default.tmpdir(), `mup-meteor-${_uuid.default.v4({
67
- random: uuidNumbers
68
- })}`);
60
+ const rand = random_seed_1.default.create(appPath);
61
+ const uuidNumbers = [];
62
+ for (let i = 0; i < 16; i++) {
63
+ uuidNumbers.push(rand(255));
64
+ }
65
+ return api.resolvePath(os_1.default.tmpdir(), `mup-meteor-${(0, uuid_1.v4)({ random: uuidNumbers })}`);
69
66
  }
70
67
  function names(config) {
71
- const name = config.app.name.toLowerCase();
72
- return {
73
- bucket: `mup-${name}`,
74
- environment: config.app.envName || `mup-env-${name}`,
75
- app: `mup-${name}`,
76
- bundlePrefix: `mup/bundles/${name}/`,
77
- instanceProfile: 'aws-elasticbeanstalk-ec2-role',
78
- serviceRole: 'aws-elasticbeanstalk-service-role',
79
- trailBucketPrefix: 'mup-graceful-shutdown-trail',
80
- trailName: 'mup-graceful-shutdown-trail',
81
- deregisterRuleName: 'mup-target-deregister',
82
- eventTargetRole: `mup-envoke-run-command-${name}`,
83
- eventTargetPolicyName: 'Invoke_Run_Command',
84
- eventTargetPassRoleName: 'Pass_Role',
85
- automationDocument: 'mup-graceful-shutdown'
86
- };
68
+ const name = config.app.name.toLowerCase();
69
+ return {
70
+ bucket: `mup-${name}`,
71
+ environment: config.app.envName || `mup-env-${name}`,
72
+ app: `mup-${name}`,
73
+ bundlePrefix: `mup/bundles/${name}/`,
74
+ instanceProfile: 'aws-elasticbeanstalk-ec2-role',
75
+ serviceRole: 'aws-elasticbeanstalk-service-role',
76
+ trailBucketPrefix: 'mup-graceful-shutdown-trail',
77
+ trailName: 'mup-graceful-shutdown-trail',
78
+ deregisterRuleName: 'mup-target-deregister',
79
+ eventTargetRole: `mup-envoke-run-command-${name}`,
80
+ eventTargetPolicyName: 'Invoke_Run_Command',
81
+ eventTargetPassRoleName: 'Pass_Role',
82
+ automationDocument: 'mup-graceful-shutdown'
83
+ };
87
84
  }
88
85
  function createUniqueName(prefix = '') {
89
- const randomNumbers = Math.floor(Math.random() * 10000);
90
- return `${prefix}-${Date.now()}-${randomNumbers}`;
86
+ const randomNumbers = Math.floor(Math.random() * 10000);
87
+ return `${prefix}-${Date.now()}-${randomNumbers}`;
91
88
  }
92
- async function retrieveEnvironmentInfo(api, count) {
93
- const config = api.getConfig();
94
- const {
95
- environment
96
- } = names(config);
97
- const {
98
- EnvironmentInfo
99
- } = await _aws.beanstalk.retrieveEnvironmentInfo({
100
- EnvironmentName: environment,
101
- InfoType: 'tail'
102
- }).promise();
103
- if (EnvironmentInfo.length > 0) {
104
- return EnvironmentInfo;
105
- } else if (count > 5) {
106
- throw new Error('No logs');
107
- }
108
- return new Promise((resolve, reject) => {
109
- setTimeout(() => {
110
- // The logs aren't always available, so retry until they are
111
- // Another option is to look for the event that says it is ready
112
- retrieveEnvironmentInfo(api, count + 1).then(resolve).catch(reject);
113
- }, (0, _recheck.getRecheckInterval)());
114
- });
89
+ async function retrieveEnvironmentInfo(api, count, requestTime = new Date(Date.now() - 60 * 60 * 1000), infoType = 'tail') {
90
+ const config = api.getConfig();
91
+ const { environment } = names(config);
92
+ const { EnvironmentInfo } = await aws_1.beanstalk.retrieveEnvironmentInfo({
93
+ EnvironmentName: environment,
94
+ InfoType: infoType
95
+ });
96
+ if (EnvironmentInfo && EnvironmentInfo.length > 0) {
97
+ // Filter logs by the initial request timestamp
98
+ const newestEntries = EnvironmentInfo.filter((log) => {
99
+ const sampeDate = new Date(log.SampleTimestamp);
100
+ // console.log(' - ', count, sampeDate >= requestTime, sampeDate" - ", requestTime);
101
+ return sampeDate >= requestTime;
102
+ });
103
+ return newestEntries;
104
+ }
105
+ else if (count > 5) {
106
+ throw new Error('No logs');
107
+ }
108
+ return new Promise((resolve, reject) => {
109
+ setTimeout(() => {
110
+ logStep(` - retrieveEnvironmentInfo retry [${count}]`);
111
+ // The logs aren't always available, so retry until they are
112
+ // Another option is to look for the event that says it is ready
113
+ retrieveEnvironmentInfo(api, count + 1, requestTime, infoType)
114
+ .then(resolve)
115
+ .catch(reject);
116
+ }, (0, recheck_1.getRecheckInterval)());
117
+ });
115
118
  }
116
119
  async function getLogs(api, logNames) {
117
- const config = api.getConfig();
118
- const {
119
- environment
120
- } = names(config);
121
- await (0, _envReady.waitForEnvReady)(config, false);
122
- logStep('=> Requesting Logs');
123
- await _aws.beanstalk.requestEnvironmentInfo({
124
- EnvironmentName: environment,
125
- InfoType: 'tail'
126
- }).promise();
127
- const EnvironmentInfo = await retrieveEnvironmentInfo(api, 0);
128
- logStep('=> Downloading Logs');
129
- const logsForServer = EnvironmentInfo.reduce((result, info) => {
130
- result[info.Ec2InstanceId] = info.Message;
131
- return result;
132
- }, {});
133
- return Promise.all(Object.keys(logsForServer).map(key => new Promise((resolve, reject) => {
134
- _axios.default.get(logsForServer[key]).then(({
135
- data
136
- }) => {
137
- // The separator changed with Amazon Linux 2
138
- let parts = data.split('----------------------------------------\n/var/log/');
139
- if (parts.length === 1) {
140
- parts = data.split('-------------------------------------\n/var/log/');
141
- }
142
- data = logNames.map(name => parts.find(part => part.trim().startsWith(name)));
143
- resolve({
144
- data,
145
- instance: key
146
- });
147
- }).catch(reject);
148
- })));
120
+ const config = api.getConfig();
121
+ const { environment } = names(config);
122
+ await (0, env_ready_1.waitForEnvReady)(config, false);
123
+ logStep('=> Requesting Logs');
124
+ await aws_1.beanstalk.requestEnvironmentInfo({
125
+ EnvironmentName: environment,
126
+ InfoType: 'tail'
127
+ });
128
+ const EnvironmentInfo = await retrieveEnvironmentInfo(api, 0);
129
+ logStep('=> Downloading Logs');
130
+ const logsForServer = EnvironmentInfo && EnvironmentInfo.reduce((result, { Ec2InstanceId, Message }) => {
131
+ if ((0, lodash_1.isString)(Ec2InstanceId)) {
132
+ result[Ec2InstanceId] = Message;
133
+ }
134
+ return result;
135
+ }, {});
136
+ return Promise.all(Object.keys(logsForServer).map(key => new Promise((resolve, reject) => {
137
+ axios_1.default.get(logsForServer[key]).then(({ data }) => {
138
+ // The separator changed with Amazon Linux 2
139
+ let parts = data.split('----------------------------------------\n/var/log/');
140
+ if (parts.length === 1) {
141
+ parts = data.split('-------------------------------------\n/var/log/');
142
+ }
143
+ const logParts = logNames.map(name => parts.find(part => part.trim().startsWith(name)) || '');
144
+ resolve({
145
+ data: logParts,
146
+ instance: key
147
+ });
148
+ }).catch(reject);
149
+ })));
150
+ }
151
+ async function downloadFullServerLogs(api) {
152
+ const config = api.getConfig();
153
+ const { environment } = names(config);
154
+ // Ensure the logs folder exists
155
+ const logsFolder = './fullLogs/';
156
+ if (!fs_1.default.existsSync(logsFolder)) {
157
+ fs_1.default.mkdirSync(logsFolder);
158
+ }
159
+ await (0, env_ready_1.waitForEnvReady)(config, false);
160
+ // Record the time of the request
161
+ const requestTime = new Date();
162
+ logStep('=> Requesting FullServerLogs');
163
+ await aws_1.beanstalk.requestEnvironmentInfo({
164
+ EnvironmentName: environment,
165
+ InfoType: 'bundle' // Request full logs instead of just the tail
166
+ });
167
+ const latestData = await retrieveEnvironmentInfo(api, 0, requestTime, 'bundle');
168
+ logStep('=> Downloading Logs Bundle');
169
+ if (!latestData) {
170
+ throw new Error('No logs bundle found.');
171
+ }
172
+ const filePaths = Promise.allSettled(latestData.map(async (bundleInfo) => {
173
+ // Download the zip file
174
+ const response = await axios_1.default.get(bundleInfo.Message, {
175
+ responseType: 'arraybuffer'
176
+ });
177
+ const timestamp = `${bundleInfo.SampleTimestamp.toISOString()
178
+ .split('T')[0]}_${bundleInfo.SampleTimestamp.toTimeString().split(' ')[0]}`;
179
+ const filename = `${timestamp}__${bundleInfo.Ec2InstanceId}.zip`;
180
+ const filePath = path_1.default.join(logsFolder, filename);
181
+ fs_1.default.writeFileSync(filePath, response.data);
182
+ // logStep(`Logs bundle saved to ${filePath}`);
183
+ return filePath;
184
+ }));
185
+ // console.log('filePaths', filePaths);
186
+ return filePaths;
149
187
  }
150
188
  function getNodeVersion(api, bundlePath) {
151
- let star = _fs.default.readFileSync(api.resolvePath(bundlePath, 'bundle/star.json')).toString();
152
- const nodeVersionTxt = _fs.default.readFileSync(api.resolvePath(bundlePath, 'bundle/.node_version.txt')).toString();
153
- star = JSON.parse(star);
154
- if (star.npmVersion) {
155
- return {
156
- nodeVersion: star.nodeVersion,
157
- npmVersion: star.npmVersion
158
- };
159
- }
160
- const nodeVersion = nodeVersionTxt.substr(1);
161
- if (nodeVersion.startsWith('4')) {
189
+ var _a;
190
+ const starString = fs_1.default.readFileSync(api.resolvePath(bundlePath, 'bundle/star.json')).toString();
191
+ const nodeVersionTxt = fs_1.default.readFileSync(api.resolvePath(bundlePath, 'bundle/.node_version.txt')).toString();
192
+ const star = JSON.parse(starString);
193
+ const meteorVersion = ((_a = star === null || star === void 0 ? void 0 : star.meteorRelease) === null || _a === void 0 ? void 0 : _a.split('@')[1]) || "2.12";
194
+ if (star.npmVersion) {
195
+ return {
196
+ meteorVersion,
197
+ nodeVersion: star.nodeVersion,
198
+ npmVersion: star.npmVersion
199
+ };
200
+ }
201
+ const nodeVersion = nodeVersionTxt.substr(1);
202
+ if (nodeVersion.startsWith('4')) {
203
+ return {
204
+ nodeVersion,
205
+ npmVersion: '4.6.1'
206
+ };
207
+ }
162
208
  return {
163
- nodeVersion,
164
- npmVersion: '4.6.1'
209
+ nodeVersion,
210
+ npmVersion: '3.10.5'
165
211
  };
166
- }
167
- return {
168
- nodeVersion,
169
- npmVersion: '3.10.5'
170
- };
171
212
  }
172
213
  async function selectPlatformArn(awsPlatformBranchName) {
173
- console.log('----> Amazon BranchName:', awsPlatformBranchName);
174
- const {
175
- PlatformBranchSummaryList
176
- } = await _aws.beanstalk.listPlatformBranches({
177
- Filters: [{
178
- Attribute: 'PlatformName',
179
- Operator: '=',
180
- Values: ['Node.js']
181
- }, {
182
- Attribute: 'TierType',
183
- Operator: '=',
184
- Values: ['WebServer/Standard']
185
- }, {
186
- Attribute: 'BranchName',
187
- Operator: 'begins_with',
188
- Values: [awsPlatformBranchName]
189
- }]
190
- }).promise();
191
- if (PlatformBranchSummaryList.length === 0) {
192
- throw new Error('Unable to find supported Node.js platform');
193
- }
194
- const branchName = PlatformBranchSummaryList[0].BranchName;
195
- console.log('----> Amazon Platform:', branchName);
196
- const {
197
- PlatformSummaryList
198
- } = await _aws.beanstalk.listPlatformVersions({
199
- Filters: [{
200
- Type: 'PlatformBranchName',
201
- Operator: '=',
202
- Values: [branchName]
203
- }, {
204
- Type: 'PlatformStatus',
205
- Operator: '=',
206
- Values: ['Ready']
207
- }]
208
- }).promise();
209
- const arn = PlatformSummaryList[0].PlatformArn;
210
- console.log('----> Amazon ARN:', arn);
211
- return arn;
214
+ console.log('----> Amazon BranchName:', awsPlatformBranchName);
215
+ const { PlatformBranchSummaryList } = await aws_1.beanstalk.listPlatformBranches({
216
+ Filters: [
217
+ {
218
+ Attribute: 'PlatformName',
219
+ Operator: '=',
220
+ Values: ['Node.js']
221
+ }, {
222
+ Attribute: 'TierType',
223
+ Operator: '=',
224
+ Values: ['WebServer/Standard']
225
+ }, {
226
+ Attribute: 'BranchName',
227
+ Operator: 'begins_with',
228
+ Values: [awsPlatformBranchName]
229
+ }
230
+ ]
231
+ });
232
+ if (!PlatformBranchSummaryList || PlatformBranchSummaryList.length === 0) {
233
+ throw new Error('Unable to find supported Node.js platform');
234
+ }
235
+ const branchName = PlatformBranchSummaryList[0].BranchName;
236
+ console.log('----> Amazon Platform:', branchName, "allBranches:", PlatformBranchSummaryList.length, "branches:", JSON.stringify(PlatformBranchSummaryList.map((pb) => pb.BranchName)));
237
+ const { PlatformSummaryList } = await aws_1.beanstalk.listPlatformVersions({
238
+ Filters: [
239
+ {
240
+ Type: 'PlatformBranchName',
241
+ Operator: '=',
242
+ Values: [branchName]
243
+ },
244
+ {
245
+ Type: 'PlatformStatus',
246
+ Operator: '=',
247
+ Values: ['Ready']
248
+ }
249
+ ]
250
+ });
251
+ const arn = PlatformSummaryList === null || PlatformSummaryList === void 0 ? void 0 : PlatformSummaryList[0].PlatformArn;
252
+ console.log('----> Amazon ARN:', arn);
253
+ return arn;
212
254
  }
213
- async function attachPolicies(config, roleName, policies) {
214
- const promises = [];
215
- policies.forEach(policy => {
216
- const promise = _aws.iam.attachRolePolicy({
217
- RoleName: roleName,
218
- PolicyArn: policy
219
- }).promise();
220
- promises.push(promise);
221
- });
222
- await Promise.all(promises);
255
+ async function attachPolicies(roleName, policies) {
256
+ const promises = [];
257
+ policies.forEach((policy) => {
258
+ const promise = aws_1.iam.attachRolePolicy({
259
+ RoleName: roleName,
260
+ PolicyArn: policy
261
+ });
262
+ promises.push(promise);
263
+ });
264
+ await Promise.all(promises);
223
265
  }
224
- function getAccountId() {
225
- return _aws.sts.getCallerIdentity().promise().then(({
226
- Account
227
- }) => Account);
266
+ async function getAccountId() {
267
+ const identity = await aws_1.sts.getCallerIdentity({});
268
+ return identity.Account;
228
269
  }
229
270
  async function ensureRoleExists(name, assumeRolePolicyDocument, ensureAssumeRolePolicy) {
230
- let exists = true;
231
- let updateAssumeRolePolicy = false;
232
- try {
233
- const {
234
- Role
235
- } = await _aws.iam.getRole({
236
- RoleName: name
237
- }).promise();
238
- const currentAssumeRolePolicy = decodeURIComponent(Role.AssumeRolePolicyDocument);
239
- // Make the whitespace consistent with the current document
240
- assumeRolePolicyDocument = JSON.stringify(JSON.parse(assumeRolePolicyDocument));
241
- if (currentAssumeRolePolicy !== assumeRolePolicyDocument && ensureAssumeRolePolicy) {
242
- updateAssumeRolePolicy = true;
243
- }
244
- } catch (e) {
245
- exists = false;
246
- }
247
- if (!exists) {
248
- await _aws.iam.createRole({
249
- RoleName: name,
250
- AssumeRolePolicyDocument: assumeRolePolicyDocument
251
- }).promise();
252
- } else if (updateAssumeRolePolicy) {
253
- await _aws.iam.updateAssumeRolePolicy({
254
- RoleName: name,
255
- PolicyDocument: assumeRolePolicyDocument
256
- }).promise();
257
- }
271
+ let exists = true;
272
+ let updateAssumeRolePolicy = false;
273
+ try {
274
+ const { Role } = await aws_1.iam.getRole({
275
+ RoleName: name
276
+ });
277
+ const currentAssumeRolePolicy = decodeURIComponent(Role.AssumeRolePolicyDocument);
278
+ // Make the whitespace consistent with the current document
279
+ const consistentAssumeRolePolicyDocument = JSON.stringify(JSON.parse(assumeRolePolicyDocument));
280
+ if (currentAssumeRolePolicy !== consistentAssumeRolePolicyDocument && ensureAssumeRolePolicy) {
281
+ updateAssumeRolePolicy = true;
282
+ }
283
+ }
284
+ catch (e) {
285
+ exists = false;
286
+ }
287
+ if (!exists) {
288
+ await aws_1.iam.createRole({
289
+ RoleName: name,
290
+ AssumeRolePolicyDocument: assumeRolePolicyDocument
291
+ });
292
+ }
293
+ else if (updateAssumeRolePolicy) {
294
+ await aws_1.iam.updateAssumeRolePolicy({
295
+ RoleName: name,
296
+ PolicyDocument: assumeRolePolicyDocument
297
+ });
298
+ }
258
299
  }
259
- async function ensureInstanceProfileExists(config, name) {
260
- let exists = true;
261
- try {
262
- await _aws.iam.getInstanceProfile({
263
- InstanceProfileName: name
264
- }).promise();
265
- } catch (e) {
266
- exists = false;
267
- }
268
- if (!exists) {
269
- await _aws.iam.createInstanceProfile({
270
- InstanceProfileName: name
271
- }).promise();
272
- }
300
+ async function ensureInstanceProfileExists(name) {
301
+ let exists = true;
302
+ try {
303
+ await aws_1.iam.getInstanceProfile({
304
+ InstanceProfileName: name
305
+ });
306
+ }
307
+ catch (e) {
308
+ exists = false;
309
+ }
310
+ if (!exists) {
311
+ await aws_1.iam.createInstanceProfile({
312
+ InstanceProfileName: name
313
+ });
314
+ }
273
315
  }
274
- async function ensureRoleAdded(config, instanceProfile, role) {
275
- let added = true;
276
- const {
277
- InstanceProfile
278
- } = await _aws.iam.getInstanceProfile({
279
- InstanceProfileName: instanceProfile
280
- }).promise();
281
- if (InstanceProfile.Roles.length === 0 || InstanceProfile.Roles[0].RoleName !== role) {
282
- added = false;
283
- }
284
- if (!added) {
285
- await _aws.iam.addRoleToInstanceProfile({
286
- InstanceProfileName: instanceProfile,
287
- RoleName: role
288
- }).promise();
289
- }
316
+ async function ensureRoleAdded(instanceProfile, role) {
317
+ let added = true;
318
+ const { InstanceProfile } = await aws_1.iam.getInstanceProfile({
319
+ InstanceProfileName: instanceProfile
320
+ });
321
+ if (InstanceProfile.Roles.length === 0 || InstanceProfile.Roles[0].RoleName !== role) {
322
+ added = false;
323
+ }
324
+ if (!added) {
325
+ await aws_1.iam.addRoleToInstanceProfile({
326
+ InstanceProfileName: instanceProfile,
327
+ RoleName: role
328
+ });
329
+ }
290
330
  }
291
- async function ensurePoliciesAttached(config, role, policies) {
292
- let {
293
- AttachedPolicies
294
- } = await _aws.iam.listAttachedRolePolicies({
295
- RoleName: role
296
- }).promise();
297
- AttachedPolicies = AttachedPolicies.map(policy => policy.PolicyArn);
298
- const unattachedPolicies = policies.reduce((result, policy) => {
299
- if (AttachedPolicies.indexOf(policy) === -1) {
300
- result.push(policy);
301
- }
302
- return result;
303
- }, []);
304
- if (unattachedPolicies.length > 0) {
305
- await attachPolicies(config, role, unattachedPolicies);
306
- }
331
+ async function ensurePoliciesAttached(role, policies) {
332
+ let { AttachedPolicies } = await aws_1.iam.listAttachedRolePolicies({
333
+ RoleName: role
334
+ });
335
+ const arns = AttachedPolicies.map(policy => policy.PolicyArn);
336
+ const unattachedPolicies = policies.reduce((result, policy) => {
337
+ if (arns.indexOf(policy) === -1) {
338
+ result.push(policy);
339
+ }
340
+ return result;
341
+ }, []);
342
+ if (unattachedPolicies.length > 0) {
343
+ await attachPolicies(role, unattachedPolicies);
344
+ }
307
345
  }
308
346
  async function ensureInlinePolicyAttached(role, policyName, policyDocument) {
309
- let exists = true;
310
- let needsUpdating = false;
311
- try {
312
- const result = await _aws.iam.getRolePolicy({
313
- RoleName: role,
314
- PolicyName: policyName
315
- }).promise();
316
- const currentPolicyDocument = decodeURIComponent(result.PolicyDocument);
317
- if (currentPolicyDocument !== policyDocument) {
318
- needsUpdating = true;
319
- }
320
- } catch (e) {
321
- exists = false;
322
- }
323
- if (!exists || needsUpdating) {
324
- await _aws.iam.putRolePolicy({
325
- RoleName: role,
326
- PolicyName: policyName,
327
- PolicyDocument: policyDocument
328
- }).promise();
329
- }
347
+ let exists = true;
348
+ let needsUpdating = false;
349
+ try {
350
+ const result = await aws_1.iam.getRolePolicy({
351
+ RoleName: role,
352
+ PolicyName: policyName
353
+ });
354
+ const currentPolicyDocument = decodeURIComponent(result.PolicyDocument);
355
+ if (currentPolicyDocument !== policyDocument) {
356
+ needsUpdating = true;
357
+ }
358
+ }
359
+ catch (e) {
360
+ exists = false;
361
+ }
362
+ if (!exists || needsUpdating) {
363
+ await aws_1.iam.putRolePolicy({
364
+ RoleName: role,
365
+ PolicyName: policyName,
366
+ PolicyDocument: policyDocument
367
+ });
368
+ }
330
369
  }
331
370
  async function ensureBucketExists(buckets, bucketName, region) {
332
- if (!buckets.find(bucket => bucket.Name === bucketName)) {
333
- await _aws.s3.createBucket(_objectSpread({
334
- Bucket: bucketName
335
- }, region ? {
336
- CreateBucketConfiguration: {
337
- LocationConstraint: region
338
- }
339
- } : {})).promise();
340
- return true;
341
- }
371
+ if (!buckets.find(bucket => bucket.Name === bucketName)) {
372
+ // @ts-ignore
373
+ await aws_1.s3.createBucket({
374
+ Bucket: bucketName,
375
+ ...(region ? {
376
+ CreateBucketConfiguration: {
377
+ LocationConstraint: region
378
+ }
379
+ } : {})
380
+ });
381
+ return true;
382
+ }
342
383
  }
343
384
  function findBucketWithPrefix(buckets, prefix) {
344
- return buckets.find(bucket => bucket.Name.indexOf(prefix) === 0);
385
+ return buckets.find(bucket => bucket.Name.indexOf(prefix) === 0);
345
386
  }
346
387
  async function ensureBucketPolicyAttached(bucketName, policy) {
347
- let error = false;
348
- let currentPolicy;
349
- try {
350
- const {
351
- Policy
352
- } = await _aws.s3.getBucketPolicy({
353
- Bucket: bucketName
354
- }).promise();
355
- currentPolicy = Policy;
356
- } catch (e) {
357
- error = true;
358
- }
359
- if (error || currentPolicy !== policy) {
360
- const params = {
361
- Bucket: bucketName,
362
- Policy: policy
363
- };
364
- await _aws.s3.putBucketPolicy(params).promise();
365
- }
388
+ let error = false;
389
+ let currentPolicy;
390
+ try {
391
+ const { Policy } = await aws_1.s3.getBucketPolicy({ Bucket: bucketName });
392
+ currentPolicy = Policy;
393
+ }
394
+ catch (e) {
395
+ error = true;
396
+ }
397
+ if (error || currentPolicy !== policy) {
398
+ const params = {
399
+ Bucket: bucketName,
400
+ Policy: policy
401
+ };
402
+ await aws_1.s3.putBucketPolicy(params);
403
+ }
366
404
  }
367
405
  async function ensureCloudWatchRule(name, description, eventPattern) {
368
- let error = false;
369
- try {
370
- await _aws.cloudWatchEvents.describeRule({
371
- Name: name
372
- }).promise();
373
- } catch (e) {
374
- error = true;
375
- }
376
- if (error) {
377
- await _aws.cloudWatchEvents.putRule({
378
- Name: name,
379
- Description: description,
380
- EventPattern: eventPattern
381
- }).promise();
382
- return true;
383
- }
384
- return false;
406
+ let error = false;
407
+ try {
408
+ await aws_1.cloudWatchEvents.describeRule({ Name: name });
409
+ }
410
+ catch (e) {
411
+ error = true;
412
+ }
413
+ if (error) {
414
+ await aws_1.cloudWatchEvents.putRule({
415
+ Name: name,
416
+ Description: description,
417
+ EventPattern: eventPattern
418
+ });
419
+ return true;
420
+ }
421
+ return false;
385
422
  }
386
423
  async function ensureRuleTargetExists(ruleName, target) {
387
- const {
388
- Targets
389
- } = await _aws.cloudWatchEvents.listTargetsByRule({
390
- Rule: ruleName
391
- }).promise();
392
- if (!Targets.find(_target => (0, _lodash.isEqual)(_target, target))) {
393
- const params = {
394
- Rule: ruleName,
395
- Targets: [target]
396
- };
397
- await _aws.cloudWatchEvents.putTargets(params).promise();
398
- return true;
399
- }
424
+ const { Targets } = await aws_1.cloudWatchEvents.listTargetsByRule({
425
+ Rule: ruleName
426
+ });
427
+ if (!Targets.find(_target => (0, lodash_1.isEqual)(_target, target))) {
428
+ const params = {
429
+ Rule: ruleName,
430
+ Targets: [target]
431
+ };
432
+ await aws_1.cloudWatchEvents.putTargets(params);
433
+ return true;
434
+ }
400
435
  }
401
436
  function coloredStatusText(envColor, text) {
402
- if (envColor === 'Green') {
403
- return _chalk.default.green(text);
404
- } else if (envColor === 'Yellow') {
405
- return _chalk.default.yellow(text);
406
- } else if (envColor === 'Red') {
407
- return _chalk.default.red(text);
408
- }
409
- return text;
437
+ if (envColor === 'Green') {
438
+ return chalk_1.default.green(text);
439
+ }
440
+ else if (envColor === 'Yellow') {
441
+ return chalk_1.default.yellow(text);
442
+ }
443
+ else if (envColor === 'Red') {
444
+ return chalk_1.default.red(text);
445
+ }
446
+ return text;
410
447
  }
411
448
  function createVersionDescription(api, appConfig) {
412
- const appPath = api.resolvePath(api.getBasePath(), appConfig.path);
413
- let description = '';
414
- try {
415
- description = (0, _child_process.execSync)('git log -1 --pretty=%B', {
416
- cwd: appPath,
417
- stdio: 'pipe'
418
- }).toString();
419
- } catch (e) {
420
- description = `Deployed by Mup on ${new Date().toUTCString()}`;
421
- }
422
- return description.split('\n')[0].slice(0, 195);
449
+ const appPath = api.resolvePath(api.getBasePath(), appConfig.path);
450
+ let description = '';
451
+ try {
452
+ description = (0, child_process_1.execSync)('git log -1 --pretty=%B', {
453
+ cwd: appPath,
454
+ stdio: 'pipe'
455
+ }).toString();
456
+ }
457
+ catch (e) {
458
+ description = `Deployed by Mup on ${new Date().toUTCString()}`;
459
+ }
460
+ return description.split('\n')[0].slice(0, 195);
423
461
  }
424
462
  async function ensureSsmDocument(name, content) {
425
- let exists = true;
426
- let needsUpdating = false;
427
- try {
428
- const result = await _aws.ssm.getDocument({
429
- Name: name,
430
- DocumentVersion: '$DEFAULT'
431
- }).promise();
432
- // If the document was created or edited on the AWS console, there is extra new
433
- // line characters and whitespace
434
- const currentContent = JSON.stringify(JSON.parse(result.Content.replace(/\r?\n|\r/g, '')));
435
- if (currentContent !== content) {
436
- needsUpdating = true;
437
- }
438
- } catch (e) {
439
- exists = false;
440
- }
441
- if (!exists) {
442
- await _aws.ssm.createDocument({
443
- Content: content,
444
- Name: name,
445
- DocumentType: 'Automation'
446
- }).promise();
447
- return true;
448
- } else if (needsUpdating) {
463
+ let exists = true;
464
+ let needsUpdating = false;
449
465
  try {
450
- await _aws.ssm.updateDocument({
451
- Content: content,
452
- Name: name,
453
- DocumentVersion: '$LATEST'
454
- }).promise();
455
- } catch (e) {
456
- // If the latest document version has the correct content
457
- // then it must not be the default version. Ignore the error
458
- // so we can fix the default version
459
- if (e.code !== 'DuplicateDocumentContent') {
460
- throw e;
461
- }
462
- }
463
- const result = await _aws.ssm.getDocument({
464
- Name: name,
465
- DocumentVersion: '$LATEST'
466
- }).promise();
467
- await _aws.ssm.updateDocumentDefaultVersion({
468
- DocumentVersion: result.DocumentVersion,
469
- Name: name
470
- }).promise();
471
- }
466
+ const result = await aws_1.ssm.getDocument({ Name: name, DocumentVersion: '$DEFAULT' });
467
+ // If the document was created or edited on the AWS console, there is extra new
468
+ // line characters and whitespace
469
+ const currentContent = JSON.stringify(JSON.parse(result.Content.replace(/\r?\n|\r/g, '')));
470
+ if (currentContent !== content) {
471
+ needsUpdating = true;
472
+ }
473
+ }
474
+ catch (e) {
475
+ exists = false;
476
+ }
477
+ if (!exists) {
478
+ await aws_1.ssm.createDocument({
479
+ Content: content,
480
+ Name: name,
481
+ DocumentType: 'Automation'
482
+ });
483
+ return true;
484
+ }
485
+ else if (needsUpdating) {
486
+ try {
487
+ await aws_1.ssm.updateDocument({
488
+ Content: content,
489
+ Name: name,
490
+ DocumentVersion: '$LATEST'
491
+ });
492
+ }
493
+ catch (e) {
494
+ // If the latest document version has the correct content
495
+ // then it must not be the default version. Ignore the error
496
+ // so we can fix the default version
497
+ // @ts-ignore
498
+ if (e.code !== 'DuplicateDocumentContent') {
499
+ throw e;
500
+ }
501
+ }
502
+ const result = await aws_1.ssm.getDocument({ Name: name, DocumentVersion: '$LATEST' });
503
+ await aws_1.ssm.updateDocumentDefaultVersion({
504
+ DocumentVersion: result.DocumentVersion,
505
+ Name: name
506
+ });
507
+ }
472
508
  }
473
509
  async function pickInstance(config, instance) {
474
- const {
475
- environment
476
- } = names(config);
477
- const {
478
- EnvironmentResources
479
- } = await _aws.beanstalk.describeEnvironmentResources({
480
- EnvironmentName: environment
481
- }).promise();
482
- const instanceIds = EnvironmentResources.Instances.map(({
483
- Id
484
- }) => Id);
485
- const description = ['Available instances', ...instanceIds.map(id => ` - ${id}`)].join('\n');
486
- return {
487
- selected: instanceIds.includes(instance) ? instance : null,
488
- description
489
- };
510
+ const { environment } = names(config);
511
+ const { EnvironmentResources } = await aws_1.beanstalk.describeEnvironmentResources({
512
+ EnvironmentName: environment
513
+ });
514
+ const instanceIds = EnvironmentResources.Instances.map(({ Id }) => Id);
515
+ const description = [
516
+ 'Available instances',
517
+ ...instanceIds.map(id => ` - ${id}`)
518
+ ].join('\n');
519
+ return {
520
+ selected: instanceIds.includes(instance) ? instance : null,
521
+ description
522
+ };
490
523
  }
491
524
  async function connectToInstance(api, instanceId, commandLabel) {
492
- const {
493
- sshKey
494
- } = api.getConfig().app;
495
- if (!sshKey) {
496
- const error = new Error('missing sshKey config');
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';
498
- throw error;
499
- }
500
- const {
501
- Reservations
502
- } = await _aws.ec2.describeInstances({
503
- InstanceIds: [instanceId]
504
- }).promise();
505
- const instance = Reservations[0].Instances[0];
506
- const availabilityZone = instance.Placement.AvailabilityZone;
507
- const securityGroups = instance.SecurityGroups.map(g => g.GroupId);
508
- let {
509
- data: ipAddress
510
- } = await _axios.default.get('https://ipv4.icanhazip.com');
511
- ipAddress = ipAddress.trim();
512
- if (securityGroups.length > 1) {
513
- console.warn('Instance has more than one security group. Please open a GitHub issue for mup-aws-beanstalk');
514
- }
515
- let ruleIds = [];
516
- try {
517
- const {
518
- SecurityGroupRules
519
- } = await _aws.ec2.authorizeSecurityGroupIngress({
520
- GroupId: securityGroups[0],
521
- IpPermissions: [{
522
- FromPort: 22,
523
- IpProtocol: 'tcp',
524
- IpRanges: [{
525
- CidrIp: `${ipAddress}/32`,
526
- Description: `Temporary SSH access for ${commandLabel}`
527
- }],
528
- ToPort: 22
529
- }]
530
- }).promise();
531
- ruleIds = SecurityGroupRules.map(rule => rule.SecurityGroupRuleId);
532
- } catch (e) {
533
- if (e.code === 'InvalidPermission.Duplicate') {
534
- // This rule already exists
535
- // TODO: should we find the rule id so we can remove it, or leave it in
536
- // case the user had manually added this rule?
537
- } else {
538
- throw e;
539
- }
540
- }
541
- await _aws.ec2InstanceConnect.sendSSHPublicKey({
542
- InstanceId: instanceId,
543
- AvailabilityZone: availabilityZone,
544
- InstanceOSUser: 'ec2-user',
545
- SSHPublicKey: _fs.default.readFileSync(api.resolvePath(sshKey.publicKey), 'utf-8')
546
- }).promise();
547
- const sshOptions = {
548
- host: instance.PublicDnsName,
549
- port: 22,
550
- username: 'ec2-user',
551
- privateKey: _fs.default.readFileSync(api.resolvePath(sshKey.privateKey), 'utf-8')
552
- };
553
- return {
554
- sshOptions,
555
- removeSSHAccess() {
556
- if (ruleIds.length === 0) {
557
- return;
558
- }
559
- console.log('Removing temporary security group rule for SSH');
560
- return _aws.ec2.revokeSecurityGroupIngress({
561
- GroupId: securityGroups[0],
562
- SecurityGroupRuleIds: ruleIds
563
- }).promise();
564
- }
565
- };
525
+ const { sshKey } = api.getConfig().app;
526
+ if (!sshKey) {
527
+ const error = new Error('missing sshKey config');
528
+ // @ts-ignore
529
+ error.solution = 'Learn how to configure sshKey at https://github.com/zodern/mup-aws-beanstalk/blob/master/docs/index.md#meteor-shell-and-debug';
530
+ throw error;
531
+ }
532
+ const { Reservations } = await aws_1.ec2.describeInstances({
533
+ InstanceIds: [
534
+ instanceId
535
+ ]
536
+ });
537
+ const instance = Reservations[0].Instances[0];
538
+ const availabilityZone = instance.Placement.AvailabilityZone;
539
+ const securityGroups = instance.SecurityGroups.map(g => g.GroupId);
540
+ let { data: ipAddress } = await axios_1.default.get('https://ipv4.icanhazip.com');
541
+ ipAddress = ipAddress.trim();
542
+ if (securityGroups.length > 1) {
543
+ console.warn('Instance has more than one security group. Please open a GitHub issue for mup-aws-beanstalk');
544
+ }
545
+ let ruleIds = [];
546
+ try {
547
+ const { SecurityGroupRules } = await aws_1.ec2.authorizeSecurityGroupIngress({
548
+ GroupId: securityGroups[0],
549
+ IpPermissions: [
550
+ {
551
+ FromPort: 22,
552
+ IpProtocol: 'tcp',
553
+ IpRanges: [
554
+ {
555
+ CidrIp: `${ipAddress}/32`,
556
+ Description: `Temporary SSH access for ${commandLabel}`
557
+ }
558
+ ],
559
+ ToPort: 22
560
+ }
561
+ ]
562
+ });
563
+ ruleIds = SecurityGroupRules.map(rule => rule.SecurityGroupRuleId);
564
+ }
565
+ catch (e) {
566
+ // @ts-ignore
567
+ if (e.code === 'InvalidPermission.Duplicate') {
568
+ // This rule already exists
569
+ // TODO: should we find the rule id so we can remove it, or leave it in
570
+ // case the user had manually added this rule?
571
+ }
572
+ else {
573
+ throw e;
574
+ }
575
+ }
576
+ await aws_1.ec2InstanceConnect.sendSSHPublicKey({
577
+ InstanceId: instanceId,
578
+ AvailabilityZone: availabilityZone,
579
+ InstanceOSUser: 'ec2-user',
580
+ SSHPublicKey: fs_1.default.readFileSync(api.resolvePath(sshKey.publicKey), 'utf-8')
581
+ });
582
+ const sshOptions = {
583
+ host: instance.PublicDnsName,
584
+ port: 22,
585
+ username: 'ec2-user',
586
+ privateKey: fs_1.default.readFileSync(api.resolvePath(sshKey.privateKey), 'utf-8')
587
+ };
588
+ return {
589
+ sshOptions,
590
+ removeSSHAccess() {
591
+ if (ruleIds.length === 0) {
592
+ return;
593
+ }
594
+ console.log('Removing temporary security group rule for SSH');
595
+ return aws_1.ec2.revokeSecurityGroupIngress({
596
+ GroupId: securityGroups[0],
597
+ SecurityGroupRuleIds: ruleIds
598
+ });
599
+ }
600
+ };
566
601
  }
567
602
  async function executeSSHCommand(conn, command) {
568
- return new Promise((resolve, reject) => {
569
- conn.exec(command, (err, outputStream) => {
570
- if (err) {
571
- conn.end();
572
- reject(err);
573
- return;
574
- }
575
- let output = '';
576
- outputStream.on('data', data => {
577
- output += data;
578
- });
579
- outputStream.stderr.on('data', data => {
580
- output += data;
581
- });
582
- outputStream.once('close', code => {
583
- conn.end();
584
- resolve({
585
- code,
586
- output
603
+ return new Promise((resolve, reject) => {
604
+ conn.exec(command, (err, outputStream) => {
605
+ if (err) {
606
+ conn.end();
607
+ reject(err);
608
+ return;
609
+ }
610
+ let output = '';
611
+ outputStream.on('data', (data) => {
612
+ output += data;
613
+ });
614
+ outputStream.stderr.on('data', (data) => {
615
+ output += data;
616
+ });
617
+ outputStream.once('close', (code) => {
618
+ conn.end();
619
+ resolve({ code, output });
620
+ });
587
621
  });
588
- });
589
622
  });
590
- });
591
623
  }
592
624
  //# sourceMappingURL=utils.js.map