UNPKG

@axway/axway-central-cli

Version:

Manage APIs, services and publish to the Amplify Marketplace

520 lines (510 loc) 26.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.testables = exports.askBundleType = exports.AzureSaaSInstallMethods = void 0; var _chalk = _interopRequireDefault(require("chalk")); var _snooplogg = _interopRequireDefault(require("snooplogg")); var _basicPrompts = require("../../common/basicPrompts"); var _types = require("../../common/types"); var _utils = require("../../common/utils"); var _agents = require("./agents"); var helpers = _interopRequireWildcard(require("./helpers")); var _crypto = _interopRequireDefault(require("crypto")); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } 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; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } 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); } const { log } = (0, _snooplogg.default)('engage: install: agents: saas'); const InvalidMessages = { 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.` }; class DataplaneConfig { constructor(type) { _defineProperty(this, "type", void 0); this.type = type || ''; } } class AzureDataplaneConfig extends DataplaneConfig { constructor(tenantId, resourceGroup, subscriptionId, apimServiceName, mode, eventHubName, eventHubNamespace, eventHubConsumerGroup) { super('Azure'); _defineProperty(this, "tenantId", void 0); _defineProperty(this, "resourceGroup", void 0); _defineProperty(this, "subscriptionId", void 0); _defineProperty(this, "apimServiceName", void 0); _defineProperty(this, "mode", void 0); _defineProperty(this, "eventHubName", void 0); _defineProperty(this, "eventHubNamespace", void 0); _defineProperty(this, "eventHubConsumerGroup", void 0); this.tenantId = tenantId; this.resourceGroup = resourceGroup; this.subscriptionId = subscriptionId; this.apimServiceName = apimServiceName; this.mode = mode; this.eventHubName = eventHubName; this.eventHubNamespace = eventHubNamespace; this.eventHubConsumerGroup = eventHubConsumerGroup; } } class Sampling { constructor() { _defineProperty(this, "onlyErrors", void 0); this.onlyErrors = true; } } class Sanitize { constructor(k, m) { _defineProperty(this, "keyMatch", void 0); _defineProperty(this, "valueMatch", void 0); this.keyMatch = k; this.valueMatch = m; } } class RedactionSet { constructor() { _defineProperty(this, "show", void 0); _defineProperty(this, "sanitize", void 0); this.show = []; this.sanitize = []; } } class Redaction { constructor() { _defineProperty(this, "maskingCharacter", void 0); _defineProperty(this, "path", void 0); _defineProperty(this, "queryArgument", void 0); _defineProperty(this, "requestHeaders", void 0); _defineProperty(this, "responseHeaders", void 0); this.maskingCharacter = '{*}'; this.path = []; this.queryArgument = new RedactionSet(); this.requestHeaders = new RedactionSet(); this.responseHeaders = new RedactionSet(); } } class SaasAgentValues { constructor() { _defineProperty(this, "frequencyDA", void 0); _defineProperty(this, "queueDA", void 0); _defineProperty(this, "filterDA", void 0); _defineProperty(this, "frequencyTA", void 0); _defineProperty(this, "sampling", void 0); _defineProperty(this, "redaction", void 0); _defineProperty(this, "dataplaneConfig", void 0); _defineProperty(this, "centralConfig", void 0); this.frequencyDA = ''; this.queueDA = false; this.filterDA = ''; this.frequencyTA = ''; this.sampling = new Sampling(); this.redaction = new Redaction(); this.dataplaneConfig = new DataplaneConfig(); this.centralConfig = new _types.CentralAgentConfig(); } getAccessData() { return ''; } } class SaasAzureAgentValues extends SaasAgentValues { constructor() { super(); _defineProperty(this, "clientID", void 0); _defineProperty(this, "clientSecret", void 0); _defineProperty(this, "sharedAccessKeyName", void 0); _defineProperty(this, "sharedAccessKeyValue", void 0); _defineProperty(this, "eventHubName", void 0); _defineProperty(this, "eventHubNamespace", void 0); _defineProperty(this, "eventHubConsumerGroup", void 0); _defineProperty(this, "resourceGroup", void 0); _defineProperty(this, "apimManagementServiceName", void 0); _defineProperty(this, "subscriptionId", void 0); _defineProperty(this, "tenantId", void 0); _defineProperty(this, "mode", void 0); this.clientID = ''; this.clientSecret = ''; this.sharedAccessKeyName = ''; this.sharedAccessKeyValue = ''; this.eventHubName = ''; this.eventHubNamespace = ''; this.eventHubConsumerGroup = ''; this.resourceGroup = ''; this.apimManagementServiceName = ''; this.subscriptionId = ''; this.tenantId = ''; this.mode = _types.AzureDataplaneMode.APIM; } getAccessData() { let data = JSON.stringify({ clientID: this.clientID, clientSecret: this.clientSecret, sharedAccessKeyName: this.sharedAccessKeyName, sharedAccessKeyValue: this.sharedAccessKeyValue }); return data; } } // ConfigFiles - all the config file that are used in the setup const ConfigFiles = {}; // AzureSaaSPrompts - all Azure Saas prompts to the user for input const SaasPrompts = { AUTHENTICATION_TYPE: 'Authenticate with Client and Shared Access Key', TENANT_ID: 'Enter the Azure Tenant ID', SUBSCRIPTION_ID: 'Enter the Azure Subscription ID', CLIENT_ID: 'Enter the Azure Service Principal Client ID', CLIENT_SECRET: 'Enter the Azure Service Principal Client Secret', RESOURCE_GROUP_NAME: 'Enter the Azure Resource Group Name', APIM_SERVICE_MANAGEMENT_NAME: 'Enter the Azure API Management Service Name', SHARED_ACCESS_KEY_NAME: 'Enter the Azure Policy Name', SHARED_ACCESS_KEY_VALUE: 'Enter the Azure Policy Key', EVENT_HUB_NAME: 'Enter the Azure Event Hub Name', EVENT_HUB_NAMESPACE: 'Enter the Azure Event Hub Namespace', EVENT_HUB_CONSUMER_GROUP: 'Enter the Azure Event Hub Consumer Group', // general prompts DA_FREQUENCY: 'How often should the discovery run, leave blank for integrating in CI/CD process', DA_FILTER: 'Please enter the filter conditions for discovery of API Services based on tags', TA_FREQUENCY: 'How often should the traffic collection run, leave blank for manual trigger only', QUEUE: 'Do you want to discover immediately after installation', REDACT_SHOW: 'Enter a regular expression for {0}s that may be shown', ENTER_SANITIZE_RULE: 'Do you want to add sanitization rules for {0}s', SANITIZE_KEY: 'Enter a regular expression for {0} keys that values should be sanitized', SANITIZE_VAL: 'Enter a regular expression for sanitization of values when matching a {0} key', MASKING_CHARS: 'Enter the characters to use when sanitizing a value', ENTER_MORE: 'Do you want to enter another {0} for {1}' }; const askBundleType = async gateway => { if (gateway === _types.GatewayTypes.AZURE_GATEWAY) { return await (0, _basicPrompts.askList)({ msg: helpers.agentMessages.selectAgentType, choices: [_types.BundleType.ALL_AGENTS, _types.BundleType.DISCOVERY] }); } else { return _types.BundleType.DISCOVERY; } }; exports.askBundleType = askBundleType; const askConfigType = async () => { return _types.AgentConfigTypes.HOSTED; }; // // Complex prompts // const askForRedactionSet = async (setting, redactionSet) => { // ask for path reg exs let askShow = true; console.log(_chalk.default.gray((0, _utils.FormatString)('\nRedaction settings for {0}s', setting))); while (askShow) { const input = await (0, _basicPrompts.askInput)({ msg: (0, _utils.FormatString)(SaasPrompts.REDACT_SHOW, setting), defaultValue: '.*', validate: (0, _basicPrompts.validateValidRegex)() }); redactionSet.show.push(input); askShow = (await (0, _basicPrompts.askList)({ msg: (0, _utils.FormatString)(SaasPrompts.ENTER_MORE, 'redaction regular expression', setting), default: _types.YesNo.No, choices: _types.YesNoChoices })) === _types.YesNo.Yes; } console.log(_chalk.default.gray((0, _utils.FormatString)('Sanitization settings for {0}s', setting))); let askSanitize = (await (0, _basicPrompts.askList)({ msg: (0, _utils.FormatString)(SaasPrompts.ENTER_SANITIZE_RULE, setting), default: _types.YesNo.No, choices: _types.YesNoChoices })) === _types.YesNo.Yes; 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)')); while (askSanitize) { const keyMatch = await (0, _basicPrompts.askInput)({ msg: (0, _utils.FormatString)(SaasPrompts.SANITIZE_KEY, setting), allowEmptyInput: true, validate: (0, _basicPrompts.validateValidRegex)() }); const valMatch = await (0, _basicPrompts.askInput)({ msg: (0, _utils.FormatString)(SaasPrompts.SANITIZE_VAL, setting), allowEmptyInput: true, validate: (0, _basicPrompts.validateValidRegex)() }); if (keyMatch === '' || valMatch === '') { console.log("can't add sanitization rule with an empty key or value regular expression"); } else { redactionSet.sanitize.push(new Sanitize(keyMatch, valMatch)); } askSanitize = (await (0, _basicPrompts.askList)({ msg: (0, _utils.FormatString)(SaasPrompts.ENTER_MORE, 'sanitization rule', setting), default: _types.YesNo.No, choices: _types.YesNoChoices })) === _types.YesNo.Yes; } return redactionSet; }; const askForRedaction = async hostedAgentValues => { console.log(_chalk.default.gray('\nRedaction and Sanitization settings')); // ask for path reg exps let askPaths = true; console.log(_chalk.default.gray('\nRedaction settings for URL paths')); while (askPaths) { const input = await (0, _basicPrompts.askInput)({ msg: (0, _utils.FormatString)(SaasPrompts.REDACT_SHOW, 'URL path'), defaultValue: '.*', validate: (0, _basicPrompts.validateValidRegex)() }); hostedAgentValues.redaction.path.push(input); askPaths = (await (0, _basicPrompts.askList)({ msg: (0, _utils.FormatString)(SaasPrompts.ENTER_MORE, 'redaction regular expression', 'URL path'), default: _types.YesNo.No, choices: _types.YesNoChoices })) === _types.YesNo.Yes; } hostedAgentValues.redaction.queryArgument = await askForRedactionSet('query argument', hostedAgentValues.redaction.queryArgument); hostedAgentValues.redaction.requestHeaders = await askForRedactionSet('request header', hostedAgentValues.redaction.requestHeaders); hostedAgentValues.redaction.responseHeaders = await askForRedactionSet('response header', hostedAgentValues.redaction.responseHeaders); hostedAgentValues.redaction.maskingCharacter = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.MASKING_CHARS, defaultValue: '{*}', validate: (0, _basicPrompts.validateRegex)(helpers.maskingRegex, 'Please enter a valid value') }); return hostedAgentValues; }; const askForAzureCredentials = async (hostedAgentValues, installConfig) => { log('gathering access details for azure'); hostedAgentValues.tenantId = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.TENANT_ID }); hostedAgentValues.subscriptionId = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.SUBSCRIPTION_ID }); hostedAgentValues.clientID = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.CLIENT_ID }); hostedAgentValues.clientSecret = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.CLIENT_SECRET }); hostedAgentValues.resourceGroup = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.RESOURCE_GROUP_NAME }); if (installConfig.gatewayType === _types.GatewayTypes.AZURE_GATEWAY) { hostedAgentValues.apimManagementServiceName = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.APIM_SERVICE_MANAGEMENT_NAME, validate: (0, _basicPrompts.validateRegex)(helpers.AzureRegexPatterns.azureApiManagementServiceNameRegex, InvalidMessages.enterApiManagementServiceName) }); } if (installConfig.switches.isTaEnabled) { hostedAgentValues.sharedAccessKeyName = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.SHARED_ACCESS_KEY_NAME, defaultValue: 'RootManageSharedAccessKey' }); hostedAgentValues.sharedAccessKeyValue = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.SHARED_ACCESS_KEY_VALUE }); } return hostedAgentValues; }; // @ts-ignore const gatewayConnectivity = async installConfig => { console.log('\nCONNECTION TO Azure API GATEWAY:'); console.log(_chalk.default.gray("The Discovery Agent needs to connect to the Azure API Gateway to discover API's for publishing to Amplify Engage")); // DeploymentType let hostedAgentValues = new SaasAgentValues(); if (installConfig.gatewayType === _types.GatewayTypes.AZURE_GATEWAY || installConfig.gatewayType === _types.GatewayTypes.AZURE_EVENTHUB) { // Azure connection details hostedAgentValues = new SaasAzureAgentValues(); hostedAgentValues = await askForAzureCredentials(hostedAgentValues, installConfig); if (installConfig.gatewayType === _types.GatewayTypes.AZURE_EVENTHUB) { hostedAgentValues.eventHubNamespace = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.EVENT_HUB_NAMESPACE }); } if (installConfig.switches.isTaEnabled) { hostedAgentValues.eventHubName = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.EVENT_HUB_NAME }); hostedAgentValues.eventHubNamespace = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.EVENT_HUB_NAMESPACE }); hostedAgentValues.eventHubConsumerGroup = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.EVENT_HUB_CONSUMER_GROUP, validate: (0, _basicPrompts.validateRegex)(helpers.AzureRegexPatterns.azureEventHubConsumerGroupRegex, helpers.invalidValueExampleErrMsg('Event Hub Consumer Group', 'azure-event-hub-c-group')), defaultValue: '$Default' }); } } // Ask to queue discovery now log('getting the frequency and if the agent should run now'); 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.')); hostedAgentValues.frequencyDA = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.DA_FREQUENCY, validate: (0, _agents.validateFrequency)(), allowEmptyInput: true }); hostedAgentValues.queueDA = (await (0, _basicPrompts.askList)({ msg: SaasPrompts.QUEUE, default: _types.YesNo.No, choices: _types.YesNoChoices })) === _types.YesNo.Yes; hostedAgentValues.filterDA = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.DA_FILTER, allowEmptyInput: true }); if (installConfig.switches.isTaEnabled) { 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.')); hostedAgentValues.frequencyTA = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.TA_FREQUENCY, defaultValue: '30m', validate: (0, _agents.validateFrequency)(), allowEmptyInput: true }); hostedAgentValues = await askForRedaction(hostedAgentValues); } return hostedAgentValues; }; const generateOutput = async installConfig => { return `Install complete of hosted agent for ${installConfig.gatewayType} region`; }; const createEncryptedAccessData = async (agentValues, dataplaneRes) => { var _dataplaneRes$securit, _dataplaneRes$securit2; // grab key from data plane resource let key = ((_dataplaneRes$securit = dataplaneRes.security) === null || _dataplaneRes$securit === void 0 ? void 0 : _dataplaneRes$securit.encryptionKey) || ''; let hash = ((_dataplaneRes$securit2 = dataplaneRes.security) === null || _dataplaneRes$securit2 === void 0 ? void 0 : _dataplaneRes$securit2.encryptionHash) || ''; if (key === '' || hash === '') { throw Error(`cannot encrypt access data as the encryption key info was incomplete`); } let encData = _crypto.default.publicEncrypt({ key: key, padding: _crypto.default.constants.RSA_PKCS1_OAEP_PADDING, oaepHash: hash }, Buffer.from(agentValues.getAccessData())); return encData.toString('base64'); }; const completeInstall = async (installConfig, apiServerClient, defsManager) => { /** * Create agent resources */ console.log('\n'); let azureAgentValues = installConfig.gatewayConfig; let resourceFuncsForCleanup = []; let referencedIDPs = []; let providedIDPs = installConfig.idpConfig[0]; let providedIDPAuths = installConfig.idpConfig[1]; // create Identity Provider resource try { for (let i = 0; i < providedIDPs.length; i++) { let idpResource = await helpers.createNewIDPResource(apiServerClient, defsManager, providedIDPs[i]); let cleanupFunc = async () => await helpers.deleteByResourceType(apiServerClient, defsManager, idpResource === null || idpResource === void 0 ? void 0 : idpResource.name, 'IdentityProvider', 'idp'); resourceFuncsForCleanup.push(cleanupFunc); referencedIDPs.push({ name: idpResource === null || idpResource === void 0 ? void 0 : idpResource.name }); log(idpResource); let encryptedAccessData = await createEncryptedAccessData(providedIDPAuths[i], idpResource); providedIDPAuths[i].setAccessData(encryptedAccessData); let idpSecResource = await helpers.createNewIDPSecretResource(apiServerClient, defsManager, providedIDPAuths[i], idpResource); let anotherCleanupFunc = async () => await helpers.deleteByResourceType(apiServerClient, defsManager, idpSecResource === null || idpSecResource === void 0 ? void 0 : idpSecResource.name, 'IdentityProviderSecret', 'idpsec', idpResource === null || idpResource === void 0 ? void 0 : idpResource.name); resourceFuncsForCleanup.push(anotherCleanupFunc); } } catch (error) { log(error); console.log(_chalk.default.redBright('rolling back installation. Could not create the Identity Provider resources')); await cleanResources(resourceFuncsForCleanup); return; } let refIDPsSubResources = { references: { identityProviders: referencedIDPs } }; // create the environment, if necessary if (installConfig.centralConfig.ampcEnvInfo.isNew) { installConfig.centralConfig.environment = await helpers.createByResourceType(apiServerClient, defsManager, installConfig.centralConfig.ampcEnvInfo.name, 'Environment', 'env', { axwayManaged: installConfig.centralConfig.axwayManaged, production: installConfig.centralConfig.production }, '', refIDPsSubResources); let cleanupFunc = async () => await helpers.deleteByResourceType(apiServerClient, defsManager, installConfig.centralConfig.ampcEnvInfo.name, 'Environment', 'env'); resourceFuncsForCleanup.push(cleanupFunc); } else { // if the env exists, we simply update the references with the newly created IDPs, while preserving the existing IDP references // In the case of any failure during the whole process, we return everything back to how it was before. installConfig.centralConfig.environment = installConfig.centralConfig.ampcEnvInfo.name; refIDPsSubResources.references.identityProviders.push(...installConfig.centralConfig.ampcEnvInfo.referencedIdentityProviders); await helpers.updateSubResourceType(apiServerClient, defsManager, installConfig.centralConfig.ampcEnvInfo.name, 'Environment', 'env', '', refIDPsSubResources); let oldIDPRef = { references: { identityProviders: installConfig.centralConfig.ampcEnvInfo.referencedIdentityProviders } }; let cleanupFunc = async () => await helpers.updateSubResourceType(apiServerClient, defsManager, installConfig.centralConfig.ampcEnvInfo.name, 'Environment', 'env', '', oldIDPRef); resourceFuncsForCleanup.push(cleanupFunc); } if (installConfig.gatewayType === _types.GatewayTypes.AZURE_GATEWAY) { azureAgentValues.dataplaneConfig = new AzureDataplaneConfig(azureAgentValues.tenantId, azureAgentValues.resourceGroup, azureAgentValues.subscriptionId, azureAgentValues.apimManagementServiceName, _types.AzureDataplaneMode.APIM); if (installConfig.switches.isTaEnabled) { azureAgentValues.dataplaneConfig = new AzureDataplaneConfig(azureAgentValues.tenantId, azureAgentValues.resourceGroup, azureAgentValues.subscriptionId, azureAgentValues.apimManagementServiceName, _types.AzureDataplaneMode.APIM, azureAgentValues.eventHubName, azureAgentValues.eventHubNamespace, azureAgentValues.eventHubConsumerGroup); } } if (installConfig.gatewayType === _types.GatewayTypes.AZURE_EVENTHUB) { azureAgentValues.dataplaneConfig = new AzureDataplaneConfig(azureAgentValues.tenantId, azureAgentValues.resourceGroup, azureAgentValues.subscriptionId, '', _types.AzureDataplaneMode.EventHub, undefined, azureAgentValues.eventHubNamespace); } // create the data plane resource let dataplaneRes; try { dataplaneRes = await helpers.createNewDataPlaneResource(apiServerClient, defsManager, installConfig.centralConfig.environment, _types.GatewayTypeToDataPlane[installConfig.gatewayType], azureAgentValues.dataplaneConfig); let cleanupFunc = async () => await helpers.deleteByResourceType(apiServerClient, defsManager, dataplaneRes.name, 'Dataplane', 'dp', installConfig.centralConfig.environment); resourceFuncsForCleanup.push(cleanupFunc); } catch (error) { console.log(_chalk.default.redBright('rolling back installation. Please check the configuration data before re-running install')); await cleanResources(resourceFuncsForCleanup); return; } // create data plane secret resource try { let dataplaneSecretRes = await helpers.createNewDataPlaneSecretResource(apiServerClient, defsManager, installConfig.centralConfig.environment, _types.GatewayTypeToDataPlane[installConfig.gatewayType], dataplaneRes.name, await createEncryptedAccessData(azureAgentValues, dataplaneRes)); let cleanupFunc = async () => await helpers.deleteByResourceType(apiServerClient, defsManager, dataplaneSecretRes === null || dataplaneSecretRes === void 0 ? void 0 : dataplaneSecretRes.name, 'DataplaneSecret', 'dps', installConfig.centralConfig.environment); resourceFuncsForCleanup.push(cleanupFunc); } catch (error) { console.log(_chalk.default.redBright('rolling back installation. Please check the credential data before re-running install')); await cleanResources(resourceFuncsForCleanup); return; } // create discovery agent resource 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, undefined, azureAgentValues.filterDA); if (installConfig.switches.isTaEnabled) { // create traceability agent resource 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, // Azure TA is never triggered at install, as DA has to run prior { sampling: azureAgentValues.sampling, redaction: azureAgentValues.redaction }); } console.log(await generateOutput(installConfig)); }; const AzureSaaSInstallMethods = exports.AzureSaaSInstallMethods = { GetBundleType: askBundleType, GetDeploymentType: askConfigType, AskGatewayQuestions: gatewayConnectivity, AddIDP: true, FinalizeGatewayInstall: completeInstall, ConfigFiles: [], AgentNameMap: { [_types.AgentTypes.da]: _types.AgentNames.AZURE_DA, [_types.AgentTypes.ta]: _types.AgentNames.AZURE_TA }, GatewayDisplay: _types.GatewayTypes.AZURE_GATEWAY }; // These are the items that are not exported, but need to be for testing const testables = exports.testables = { SaasAgentValues, SaasAzureAgentValues, SaasPrompts, ConfigFiles }; // These are useful because there are multiple resources created in a specific order and in case of failure, this goes through // everything that was created and deletes it one by one. It deletes the resources in opposite order because resources added // at the beginning might be referred by resources added afterwards const cleanResources = async cleanupFuncs => { for (let i = cleanupFuncs.length - 1; i >= 0; i--) { await cleanupFuncs[i](); } };