Skip to content

Commit

Permalink
Merge pull request #27 from MarcioMeier/fix/wso2-custom-lambda-bundle…
Browse files Browse the repository at this point in the history
…-size
  • Loading branch information
flaviostutz authored Aug 11, 2024
2 parents 5dd51c3 + 6ecb799 commit 22fd916
Show file tree
Hide file tree
Showing 7 changed files with 896 additions and 801 deletions.
1,511 changes: 801 additions & 710 deletions examples/pnpm-lock.yaml

Large diffs are not rendered by default.

68 changes: 68 additions & 0 deletions lib/src/wso2/utils-cdk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/* eslint-disable no-console */
import { existsSync } from 'fs';

import { Duration, ScopedAws } from 'aws-cdk-lib/core';
import { PolicyStatement } from 'aws-cdk-lib/aws-iam';
import { Runtime } from 'aws-cdk-lib/aws-lambda';
import { RetentionDays } from 'aws-cdk-lib/aws-logs';
import { Provider } from 'aws-cdk-lib/custom-resources';
import { Construct } from 'constructs';

import { BaseNodeJsFunction } from '../lambda/lambda-base';
import { EventType } from '../lambda/types';

import { Wso2BaseProperties } from './types';

export const addLambdaAndProviderForWso2Operations = (args: {
scope: Construct;
id: string;
props: Wso2BaseProperties;
baseDir: string;
}): { customResourceProvider: Provider; customResourceFunction: BaseNodeJsFunction } => {
const logGroupRetention =
args.props.customResourceConfig?.logGroupRetention ?? RetentionDays.ONE_MONTH;

const { accountId, region } = new ScopedAws(args.scope);

// resolve the entry file from workspace (.ts file), or
// from the dist dir (.js file) when being used as a lib
let wso2LambdaEntry = `${args.baseDir}/handler/index.ts`;
if (!existsSync(wso2LambdaEntry)) {
wso2LambdaEntry = `${args.baseDir}/handler/index.js`;
}

// lambda function used for invoking WSO2 APIs during CFN operations
const customResourceFunction = new BaseNodeJsFunction(args.scope, `${args.id}-custom-lambda`, {
...args.props.customResourceConfig,
stage: 'wso2-custom-lambda',
timeout: Duration.minutes(10),
memorySize: 256,
runtime: Runtime.NODEJS_18_X,
eventType: EventType.CustomResource,
createLiveAlias: false,
createDefaultLogGroup: true,
entry: wso2LambdaEntry,
initialPolicy: [
PolicyStatement.fromJson({
Effect: 'Allow',
Action: 'secretsmanager:GetSecretValue',
Resource: `arn:aws:secretsmanager:${region}:${accountId}:secret:${args.props.wso2Config.credentialsSecretId}*`,
}),
],
logGroupRetention,
// allow all outbound by default
allowAllOutbound: typeof args.props.customResourceConfig?.network !== 'undefined',
});

if (args.props.customResourceConfig?.logGroupRemovalPolicy) {
customResourceFunction.nodeJsFunction.applyRemovalPolicy(
args.props.customResourceConfig.logGroupRemovalPolicy,
);
}

const customResourceProvider = new Provider(args.scope, `${args.id}-custom-provider`, {
onEventHandler: customResourceFunction.nodeJsFunction,
});

return { customResourceProvider, customResourceFunction };
};
102 changes: 19 additions & 83 deletions lib/src/wso2/utils.ts
Original file line number Diff line number Diff line change
@@ -1,89 +1,7 @@
/* eslint-disable no-console */
import { existsSync } from 'fs';

import { Duration, ScopedAws } from 'aws-cdk-lib/core';
import { PolicyStatement } from 'aws-cdk-lib/aws-iam';
import { Runtime } from 'aws-cdk-lib/aws-lambda';
import { RetentionDays } from 'aws-cdk-lib/aws-logs';
import { Provider } from 'aws-cdk-lib/custom-resources';
import { Construct } from 'constructs';
import { GetSecretValueCommand, SecretsManagerClient } from '@aws-sdk/client-secrets-manager';

import { BaseNodeJsFunction } from '../lambda/lambda-base';
import { EventType } from '../lambda/types';

import { RetryOptions, Wso2BaseProperties } from './types';

