Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/lib/engage/clients-external/apiserverclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
ApiServerVersions,
BasePaths,
CommandLineInterface,
Component,
GenericResource,
GenericResourceWithoutName,
LanguageTypes,
Expand Down Expand Up @@ -894,6 +895,21 @@ export class ApiServerClient {
}
}

async getComponentDefinitionsByName(componentName: string, version = ApiServerVersions.v1alpha1): Promise<Component> {
const log = logger('ApiServerClient.getComponentDefinitionsByName');
log.info('get component definitions');
try {
const service = await this.initializeDataService();
const component: Component = await service.get(`/definitions/${version}/components/${componentName}`);

return component;

} catch (e: any) {
log.error('get specs, error: ', e);
throw e;
}
}

async bulkCreate(
resources: Array<GenericResourceWithoutName | GenericResource>,
sortedDefsMap: Map<string, ResourceDefinition>,
Expand Down
10 changes: 5 additions & 5 deletions src/lib/engage/services/install-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,17 +89,17 @@ const determineRegion = async (region: string | undefined): Promise<string> => {
return configurationRegion ? configurationRegion : Regions.US;
};

async function getAgentVersions(agentInstallFlow: InstallationFlowMethods, installConfig: AgentInstallConfig, account: Account): Promise<void> {
async function getAgentVersions(agentInstallFlow: InstallationFlowMethods, installConfig: AgentInstallConfig, apiServerClient: ApiServerClient): Promise<void> {
if (agentInstallFlow.AgentNameMap && !installConfig.switches.isHostedInstall && installConfig.switches.isDaEnabled) {
installConfig.daVersion = await helpers.getLatestAgentVersion(
apiServerClient,
agentInstallFlow.AgentNameMap[AgentTypes.da] as string,
account
);
}
if (agentInstallFlow.AgentNameMap && !installConfig.switches.isHostedInstall && installConfig.switches.isTaEnabled) {
installConfig.taVersion = await helpers.getLatestAgentVersion(
apiServerClient,
agentInstallFlow.AgentNameMap[AgentTypes.ta] as string,
account
);
}
}
Expand Down Expand Up @@ -249,8 +249,8 @@ export async function installAgents(params: InstallAgentsCommandParams): Promise
installConfig.switches.isDockerInstall = installConfig.deploymentType === AgentConfigTypes.DOCKERIZED;
installConfig.switches.isBinaryInstall = installConfig.deploymentType === AgentConfigTypes.BINARIES;

// Get the version of the agents from jfrog, not needed in hosted install
await getAgentVersions(agentInstallFlow, installConfig, params.account);
// Get the version of the agents from Engage, not needed in hosted install
await getAgentVersions(agentInstallFlow, installConfig, apiServerClient);

// if EDGE_GATEWAY or EDGE_GATEWAY_ONLY and isDaEnabled, ask if the organization structure should replicate
if (
Expand Down
47 changes: 44 additions & 3 deletions src/lib/engage/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,49 @@ export interface CommandLineInterface {
};
}

export interface Component {
group: 'definitions',
apiVersion: ApiServerVersions,
kind: 'Component',
name: string,
title: string,
metadata: {
id: string,
audit: {
createTimestamp: string,
modifyTimestamp: string
},
accessRights: {
canChangeOwner: boolean,
canDelete: boolean,
canWrite: boolean,
canRead: boolean
},
resourceVersion: string,
selfLink: string
},
spec: {
type: ComponentType,
latest: ComponentSpecVersionInfo,
retracted: string[],
supported: ComponentSpecVersionInfo[]
}

}

export enum ComponentType {
Agent = 'agent',
DA = 'DiscoveryAgent',
TA = 'TraceabilityAgent',
CA = 'ComplianceAgent'
}

export interface ComponentSpecVersionInfo {
version: string;
releaseDate: string;
endOfSupportDate: string;
}

export interface AuditMetadata {
createTimestamp: string; // '2020-08-04T21:05:32.106Z';
createUserId: string; // '07e6b449-3a31-4a96-8920-e87dd504cb87';
Expand Down Expand Up @@ -349,7 +392,6 @@ export enum BasePaths {
V7Agents = '/artifactory/ampc-public-generic-release/v7-agents',
AWSAgents = '/artifactory/ampc-public-generic-release/aws-agents',
DockerAgentPublicRepo = '/agent',
DockerAgentAPIRepoPath = '/artifactory/api/docker/ampc-public-docker-release/v2/agent',
}

export interface ValidatedDocs {
Expand Down Expand Up @@ -836,8 +878,7 @@ export const GatewayTypeToDataPlane = {
[GatewayTypes.WSO2]: DataPlaneNames.WSO2,
};

export const PublicRepoUrl = 'https://axway.jfrog.io';
export const PublicDockerRepoBaseUrl = 'axway.jfrog.io/ampc-public-docker-release';
export const PublicDockerRepoBaseUrl = 'repository.axway.com/ampc-public-docker-release';

export class DOSAConfigInfo {
clientId: string | null;
Expand Down
83 changes: 14 additions & 69 deletions src/lib/engage/utils/agents/flows/awsAgents.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import chalk from 'chalk';
import fs from 'fs';
import logger from '../../../../logger.js';
import { dataService } from '../../../../request.js';
import { AgentConfigTypes, AgentInstallConfig, AgentNames, AgentTypes, AWSRegions, BasePaths, BundleType, GatewayTypes, InstallationFlowMethods, PublicDockerRepoBaseUrl, PublicRepoUrl, TrueFalse, YesNo, YesNoChoices } from '../../../types.js';
import { AgentConfigTypes, AgentInstallConfig, AgentNames, AgentTypes, AWSRegions, BasePaths, BundleType, GatewayTypes, InstallationFlowMethods, PublicDockerRepoBaseUrl, TrueFalse, YesNo, YesNoChoices } from '../../../types.js';
import { askInput, askList, validateInputLength, validateRegex } from '../../basic-prompts.js';
import { isWindows, writeTemplates, writeToFile } from '../../utils.js';
import { AWSAgentValues } from '../index.js';
import * as helpers from '../index.js';
import { Account } from '../../../../../types.js';

const debugLog = logger('lib: engage: utils: agents: flows: awsAgents');
const daImage = `${PublicDockerRepoBaseUrl}${BasePaths.DockerAgentPublicRepo}/${AgentNames.AWS_DA}`;
Expand Down Expand Up @@ -361,8 +358,6 @@ ${chalk.cyan(
${chalk.cyan(
` aws ssm put-parameter --type SecureString --name ${awsAgentValues.cloudFormationConfig.SSMPublicKeyParameter} --value "file://public_key.pem"`
)}`;
// Cleanup EC2 file
fs.unlinkSync(ConfigFiles.EC2DeployYAML);
break;
}
case DeploymentTypes.OTHER: {
Expand All @@ -373,10 +368,6 @@ ${chalk.cyan(
(value) => (s3ResourcesIncludes += `--include "${value}" `)
);

// Cleanup EC2 file
fs.unlinkSync(ConfigFiles.EC2DeployYAML);
// Cleanup ECS Fargate file
fs.unlinkSync(ConfigFiles.FargateDeployYAML);
const info = `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}):`;

dockerEnvConfig = `Wait for the CloudFormation Stack to complete.
Expand Down Expand Up @@ -451,8 +442,6 @@ ${chalk.cyan(
${chalk.cyan(
` aws ssm put-parameter --type SecureString --name ${awsAgentValues.cloudFormationConfig.SSMPublicKeyParameter} --value "file://public_key.pem"`
)}`;
// Cleanup Fargate file
fs.unlinkSync(ConfigFiles.FargateDeployYAML);
break;
}
}
Expand All @@ -463,7 +452,13 @@ ${chalk.cyan(
const s3Region = awsAgentValues.region === AWSRegions.US_EAST_1 ? 's3' : `s3.${awsAgentValues.region}`;

return `
To complete the install, run the following AWS CLI command:
To complete the install, first download and extract the CloudFormation templates:
- Download the CloudFormation package:
${chalk.cyan(` curl -O https://repository.axway.com/artifactory/ampc-public-generic-release/aws-agents/aws_apigw_agent_config/latest/${ConfigFiles.AgentConfigZip}`)}
- Extract the package:
${chalk.cyan(` unzip ${ConfigFiles.AgentConfigZip}`)}

Then run the following AWS CLI commands:
- Create, if necessary, and upload all files to your S3 bucket
${chalk.cyan(
` aws s3api create-bucket --bucket ${awsAgentValues.cloudFormationConfig.AgentResourcesBucket} --create-bucket-configuration LocationConstraint=${awsAgentValues.region}`
Expand All @@ -487,55 +482,6 @@ ${chalk.gray(`Additional information about agent features can be found here:\n${
`;
};

// Download latest aws apigw config zip
const downloadAPIGWAgentConfigZip = async (account: Account): Promise<string> => {
const url = `${BasePaths.AWSAgents}/aws_apigw_agent_config/latest/${ConfigFiles.AgentConfigZip}`;

const service = await dataService({
account,
baseUrl: PublicRepoUrl,
});
try {
const token = account.auth?.tokens?.access_token;
if (!token) {
throw new Error('Invalid/expired account');
}
const { stream } = await service.download(url);
await helpers.streamPipeline(stream, fs.createWriteStream(ConfigFiles.AgentConfigZip));
return ConfigFiles.AgentConfigZip;
} catch (err: any) {
throw new Error(`Failed to download the agent: ${err.message}`);
}
};

// Unzip latest aws apigw config zip
const unzipAPIGWAgentConfigZip = async (zipFile: string, log: (text: string) => void = () => {}): Promise<boolean> => {
await helpers.unzip(zipFile);
fs.unlinkSync(zipFile);

const isCloudFormation = fs.existsSync(ConfigFiles.DeployAllYAML);
if (!isCloudFormation) {
log(`${ConfigFiles.DeployAllYAML} was not extracted from ${ConfigFiles.AgentConfigZip}`);
return false;
}
return true;
};

export const installPreprocess = async (installConfig: AgentInstallConfig): Promise<AgentInstallConfig> => {
// attempt to download the cloud formation files
installConfig.log(chalk.gray('Downloading the latest Cloud formation template...'));
const account = installConfig.centralConfig.apiServerClient?.account;
if (!account) {
throw new Error('Unable to resolve account for DataService call during AWS agent install preprocess');
}
const apigwAgentConfigZipFile = await downloadAPIGWAgentConfigZip(account);
if (apigwAgentConfigZipFile !== '') {
installConfig.log(chalk.gray('\nSuccess'));
}
(installConfig.gatewayConfig as helpers.AWSAgentValues).apigwAgentConfigZipFile = apigwAgentConfigZipFile;
return installConfig;
};

export const completeInstall = async (installConfig: AgentInstallConfig): Promise<void> => {
/**
* Create agent resources
Expand All @@ -546,11 +492,7 @@ export const completeInstall = async (installConfig: AgentInstallConfig): Promis
awsAgentValues.centralConfig = installConfig.centralConfig;
awsAgentValues.traceabilityConfig = installConfig.traceabilityConfig;

const unpackZip = await unzipAPIGWAgentConfigZip(awsAgentValues.apigwAgentConfigZipFile, installConfig.log);
if (unpackZip) {
installConfig.log('\nCreating the agent environment files for AWS...');
}

installConfig.log('\nCreating the agent environment files for AWS...');
installConfig.log('Generating the configuration file(s)...');

installConfig.log('Generating the cloud formation parameters file...');
Expand Down Expand Up @@ -586,9 +528,12 @@ export const AWSInstallMethods: InstallationFlowMethods = {
GetBundleType: askBundleType,
GetDeploymentType: askConfigType,
AskGatewayQuestions: gatewayConnectivity,
InstallPreprocess: installPreprocess,
FinalizeGatewayInstall: completeInstall,
ConfigFiles: Object.values(ConfigFiles),
ConfigFiles: [
ConfigFiles.DAEnvVars,
ConfigFiles.TAEnvVars,
ConfigFiles.CFProperties,
],
AgentNameMap: {
[AgentTypes.da]: AgentNames.AWS_DA,
[AgentTypes.ta]: AgentNames.AWS_TA,
Expand Down
70 changes: 18 additions & 52 deletions src/lib/engage/utils/agents/flows/edgeAgents.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
import chalk from 'chalk';
import fs from 'fs';
import { dataService } from '../../../../request.js';
import { AgentConfigTypes, AgentInstallConfig, AgentNames, AgentTypes, BasePaths, BundleType, GatewayTypes, InstallationFlowMethods, localhost, LoggingSource, PublicDockerRepoBaseUrl, PublicRepoUrl, svcAccMsg, YesNo, YesNoChoices } from '../../../types.js';
import { AgentConfigTypes, AgentInstallConfig, AgentNames, AgentTypes, BasePaths, BundleType, GatewayTypes, InstallationFlowMethods, localhost, LoggingSource, PublicDockerRepoBaseUrl, svcAccMsg, YesNo, YesNoChoices } from '../../../types.js';
import { askInput, askList, askUsernameAndPassword } from '../../basic-prompts.js';
import { writeTemplates, isWindows, AgentHelmInfo, helmImageSecretInfo, helmInstallInfo } from '../../utils.js';
import { V7AgentValues } from '../index.js';
import * as helpers from '../index.js';
import { kubectl } from '../kubectl.js';
import { amplifyAgentsNs } from './akamaiAgent.js';
import { Account } from '../../../../../types.js';

const defaultLogFiles = '/group-*_instance-*.log';
const defaultOTLogFiles = '/group-*_instance-*_traffic*.log';
Expand Down Expand Up @@ -45,47 +42,6 @@ export const prompts = {
'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 (account: Account, type: BundleType, version: string): Promise<string> => {
const fileName
= type === BundleType.DISCOVERY ? `discovery_agent-${version}.zip` : `traceability_agent-${version}.zip`;
const url
= type === BundleType.DISCOVERY
? `${BasePaths.V7Agents}/v7_discovery_agent/${version}/discovery_agent-${version}.zip`
: `${BasePaths.V7Agents}/v7_traceability_agent/${version}/traceability_agent-${version}.zip`;
const service = await dataService({
account: account,
baseUrl: PublicRepoUrl,
});
try {
const { stream } = await service.download(url);
await helpers.streamPipeline(stream, fs.createWriteStream(fileName));
return fileName;
} catch (err: any) {
throw new Error(`Failed to download the agent: ${err.message}`);
}
};

const downloadBinary = async (account: Account, bundleType: BundleType, version: string) => {
const fileName = await downloadV7AgentBundle(account, bundleType, version);
await helpers.unzip(fileName);
fs.unlinkSync(fileName);
};

const downloadBinaries = async (installConfig: AgentInstallConfig) => {
const account = installConfig.centralConfig.apiServerClient?.account;
if (!account) {
throw new Error('Unable to resolve account for DataService call during AWS agent install preprocess');
}
installConfig.log('Downloading and unpacking binary files...');
if (installConfig.switches.isDaEnabled) {
await downloadBinary(account, BundleType.DISCOVERY, installConfig.daVersion);
}
if (installConfig.switches.isTaEnabled) {
await downloadBinary(account, BundleType.TRACEABILITY, installConfig.taVersion);
}
installConfig.log('Downloading and unpacking is complete.');
};

export const askIsGatewayOnlyMode = async (): Promise<GatewayTypes> => {
const mode = await askList({
msg: prompts.enterGatewayManagerMode,
Expand Down Expand Up @@ -273,6 +229,8 @@ const generateSuccessHelpMsg = (installConfig: AgentInstallConfig) => {
installConfig.centralConfig.ampcDosaInfo.isNew,
installConfig.switches.isDaEnabled,
installConfig.switches.isTaEnabled,
installConfig.daVersion,
installConfig.taVersion,
installConfig.log
);
} else if (configType === AgentConfigTypes.DOCKERIZED) {
Expand All @@ -298,11 +256,6 @@ export const installPreprocess = async (installConfig: AgentInstallConfig): Prom
= await helpers.askPublicAndPrivateKeysPath();
}

// attempt to download the binaries prior to creating resources
if (installConfig.switches.isBinaryInstall) {
await downloadBinaries(installConfig);
}

return installConfig;
};

Expand Down Expand Up @@ -418,7 +371,20 @@ const dockerSuccessMsg = (installConfig: AgentInstallConfig, eventLogPath: strin
}
};

const binarySuccessMsg = (isNewDosa: boolean, isDaEnabled: boolean, isTaEnabled: boolean, log: (text: string) => void = () => {}) => {
const binarySuccessMsg = (isNewDosa: boolean, isDaEnabled: boolean, isTaEnabled: boolean, daVersion: string, taVersion: string, log: (text: string) => void = () => {}) => {
const baseUrl = 'https://repository.axway.com/artifactory/ampc-public-generic-release/v7-agents';

if (isDaEnabled) {
log(chalk.whiteBright('\nDownload the Discovery Agent binary:'));
log(chalk.cyan(`curl -O ${baseUrl}/v7_discovery_agent/${daVersion}/discovery_agent-${daVersion}.zip`));
log(chalk.cyan(`unzip discovery_agent-${daVersion}.zip`));
}
if (isTaEnabled) {
log(chalk.whiteBright('\nDownload the Traceability Agent binary:'));
log(chalk.cyan(`curl -O ${baseUrl}/v7_traceability_agent/${taVersion}/traceability_agent-${taVersion}.zip`));
log(chalk.cyan(`unzip traceability_agent-${taVersion}.zip`));
}

const daFiles = [ ConfigFiles.DAEnvVars, ConfigFiles.EdgeDABinaryFile, ConfigFiles.EdgeDAYaml ];
const taFiles = [ ConfigFiles.TAEnvVars, ConfigFiles.EdgeTABinaryFile, ConfigFiles.EdgeTAYaml ];
const keys = [ 'private_key.pem', 'public_key.pem' ];
Expand All @@ -435,7 +401,7 @@ const binarySuccessMsg = (isNewDosa: boolean, isDaEnabled: boolean, isTaEnabled:
}
const agents = isDaEnabled && isTaEnabled ? 'agents' : 'agent';

log(chalk.whiteBright('Please copy following files from current folder to API Gateway machine:'));
log(chalk.whiteBright('\nPlease copy following files from current folder to API Gateway machine:'));
log(chalk.cyan(files.join('\n')));
log(chalk.whiteBright('for example') + ' ' + chalk.cyan(`scp ${files.join(' ')} root@host:~/some_folder/`));

Expand Down
Loading
Loading