UNPKG

@axway/axway-central-cli

Version:

Manage APIs, services and publish to the Amplify Marketplace

300 lines (289 loc) 15.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.testables = exports.askBundleType = exports.APIGEEXSaaSInstallMethods = void 0; var _chalk = _interopRequireDefault(require("chalk")); var _snooplogg = _interopRequireDefault(require("snooplogg")); var _basicPrompts = require("../../common/basicPrompts"); var _types = require("../../common/types"); var helpers = _interopRequireWildcard(require("./helpers")); var _crypto = _interopRequireDefault(require("crypto")); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } 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'); class DataplaneConfig { constructor(type) { _defineProperty(this, "type", void 0); this.type = type || ""; } } class APIGEEXDataplaneConfig extends DataplaneConfig { constructor(projectID, developerEmail, mode, metricsFilter, environment) { super("Apigee X"); _defineProperty(this, "projectId", void 0); _defineProperty(this, "developerEmail", void 0); _defineProperty(this, "mode", void 0); _defineProperty(this, "metricsFilter", void 0); _defineProperty(this, "environment", void 0); this.projectId = projectID; this.developerEmail = developerEmail; this.mode = mode; this.metricsFilter = metricsFilter; this.environment = environment; } } class SaasAgentValues { constructor() { _defineProperty(this, "frequencyDA", void 0); _defineProperty(this, "queueDA", void 0); _defineProperty(this, "frequencyTA", void 0); _defineProperty(this, "dataplaneConfig", void 0); _defineProperty(this, "centralConfig", void 0); this.frequencyDA = ''; this.queueDA = false; this.frequencyTA = ''; this.dataplaneConfig = new DataplaneConfig(); this.centralConfig = new _types.CentralAgentConfig(); } } class SaasAPIGEEXAgentValues extends SaasAgentValues { constructor() { super(); _defineProperty(this, "authType", void 0); _defineProperty(this, "clientEmailAddress", void 0); _defineProperty(this, "credentialJSON", void 0); _defineProperty(this, "projectId", void 0); _defineProperty(this, "developerEmailAddress", void 0); _defineProperty(this, "mode", void 0); _defineProperty(this, "metricsFilter", void 0); _defineProperty(this, "environment", void 0); this.authType = _types.APIGEEXAuthType.IMP_SVC_ACC; this.clientEmailAddress = ''; this.credentialJSON = ''; this.projectId = ''; this.developerEmailAddress = ''; this.mode = _types.APIGEEXDISCOVERYMODES.PROXY; this.metricsFilter = new _types.ApigeeMetricsFilterConfig(true, []); this.environment = ''; } getAccessData() { let data = JSON.stringify({ client_email: this.clientEmailAddress }); if (this.authType == _types.APIGEEXAuthType.ACCESS_CREDENTIAL) { data = JSON.stringify(this.credentialJSON); } return data; } } // ConfigFiles - all the config file that are used in the setup const ConfigFiles = {}; // APIGEEX SaaSPrompts - all APIGEEX Saas prompts to the user for input const SaasPrompts = { AUTHENTICATION_TYPE: 'Authenticate with an Impersonation of a Service Account or by providing a Credential File', PROJECT_ID: 'Enter the APIGEE X Project ID the agent will use', DEVELOPER_EMAIL_ADDRESS: 'Enter the APIGEE X Developer Email Address the agent will use', CLIENT_EMAIL_ADDRESS: 'Enter the Client Email Address the agent will use for the APIGEE X Service Account', UPLOAD_CREDENTIAL_FILE: 'Upload a JSON Credential file to be used for APIGEE X Authentication', DA_FREQUENCY: 'How often should the discovery run, leave blank for integrating in CI/CD process', TA_FREQUENCY: 'How often should the traffic collection run, leave blank for manual trigger only', QUEUE: 'Do you want to discover immediately after installation', ENTER_MORE: 'Do you want to enter another {0} for {1}', FILTER_METRICS: 'Do you want metrics filtering? (defaults to true)', FILTERED_APIS: 'Enter APIs to filter metrics for', ENTER_MORE_APIS: 'Do you want to add another API?', ENVIRONMENT: 'Enter the Apigee Environment to filter discovered APIs/metrics' }; const askBundleType = async () => { return await (0, _basicPrompts.askList)({ msg: helpers.agentMessages.selectAgentType, choices: [_types.BundleType.ALL_AGENTS, _types.BundleType.DISCOVERY] }); }; exports.askBundleType = askBundleType; const askConfigType = async () => { return _types.AgentConfigTypes.HOSTED; }; const askForAPIGEEXCredentials = async hostedAgentValues => { log("gathering access details for apigee x"); hostedAgentValues.projectId = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.PROJECT_ID, defaultValue: hostedAgentValues.projectId !== '' ? hostedAgentValues.projectId : undefined, validate: (0, _basicPrompts.validateRegex)(helpers.APIGEEXRegexPatterns.APIGEEX_REGEXP_PROJECT_ID, helpers.invalidValueExampleErrMsg('Project ID', 'rd-amplify-apigee-x')) }); // get developer email address hostedAgentValues.developerEmailAddress = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.DEVELOPER_EMAIL_ADDRESS, defaultValue: hostedAgentValues.developerEmailAddress !== '' ? hostedAgentValues.developerEmailAddress : undefined, allowEmptyInput: true }); hostedAgentValues.authType = _types.APIGEEXAuthType.IMP_SVC_ACC; console.log(_chalk.default.gray("Please refer to docs.axway.com for information on creating the necessary APIGEE X IAM policies")); if (hostedAgentValues.authType === _types.APIGEEXAuthType.IMP_SVC_ACC) { log("using impersonate service account authentication"); // get client email address hostedAgentValues.clientEmailAddress = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.CLIENT_EMAIL_ADDRESS, defaultValue: hostedAgentValues.clientEmailAddress !== '' ? hostedAgentValues.clientEmailAddress : undefined, allowEmptyInput: true }); } hostedAgentValues.metricsFilter.filterMetrics = (await (0, _basicPrompts.askList)({ msg: SaasPrompts.FILTER_METRICS, default: _types.YesNo.No, choices: _types.YesNoChoices })) === _types.YesNo.Yes; if (hostedAgentValues.metricsFilter.filterMetrics) { let askFilteredAPIs = true; console.log(_chalk.default.gray("An array of APIs to filter metrics for")); while (askFilteredAPIs) { const api = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.FILTERED_APIS, allowEmptyInput: true }); hostedAgentValues.metricsFilter.filteredAPIs.push(api); askFilteredAPIs = (await (0, _basicPrompts.askList)({ msg: SaasPrompts.ENTER_MORE_APIS, default: _types.YesNo.No, choices: _types.YesNoChoices })) === _types.YesNo.Yes; } } hostedAgentValues.environment = await (0, _basicPrompts.askInput)({ msg: SaasPrompts.ENVIRONMENT, defaultValue: '', allowEmptyInput: true }); return hostedAgentValues; }; const validateFrequency = () => input => { let val = (0, _basicPrompts.validateRegex)(helpers.frequencyRegex, helpers.invalidValueExampleErrMsg('frequency', '3d5h12m'))(input); if (typeof val === "string") { return val; } let r = input.toString().match(/^(\d*)m/); if (r) { // only minutes let mins = r[1]; if (parseInt(mins, 10) < 30) { return "Minimum frequency is 30m"; } } return true; }; // @ts-ignore const gatewayConnectivity = async installConfig => { console.log('\nCONNECTION TO APIGEE X API GATEWAY:'); console.log(_chalk.default.gray("The Discovery Agent needs to connect to the APIGEE X API Gateway to discover API's for publishing to Amplify Engage")); // DeploymentType let hostedAgentValues = new SaasAgentValues(); if (installConfig.gatewayType === _types.SaaSGatewayTypes.APIGEEX_GATEWAY) { // APIGEE X connection details hostedAgentValues = new SaasAPIGEEXAgentValues(); hostedAgentValues = await askForAPIGEEXCredentials(hostedAgentValues); } // 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: validateFrequency(), allowEmptyInput: true }); hostedAgentValues.queueDA = (await (0, _basicPrompts.askList)({ msg: SaasPrompts.QUEUE, default: _types.YesNo.No, choices: _types.YesNoChoices })) === _types.YesNo.Yes; 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: validateFrequency(), allowEmptyInput: true }); } return hostedAgentValues; }; const generateOutput = async installConfig => { return `Install complete of hosted agent for ${installConfig.gatewayType} region`; }; const createEncryptedAccessData = async (hostedAgentValues, 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(hostedAgentValues.getAccessData())); return encData.toString("base64"); }; const completeInstall = async (installConfig, apiServerClient, defsManager) => { /** * Create agent resources */ console.log("\n"); let apigeeXAgentValues = installConfig.gatewayConfig; // create the environment, if necessary installConfig.centralConfig.environment = installConfig.centralConfig.ampcEnvInfo.isNew ? await helpers.createByResourceType(apiServerClient, defsManager, installConfig.centralConfig.ampcEnvInfo.name, 'Environment', 'env', { axwayManaged: installConfig.centralConfig.axwayManaged, production: installConfig.centralConfig.production }) : installConfig.centralConfig.ampcEnvInfo.name; if (installConfig.gatewayType === _types.SaaSGatewayTypes.APIGEEX_GATEWAY) { apigeeXAgentValues.dataplaneConfig = new APIGEEXDataplaneConfig(apigeeXAgentValues.projectId, apigeeXAgentValues.developerEmailAddress, apigeeXAgentValues.mode, apigeeXAgentValues.metricsFilter, apigeeXAgentValues.environment); } // create the data plane resource let dataplaneRes = await helpers.createNewDataPlaneResource(apiServerClient, defsManager, installConfig.centralConfig.environment, _types.GatewayTypeToDataPlane[installConfig.gatewayType], apigeeXAgentValues.dataplaneConfig); // create data plane secret resource try { await helpers.createNewDataPlaneSecretResource(apiServerClient, defsManager, installConfig.centralConfig.environment, _types.GatewayTypeToDataPlane[installConfig.gatewayType], dataplaneRes.name, await createEncryptedAccessData(apigeeXAgentValues, dataplaneRes)); } catch (error) { console.log(_chalk.default.redBright("rolling back installation. Please check the credential data before re-running install")); if (installConfig.centralConfig.ampcEnvInfo.isNew) { await helpers.deleteByResourceType(apiServerClient, defsManager, installConfig.centralConfig.ampcEnvInfo.name, 'Environment', 'env'); } else { await helpers.deleteByResourceType(apiServerClient, defsManager, dataplaneRes.name, "Dataplane", "dp", installConfig.centralConfig.environment); } 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, apigeeXAgentValues.frequencyDA, apigeeXAgentValues.queueDA); 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, apigeeXAgentValues.frequencyTA, false // APIGEE X TA is never triggered at install, as DA has to run prior ); } console.log(await generateOutput(installConfig)); }; const APIGEEXSaaSInstallMethods = exports.APIGEEXSaaSInstallMethods = { GetBundleType: askBundleType, GetDeploymentType: askConfigType, AskGatewayQuestions: gatewayConnectivity, FinalizeGatewayInstall: completeInstall, ConfigFiles: [], AgentNameMap: { [_types.AgentTypes.da]: _types.AgentNames.APIGEEX_DA, [_types.AgentTypes.ta]: _types.AgentNames.APIGEEX_TA }, GatewayDisplay: _types.SaaSGatewayTypes.APIGEEX_GATEWAY }; // These are the items that are not exported, but need to be for testing const testables = exports.testables = { SaasAgentValues, SaasAPIGEEXAgentValues, APIGEEXAuthType: _types.APIGEEXAuthType, SaasPrompts, ConfigFiles };