Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added awsRequest for aws-sdk call backoff and retry in customResources #8338

Merged
merged 16 commits into from Oct 7, 2020
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -1,7 +1,6 @@
'use strict';

const ApiGateway = require('aws-sdk/clients/apigateway');
const Iam = require('aws-sdk/clients/iam');
const { awsRequest } = require('../utils');
const { getEnvironment, handlerWrapper, wait } = require('../utils');

function handler(event, context) {
Expand All @@ -19,8 +18,9 @@ async function create(event, context) {
const { RoleArn } = event.ResourceProperties;
const { Partition: partition, AccountId: accountId, Region: region } = getEnvironment(context);

const apiGateway = new ApiGateway({ region });
const assignedRoleArn = (await apiGateway.getAccount().promise()).cloudwatchRoleArn;
const assignedRoleArn = (
await awsRequest({ name: 'APIGateway', params: { region } }, 'getAccount').promise()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awsRequest should return promise directly, there should be no need for promise()

).cloudwatchRoleArn;

let roleArn = `arn:${partition}:iam::${accountId}:role/serverlessApiGatewayCloudWatchRole`;
if (RoleArn) {
Expand All @@ -32,33 +32,30 @@ async function create(event, context) {

const roleName = roleArn.slice(roleArn.lastIndexOf('/') + 1);

const iam = new Iam();

const attachedPolicies = await (async () => {
try {
return (await iam.listAttachedRolePolicies({ RoleName: roleName }).promise())
.AttachedPolicies;
return (
await awsRequest('IAM', 'listAttachedRolePolicies', { RoleName: roleName }).promise()
).AttachedPolicies;
} catch (error) {
if (error.code === 'NoSuchEntity') {
// Role doesn't exist yet, create;
await iam
.createRole({
AssumeRolePolicyDocument: JSON.stringify({
Version: '2012-10-17',
Statement: [
{
Effect: 'Allow',
Principal: {
Service: ['apigateway.amazonaws.com'],
},
Action: ['sts:AssumeRole'],
await awsRequest('IAM', 'createRole', {
AssumeRolePolicyDocument: JSON.stringify({
Version: '2012-10-17',
Statement: [
{
Effect: 'Allow',
Principal: {
Service: ['apigateway.amazonaws.com'],
},
],
}),
Path: '/',
RoleName: roleName,
})
.promise();
Action: ['sts:AssumeRole'],
},
],
}),
Path: '/',
RoleName: roleName,
}).promise();
return [];
}
throw error;
Expand All @@ -68,12 +65,10 @@ async function create(event, context) {
if (
!attachedPolicies.some(policy => policy.PolicyArn === apiGatewayPushToCloudWatchLogsPolicyArn)
) {
await iam
.attachRolePolicy({
PolicyArn: apiGatewayPushToCloudWatchLogsPolicyArn,
RoleName: roleName,
})
.promise();
await awsRequest('IAM', 'attachRolePolicy', {
PolicyArn: apiGatewayPushToCloudWatchLogsPolicyArn,
RoleName: roleName,
}).promise();
}
}

Expand All @@ -82,17 +77,15 @@ async function create(event, context) {

const updateAccount = async (counter = 1) => {
try {
await apiGateway
.updateAccount({
patchOperations: [
{
op: 'replace',
path: '/cloudwatchRoleArn',
value: roleArn,
},
],
})
.promise();
await awsRequest({ name: 'APIGateway', params: { region } }, 'updateAccount', {
patchOperations: [
{
op: 'replace',
path: '/cloudwatchRoleArn',
value: roleArn,
},
],
}).promise();
} catch (error) {
if (counter < 10) {
// Observed fails with errors marked as non-retryable. Still they're outcome of
Expand Down
@@ -1,6 +1,6 @@
'use strict';

const Lambda = require('aws-sdk/clients/lambda');
const { awsRequest } = require('../../utils');

function getStatementId(functionName, userPoolName) {
const normalizedUserPoolName = userPoolName.toLowerCase().replace(/[.:*\s]/g, '');
Expand All @@ -13,25 +13,23 @@ function getStatementId(functionName, userPoolName) {

function addPermission(config) {
const { functionName, userPoolName, partition, region, accountId, userPoolId } = config;
const lambda = new Lambda({ region });
const params = {
const payload = {
Action: 'lambda:InvokeFunction',
FunctionName: functionName,
Principal: 'cognito-idp.amazonaws.com',
StatementId: getStatementId(functionName, userPoolName),
SourceArn: `arn:${partition}:cognito-idp:${region}:${accountId}:userpool/${userPoolId}`,
};
return lambda.addPermission(params).promise();
return awsRequest({ name: 'Lambda', params: { region } }, 'addPermission', payload).promise();
}

function removePermission(config) {
const { functionName, userPoolName, region } = config;
const lambda = new Lambda({ region });
const params = {
const payload = {
FunctionName: functionName,
StatementId: getStatementId(functionName, userPoolName),
};
return lambda.removePermission(params).promise();
return awsRequest({ name: 'Lambda', params: { region } }, 'removePermission', payload).promise();
}

module.exports = {
Expand Down
@@ -1,6 +1,6 @@
'use strict';

const CognitoIdentityServiceProvider = require('aws-sdk/clients/cognitoidentityserviceprovider');
const { awsRequest } = require('../../utils');

function getUpdateConfigFromCurrentSetup(currentSetup) {
const updatedConfig = Object.assign({}, currentSetup);
Expand Down Expand Up @@ -28,16 +28,18 @@ function getUpdateConfigFromCurrentSetup(currentSetup) {

function findUserPoolByName(config) {
const { userPoolName, region } = config;
const cognito = new CognitoIdentityServiceProvider({ region });

const params = {
const payload = {
MaxResults: 60,
};

function recursiveFind(nextToken) {
if (nextToken) params.NextToken = nextToken;
return cognito
.listUserPools(params)
if (nextToken) payload.NextToken = nextToken;
return awsRequest(
{ name: 'CognitoIdentityServiceProvider', params: { region } },
'listUserPools',
payload
)
.promise()
.then(result => {
const matches = result.UserPools.filter(pool => pool.Name === userPoolName);
Expand All @@ -54,20 +56,16 @@ function findUserPoolByName(config) {

function getConfiguration(config) {
const { region } = config;
const cognito = new CognitoIdentityServiceProvider({ region });

return findUserPoolByName(config).then(userPool =>
cognito
.describeUserPool({
UserPoolId: userPool.Id,
})
.promise()
awsRequest({ name: 'CognitoIdentityServiceProvider', params: { region } }, 'describeUserPool', {
UserPoolId: userPool.Id,
}).promise()
);
}

function updateConfiguration(config) {
const { lambdaArn, userPoolConfigs, region } = config;
const cognito = new CognitoIdentityServiceProvider({ region });

return getConfiguration(config).then(res => {
const UserPoolId = res.UserPool.Id;
Expand All @@ -88,13 +86,16 @@ function updateConfiguration(config) {
LambdaConfig,
});

return cognito.updateUserPool(updatedConfig).promise();
return awsRequest(
{ name: 'CognitoIdentityServiceProvider', params: { region } },
'updateUserPool',
updatedConfig
).promise();
});
}

function removeConfiguration(config) {
const { lambdaArn, region } = config;
const cognito = new CognitoIdentityServiceProvider({ region });

return getConfiguration(config).then(res => {
const UserPoolId = res.UserPool.Id;
Expand All @@ -111,7 +112,11 @@ function removeConfiguration(config) {
LambdaConfig,
});

return cognito.updateUserPool(updatedConfig).promise();
return awsRequest(
{ name: 'CognitoIdentityServiceProvider', params: { region } },
'updateUserPool',
updatedConfig
).promise();
});
}

Expand Down
@@ -1,6 +1,6 @@
'use strict';

const EventBridge = require('aws-sdk/clients/eventbridge');
const { awsRequest } = require('../../utils');
const { getEventBusName, getEventBusTargetId } = require('./utils');

function createEventBus(config) {
Expand All @@ -10,12 +10,9 @@ function createEventBus(config) {
if (eventBus.startsWith('arn')) {
return Promise.resolve();
}
const eventBridge = new EventBridge({ region });
return eventBridge
.createEventBus({
Name: eventBus,
})
.promise();
return awsRequest({ name: 'EventBridge', params: { region } }, 'createEventBus', {
Name: eventBus,
}).promise();
}
return Promise.resolve();
}
Expand All @@ -28,50 +25,40 @@ function deleteEventBus(config) {
return Promise.resolve();
}

const eventBridge = new EventBridge({ region });
return eventBridge
.deleteEventBus({
Name: eventBus,
})
.promise();
return awsRequest({ name: 'EventBridge', params: { region } }, 'deleteEventBus', {
Name: eventBus,
}).promise();
}
return Promise.resolve();
}

function updateRuleConfiguration(config) {
const { ruleName, eventBus, pattern, schedule, region } = config;
const eventBridge = new EventBridge({ region });

const EventBusName = getEventBusName(eventBus);

return eventBridge
.putRule({
Name: ruleName,
EventBusName,
EventPattern: JSON.stringify(pattern),
ScheduleExpression: schedule,
State: 'ENABLED',
})
.promise();
return awsRequest({ name: 'EventBridge', params: { region } }, 'putRule', {
Name: ruleName,
EventBusName,
EventPattern: JSON.stringify(pattern),
ScheduleExpression: schedule,
State: 'ENABLED',
}).promise();
}

function removeRuleConfiguration(config) {
const { ruleName, eventBus, region } = config;
const eventBridge = new EventBridge({ region });

const EventBusName = getEventBusName(eventBus);

return eventBridge
.deleteRule({
Name: ruleName,
EventBusName,
})
.promise();
return awsRequest({ name: 'EventBridge', params: { region } }, 'deleteRule', {
Name: ruleName,
EventBusName,
}).promise();
}

function updateTargetConfiguration(config) {
const { lambdaArn, ruleName, eventBus, input, inputPath, inputTransformer, region } = config;
const eventBridge = new EventBridge({ region });

const EventBusName = getEventBusName(eventBus);

Expand All @@ -89,29 +76,24 @@ function updateTargetConfiguration(config) {
}

return removeTargetConfiguration(config).then(() =>
eventBridge
.putTargets({
Rule: ruleName,
EventBusName,
Targets: [target],
})
.promise()
awsRequest({ name: 'EventBridge', params: { region } }, 'putTargets', {
Rule: ruleName,
EventBusName,
Targets: [target],
}).promise()
);
}

function removeTargetConfiguration(config) {
const { ruleName, eventBus, region } = config;
const eventBridge = new EventBridge({ region });

const EventBusName = getEventBusName(eventBus);

return eventBridge
.removeTargets({
Ids: [getEventBusTargetId(ruleName)],
Rule: ruleName,
EventBusName,
})
.promise();
return awsRequest({ name: 'EventBridge', params: { region } }, 'removeTargets', {
Ids: [getEventBusTargetId(ruleName)],
Rule: ruleName,
EventBusName,
}).promise();
}

module.exports = {
Expand Down