serverless-iam-roles-per-function
Advanced tools
Comparing version 2.0.2 to 3.0.0-354af97
@@ -5,2 +5,15 @@ # Changelog | ||
## [3.0.0](https://github.com/functionalone/serverless-iam-roles-per-function/compare/v2.0.2...v3.0.0) (2020-11-02) | ||
### Features | ||
* Support for Serverless v2.5.0 ([#53](https://github.com/functionalone/serverless-iam-roles-per-function/issues/53)) ([09e56ae](https://github.com/functionalone/serverless-iam-roles-per-function/commit/09e56ae)) | ||
### Features | ||
* nodejs 12 support ([#32](https://github.com/functionalone/serverless-iam-roles-per-function/issues/32)) ([4dd58a2](https://github.com/functionalone/serverless-iam-roles-per-function/commit/4dd58a2)) | ||
* Use resolved region name in counting length of role name ([#33](https://github.com/functionalone/serverless-iam-roles-per-function/issues/33)) ([f9fd677](https://github.com/functionalone/serverless-iam-roles-per-function/commit/f9fd677)), closes [#26](https://github.com/functionalone/serverless-iam-roles-per-function/issues/26) | ||
### [2.0.2](https://github.com/functionalone/serverless-iam-roles-per-function/compare/v2.0.1...v2.0.2) (2019-08-30) | ||
@@ -7,0 +20,0 @@ |
@@ -34,18 +34,37 @@ "use strict"; | ||
validateStatements(statements) { | ||
// Verify that iamRoleStatements (if present) is an array of { Effect: ..., | ||
// Action: ..., Resource: ... } objects. | ||
if (lodash_1.default.isEmpty(statements)) { | ||
return; | ||
} | ||
const awsPackagePluginName = "AwsPackage"; | ||
if (!this.awsPackagePlugin) { | ||
for (const plugin of this.serverless.pluginManager.plugins) { | ||
if (plugin.constructor && plugin.constructor.name === awsPackagePluginName) { | ||
this.awsPackagePlugin = plugin; | ||
break; | ||
} | ||
let violationsFound; | ||
if (!Array.isArray(statements)) { | ||
violationsFound = 'it is not an array'; | ||
} | ||
else { | ||
const descriptions = statements.map((statement, i) => { | ||
const missing = [ | ||
['Effect'], | ||
['Action', 'NotAction'], | ||
['Resource', 'NotResource'], | ||
].filter(props => props.every(prop => !statement[prop])); | ||
return missing.length === 0 | ||
? null | ||
: `statement ${i} is missing the following properties: ${missing | ||
.map(m => m.join(' / ')) | ||
.join(', ')}`; | ||
}); | ||
const flawed = descriptions.filter(curr => curr); | ||
if (flawed.length) { | ||
violationsFound = flawed.join('; '); | ||
} | ||
} | ||
if (!this.awsPackagePlugin) { | ||
this.throwError(`ERROR: could not find ${awsPackagePluginName} plugin to verify statements.`); | ||
if (violationsFound) { | ||
const errorMessage = [ | ||
'iamRoleStatements should be an array of objects,', | ||
' where each object has Effect, Action / NotAction, Resource / NotResource fields.', | ||
` Specifically, ${violationsFound}`, | ||
].join(''); | ||
this.throwError(errorMessage); | ||
} | ||
this.awsPackagePlugin.validateStatements(statements); | ||
} | ||
@@ -56,3 +75,8 @@ getRoleNameLength(name_parts) { | ||
if (part.Ref) { | ||
length += part.Ref.length; | ||
if (part.Ref === 'AWS::Region') { | ||
length += this.serverless.service.provider.region.length; | ||
} | ||
else { | ||
length += part.Ref.length; | ||
} | ||
} | ||
@@ -59,0 +83,0 @@ else { |
{ | ||
"name": "serverless-iam-roles-per-function", | ||
"private": false, | ||
"version": "2.0.2", | ||
"version": "3.0.0-354af97", | ||
"engines": { | ||
"node": ">=6.10.0" | ||
"node": ">=10" | ||
}, | ||
@@ -82,3 +82,8 @@ "description": "A Serverless plugin to define IAM Role statements as part of the function definition block", | ||
"all": true | ||
}, | ||
"standard-version": { | ||
"skip": { | ||
"tag": true | ||
} | ||
} | ||
} | ||
} |
@@ -46,19 +46,38 @@ import _ from 'lodash'; | ||
validateStatements(statements: any): void { | ||
validateStatements(statements: any): void { | ||
// Verify that iamRoleStatements (if present) is an array of { Effect: ..., | ||
// Action: ..., Resource: ... } objects. | ||
if(_.isEmpty(statements)) { | ||
return; | ||
} | ||
const awsPackagePluginName = "AwsPackage"; | ||
if(!this.awsPackagePlugin) { | ||
for (const plugin of this.serverless.pluginManager.plugins) { | ||
if(plugin.constructor && plugin.constructor.name === awsPackagePluginName) { | ||
this.awsPackagePlugin = plugin; | ||
break; | ||
} | ||
} | ||
} | ||
if(!this.awsPackagePlugin) { | ||
this.throwError(`ERROR: could not find ${awsPackagePluginName} plugin to verify statements.`); | ||
} | ||
this.awsPackagePlugin.validateStatements(statements); | ||
let violationsFound; | ||
if (!Array.isArray(statements)) { | ||
violationsFound = 'it is not an array'; | ||
} else { | ||
const descriptions = statements.map((statement, i) => { | ||
const missing = [ | ||
['Effect'], | ||
['Action', 'NotAction'], | ||
['Resource', 'NotResource'], | ||
].filter(props => props.every(prop => !statement[prop])); | ||
return missing.length === 0 | ||
? null | ||
: `statement ${i} is missing the following properties: ${missing | ||
.map(m => m.join(' / ')) | ||
.join(', ')}`; | ||
}); | ||
const flawed = descriptions.filter(curr => curr); | ||
if (flawed.length) { | ||
violationsFound = flawed.join('; '); | ||
} | ||
} | ||
if (violationsFound) { | ||
const errorMessage = [ | ||
'iamRoleStatements should be an array of objects,', | ||
' where each object has Effect, Action / NotAction, Resource / NotResource fields.', | ||
` Specifically, ${violationsFound}`, | ||
].join(''); | ||
this.throwError(errorMessage); | ||
} | ||
} | ||
@@ -70,8 +89,10 @@ | ||
if (part.Ref) { | ||
length += part.Ref.length; | ||
} | ||
else { | ||
if (part.Ref === 'AWS::Region') { | ||
length += this.serverless.service.provider.region.length; | ||
} else { | ||
length += part.Ref.length; | ||
} | ||
} else { | ||
length += part.length; | ||
} | ||
} | ||
@@ -78,0 +99,0 @@ length += (name_parts.length - 1); //take into account the dashes between parts |
@@ -5,5 +5,3 @@ // tslint:disable:no-var-requires | ||
const Serverless = require('serverless/lib/Serverless'); | ||
const sls_config = require('serverless/lib/utils/config'); | ||
const funcWithIamTemplate = require('../../src/test/funcs-with-iam.json'); | ||
const writeFileAtomic = require('write-file-atomic'); | ||
import _ from 'lodash'; | ||
@@ -32,13 +30,2 @@ import os from 'os'; | ||
} | ||
const rc = sls_config.CONFIG_FILE_PATH; | ||
writeFileAtomic.sync(rc, JSON.stringify({ | ||
userId: null, | ||
frameworkId: "test", | ||
trackingDisabled: true, | ||
enterpriseDisabled: true, | ||
meta: { | ||
created_at: 1567187050, | ||
updated_at: null, | ||
}, | ||
}, null, 2)); | ||
const packageFile = path.join(dir, funcWithIamTemplate.package.artifact); | ||
@@ -120,11 +107,49 @@ fs.writeFileSync(packageFile, "test123"); | ||
}); | ||
}); | ||
it('should throw error if no awsPackage plugin', () => { | ||
const indx = serverless.pluginManager.plugins.findIndex((p: any) => p.constructor.name === "AwsPackage"); | ||
assert.isAtLeast(indx, 0); | ||
serverless.pluginManager.plugins.splice(indx, 1); | ||
assert.throws(() => { | ||
plugin.validateStatements(statements); | ||
}); | ||
describe('#getRoleNameLength', () => { | ||
it('Should calculate the acurate role name length us-east-1', () => { | ||
serverless.service.provider.region = 'us-east-1'; | ||
let function_name = 'a'.repeat(10); | ||
let name_parts = [ | ||
serverless.service.service, // test-service , length of 12 | ||
serverless.service.provider.stage, // dev, length of 3 : 15 | ||
{ Ref: 'AWS::Region' }, // us-east-1, length 9 : 24 | ||
function_name, // 'a'.repeat(10), length 10 : 34 | ||
'lambdaRole' // lambdaRole, length 10 : 44 | ||
]; | ||
let role_name_length = plugin.getRoleNameLength(name_parts) | ||
let expected = 44 // 12 + 3 + 9 + 10 + 10 == 44 | ||
assert.equal(role_name_length, expected + name_parts.length - 1); | ||
}); | ||
it('Should calculate the acurate role name length ap-northeast-1', () => { | ||
serverless.service.provider.region = 'ap-northeast-1'; | ||
let function_name = 'a'.repeat(10); | ||
let name_parts = [ | ||
serverless.service.service, // test-service , length of 12 | ||
serverless.service.provider.stage, // dev, length of 3 | ||
{ Ref: 'AWS::Region' }, // ap-northeast-1, length 14 | ||
function_name, // 'a'.repeat(10), length 10 | ||
'lambdaRole' // lambdaRole, length 10 | ||
]; | ||
let role_name_length = plugin.getRoleNameLength(name_parts) | ||
let expected = 49 // 12 + 3 + 14 + 10 + 10 == 49 | ||
assert.equal(role_name_length, expected + name_parts.length - 1); | ||
}); | ||
it('Should calculate the actual length for a non AWS::Region ref to maintain backward compatability', () => { | ||
serverless.service.provider.region = 'ap-northeast-1'; | ||
let function_name = 'a'.repeat(10); | ||
let name_parts = [ | ||
serverless.service.service, // test-service , length of 12 | ||
{ Ref: 'bananas'}, // bananas, length of 7 | ||
{ Ref: 'AWS::Region' }, // ap-northeast-1, length 14 | ||
function_name, // 'a'.repeat(10), length 10 | ||
'lambdaRole' // lambdaRole, length 10 | ||
]; | ||
let role_name_length = plugin.getRoleNameLength(name_parts) | ||
let expected = 53 // 12 + 7 + 14 + 10 + 10 == 53 | ||
assert.equal(role_name_length, expected + name_parts.length - 1); | ||
}); | ||
}); | ||
@@ -223,3 +248,4 @@ | ||
const helloNoPerFunctionResource = serverless.service.provider.compiledCloudFormationTemplate.Resources.HelloNoPerFunctionLambdaFunction; | ||
assert.isTrue(helloNoPerFunctionResource.DependsOn.indexOf('IamRoleLambdaExecution') >= 0, 'function resource depends on global role'); | ||
//no DependsOn is added when using global role: https://github.com/serverless/serverless/blob/9303d8ecd46059121082c3308e5fe5385e0be38e/lib/plugins/aws/package/compile/functions/index.js#L42 | ||
assert.isFalse(helloNoPerFunctionResource.DependsOn.indexOf('IamRoleLambdaExecution') >= 0, 'function resource depends on global role'); | ||
assert.equal(helloNoPerFunctionResource.Properties.Role["Fn::GetAtt"][0], 'IamRoleLambdaExecution', "function resource role is set to global role"); | ||
@@ -269,3 +295,3 @@ //verify helloEmptyIamStatements | ||
assert.isTrue(msg.startsWith('serverless-iam-roles-per-function: ERROR:')); | ||
assert.isTrue(msg.endsWith('testing')); | ||
assert.isTrue(msg.includes('testing')); | ||
} | ||
@@ -272,0 +298,0 @@ }); |
Sorry, the diff of this file is not supported yet
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
75680
1133
2