export const addLambdaAndProviderForWso2Operations = (args: {
scope: Construct;
id: string;
props: Wso2BaseProperties;
baseDir: string;
}): { customResourceProvider: Provider; customResourceFunction: BaseNodeJsFunction } => {
const logGroupRetention =
args.props.customResourceConfig?.logGroupRetention ?? RetentionDays.ONE_MONTH;

const { accountId, region } = new ScopedAws(args.scope);

// resolve the entry file from workspace (.ts file), or
// from the dist dir (.js file) when being used as a lib
let wso2LambdaEntry = `${args.baseDir}/handler/index.ts`;
if (!existsSync(wso2LambdaEntry)) {
wso2LambdaEntry = `${args.baseDir}/handler/index.js`;
}

// lambda function used for invoking WSO2 APIs during CFN operations
const customResourceFunction = new BaseNodeJsFunction(args.scope, `${args.id}-custom-lambda`, {
...args.props.customResourceConfig,
stage: 'wso2-custom-lambda',
timeout: Duration.minutes(10),
memorySize: 256,
runtime: Runtime.NODEJS_18_X,
eventType: EventType.CustomResource,
createLiveAlias: false,
createDefaultLogGroup: true,
entry: wso2LambdaEntry,
initialPolicy: [
PolicyStatement.fromJson({
Effect: 'Allow',
Action: 'secretsmanager:GetSecretValue',
Resource: `arn:aws:secretsmanager:${region}:${accountId}:secret:${args.props.wso2Config.credentialsSecretId}*`,
}),
],
logGroupRetention,
// allow all outbound by default
allowAllOutbound: typeof args.props.customResourceConfig?.network !== 'undefined',
});

if (args.props.customResourceConfig?.logGroupRemovalPolicy) {
customResourceFunction.nodeJsFunction.applyRemovalPolicy(
args.props.customResourceConfig.logGroupRemovalPolicy,
);
}

const customResourceProvider = new Provider(args.scope, `${args.id}-custom-provider`, {
onEventHandler: customResourceFunction.nodeJsFunction,
});

return { customResourceProvider, customResourceFunction };
};

export const getSecretValue = async (secretId: string): Promise<string> => {
const client = new SecretsManagerClient();
const response = await client.send(
new GetSecretValueCommand({
SecretId: secretId,
}),
);
if (response.SecretString) {
return response.SecretString;
}
if (!response.SecretBinary) {
throw new Error('Invalid type of secret found');
}
const buff = Buffer.from(response.SecretBinary);
return buff.toString('ascii');
};
import { RetryOptions } from './types';

const defaultRetryOpts = {
checkRetries: {
Expand All @@ -103,6 +21,7 @@ const defaultRetryOpts = {
// 2000, 3000
},
};

export const applyRetryDefaults = (retryOptions?: RetryOptions): RetryOptions => {
const ropts: RetryOptions = {
// default config for backoff
Expand Down Expand Up @@ -138,3 +57,20 @@ export const applyRetryDefaults = (retryOptions?: RetryOptions): RetryOptions =>
export const truncateStr = (str: string, size: number): string => {
return str.substring(0, Math.min(str.length, size));
};

export const getSecretValue = async (secretId: string): Promise<string> => {
const client = new SecretsManagerClient();
const response = await client.send(
new GetSecretValueCommand({
SecretId: secretId,
}),
);
if (response.SecretString) {
return response.SecretString;
}
if (!response.SecretBinary) {
throw new Error('Invalid type of secret found');
}
const buff = Buffer.from(response.SecretBinary);
return buff.toString('ascii');
};
2 changes: 1 addition & 1 deletion lib/src/wso2/wso2-api/wso2-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { IFunction } from 'aws-cdk-lib/aws-lambda';
import { OpenAPIObject } from 'openapi3-ts/oas30';

import { lintOpenapiDocument } from '../../utils/openapi-lint';
import { addLambdaAndProviderForWso2Operations } from '../utils';
import { addLambdaAndProviderForWso2Operations } from '../utils-cdk';

import { Wso2ApiCustomResourceProperties, Wso2ApiProps } from './types';
import { applyDefaultsWso2ApiDefinition, validateWso2ApiDefs } from './api-defs';
Expand Down
8 changes: 4 additions & 4 deletions lib/src/wso2/wso2-application/handler/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
/* eslint-disable no-console */

import { CdkCustomResourceEvent, CdkCustomResourceResponse } from 'aws-lambda';
import { AxiosInstance } from 'axios';
import type { CdkCustomResourceEvent, CdkCustomResourceResponse } from 'aws-lambda';
import type { AxiosInstance } from 'axios';

import { Wso2ApplicationCustomResourceProperties } from '../types';
import { prepareAxiosForWso2Calls } from '../../wso2-utils';
import { Wso2ApplicationInfo } from '../v1/types';
import { applyRetryDefaults, truncateStr } from '../../utils';
import type { Wso2ApplicationInfo } from '../v1/types';
import type { Wso2ApplicationCustomResourceProperties } from '../types';

import { createUpdateApplicationInWso2, removeApplicationInWso2 } from './wso2-v1';

Expand Down
4 changes: 2 additions & 2 deletions lib/src/wso2/wso2-application/handler/wso2-v1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import { backOff } from 'exponential-backoff';
import { AxiosInstance } from 'axios';

import { Wso2ApplicationDefinition, Wso2ApplicationInfo } from '../v1/types';
import { RetryOptions } from '../../types';
import type { Wso2ApplicationDefinition, Wso2ApplicationInfo } from '../v1/types';
import type { RetryOptions } from '../../types';

export type UpsertWso2Args = {
wso2Axios: AxiosInstance;
Expand Down
2 changes: 1 addition & 1 deletion lib/src/wso2/wso2-application/wso2-application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Construct } from 'constructs';
import { CustomResource, RemovalPolicy } from 'aws-cdk-lib/core';
import { IFunction } from 'aws-cdk-lib/aws-lambda';

import { addLambdaAndProviderForWso2Operations } from '../utils';
import { addLambdaAndProviderForWso2Operations } from '../utils-cdk';

import { Wso2ApplicationCustomResourceProperties, Wso2ApplicationProps } from './types';

Expand Down

0 comments on commit 22fd916

Please sign in to comment.