UNPKG

@axway/axway-central-cli

Version:

Manage APIs, services and publish to the Amplify Marketplace

409 lines (404 loc) 21.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.testables = exports.prompts = exports.installPreprocess = exports.gatewayConnectivity = exports.dockerPublicKey = exports.dockerPrivateKey = exports.completeInstall = exports.askOrganizationReplication = exports.askIsGatewayOnlyMode = exports.askConfigType = exports.askBundleTypeGWOnly = exports.askBundleType = exports.EdgeInstallMethods = exports.EdgeGWOnlyInstallMethods = exports.ConfigFiles = void 0; var _cliKit = require("cli-kit"); var _fs = _interopRequireDefault(require("fs")); var _snooplogg = _interopRequireDefault(require("snooplogg")); var _basicPrompts = require("../../common/basicPrompts"); var _dataService = require("../../common/dataService"); var _Kubectl = require("../../common/Kubectl"); var _types = require("../../common/types"); var _utils = require("../../common/utils"); var _agents = require("./agents"); var helpers = _interopRequireWildcard(require("./helpers")); var _edgeTemplates = require("./helpers/templates/edgeTemplates"); var _istioAgents = require("./istioAgents"); 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 }; } const defaultLogFiles = '/group-*_instance-*.log'; const defaultOTLogFiles = '/group-*_instance-*_traffic*.log'; const dockerPrivateKey = exports.dockerPrivateKey = '/keys/private_key.pem'; const dockerPublicKey = exports.dockerPublicKey = '/keys/public_key.pem'; // @ts-ignore const { log } = (0, _snooplogg.default)('engage: install: agents: edge'); const daImage = `${_types.PublicDockerRepoBaseUrl}${_types.BasePaths.DockerAgentPublicRepo}/${_types.AgentNames.EDGE_DA}`; const taImage = `${_types.PublicDockerRepoBaseUrl}${_types.BasePaths.DockerAgentPublicRepo}/${_types.AgentNames.EDGE_TA}`; // ConfigFiles - all the config file that are used in the setup const ConfigFiles = exports.ConfigFiles = { DAEnvVars: `${helpers.configFiles.DA_ENV_VARS}`, DAHelmOverride: 'da-overrides.yaml', EdgeDABinaryFile: 'discovery_agent', EdgeDAYaml: 'discovery_agent.yml', EdgeTABinaryFile: 'traceability_agent', EdgeTAYaml: 'traceability_agent.yml', TAEnvVars: `${helpers.configFiles.TA_ENV_VARS}`, TAHelmOverride: 'ta-overrides.yaml' }; const prompts = exports.prompts = { configTypeMsg: 'Select the mode of installation', askApiGatewayHost: 'Enter the API Gateway hostname', askApiGatewayPort: 'Enter the API Gateway port', askApiManagerHost: 'Enter the API Manager hostname', askApiManagerPort: 'Enter the API Manager port', askLoggingSource: 'What is the source of logging for the traceability agent', askEventsPath: 'Enter the path to the API Gateway event log directory', askOpenTrafficPath: 'Enter the path to the API Gateway open traffic log directory', enterGatewayAgentNs: 'Enter the namespace to use for the Amplify Gateway Agents', enterGatewayManagerMode: 'Do you want to use API Manager with the API Gateway', askIfOrgReplication: 'Do you want to replicate your original organization structure for your newly discovered APIs? If yes, make sure the organization names match the team names that are created in Amplify platform' }; const downloadV7AgentBundle = async (type, version) => { const fileName = type === _types.BundleType.DISCOVERY ? `discovery_agent-${version}.zip` : `traceability_agent-${version}.zip`; const url = type === _types.BundleType.DISCOVERY ? `/v7_discovery_agent/${version}/discovery_agent-${version}.zip` : `/v7_traceability_agent/${version}/traceability_agent-${version}.zip`; const service = await (0, _dataService.dataService)({ baseUrl: _types.PublicRepoUrl, basePath: _types.BasePaths.V7Agents }); try { const { stream } = await service.download(url); await helpers.streamPipeline(stream, _fs.default.createWriteStream(fileName)); return fileName; } catch (err) { throw new Error(`Failed to download the agent: ${err.message}`); } }; const downloadBinary = async (bundleType, version) => { const fileName = await downloadV7AgentBundle(bundleType, version); await helpers.unzip(fileName); _fs.default.unlinkSync(fileName); }; const downloadBinaries = async installConfig => { console.log('Downloading and unpacking binary files...'); if (installConfig.switches.isDaEnabled) { await downloadBinary(_types.BundleType.DISCOVERY, installConfig.daVersion); } if (installConfig.switches.isTaEnabled) { await downloadBinary(_types.BundleType.TRACEABILITY, installConfig.taVersion); } console.log('Downloading and unpacking is complete.'); }; const askIsGatewayOnlyMode = async () => { const mode = await (0, _basicPrompts.askList)({ msg: prompts.enterGatewayManagerMode, default: _types.YesNo.Yes, choices: _types.YesNoChoices }); return mode == _types.YesNo.Yes ? _types.GatewayTypes.EDGE_GATEWAY : _types.GatewayTypes.EDGE_GATEWAY_ONLY; }; exports.askIsGatewayOnlyMode = askIsGatewayOnlyMode; const askOrganizationReplication = async () => { const mode = await (0, _basicPrompts.askList)({ msg: prompts.askIfOrgReplication, default: _types.YesNo.Yes, choices: _types.YesNoChoices }); return mode == _types.YesNo.Yes; }; exports.askOrganizationReplication = askOrganizationReplication; const askBundleType = async () => { return await (0, _basicPrompts.askList)({ msg: helpers.agentMessages.selectAgentType, choices: [_types.BundleType.ALL_AGENTS, _types.BundleType.DISCOVERY, _types.BundleType.TRACEABILITY] }); }; exports.askBundleType = askBundleType; const askBundleTypeGWOnly = async () => { return await (0, _basicPrompts.askList)({ msg: helpers.agentMessages.selectAgentType, choices: [_types.BundleType.TRACEABILITY, _types.BundleType.TRACEABILITY_OFFLINE] }); }; exports.askBundleTypeGWOnly = askBundleTypeGWOnly; const askConfigType = async () => { return await (0, _basicPrompts.askList)({ msg: prompts.configTypeMsg, choices: [_types.AgentConfigTypes.BINARIES, _types.AgentConfigTypes.DOCKERIZED, _types.AgentConfigTypes.HELM] }); }; exports.askConfigType = askConfigType; const askLoggingSource = async () => { console.log(_cliKit.chalk.white(`\nThe API Gateway can provide the API traffic either within event logs or open traffic logs.`)); return (await (0, _basicPrompts.askList)({ msg: prompts.askLoggingSource, default: _types.LoggingSource.Event, choices: [_types.LoggingSource.Event, _types.LoggingSource.OpenTraffic] })) === _types.LoggingSource.OpenTraffic; }; const askEventsPath = async isOpenTraffic => { return await (0, _basicPrompts.askInput)({ msg: isOpenTraffic ? prompts.askOpenTrafficPath : prompts.askEventsPath, defaultValue: isOpenTraffic ? '/apigateway/logs/opentraffic' : '/apigateway/events', type: 'string' }); }; const askApiManagerHost = async () => { return await (0, _basicPrompts.askInput)({ msg: prompts.askApiManagerHost, defaultValue: _agents.localhost }); }; const askApiManagerPort = async () => { return await (0, _basicPrompts.askInput)({ msg: prompts.askApiManagerPort, defaultValue: 8075, type: 'number' }); }; const askApiGatewayHost = async () => { return await (0, _basicPrompts.askInput)({ msg: prompts.askApiGatewayHost, defaultValue: _agents.localhost }); }; const askApiGatewayPort = async () => { return await (0, _basicPrompts.askInput)({ msg: prompts.askApiGatewayPort, defaultValue: 8090, type: 'number' }); }; const gatewayConnectivity = async installConfig => { let v7AgentValues = new _edgeTemplates.V7AgentValues(); if (installConfig.switches.isHelmInstall) { const { error } = await _Kubectl.kubectl.isInstalled(); if (error) { throw new Error(`Kubectl is required to fill out the following prompts. It appears to be missing or misconfigured.\n${error}`); } } if (!installConfig.switches.isGatewayOnly || installConfig.switches.isDaEnabled) { console.log('\nCONNECTION TO API MANAGER:'); console.log(_cliKit.chalk.gray(`The agents need to connect to the Axway API Manager to discover APIs for publishing to Amplify.\n` + `Use the credentials of an API Manager Administrator user or an Organization Administrator user.`)); if (installConfig.switches.isHelmInstall) { console.log(_cliKit.chalk.white(`Please use the name of the API Manager Service as hostname.`)); } v7AgentValues.apiManagerHost = await askApiManagerHost(); v7AgentValues.apiManagerPort = await askApiManagerPort(); const apimCreds = await (0, _basicPrompts.askUsernameAndPassword)('the API Manager', 'apiadmin'); v7AgentValues.apiManagerAuthUser = apimCreds.username; v7AgentValues.apiManagerAuthPass = apimCreds.password; } if (installConfig.switches.isTaEnabled) { v7AgentValues.isOpenTraffic = await askLoggingSource(); if (!v7AgentValues.isOpenTraffic && installConfig.bundleType !== _types.BundleType.TRACEABILITY_OFFLINE) { console.log('\nCONNECTION TO API GATEWAY:'); console.log(_cliKit.chalk.gray(`The traceability agent needs to connect to Axway API Gateway.\n` + `Use the credentials of an Operator user.`)); if (installConfig.switches.isHelmInstall) { console.log(_cliKit.chalk.white(`Please use the name of the API Gateway Service as hostname.`)); } v7AgentValues.apiGatewayHost = await askApiGatewayHost(); v7AgentValues.apiGatewayPort = await askApiGatewayPort(); const apigwCreds = await (0, _basicPrompts.askUsernameAndPassword)('the API Gateway', 'admin'); v7AgentValues.apiGatewayAuthUser = apigwCreds.username; v7AgentValues.apiGatewayAuthPass = apigwCreds.password; } if (installConfig.switches.isBinaryInstall || installConfig.switches.isDockerInstall) { const eventLogPaths = await askEventsPath(v7AgentValues.isOpenTraffic); const trimmedDir = eventLogPaths.trim(); v7AgentValues.eventLogPath = eventLogPaths ? trimmedDir[trimmedDir.length - 1] === '/' ? `${trimmedDir.slice(0, -1)}` : `${trimmedDir}` : ''; v7AgentValues.eventLogPathTemplate = installConfig.switches.isBinaryInstall ? `${v7AgentValues.eventLogPath}${v7AgentValues.isOpenTraffic ? defaultOTLogFiles : defaultLogFiles}` : ''; } } if (installConfig.switches.isHelmInstall) { v7AgentValues.namespace = await helpers.askNamespace(prompts.enterGatewayAgentNs, _istioAgents.amplifyAgentsNs); } return v7AgentValues; }; exports.gatewayConnectivity = gatewayConnectivity; const generateSuccessHelpMsg = installConfig => { var _v7AgentValues$eventL; const v7AgentValues = installConfig.gatewayConfig; const configType = installConfig.deploymentType; const trimmedDir = (_v7AgentValues$eventL = v7AgentValues.eventLogPath) === null || _v7AgentValues$eventL === void 0 ? void 0 : _v7AgentValues$eventL.trim(); const verifiedEventsPath = v7AgentValues.eventLogPath ? trimmedDir[trimmedDir.length - 1] === '/' ? `${trimmedDir.slice(0, -1)}:/events` : `${trimmedDir}:/events` : ''; if (installConfig.centralConfig.ampcDosaInfo.isNew && !installConfig.switches.isHelmInstall) { console.log(_cliKit.chalk.yellow(_agents.svcAccMsg)); } if (configType === _types.AgentConfigTypes.BINARIES) { binarySuccessMsg(installConfig.centralConfig.ampcDosaInfo.isNew, installConfig.switches.isDaEnabled, installConfig.switches.isTaEnabled); } else if (configType === _types.AgentConfigTypes.DOCKERIZED) { dockerSuccessMsg(installConfig, verifiedEventsPath); } else if (installConfig.switches.isHelmInstall) { helmSuccessMsg(v7AgentValues.namespace.name, installConfig.switches.isDaEnabled, installConfig.switches.isTaEnabled); } console.log(_cliKit.chalk.gray(`\nAdditional information about agent features can be found here:\n${helpers.agentsDocsUrl.V7}`)); }; const installPreprocess = async installConfig => { // Ask for key paths if HELM, and dosa NOT new if (installConfig.deploymentType === _types.AgentConfigTypes.HELM && !installConfig.centralConfig.ampcDosaInfo.isNew) { [installConfig.centralConfig.dosaAccount.publicKey, installConfig.centralConfig.dosaAccount.privateKey] = await helpers.askPublicAndPrivateKeysPath(); } // attempt to download the binaries prior to creating resources if (installConfig.switches.isBinaryInstall) { await downloadBinaries(installConfig); } return installConfig; }; exports.installPreprocess = installPreprocess; const completeInstall = async installConfig => { /** * Create agent resources */ const v7AgentValues = installConfig.gatewayConfig; // Add final settings to v7AgentsValues v7AgentValues.centralConfig = installConfig.centralConfig; v7AgentValues.traceabilityConfig = installConfig.traceabilityConfig; v7AgentValues.isGatewayOnly = installConfig.switches.isGatewayOnly; v7AgentValues.daVersion = installConfig.daVersion; v7AgentValues.taVersion = installConfig.taVersion; if (installConfig.switches.isHelmInstall) { if (v7AgentValues.namespace.isNew) { await helpers.createNamespace(v7AgentValues.namespace.name); } await helpers.createSecret(v7AgentValues.namespace.name, helpers.amplifyAgentsKeysSecret, async () => { if (installConfig.centralConfig.ampcDosaInfo.isNew) { console.log(_cliKit.chalk.yellow(`The secret '${helpers.amplifyAgentsKeysSecret}' will be created with the same "private_key.pem" and "public_key.pem" that was auto generated to create the Service Account.`)); } await helpers.createAmplifyAgentKeysSecret(v7AgentValues.namespace.name, helpers.amplifyAgentsKeysSecret, 'public_key', v7AgentValues.centralConfig.dosaAccount.publicKey, 'private_key', v7AgentValues.centralConfig.dosaAccount.privateKey); }); await helpers.createSecret(v7AgentValues.namespace.name, helpers.amplifyAgentsCredsSecret, async () => { await helpers.createGatewayAgentCredsSecret(v7AgentValues.namespace.name, helpers.amplifyAgentsCredsSecret, v7AgentValues.apiManagerAuthUser, v7AgentValues.apiManagerAuthPass, v7AgentValues.apiGatewayAuthUser, v7AgentValues.apiGatewayAuthPass); }); } console.log('Generating the configuration file(s)...'); if (installConfig.switches.isHelmInstall) { if (installConfig.switches.isDaEnabled) { (0, _utils.writeTemplates)(ConfigFiles.DAHelmOverride, v7AgentValues, helpers.v7DAHelmOverrideTemplate); } if (installConfig.switches.isTaEnabled) { (0, _utils.writeTemplates)(ConfigFiles.TAHelmOverride, v7AgentValues, helpers.v7TAHelmOverrideTemplate); } } else { if (installConfig.switches.isDaEnabled) { (0, _utils.writeTemplates)(ConfigFiles.DAEnvVars, v7AgentValues, helpers.v7DAEnvVarTemplate); } if (installConfig.switches.isTaEnabled) { (0, _utils.writeTemplates)(ConfigFiles.TAEnvVars, v7AgentValues, helpers.v7TAEnvVarTemplate); } } console.log('Configuration file(s) have been successfully created.\n'); generateSuccessHelpMsg(installConfig); }; exports.completeInstall = completeInstall; const dockerSuccessMsg = (installConfig, eventLogPath) => { let dockerInfo; const runDaLinuxMsg = `docker run -it --env-file ${helpers.pwd}/${helpers.configFiles.DA_ENV_VARS} -v ${helpers.pwd}:/keys ${helpers.eolChar}`; const runDaWinMsg = `docker run -it --env-file ${helpers.pwdWin}/${helpers.configFiles.DA_ENV_VARS} -v ${helpers.pwdWin}:/keys ${helpers.eolCharWin}`; const runTaLinuxMsg = `docker run -it --env-file ${helpers.pwd}/${helpers.configFiles.TA_ENV_VARS} -v ${helpers.pwd}:/keys ${helpers.eolChar}`; const runTaWinMsg = `docker run -it --env-file ${helpers.pwdWin}/${helpers.configFiles.TA_ENV_VARS} -v ${helpers.pwdWin}:/keys ${helpers.eolCharWin}`; const startDaLinuxMsg = `\nStart the Discovery Agent on a Linux based machine`; const startDaWinMsg = `\nStart the Discovery Agent on a Windows machine`; const startTaLinuxMsg = `\nStart the Traceability Agent on a Linux based machine`; const startTaWinMsg = `\nStart the Traceability Agent on a Windows machine`; if (installConfig.switches.isDaEnabled && installConfig.switches.isTaEnabled) { dockerInfo = `To utilize the agents, pull the latest Docker images and run them using the appropriate supplied environment files, (${helpers.configFiles.DA_ENV_VARS} & ${helpers.configFiles.TA_ENV_VARS}):`; } else if (installConfig.switches.isDaEnabled) { dockerInfo = `To utilize the discovery agent, pull the latest Docker image and run it using the supplied environment file, (${helpers.configFiles.DA_ENV_VARS}):`; } else { dockerInfo = `To utilize the traceability agent, pull the latest Docker image and run it using the supplied environment file, (${helpers.configFiles.TA_ENV_VARS}):`; } console.log(_cliKit.chalk.whiteBright(dockerInfo), '\n'); if (installConfig.switches.isDaEnabled) { const daImageVersion = `${daImage}:${installConfig.daVersion}`; console.log(_cliKit.chalk.white('Pull the latest image of the Discovery Agent:')); console.log(_cliKit.chalk.cyan(`docker pull ${daImageVersion}`)); console.log(_cliKit.chalk.white(_utils.isWindows ? startDaWinMsg : startDaLinuxMsg)); console.log(_cliKit.chalk.cyan(_utils.isWindows ? runDaWinMsg : runDaLinuxMsg)); console.log('\t', _cliKit.chalk.cyan(`-v /data ${daImageVersion}`)); } if (installConfig.switches.isTaEnabled) { const taImageVersion = `${taImage}:${installConfig.taVersion}`; console.log(_cliKit.chalk.white('Pull the latest image of the Traceability Agent:')); console.log(_cliKit.chalk.cyan(`docker pull ${taImageVersion}`)); console.log(_cliKit.chalk.white(_utils.isWindows ? startTaWinMsg : startTaLinuxMsg)); console.log(_cliKit.chalk.cyan(_utils.isWindows ? runTaWinMsg : runTaLinuxMsg)); console.log('\t', _cliKit.chalk.cyan(`-v ${eventLogPath} -v /data ${taImageVersion}`)); } }; const binarySuccessMsg = (isNewDosa, isDaEnabled, isTaEnabled) => { const daFiles = [ConfigFiles.DAEnvVars, ConfigFiles.EdgeDABinaryFile, ConfigFiles.EdgeDAYaml]; const taFiles = [ConfigFiles.TAEnvVars, ConfigFiles.EdgeTABinaryFile, ConfigFiles.EdgeTAYaml]; const keys = ['private_key.pem', 'public_key.pem']; let files = []; if (isNewDosa) { files = files.concat(keys); } if (isDaEnabled) { files = files.concat(daFiles); } if (isTaEnabled) { files = files.concat(taFiles); } const agents = isDaEnabled && isTaEnabled ? 'agents' : 'agent'; console.log(_cliKit.chalk.whiteBright('Please copy following files from current folder to API Gateway machine:')); console.log(_cliKit.chalk.cyan(files.join('\n'))); console.log(_cliKit.chalk.whiteBright('for example'), _cliKit.chalk.cyan(`scp ${files.join(' ')} root@host:~/some_folder/`)); console.log(_cliKit.chalk.whiteBright(`\nTo start the ${agents}:`)); if (isDaEnabled) { console.log(_cliKit.chalk.cyan(`./discovery_agent --envFile ./${helpers.configFiles.DA_ENV_VARS}`)); } if (isTaEnabled) { console.log(_cliKit.chalk.cyan(`./traceability_agent --envFile ./${helpers.configFiles.TA_ENV_VARS}`)); } }; const helmSuccessMsg = (namespace, isDaEnabled, isTaEnabled) => { const imagePullOverrides = `--set image.pullSecret=<image-pull-secret-name>`; let agentHelmInfo = new Set(); if (isDaEnabled) { console.log(_cliKit.chalk.white(`Discovery Agent override file has been placed at ${process.cwd()}/${ConfigFiles.DAHelmOverride}`)); agentHelmInfo.add({ helmReleaseName: 'v7-discovery', helmChartName: 'axway/v7-discovery', overrideFileName: ConfigFiles.DAHelmOverride, imageSecretOverrides: imagePullOverrides }); } if (isTaEnabled) { console.log(_cliKit.chalk.white(`Traceability Agent override file has been placed at ${process.cwd()}/${ConfigFiles.TAHelmOverride}`)); agentHelmInfo.add({ helmReleaseName: 'v7-traceability', helmChartName: 'axway/v7-traceability', overrideFileName: ConfigFiles.TAHelmOverride, imageSecretOverrides: imagePullOverrides }); } helpers.helmImageSecretInfo(namespace); helpers.helmInstallInfo('Edge', namespace, agentHelmInfo); }; const edgeAgentNameMap = { [_types.AgentTypes.da]: _types.AgentNames.EDGE_DA, [_types.AgentTypes.ta]: _types.AgentNames.EDGE_TA }; const EdgeInstallMethods = exports.EdgeInstallMethods = { GetBundleType: askBundleType, GetDeploymentType: askConfigType, AskGatewayQuestions: gatewayConnectivity, InstallPreprocess: installPreprocess, FinalizeGatewayInstall: completeInstall, ConfigFiles: Object.values(ConfigFiles), AgentNameMap: edgeAgentNameMap, GatewayDisplay: _types.GatewayTypes.EDGE_GATEWAY }; const EdgeGWOnlyInstallMethods = exports.EdgeGWOnlyInstallMethods = { GetBundleType: askBundleTypeGWOnly, GetDeploymentType: askConfigType, AskGatewayQuestions: gatewayConnectivity, InstallPreprocess: installPreprocess, FinalizeGatewayInstall: completeInstall, ConfigFiles: Object.values(ConfigFiles), AgentNameMap: edgeAgentNameMap, GatewayDisplay: _types.GatewayTypes.EDGE_GATEWAY }; const testables = exports.testables = { prompts, ConfigFiles, defaultLogFiles, defaultOTLogFiles };