@axway/axway-central-cli 2.26.0 → 2.27.0-rc.1
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/README.md
CHANGED
|
@@ -560,7 +560,7 @@ USAGE: axway central install <command> [options] [<args...>]
|
|
|
560
560
|
Install additional platform resources
|
|
561
561
|
|
|
562
562
|
INSTALL COMMANDS:
|
|
563
|
-
agents Install Amplify API Gateway / Amazon API Gateway / Azure API Gateway / Istio
|
|
563
|
+
agents Install Amplify API Gateway / Amazon API Gateway / Azure API Gateway / Istio / Apigee X Gateway / GitHub / GitLab / Kafka / SwaggerHub
|
|
564
564
|
|
|
565
565
|
INSTALL ARGUMENTS:
|
|
566
566
|
args... Command arguments, run "axway central install" to see the examples
|
|
@@ -576,7 +576,7 @@ INSTALL OPTIONS:
|
|
|
576
576
|
```text
|
|
577
577
|
USAGE: axway central install agents [options]
|
|
578
578
|
|
|
579
|
-
Amplify API Gateway / Amazon API Gateway / Azure API Gateway / Istio
|
|
579
|
+
Amplify API Gateway / Amazon API Gateway / Azure API Gateway / Istio / Apigee X Gateway / GitHub / GitLab / Kafka / SwaggerHub
|
|
580
580
|
|
|
581
581
|
INSTALL OPTIONS:
|
|
582
582
|
--account [value] Override your default account config
|
|
@@ -24,6 +24,7 @@ var edgeAgents = _interopRequireWildcard(require("./edgeAgents"));
|
|
|
24
24
|
var apigeeSaaSAgents = _interopRequireWildcard(require("./apigeexSaasAgents"));
|
|
25
25
|
var helpers = _interopRequireWildcard(require("./helpers"));
|
|
26
26
|
var istioAgents = _interopRequireWildcard(require("./istioAgents"));
|
|
27
|
+
var azureSaasAgents = _interopRequireWildcard(require("./azureSaasAgents"));
|
|
27
28
|
var kafkaAgents = _interopRequireWildcard(require("./kafkaAgents"));
|
|
28
29
|
var swaggerHubAgents = _interopRequireWildcard(require("./swaggerHubSaasAgents"));
|
|
29
30
|
var platform = _interopRequireWildcard(require("./platform"));
|
|
@@ -51,7 +52,8 @@ const saasAgentInstallFlows = {
|
|
|
51
52
|
[_types.SaaSGatewayTypes.AWS_GATEWAY]: awsSaaSAgents.AWSSaaSInstallMethods,
|
|
52
53
|
[_types.SaaSGatewayTypes.GITHUB]: gitHubAgents.GitHubSaaSInstallMethods,
|
|
53
54
|
[_types.SaaSGatewayTypes.APIGEEX_GATEWAY]: apigeeSaaSAgents.APIGEEXSaaSInstallMethods,
|
|
54
|
-
[_types.SaaSGatewayTypes.SWAGGERHUB]: swaggerHubAgents.SwaggerHubSaaSInstallMethods
|
|
55
|
+
[_types.SaaSGatewayTypes.SWAGGERHUB]: swaggerHubAgents.SwaggerHubSaaSInstallMethods,
|
|
56
|
+
[_types.GatewayTypes.AZURE_GATEWAY]: azureSaasAgents.AzureSaaSInstallMethods
|
|
55
57
|
};
|
|
56
58
|
const createConfigBackup = async (configFiles, gatewayType) => {
|
|
57
59
|
// If current configurations exist, back them up
|
|
@@ -115,11 +117,14 @@ const agents = exports.agents = {
|
|
|
115
117
|
let gatewayTypeChoices = [];
|
|
116
118
|
Object.values(_types.GatewayTypes).forEach(v => gatewayTypeChoices.push(v));
|
|
117
119
|
Object.values(_types.SaaSGatewayTypes).filter(v => v !== _types.SaaSGatewayTypes.AWS_GATEWAY).forEach(v => gatewayTypeChoices.push(v));
|
|
120
|
+
let gatewayChoices = gatewayTypeChoices.sort().filter(v => v !== _types.GatewayTypes.EDGE_GATEWAY_ONLY);
|
|
118
121
|
let gatewayType = await (0, _basicPrompts.askList)({
|
|
119
122
|
msg: prompts.selectGatewayType,
|
|
120
|
-
choices:
|
|
123
|
+
choices: gatewayChoices
|
|
121
124
|
});
|
|
122
|
-
|
|
125
|
+
|
|
126
|
+
// if this check gets bigger, may think about an array of agents that can be both ground and embedded until ground agents become obsolete
|
|
127
|
+
if (gatewayType === _types.GatewayTypes.AWS_GATEWAY || gatewayType == _types.GatewayTypes.AZURE_GATEWAY) {
|
|
123
128
|
// hosted vs on premise
|
|
124
129
|
installConfig.switches.isHostedInstall = (await (0, _basicPrompts.askList)({
|
|
125
130
|
msg: prompts.hostedAgentOption,
|
|
@@ -192,7 +197,7 @@ const agents = exports.agents = {
|
|
|
192
197
|
process.exit(0);
|
|
193
198
|
}
|
|
194
199
|
},
|
|
195
|
-
desc: 'Amplify API Gateway / Amazon API Gateway / Azure API Gateway / Istio',
|
|
200
|
+
desc: 'Amplify API Gateway / Amazon API Gateway / Azure API Gateway / Istio / Apigee X Gateway / GitHub / GitLab / Kafka / SwaggerHub',
|
|
196
201
|
options: {
|
|
197
202
|
..._types.commonCmdArgsDescription
|
|
198
203
|
}
|
|
@@ -23,12 +23,12 @@ const {
|
|
|
23
23
|
class DataplaneConfig {
|
|
24
24
|
constructor(type) {
|
|
25
25
|
_defineProperty(this, "type", void 0);
|
|
26
|
-
this.type = type ||
|
|
26
|
+
this.type = type || '';
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
29
|
class AWSDataplaneConfig extends DataplaneConfig {
|
|
30
30
|
constructor(arn) {
|
|
31
|
-
super(
|
|
31
|
+
super('AWS');
|
|
32
32
|
_defineProperty(this, "accessLogARN", void 0);
|
|
33
33
|
this.accessLogARN = arn;
|
|
34
34
|
}
|
|
@@ -64,7 +64,7 @@ class Redaction {
|
|
|
64
64
|
_defineProperty(this, "queryArgument", void 0);
|
|
65
65
|
_defineProperty(this, "requestHeaders", void 0);
|
|
66
66
|
_defineProperty(this, "responseHeaders", void 0);
|
|
67
|
-
this.maskingCharacter =
|
|
67
|
+
this.maskingCharacter = '{*}';
|
|
68
68
|
this.path = [];
|
|
69
69
|
this.queryArgument = new RedactionSet();
|
|
70
70
|
this.requestHeaders = new RedactionSet();
|
|
@@ -89,7 +89,7 @@ class SaasAgentValues {
|
|
|
89
89
|
this.centralConfig = new _types.CentralAgentConfig();
|
|
90
90
|
}
|
|
91
91
|
getAccessData() {
|
|
92
|
-
return
|
|
92
|
+
return '';
|
|
93
93
|
}
|
|
94
94
|
}
|
|
95
95
|
class SaasAWSAgentValues extends SaasAgentValues {
|
|
@@ -172,27 +172,27 @@ const askConfigType = async () => {
|
|
|
172
172
|
const askForRedactionSet = async (setting, redactionSet) => {
|
|
173
173
|
// ask for path reg exs
|
|
174
174
|
let askShow = true;
|
|
175
|
-
console.log(_chalk.default.gray((0, _utils.FormatString)(
|
|
175
|
+
console.log(_chalk.default.gray((0, _utils.FormatString)('\nRedaction settings for {0}s', setting)));
|
|
176
176
|
while (askShow) {
|
|
177
177
|
const input = await (0, _basicPrompts.askInput)({
|
|
178
178
|
msg: (0, _utils.FormatString)(SaasPrompts.REDACT_SHOW, setting),
|
|
179
|
-
defaultValue:
|
|
179
|
+
defaultValue: '.*',
|
|
180
180
|
validate: (0, _basicPrompts.validateValidRegex)()
|
|
181
181
|
});
|
|
182
182
|
redactionSet.show.push(input);
|
|
183
183
|
askShow = (await (0, _basicPrompts.askList)({
|
|
184
|
-
msg: (0, _utils.FormatString)(SaasPrompts.ENTER_MORE,
|
|
184
|
+
msg: (0, _utils.FormatString)(SaasPrompts.ENTER_MORE, 'redaction regular expression', setting),
|
|
185
185
|
default: _types.YesNo.No,
|
|
186
186
|
choices: _types.YesNoChoices
|
|
187
187
|
})) === _types.YesNo.Yes;
|
|
188
188
|
}
|
|
189
|
-
console.log(_chalk.default.gray((0, _utils.FormatString)(
|
|
189
|
+
console.log(_chalk.default.gray((0, _utils.FormatString)('Sanitization settings for {0}s', setting)));
|
|
190
190
|
let askSanitize = (await (0, _basicPrompts.askList)({
|
|
191
191
|
msg: (0, _utils.FormatString)(SaasPrompts.ENTER_SANITIZE_RULE, setting),
|
|
192
192
|
default: _types.YesNo.No,
|
|
193
193
|
choices: _types.YesNoChoices
|
|
194
194
|
})) === _types.YesNo.Yes;
|
|
195
|
-
console.log(_chalk.default.gray(
|
|
195
|
+
console.log(_chalk.default.gray('When a match for the key regular expression is found, a match\nfor the value regular expression will be replaced by the masking character(s)'));
|
|
196
196
|
while (askSanitize) {
|
|
197
197
|
const keyMatch = await (0, _basicPrompts.askInput)({
|
|
198
198
|
msg: (0, _utils.FormatString)(SaasPrompts.SANITIZE_KEY, setting),
|
|
@@ -204,13 +204,13 @@ const askForRedactionSet = async (setting, redactionSet) => {
|
|
|
204
204
|
allowEmptyInput: true,
|
|
205
205
|
validate: (0, _basicPrompts.validateValidRegex)()
|
|
206
206
|
});
|
|
207
|
-
if (keyMatch ===
|
|
207
|
+
if (keyMatch === '' || valMatch === '') {
|
|
208
208
|
console.log("can't add sanitization rule with an empty key or value regular expression");
|
|
209
209
|
} else {
|
|
210
210
|
redactionSet.sanitize.push(new Sanitize(keyMatch, valMatch));
|
|
211
211
|
}
|
|
212
212
|
askSanitize = (await (0, _basicPrompts.askList)({
|
|
213
|
-
msg: (0, _utils.FormatString)(SaasPrompts.ENTER_MORE,
|
|
213
|
+
msg: (0, _utils.FormatString)(SaasPrompts.ENTER_MORE, 'sanitization rule', setting),
|
|
214
214
|
default: _types.YesNo.No,
|
|
215
215
|
choices: _types.YesNoChoices
|
|
216
216
|
})) === _types.YesNo.Yes;
|
|
@@ -218,39 +218,39 @@ const askForRedactionSet = async (setting, redactionSet) => {
|
|
|
218
218
|
return redactionSet;
|
|
219
219
|
};
|
|
220
220
|
const askForRedaction = async hostedAgentValues => {
|
|
221
|
-
console.log(_chalk.default.gray(
|
|
221
|
+
console.log(_chalk.default.gray('\nRedaction and Sanitization settings'));
|
|
222
222
|
// ask for path reg exps
|
|
223
223
|
let askPaths = true;
|
|
224
|
-
console.log(_chalk.default.gray(
|
|
224
|
+
console.log(_chalk.default.gray('\nRedaction settings for URL paths'));
|
|
225
225
|
while (askPaths) {
|
|
226
226
|
const input = await (0, _basicPrompts.askInput)({
|
|
227
|
-
msg: (0, _utils.FormatString)(SaasPrompts.REDACT_SHOW,
|
|
228
|
-
defaultValue:
|
|
227
|
+
msg: (0, _utils.FormatString)(SaasPrompts.REDACT_SHOW, 'URL path'),
|
|
228
|
+
defaultValue: '.*',
|
|
229
229
|
validate: (0, _basicPrompts.validateValidRegex)()
|
|
230
230
|
});
|
|
231
231
|
hostedAgentValues.redaction.path.push(input);
|
|
232
232
|
askPaths = (await (0, _basicPrompts.askList)({
|
|
233
|
-
msg: (0, _utils.FormatString)(SaasPrompts.ENTER_MORE,
|
|
233
|
+
msg: (0, _utils.FormatString)(SaasPrompts.ENTER_MORE, 'redaction regular expression', 'URL path'),
|
|
234
234
|
default: _types.YesNo.No,
|
|
235
235
|
choices: _types.YesNoChoices
|
|
236
236
|
})) === _types.YesNo.Yes;
|
|
237
237
|
}
|
|
238
|
-
hostedAgentValues.redaction.queryArgument = await askForRedactionSet(
|
|
239
|
-
hostedAgentValues.redaction.requestHeaders = await askForRedactionSet(
|
|
240
|
-
hostedAgentValues.redaction.responseHeaders = await askForRedactionSet(
|
|
238
|
+
hostedAgentValues.redaction.queryArgument = await askForRedactionSet('query argument', hostedAgentValues.redaction.queryArgument);
|
|
239
|
+
hostedAgentValues.redaction.requestHeaders = await askForRedactionSet('request header', hostedAgentValues.redaction.requestHeaders);
|
|
240
|
+
hostedAgentValues.redaction.responseHeaders = await askForRedactionSet('response header', hostedAgentValues.redaction.responseHeaders);
|
|
241
241
|
hostedAgentValues.redaction.maskingCharacter = await (0, _basicPrompts.askInput)({
|
|
242
242
|
msg: SaasPrompts.MASKING_CHARS,
|
|
243
|
-
defaultValue:
|
|
244
|
-
validate: (0, _basicPrompts.validateRegex)(helpers.maskingRegex,
|
|
243
|
+
defaultValue: '{*}',
|
|
244
|
+
validate: (0, _basicPrompts.validateRegex)(helpers.maskingRegex, 'Please enter a valid value')
|
|
245
245
|
});
|
|
246
246
|
return hostedAgentValues;
|
|
247
247
|
};
|
|
248
248
|
const askForSampling = async hostedAgentValues => {
|
|
249
249
|
// ask sampling percentage
|
|
250
|
-
console.log(_chalk.default.gray(
|
|
251
|
-
console.log(_chalk.default.gray(
|
|
250
|
+
console.log(_chalk.default.gray('\nSampling settings'));
|
|
251
|
+
console.log(_chalk.default.gray('Sampling percentage can be a value from 0 to 10'));
|
|
252
252
|
hostedAgentValues.sampling.percentage = await (0, _basicPrompts.askInput)({
|
|
253
|
-
type:
|
|
253
|
+
type: 'number',
|
|
254
254
|
msg: SaasPrompts.SAMP_PERCENTAGE,
|
|
255
255
|
defaultValue: 1,
|
|
256
256
|
validate: (0, _basicPrompts.validateValueRange)(0, 10)
|
|
@@ -265,7 +265,7 @@ const askForSampling = async hostedAgentValues => {
|
|
|
265
265
|
};
|
|
266
266
|
const askForAWSCredentials = async hostedAgentValues => {
|
|
267
267
|
hostedAgentValues.region = await helpers.askAWSRegion();
|
|
268
|
-
log(
|
|
268
|
+
log('gathering access details for aws');
|
|
269
269
|
|
|
270
270
|
// Ask Auth type
|
|
271
271
|
hostedAgentValues.authType = await (0, _basicPrompts.askList)({
|
|
@@ -279,9 +279,9 @@ const askForAWSCredentials = async hostedAgentValues => {
|
|
|
279
279
|
value: AWSAuthType.KEYS
|
|
280
280
|
}]
|
|
281
281
|
});
|
|
282
|
-
console.log(_chalk.default.gray(
|
|
282
|
+
console.log(_chalk.default.gray('Please refer to docs.axway.com for information on creating the necessary AWS IAM policies'));
|
|
283
283
|
if (hostedAgentValues.authType === AWSAuthType.ASSUME) {
|
|
284
|
-
log(
|
|
284
|
+
log('using an assume role policy authentication');
|
|
285
285
|
// get assume role arn
|
|
286
286
|
hostedAgentValues.assumeRole = await (0, _basicPrompts.askInput)({
|
|
287
287
|
msg: SaasPrompts.ASSUME_ROLE,
|
|
@@ -296,7 +296,7 @@ const askForAWSCredentials = async hostedAgentValues => {
|
|
|
296
296
|
allowEmptyInput: true
|
|
297
297
|
});
|
|
298
298
|
} else {
|
|
299
|
-
log(
|
|
299
|
+
log('using key and secret authentication');
|
|
300
300
|
// get access key
|
|
301
301
|
hostedAgentValues.accessKey = await (0, _basicPrompts.askInput)({
|
|
302
302
|
msg: SaasPrompts.ACCESS_KEY,
|
|
@@ -315,7 +315,7 @@ const askForAWSCredentials = async hostedAgentValues => {
|
|
|
315
315
|
};
|
|
316
316
|
const validateFrequency = () => input => {
|
|
317
317
|
let val = (0, _basicPrompts.validateRegex)(helpers.frequencyRegex, helpers.invalidValueExampleErrMsg('frequency', '3d5h12m'))(input);
|
|
318
|
-
if (typeof val ===
|
|
318
|
+
if (typeof val === 'string') {
|
|
319
319
|
return val;
|
|
320
320
|
}
|
|
321
321
|
let r = input.toString().match(/^(\d*)m/);
|
|
@@ -323,7 +323,7 @@ const validateFrequency = () => input => {
|
|
|
323
323
|
// only minutes
|
|
324
324
|
let mins = r[1];
|
|
325
325
|
if (parseInt(mins, 10) < 30) {
|
|
326
|
-
return
|
|
326
|
+
return 'Minimum frequency is 30m';
|
|
327
327
|
}
|
|
328
328
|
}
|
|
329
329
|
return true;
|
|
@@ -341,7 +341,7 @@ const gatewayConnectivity = async installConfig => {
|
|
|
341
341
|
hostedAgentValues = new SaasAWSAgentValues();
|
|
342
342
|
hostedAgentValues = await askForAWSCredentials(hostedAgentValues);
|
|
343
343
|
if (installConfig.switches.isTaEnabled) {
|
|
344
|
-
console.log(_chalk.default.gray(
|
|
344
|
+
console.log(_chalk.default.gray('\nThe access log ARN is a cloud watch log group amazon resource name'));
|
|
345
345
|
hostedAgentValues.accessLogARN = await (0, _basicPrompts.askInput)({
|
|
346
346
|
msg: SaasPrompts.ACCESS_LOG_ARN,
|
|
347
347
|
validate: (0, _basicPrompts.validateRegex)(helpers.AWSRegexPatterns.AWS_ACCESS_LOG_ARN, helpers.invalidValueExampleErrMsg('access log arn', 'arn:aws:logs:region:000000000000:log-group:log-group-name'))
|
|
@@ -350,8 +350,8 @@ const gatewayConnectivity = async installConfig => {
|
|
|
350
350
|
}
|
|
351
351
|
|
|
352
352
|
// Ask to queue discovery now
|
|
353
|
-
log(
|
|
354
|
-
console.log(_chalk.default.gray(
|
|
353
|
+
log('getting the frequency and if the agent should run now');
|
|
354
|
+
console.log(_chalk.default.gray('\n00d00h00m format, where 30m = 30 minutes, 1h = 1 hour, 7d = 7 days, and 7d1h30m = 7 days 1 hour and 30 minutes. Minimum of 30m.'));
|
|
355
355
|
hostedAgentValues.frequencyDA = await (0, _basicPrompts.askInput)({
|
|
356
356
|
msg: SaasPrompts.DA_FREQUENCY,
|
|
357
357
|
validate: validateFrequency(),
|
|
@@ -363,10 +363,10 @@ const gatewayConnectivity = async installConfig => {
|
|
|
363
363
|
choices: _types.YesNoChoices
|
|
364
364
|
})) === _types.YesNo.Yes;
|
|
365
365
|
if (installConfig.switches.isTaEnabled) {
|
|
366
|
-
console.log(_chalk.default.gray(
|
|
366
|
+
console.log(_chalk.default.gray('\n00d00h00m format, where 30m = 30 minutes, 1h = 1 hour, 7d = 7 days, and 7d1h30m = 7 days 1 hour and 30 minutes. Minimum of 30m.'));
|
|
367
367
|
hostedAgentValues.frequencyTA = await (0, _basicPrompts.askInput)({
|
|
368
368
|
msg: SaasPrompts.TA_FREQUENCY,
|
|
369
|
-
defaultValue:
|
|
369
|
+
defaultValue: '30m',
|
|
370
370
|
validate: validateFrequency(),
|
|
371
371
|
allowEmptyInput: true
|
|
372
372
|
});
|
|
@@ -381,9 +381,9 @@ const generateOutput = async installConfig => {
|
|
|
381
381
|
const createEncryptedAccessData = async (hostedAgentValues, dataplaneRes) => {
|
|
382
382
|
var _dataplaneRes$securit, _dataplaneRes$securit2;
|
|
383
383
|
// grab key from data plane resource
|
|
384
|
-
let key = ((_dataplaneRes$securit = dataplaneRes.security) === null || _dataplaneRes$securit === void 0 ? void 0 : _dataplaneRes$securit.encryptionKey) ||
|
|
385
|
-
let hash = ((_dataplaneRes$securit2 = dataplaneRes.security) === null || _dataplaneRes$securit2 === void 0 ? void 0 : _dataplaneRes$securit2.encryptionHash) ||
|
|
386
|
-
if (key ===
|
|
384
|
+
let key = ((_dataplaneRes$securit = dataplaneRes.security) === null || _dataplaneRes$securit === void 0 ? void 0 : _dataplaneRes$securit.encryptionKey) || '';
|
|
385
|
+
let hash = ((_dataplaneRes$securit2 = dataplaneRes.security) === null || _dataplaneRes$securit2 === void 0 ? void 0 : _dataplaneRes$securit2.encryptionHash) || '';
|
|
386
|
+
if (key === '' || hash === '') {
|
|
387
387
|
throw Error(`cannot encrypt access data as the encryption key info was incomplete`);
|
|
388
388
|
}
|
|
389
389
|
let encData = _crypto.default.publicEncrypt({
|
|
@@ -391,13 +391,13 @@ const createEncryptedAccessData = async (hostedAgentValues, dataplaneRes) => {
|
|
|
391
391
|
padding: _crypto.default.constants.RSA_PKCS1_OAEP_PADDING,
|
|
392
392
|
oaepHash: hash
|
|
393
393
|
}, Buffer.from(hostedAgentValues.getAccessData()));
|
|
394
|
-
return encData.toString(
|
|
394
|
+
return encData.toString('base64');
|
|
395
395
|
};
|
|
396
396
|
const completeInstall = async (installConfig, apiServerClient, defsManager) => {
|
|
397
397
|
/**
|
|
398
398
|
* Create agent resources
|
|
399
399
|
*/
|
|
400
|
-
console.log(
|
|
400
|
+
console.log('\n');
|
|
401
401
|
let awsAgentValues = installConfig.gatewayConfig;
|
|
402
402
|
|
|
403
403
|
// create the environment, if necessary
|
|
@@ -409,7 +409,7 @@ const completeInstall = async (installConfig, apiServerClient, defsManager) => {
|
|
|
409
409
|
if (installConfig.switches.isTaEnabled) {
|
|
410
410
|
awsAgentValues.dataplaneConfig = new AWSDataplaneConfig(awsAgentValues.accessLogARN);
|
|
411
411
|
} else {
|
|
412
|
-
awsAgentValues.dataplaneConfig = new DataplaneConfig(
|
|
412
|
+
awsAgentValues.dataplaneConfig = new DataplaneConfig('AWS');
|
|
413
413
|
}
|
|
414
414
|
}
|
|
415
415
|
|
|
@@ -420,20 +420,20 @@ const completeInstall = async (installConfig, apiServerClient, defsManager) => {
|
|
|
420
420
|
try {
|
|
421
421
|
await helpers.createNewDataPlaneSecretResource(apiServerClient, defsManager, installConfig.centralConfig.environment, _types.GatewayTypeToDataPlane[installConfig.gatewayType], dataplaneRes.name, await createEncryptedAccessData(awsAgentValues, dataplaneRes));
|
|
422
422
|
} catch (error) {
|
|
423
|
-
console.log(_chalk.default.redBright(
|
|
423
|
+
console.log(_chalk.default.redBright('rolling back installation. Please check the credential data before re-running install'));
|
|
424
424
|
if (installConfig.centralConfig.ampcEnvInfo.isNew) {
|
|
425
425
|
await helpers.deleteByResourceType(apiServerClient, defsManager, installConfig.centralConfig.ampcEnvInfo.name, 'Environment', 'env');
|
|
426
426
|
} else {
|
|
427
|
-
await helpers.deleteByResourceType(apiServerClient, defsManager, dataplaneRes.name,
|
|
427
|
+
await helpers.deleteByResourceType(apiServerClient, defsManager, dataplaneRes.name, 'Dataplane', 'dp', installConfig.centralConfig.environment);
|
|
428
428
|
}
|
|
429
429
|
return;
|
|
430
430
|
}
|
|
431
431
|
|
|
432
|
-
// create discovery agent resource
|
|
433
|
-
installConfig.centralConfig.daAgentName = await helpers.createNewAgentResource(apiServerClient, defsManager, installConfig.centralConfig.environment, _types.GatewayTypeToDataPlane[installConfig.gatewayType], _types.AgentResourceKind.da, _types.AgentTypes.da, installConfig.centralConfig.ampcTeamName, _types.GatewayTypeToDataPlane[installConfig.gatewayType] +
|
|
432
|
+
// create discovery agent resource
|
|
433
|
+
installConfig.centralConfig.daAgentName = await helpers.createNewAgentResource(apiServerClient, defsManager, installConfig.centralConfig.environment, _types.GatewayTypeToDataPlane[installConfig.gatewayType], _types.AgentResourceKind.da, _types.AgentTypes.da, installConfig.centralConfig.ampcTeamName, _types.GatewayTypeToDataPlane[installConfig.gatewayType] + ' Discovery Agent', dataplaneRes.name, awsAgentValues.frequencyDA, awsAgentValues.queueDA);
|
|
434
434
|
if (installConfig.switches.isTaEnabled) {
|
|
435
|
-
// create traceability agent resource
|
|
436
|
-
installConfig.centralConfig.taAgentName = await helpers.createNewAgentResource(apiServerClient, defsManager, installConfig.centralConfig.environment, _types.GatewayTypeToDataPlane[installConfig.gatewayType], _types.AgentResourceKind.ta, _types.AgentTypes.ta, installConfig.centralConfig.ampcTeamName, _types.GatewayTypeToDataPlane[installConfig.gatewayType] +
|
|
435
|
+
// create traceability agent resource
|
|
436
|
+
installConfig.centralConfig.taAgentName = await helpers.createNewAgentResource(apiServerClient, defsManager, installConfig.centralConfig.environment, _types.GatewayTypeToDataPlane[installConfig.gatewayType], _types.AgentResourceKind.ta, _types.AgentTypes.ta, installConfig.centralConfig.ampcTeamName, _types.GatewayTypeToDataPlane[installConfig.gatewayType] + ' Traceability Agent', dataplaneRes.name, awsAgentValues.frequencyTA, false,
|
|
437
437
|
// AWS TA is never triggered at install, as DA has to run prior
|
|
438
438
|
{
|
|
439
439
|
sampling: awsAgentValues.sampling,
|
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.testables = exports.askBundleType = exports.AzureSaaSInstallMethods = void 0;
|
|
7
|
+
var _chalk = _interopRequireDefault(require("chalk"));
|
|
8
|
+
var _snooplogg = _interopRequireDefault(require("snooplogg"));
|
|
9
|
+
var _basicPrompts = require("../../common/basicPrompts");
|
|
10
|
+
var _types = require("../../common/types");
|
|
11
|
+
var _utils = require("../../common/utils");
|
|
12
|
+
var helpers = _interopRequireWildcard(require("./helpers"));
|
|
13
|
+
var _crypto = _interopRequireDefault(require("crypto"));
|
|
14
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
15
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
16
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
|
+
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
18
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
19
|
+
function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
|
|
20
|
+
const {
|
|
21
|
+
log
|
|
22
|
+
} = (0, _snooplogg.default)('central: install: agents: saas');
|
|
23
|
+
const InvalidMessages = {
|
|
24
|
+
enterApiManagementServiceName: `The API Management Service Name can contain only letters, numbers and hyphens. The first character must be a letter and last character must be a letter or a number.`
|
|
25
|
+
};
|
|
26
|
+
class DataplaneConfig {
|
|
27
|
+
constructor(type) {
|
|
28
|
+
_defineProperty(this, "type", void 0);
|
|
29
|
+
this.type = type || '';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
class AzureDataplaneConfig extends DataplaneConfig {
|
|
33
|
+
constructor(tenantId, resourceGroup, subscriptionId, apimServiceName, eventHubName, eventHubNamespace, eventHubConsumerGroup) {
|
|
34
|
+
super('Azure');
|
|
35
|
+
_defineProperty(this, "tenantId", void 0);
|
|
36
|
+
_defineProperty(this, "resourceGroup", void 0);
|
|
37
|
+
_defineProperty(this, "subscriptionId", void 0);
|
|
38
|
+
_defineProperty(this, "apimServiceName", void 0);
|
|
39
|
+
_defineProperty(this, "eventHubName", void 0);
|
|
40
|
+
_defineProperty(this, "eventHubNamespace", void 0);
|
|
41
|
+
_defineProperty(this, "eventHubConsumerGroup", void 0);
|
|
42
|
+
this.tenantId = tenantId;
|
|
43
|
+
this.resourceGroup = resourceGroup;
|
|
44
|
+
this.subscriptionId = subscriptionId;
|
|
45
|
+
this.apimServiceName = apimServiceName;
|
|
46
|
+
this.eventHubName = eventHubName;
|
|
47
|
+
this.eventHubNamespace = eventHubNamespace;
|
|
48
|
+
this.eventHubConsumerGroup = eventHubConsumerGroup;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
class Sampling {
|
|
52
|
+
constructor() {
|
|
53
|
+
_defineProperty(this, "percentage", void 0);
|
|
54
|
+
_defineProperty(this, "allErrors", void 0);
|
|
55
|
+
this.percentage = 1;
|
|
56
|
+
this.allErrors = true;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
class Sanitize {
|
|
60
|
+
constructor(k, m) {
|
|
61
|
+
_defineProperty(this, "keyMatch", void 0);
|
|
62
|
+
_defineProperty(this, "valueMatch", void 0);
|
|
63
|
+
this.keyMatch = k;
|
|
64
|
+
this.valueMatch = m;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
class RedactionSet {
|
|
68
|
+
constructor() {
|
|
69
|
+
_defineProperty(this, "show", void 0);
|
|
70
|
+
_defineProperty(this, "sanitize", void 0);
|
|
71
|
+
this.show = [];
|
|
72
|
+
this.sanitize = [];
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
class Redaction {
|
|
76
|
+
constructor() {
|
|
77
|
+
_defineProperty(this, "maskingCharacter", void 0);
|
|
78
|
+
_defineProperty(this, "path", void 0);
|
|
79
|
+
_defineProperty(this, "queryArgument", void 0);
|
|
80
|
+
_defineProperty(this, "requestHeaders", void 0);
|
|
81
|
+
_defineProperty(this, "responseHeaders", void 0);
|
|
82
|
+
this.maskingCharacter = '{*}';
|
|
83
|
+
this.path = [];
|
|
84
|
+
this.queryArgument = new RedactionSet();
|
|
85
|
+
this.requestHeaders = new RedactionSet();
|
|
86
|
+
this.responseHeaders = new RedactionSet();
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
class SaasAgentValues {
|
|
90
|
+
constructor() {
|
|
91
|
+
_defineProperty(this, "frequencyDA", void 0);
|
|
92
|
+
_defineProperty(this, "queueDA", void 0);
|
|
93
|
+
_defineProperty(this, "frequencyTA", void 0);
|
|
94
|
+
_defineProperty(this, "sampling", void 0);
|
|
95
|
+
_defineProperty(this, "redaction", void 0);
|
|
96
|
+
_defineProperty(this, "dataplaneConfig", void 0);
|
|
97
|
+
_defineProperty(this, "centralConfig", void 0);
|
|
98
|
+
this.frequencyDA = '';
|
|
99
|
+
this.queueDA = false;
|
|
100
|
+
this.frequencyTA = '';
|
|
101
|
+
this.sampling = new Sampling();
|
|
102
|
+
this.redaction = new Redaction();
|
|
103
|
+
this.dataplaneConfig = new DataplaneConfig();
|
|
104
|
+
this.centralConfig = new _types.CentralAgentConfig();
|
|
105
|
+
}
|
|
106
|
+
getAccessData() {
|
|
107
|
+
return '';
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
class SaasAzureAgentValues extends SaasAgentValues {
|
|
111
|
+
constructor() {
|
|
112
|
+
super();
|
|
113
|
+
_defineProperty(this, "clientID", void 0);
|
|
114
|
+
_defineProperty(this, "clientSecret", void 0);
|
|
115
|
+
_defineProperty(this, "sharedAccessKeyName", void 0);
|
|
116
|
+
_defineProperty(this, "sharedAccessKeyValue", void 0);
|
|
117
|
+
_defineProperty(this, "eventHubName", void 0);
|
|
118
|
+
_defineProperty(this, "eventHubNamespace", void 0);
|
|
119
|
+
_defineProperty(this, "eventHubConsumerGroup", void 0);
|
|
120
|
+
_defineProperty(this, "resourceGroup", void 0);
|
|
121
|
+
_defineProperty(this, "apimManagementServiceName", void 0);
|
|
122
|
+
_defineProperty(this, "subscriptionId", void 0);
|
|
123
|
+
_defineProperty(this, "tenantId", void 0);
|
|
124
|
+
this.clientID = '';
|
|
125
|
+
this.clientSecret = '';
|
|
126
|
+
this.sharedAccessKeyName = '';
|
|
127
|
+
this.sharedAccessKeyValue = '';
|
|
128
|
+
this.eventHubName = '';
|
|
129
|
+
this.eventHubNamespace = '';
|
|
130
|
+
this.eventHubConsumerGroup = '';
|
|
131
|
+
this.resourceGroup = '';
|
|
132
|
+
this.apimManagementServiceName = '';
|
|
133
|
+
this.subscriptionId = '';
|
|
134
|
+
this.tenantId = '';
|
|
135
|
+
}
|
|
136
|
+
getAccessData() {
|
|
137
|
+
let data = JSON.stringify({
|
|
138
|
+
clientID: this.clientID,
|
|
139
|
+
clientSecret: this.clientSecret,
|
|
140
|
+
sharedAccessKeyName: this.sharedAccessKeyName,
|
|
141
|
+
sharedAccessKeyValue: this.sharedAccessKeyValue
|
|
142
|
+
});
|
|
143
|
+
return data;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// ConfigFiles - all the config file that are used in the setup
|
|
148
|
+
const ConfigFiles = {};
|
|
149
|
+
|
|
150
|
+
// AzureSaaSPrompts - all Azure Saas prompts to the user for input
|
|
151
|
+
const SaasPrompts = {
|
|
152
|
+
AUTHENTICATION_TYPE: 'Authenticate with Client and Shared Access Key',
|
|
153
|
+
TENANT_ID: 'Enter the Azure Tenant ID',
|
|
154
|
+
SUBSCRIPTION_ID: 'Enter the Azure Subscription ID',
|
|
155
|
+
CLIENT_ID: 'Enter the Azure Service Principal Client ID',
|
|
156
|
+
CLIENT_SECRET: 'Enter the Azure Service Principal Client Secret',
|
|
157
|
+
RESOURCE_GROUP_NAME: 'Enter the Azure Resource Group Name',
|
|
158
|
+
APIM_SERVICE_MANAGEMENT_NAME: 'Enter the Azure API Management Service Name',
|
|
159
|
+
SHARED_ACCESS_KEY_NAME: 'Enter the Azure Policy Name',
|
|
160
|
+
SHARED_ACCESS_KEY_VALUE: 'Enter the Azure Policy Key',
|
|
161
|
+
EVENT_HUB_NAME: 'Enter the Azure Event Hub Name',
|
|
162
|
+
EVENT_HUB_NAMESPACE: 'Enter the Azure Event Hub Namespace',
|
|
163
|
+
EVENT_HUB_CONSUMER_GROUP: 'Enter the Azure Event Hub Consumer Group',
|
|
164
|
+
// general prompts
|
|
165
|
+
DA_FREQUENCY: 'How often should the discovery run, leave blank for integrating in CI/CD process',
|
|
166
|
+
TA_FREQUENCY: 'How often should the traffic collection run, leave blank for manual trigger only',
|
|
167
|
+
QUEUE: 'Do you want to discover immediately after installation',
|
|
168
|
+
SAMP_PERCENTAGE: 'Enter the percentage of transactions to sample',
|
|
169
|
+
SAMP_ALL_ERRS: 'Do you want to see all errors regardless of sampling',
|
|
170
|
+
REDACT_SHOW: 'Enter a regular expression for {0}s that may be shown',
|
|
171
|
+
ENTER_SANITIZE_RULE: 'Do you want to add sanitization rules for {0}s',
|
|
172
|
+
SANITIZE_KEY: 'Enter a regular expression for {0} keys that values should be sanitized',
|
|
173
|
+
SANITIZE_VAL: 'Enter a regular expression for sanitization of values when matching a {0} key',
|
|
174
|
+
MASKING_CHARS: 'Enter the characters to use when sanitizing a value',
|
|
175
|
+
ENTER_MORE: 'Do you want to enter another {0} for {1}'
|
|
176
|
+
};
|
|
177
|
+
const askBundleType = async () => {
|
|
178
|
+
return await (0, _basicPrompts.askList)({
|
|
179
|
+
msg: helpers.agentMessages.selectAgentType,
|
|
180
|
+
choices: [_types.BundleType.ALL_AGENTS, _types.BundleType.DISCOVERY]
|
|
181
|
+
});
|
|
182
|
+
};
|
|
183
|
+
exports.askBundleType = askBundleType;
|
|
184
|
+
const askConfigType = async () => {
|
|
185
|
+
return _types.AgentConfigTypes.HOSTED;
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
//
|
|
189
|
+
// Complex prompts
|
|
190
|
+
//
|
|
191
|
+
const askForRedactionSet = async (setting, redactionSet) => {
|
|
192
|
+
// ask for path reg exs
|
|
193
|
+
let askShow = true;
|
|
194
|
+
console.log(_chalk.default.gray((0, _utils.FormatString)('\nRedaction settings for {0}s', setting)));
|
|
195
|
+
while (askShow) {
|
|
196
|
+
const input = await (0, _basicPrompts.askInput)({
|
|
197
|
+
msg: (0, _utils.FormatString)(SaasPrompts.REDACT_SHOW, setting),
|
|
198
|
+
defaultValue: '.*',
|
|
199
|
+
validate: (0, _basicPrompts.validateValidRegex)()
|
|
200
|
+
});
|
|
201
|
+
redactionSet.show.push(input);
|
|
202
|
+
askShow = (await (0, _basicPrompts.askList)({
|
|
203
|
+
msg: (0, _utils.FormatString)(SaasPrompts.ENTER_MORE, 'redaction regular expression', setting),
|
|
204
|
+
default: _types.YesNo.No,
|
|
205
|
+
choices: _types.YesNoChoices
|
|
206
|
+
})) === _types.YesNo.Yes;
|
|
207
|
+
}
|
|
208
|
+
console.log(_chalk.default.gray((0, _utils.FormatString)('Sanitization settings for {0}s', setting)));
|
|
209
|
+
let askSanitize = (await (0, _basicPrompts.askList)({
|
|
210
|
+
msg: (0, _utils.FormatString)(SaasPrompts.ENTER_SANITIZE_RULE, setting),
|
|
211
|
+
default: _types.YesNo.No,
|
|
212
|
+
choices: _types.YesNoChoices
|
|
213
|
+
})) === _types.YesNo.Yes;
|
|
214
|
+
console.log(_chalk.default.gray('When a match for the key regular expression is found, a match\nfor the value regular expression will be replaced by the masking character(s)'));
|
|
215
|
+
while (askSanitize) {
|
|
216
|
+
const keyMatch = await (0, _basicPrompts.askInput)({
|
|
217
|
+
msg: (0, _utils.FormatString)(SaasPrompts.SANITIZE_KEY, setting),
|
|
218
|
+
allowEmptyInput: true,
|
|
219
|
+
validate: (0, _basicPrompts.validateValidRegex)()
|
|
220
|
+
});
|
|
221
|
+
const valMatch = await (0, _basicPrompts.askInput)({
|
|
222
|
+
msg: (0, _utils.FormatString)(SaasPrompts.SANITIZE_VAL, setting),
|
|
223
|
+
allowEmptyInput: true,
|
|
224
|
+
validate: (0, _basicPrompts.validateValidRegex)()
|
|
225
|
+
});
|
|
226
|
+
if (keyMatch === '' || valMatch === '') {
|
|
227
|
+
console.log("can't add sanitization rule with an empty key or value regular expression");
|
|
228
|
+
} else {
|
|
229
|
+
redactionSet.sanitize.push(new Sanitize(keyMatch, valMatch));
|
|
230
|
+
}
|
|
231
|
+
askSanitize = (await (0, _basicPrompts.askList)({
|
|
232
|
+
msg: (0, _utils.FormatString)(SaasPrompts.ENTER_MORE, 'sanitization rule', setting),
|
|
233
|
+
default: _types.YesNo.No,
|
|
234
|
+
choices: _types.YesNoChoices
|
|
235
|
+
})) === _types.YesNo.Yes;
|
|
236
|
+
}
|
|
237
|
+
return redactionSet;
|
|
238
|
+
};
|
|
239
|
+
const askForRedaction = async hostedAgentValues => {
|
|
240
|
+
console.log(_chalk.default.gray('\nRedaction and Sanitization settings'));
|
|
241
|
+
// ask for path reg exps
|
|
242
|
+
let askPaths = true;
|
|
243
|
+
console.log(_chalk.default.gray('\nRedaction settings for URL paths'));
|
|
244
|
+
while (askPaths) {
|
|
245
|
+
const input = await (0, _basicPrompts.askInput)({
|
|
246
|
+
msg: (0, _utils.FormatString)(SaasPrompts.REDACT_SHOW, 'URL path'),
|
|
247
|
+
defaultValue: '.*',
|
|
248
|
+
validate: (0, _basicPrompts.validateValidRegex)()
|
|
249
|
+
});
|
|
250
|
+
hostedAgentValues.redaction.path.push(input);
|
|
251
|
+
askPaths = (await (0, _basicPrompts.askList)({
|
|
252
|
+
msg: (0, _utils.FormatString)(SaasPrompts.ENTER_MORE, 'redaction regular expression', 'URL path'),
|
|
253
|
+
default: _types.YesNo.No,
|
|
254
|
+
choices: _types.YesNoChoices
|
|
255
|
+
})) === _types.YesNo.Yes;
|
|
256
|
+
}
|
|
257
|
+
hostedAgentValues.redaction.queryArgument = await askForRedactionSet('query argument', hostedAgentValues.redaction.queryArgument);
|
|
258
|
+
hostedAgentValues.redaction.requestHeaders = await askForRedactionSet('request header', hostedAgentValues.redaction.requestHeaders);
|
|
259
|
+
hostedAgentValues.redaction.responseHeaders = await askForRedactionSet('response header', hostedAgentValues.redaction.responseHeaders);
|
|
260
|
+
hostedAgentValues.redaction.maskingCharacter = await (0, _basicPrompts.askInput)({
|
|
261
|
+
msg: SaasPrompts.MASKING_CHARS,
|
|
262
|
+
defaultValue: '{*}',
|
|
263
|
+
validate: (0, _basicPrompts.validateRegex)(helpers.maskingRegex, 'Please enter a valid value')
|
|
264
|
+
});
|
|
265
|
+
return hostedAgentValues;
|
|
266
|
+
};
|
|
267
|
+
const askForSampling = async hostedAgentValues => {
|
|
268
|
+
// ask sampling percentage
|
|
269
|
+
console.log(_chalk.default.gray('\nSampling settings'));
|
|
270
|
+
console.log(_chalk.default.gray('Sampling percentage can be a value from 0 to 10'));
|
|
271
|
+
hostedAgentValues.sampling.percentage = await (0, _basicPrompts.askInput)({
|
|
272
|
+
type: 'number',
|
|
273
|
+
msg: SaasPrompts.SAMP_PERCENTAGE,
|
|
274
|
+
defaultValue: 1,
|
|
275
|
+
validate: (0, _basicPrompts.validateValueRange)(0, 10)
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
// ask sampling all errorsSN
|
|
279
|
+
hostedAgentValues.sampling.allErrors = (await (0, _basicPrompts.askList)({
|
|
280
|
+
msg: SaasPrompts.SAMP_ALL_ERRS,
|
|
281
|
+
choices: _types.YesNoChoices
|
|
282
|
+
})) === _types.YesNo.Yes;
|
|
283
|
+
return hostedAgentValues;
|
|
284
|
+
};
|
|
285
|
+
const askForAzureCredentials = async (hostedAgentValues, installConfig) => {
|
|
286
|
+
log('gathering access details for azure');
|
|
287
|
+
hostedAgentValues.tenantId = await (0, _basicPrompts.askInput)({
|
|
288
|
+
msg: SaasPrompts.TENANT_ID
|
|
289
|
+
});
|
|
290
|
+
hostedAgentValues.subscriptionId = await (0, _basicPrompts.askInput)({
|
|
291
|
+
msg: SaasPrompts.SUBSCRIPTION_ID
|
|
292
|
+
});
|
|
293
|
+
hostedAgentValues.clientID = await (0, _basicPrompts.askInput)({
|
|
294
|
+
msg: SaasPrompts.CLIENT_ID
|
|
295
|
+
});
|
|
296
|
+
hostedAgentValues.clientSecret = await (0, _basicPrompts.askInput)({
|
|
297
|
+
msg: SaasPrompts.CLIENT_SECRET
|
|
298
|
+
});
|
|
299
|
+
hostedAgentValues.resourceGroup = await (0, _basicPrompts.askInput)({
|
|
300
|
+
msg: SaasPrompts.RESOURCE_GROUP_NAME
|
|
301
|
+
});
|
|
302
|
+
hostedAgentValues.apimManagementServiceName = await (0, _basicPrompts.askInput)({
|
|
303
|
+
msg: SaasPrompts.APIM_SERVICE_MANAGEMENT_NAME,
|
|
304
|
+
validate: (0, _basicPrompts.validateRegex)(helpers.AzureRegexPatterns.azureApiManagementServiceNameRegex, InvalidMessages.enterApiManagementServiceName)
|
|
305
|
+
});
|
|
306
|
+
if (installConfig.switches.isTaEnabled) {
|
|
307
|
+
hostedAgentValues.sharedAccessKeyName = await (0, _basicPrompts.askInput)({
|
|
308
|
+
msg: SaasPrompts.SHARED_ACCESS_KEY_NAME,
|
|
309
|
+
defaultValue: 'RootManageSharedAccessKey'
|
|
310
|
+
});
|
|
311
|
+
hostedAgentValues.sharedAccessKeyValue = await (0, _basicPrompts.askInput)({
|
|
312
|
+
msg: SaasPrompts.SHARED_ACCESS_KEY_VALUE
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
return hostedAgentValues;
|
|
316
|
+
};
|
|
317
|
+
const validateFrequency = () => input => {
|
|
318
|
+
let val = (0, _basicPrompts.validateRegex)(helpers.frequencyRegex, helpers.invalidValueExampleErrMsg('frequency', '3d5h12m'))(input);
|
|
319
|
+
if (typeof val === 'string') {
|
|
320
|
+
return val;
|
|
321
|
+
}
|
|
322
|
+
let r = input.toString().match(/^(\d*)m/);
|
|
323
|
+
if (r) {
|
|
324
|
+
// only minutes
|
|
325
|
+
let mins = r[1];
|
|
326
|
+
if (parseInt(mins, 10) < 30) {
|
|
327
|
+
return 'Minimum frequency is 30m';
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return true;
|
|
331
|
+
};
|
|
332
|
+
|
|
333
|
+
// @ts-ignore
|
|
334
|
+
const gatewayConnectivity = async installConfig => {
|
|
335
|
+
console.log('\nCONNECTION TO Azure API GATEWAY:');
|
|
336
|
+
console.log(_chalk.default.gray("The Discovery Agent needs to connect to the Azure API Gateway to discover API's for publishing to Amplify Central"));
|
|
337
|
+
|
|
338
|
+
// DeploymentType
|
|
339
|
+
let hostedAgentValues = new SaasAgentValues();
|
|
340
|
+
if (installConfig.gatewayType === _types.GatewayTypes.AZURE_GATEWAY) {
|
|
341
|
+
// Azure connection details
|
|
342
|
+
hostedAgentValues = new SaasAzureAgentValues();
|
|
343
|
+
hostedAgentValues = await askForAzureCredentials(hostedAgentValues, installConfig);
|
|
344
|
+
if (installConfig.switches.isTaEnabled) {
|
|
345
|
+
hostedAgentValues.eventHubName = await (0, _basicPrompts.askInput)({
|
|
346
|
+
msg: SaasPrompts.EVENT_HUB_NAME
|
|
347
|
+
});
|
|
348
|
+
hostedAgentValues.eventHubNamespace = await (0, _basicPrompts.askInput)({
|
|
349
|
+
msg: SaasPrompts.EVENT_HUB_NAMESPACE
|
|
350
|
+
});
|
|
351
|
+
hostedAgentValues.eventHubConsumerGroup = await (0, _basicPrompts.askInput)({
|
|
352
|
+
msg: SaasPrompts.EVENT_HUB_CONSUMER_GROUP,
|
|
353
|
+
defaultValue: '$Default'
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// Ask to queue discovery now
|
|
359
|
+
log('getting the frequency and if the agent should run now');
|
|
360
|
+
console.log(_chalk.default.gray('\n00d00h00m format, where 30m = 30 minutes, 1h = 1 hour, 7d = 7 days, and 7d1h30m = 7 days 1 hour and 30 minutes. Minimum of 30m.'));
|
|
361
|
+
hostedAgentValues.frequencyDA = await (0, _basicPrompts.askInput)({
|
|
362
|
+
msg: SaasPrompts.DA_FREQUENCY,
|
|
363
|
+
validate: validateFrequency(),
|
|
364
|
+
allowEmptyInput: true
|
|
365
|
+
});
|
|
366
|
+
hostedAgentValues.queueDA = (await (0, _basicPrompts.askList)({
|
|
367
|
+
msg: SaasPrompts.QUEUE,
|
|
368
|
+
default: _types.YesNo.No,
|
|
369
|
+
choices: _types.YesNoChoices
|
|
370
|
+
})) === _types.YesNo.Yes;
|
|
371
|
+
if (installConfig.switches.isTaEnabled) {
|
|
372
|
+
console.log(_chalk.default.gray('\n00d00h00m format, where 30m = 30 minutes, 1h = 1 hour, 7d = 7 days, and 7d1h30m = 7 days 1 hour and 30 minutes. Minimum of 30m.'));
|
|
373
|
+
hostedAgentValues.frequencyTA = await (0, _basicPrompts.askInput)({
|
|
374
|
+
msg: SaasPrompts.TA_FREQUENCY,
|
|
375
|
+
defaultValue: '30m',
|
|
376
|
+
validate: validateFrequency(),
|
|
377
|
+
allowEmptyInput: true
|
|
378
|
+
});
|
|
379
|
+
hostedAgentValues = await askForSampling(hostedAgentValues);
|
|
380
|
+
hostedAgentValues = await askForRedaction(hostedAgentValues);
|
|
381
|
+
}
|
|
382
|
+
return hostedAgentValues;
|
|
383
|
+
};
|
|
384
|
+
const generateOutput = async installConfig => {
|
|
385
|
+
return `Install complete of hosted agent for ${installConfig.gatewayType} region`;
|
|
386
|
+
};
|
|
387
|
+
const createEncryptedAccessData = async (hostedAgentValues, dataplaneRes) => {
|
|
388
|
+
var _dataplaneRes$securit, _dataplaneRes$securit2;
|
|
389
|
+
// grab key from data plane resource
|
|
390
|
+
let key = ((_dataplaneRes$securit = dataplaneRes.security) === null || _dataplaneRes$securit === void 0 ? void 0 : _dataplaneRes$securit.encryptionKey) || '';
|
|
391
|
+
let hash = ((_dataplaneRes$securit2 = dataplaneRes.security) === null || _dataplaneRes$securit2 === void 0 ? void 0 : _dataplaneRes$securit2.encryptionHash) || '';
|
|
392
|
+
if (key === '' || hash === '') {
|
|
393
|
+
throw Error(`cannot encrypt access data as the encryption key info was incomplete`);
|
|
394
|
+
}
|
|
395
|
+
let encData = _crypto.default.publicEncrypt({
|
|
396
|
+
key: key,
|
|
397
|
+
padding: _crypto.default.constants.RSA_PKCS1_OAEP_PADDING,
|
|
398
|
+
oaepHash: hash
|
|
399
|
+
}, Buffer.from(hostedAgentValues.getAccessData()));
|
|
400
|
+
return encData.toString('base64');
|
|
401
|
+
};
|
|
402
|
+
const completeInstall = async (installConfig, apiServerClient, defsManager) => {
|
|
403
|
+
/**
|
|
404
|
+
* Create agent resources
|
|
405
|
+
*/
|
|
406
|
+
console.log('\n');
|
|
407
|
+
let azureAgentValues = installConfig.gatewayConfig;
|
|
408
|
+
|
|
409
|
+
// create the environment, if necessary
|
|
410
|
+
installConfig.centralConfig.environment = installConfig.centralConfig.ampcEnvInfo.isNew ? await helpers.createByResourceType(apiServerClient, defsManager, installConfig.centralConfig.ampcEnvInfo.name, 'Environment', 'env', {
|
|
411
|
+
axwayManaged: installConfig.centralConfig.axwayManaged,
|
|
412
|
+
production: installConfig.centralConfig.production
|
|
413
|
+
}) : installConfig.centralConfig.ampcEnvInfo.name;
|
|
414
|
+
if (installConfig.gatewayType === _types.GatewayTypes.AZURE_GATEWAY) {
|
|
415
|
+
azureAgentValues.dataplaneConfig = new AzureDataplaneConfig(azureAgentValues.tenantId, azureAgentValues.resourceGroup, azureAgentValues.subscriptionId, azureAgentValues.apimManagementServiceName);
|
|
416
|
+
if (installConfig.switches.isTaEnabled) {
|
|
417
|
+
azureAgentValues.dataplaneConfig = new AzureDataplaneConfig(azureAgentValues.tenantId, azureAgentValues.resourceGroup, azureAgentValues.subscriptionId, azureAgentValues.apimManagementServiceName, azureAgentValues.eventHubName, azureAgentValues.eventHubNamespace, azureAgentValues.eventHubConsumerGroup);
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
// create the data plane resource
|
|
421
|
+
let dataplaneRes;
|
|
422
|
+
try {
|
|
423
|
+
dataplaneRes = await helpers.createNewDataPlaneResource(apiServerClient, defsManager, installConfig.centralConfig.environment, _types.GatewayTypeToDataPlane[installConfig.gatewayType], azureAgentValues.dataplaneConfig);
|
|
424
|
+
} catch (error) {
|
|
425
|
+
console.log(_chalk.default.redBright('rolling back installation. Please check the configuration data before re-running install'));
|
|
426
|
+
if (installConfig.centralConfig.ampcEnvInfo.isNew) {
|
|
427
|
+
await helpers.deleteByResourceType(apiServerClient, defsManager, installConfig.centralConfig.ampcEnvInfo.name, 'Environment', 'env');
|
|
428
|
+
}
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// create data plane secret resource
|
|
433
|
+
try {
|
|
434
|
+
await helpers.createNewDataPlaneSecretResource(apiServerClient, defsManager, installConfig.centralConfig.environment, _types.GatewayTypeToDataPlane[installConfig.gatewayType], dataplaneRes.name, await createEncryptedAccessData(azureAgentValues, dataplaneRes));
|
|
435
|
+
} catch (error) {
|
|
436
|
+
console.log(_chalk.default.redBright('rolling back installation. Please check the credential data before re-running install'));
|
|
437
|
+
if (installConfig.centralConfig.ampcEnvInfo.isNew) {
|
|
438
|
+
await helpers.deleteByResourceType(apiServerClient, defsManager, installConfig.centralConfig.ampcEnvInfo.name, 'Environment', 'env');
|
|
439
|
+
} else {
|
|
440
|
+
await helpers.deleteByResourceType(apiServerClient, defsManager, dataplaneRes.name, 'Dataplane', 'dp', installConfig.centralConfig.environment);
|
|
441
|
+
}
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// create discovery agent resource
|
|
446
|
+
installConfig.centralConfig.daAgentName = await helpers.createNewAgentResource(apiServerClient, defsManager, installConfig.centralConfig.environment, _types.GatewayTypeToDataPlane[installConfig.gatewayType], _types.AgentResourceKind.da, _types.AgentTypes.da, installConfig.centralConfig.ampcTeamName, _types.GatewayTypeToDataPlane[installConfig.gatewayType] + ' Discovery Agent', dataplaneRes.name, azureAgentValues.frequencyDA, azureAgentValues.queueDA);
|
|
447
|
+
if (installConfig.switches.isTaEnabled) {
|
|
448
|
+
// create traceability agent resource
|
|
449
|
+
installConfig.centralConfig.taAgentName = await helpers.createNewAgentResource(apiServerClient, defsManager, installConfig.centralConfig.environment, _types.GatewayTypeToDataPlane[installConfig.gatewayType], _types.AgentResourceKind.ta, _types.AgentTypes.ta, installConfig.centralConfig.ampcTeamName, _types.GatewayTypeToDataPlane[installConfig.gatewayType] + ' Traceability Agent', dataplaneRes.name, azureAgentValues.frequencyTA, false,
|
|
450
|
+
// Azure TA is never triggered at install, as DA has to run prior
|
|
451
|
+
{
|
|
452
|
+
sampling: azureAgentValues.sampling,
|
|
453
|
+
redaction: azureAgentValues.redaction
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
console.log(await generateOutput(installConfig));
|
|
457
|
+
};
|
|
458
|
+
const AzureSaaSInstallMethods = exports.AzureSaaSInstallMethods = {
|
|
459
|
+
GetBundleType: askBundleType,
|
|
460
|
+
GetDeploymentType: askConfigType,
|
|
461
|
+
AskGatewayQuestions: gatewayConnectivity,
|
|
462
|
+
FinalizeGatewayInstall: completeInstall,
|
|
463
|
+
ConfigFiles: [],
|
|
464
|
+
AgentNameMap: {
|
|
465
|
+
[_types.AgentTypes.da]: _types.AgentNames.AZURE_DA,
|
|
466
|
+
[_types.AgentTypes.ta]: _types.AgentNames.AZURE_TA
|
|
467
|
+
},
|
|
468
|
+
GatewayDisplay: _types.GatewayTypes.AZURE_GATEWAY
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
// These are the items that are not exported, but need to be for testing
|
|
472
|
+
const testables = exports.testables = {
|
|
473
|
+
SaasAgentValues,
|
|
474
|
+
SaasAzureAgentValues,
|
|
475
|
+
SaasPrompts,
|
|
476
|
+
ConfigFiles
|
|
477
|
+
};
|