From acb44127ee4be327db8ec1371ca09ef2fcd62b8d Mon Sep 17 00:00:00 2001 From: mansurpasha Date: Mon, 18 May 2020 17:59:38 +0100 Subject: [PATCH 1/2] Check serverless.yml to correct no-default false positives --- src/components/resourceTable.js | 7 ++++--- src/guardian/index.js | 10 +++++++++- .../best_practices/no-default-memory/index.js | 14 ++++++++++++-- .../best_practices/no-default-timeout/index.js | 18 +++++++++++++----- src/services/serverless.js | 4 ++++ src/utils/abbreviateFunction.js | 7 +++++++ 6 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 src/utils/abbreviateFunction.js diff --git a/src/components/resourceTable.js b/src/components/resourceTable.js index 24d7a60e..2c7a5ffa 100644 --- a/src/components/resourceTable.js +++ b/src/components/resourceTable.js @@ -7,6 +7,7 @@ import { getStackResources } from "../services/stackResources"; import { padString } from "../utils/padString"; import { lambdaStatisticsModal, lambdaInvokeModal } from "../modals"; import { getLambdaFunctions } from "../services"; +import { abbreviateFunction } from "../utils/abbreviateFunction"; const contrib = require("blessed-contrib"); const open = require("open"); @@ -256,9 +257,9 @@ class ResourceTable { this.table.data = lambdaFunctionResources.map((lam) => { const funcName = lam.PhysicalResourceId; const func = this.lambdaFunctions[funcName]; - const shortenedFuncName = lam.PhysicalResourceId.replace( - `${this.program.stackName}-`, - "" + const shortenedFuncName = abbreviateFunction( + lam.PhysicalResourceId, + this.program.stackName ); this.fullFunctionNames[shortenedFuncName] = funcName; let timeout = "?"; diff --git a/src/guardian/index.js b/src/guardian/index.js index f2a4ccfb..7a750f6b 100644 --- a/src/guardian/index.js +++ b/src/guardian/index.js @@ -12,6 +12,7 @@ import { getStackResources, getLambdaFunctions, } from "../services"; +import Serverless from "../services/serverless"; const infoLog = chalk.greenBright; const titleLog = chalk.greenBright.underline.bold; @@ -55,6 +56,8 @@ class GuardianCI { if (this.config) { this.ignoreConfig = this.config.ignore; } + + this.SLS = new Serverless(program.location); } async getAllLambdaFunctions() { @@ -139,7 +142,12 @@ class GuardianCI { // eslint-disable-next-line no-restricted-syntax for (const Check of this.checksToRun) { console.group(); - const check = new Check(this.AWS, this.stackName, this.stackFunctions); + const check = new Check( + this.AWS, + this.stackName, + this.stackFunctions, + this.SLS + ); if (!this.ignoreCheck(check)) { const filteredStack = this.ignoreArns(check, this.stackFunctions); check.stackFunctions = filteredStack; diff --git a/src/guardian/rules/best_practices/no-default-memory/index.js b/src/guardian/rules/best_practices/no-default-memory/index.js index f78cae64..12cf6181 100644 --- a/src/guardian/rules/best_practices/no-default-memory/index.js +++ b/src/guardian/rules/best_practices/no-default-memory/index.js @@ -1,5 +1,7 @@ +import { abbreviateFunction } from "../../../../utils/abbreviateFunction"; + class NoDefaultMemory { - constructor(AWS, stackName, stackFunctions) { + constructor(AWS, stackName, stackFunctions, SLS) { this.name = "no-default-memory"; this.AWS = AWS; this.stackName = stackName; @@ -7,6 +9,7 @@ class NoDefaultMemory { this.result = false; this.defaultMemory = 1024; this.failingResources = []; + this.SLS = SLS; this.failureMessage = "The following functions have their memory set as default."; this.rulePage = @@ -14,7 +17,14 @@ class NoDefaultMemory { } hasDefaultMemory(lambdaFunction) { - return lambdaFunction.MemorySize === this.defaultMemory; + const shortenedName = abbreviateFunction( + lambdaFunction.FunctionName, + this.stackName + ); + return ( + lambdaFunction.MemorySize === this.defaultMemory && + !this.SLS.getFunctionConfig(shortenedName).memorySize + ); } async run() { diff --git a/src/guardian/rules/best_practices/no-default-timeout/index.js b/src/guardian/rules/best_practices/no-default-timeout/index.js index ba2644ea..e33d7a3b 100644 --- a/src/guardian/rules/best_practices/no-default-timeout/index.js +++ b/src/guardian/rules/best_practices/no-default-timeout/index.js @@ -1,5 +1,7 @@ +import { abbreviateFunction } from "../../../../utils/abbreviateFunction"; + class NoDefaultTimeout { - constructor(AWS, stackName, stackFunctions) { + constructor(AWS, stackName, stackFunctions, SLS) { this.name = "no-default-timeout"; this.AWS = AWS; this.stackName = stackName; @@ -8,6 +10,7 @@ class NoDefaultTimeout { this.defaultTimeoutAWS = 3; this.defaultTimeoutServerlessFramework = 6; this.failingResources = []; + this.SLS = SLS; this.failureMessage = "The following functions have their timeout set as default."; this.rulePage = @@ -15,10 +18,15 @@ class NoDefaultTimeout { } hasDefaultTimeout(lambdaFunction) { - return [ - this.defaultTimeoutAWS, - this.defaultTimeoutServerlessFramework, - ].includes(lambdaFunction.Timeout); + const shortenedName = abbreviateFunction( + lambdaFunction.FunctionName, + this.stackName + ); + return ( + [this.defaultTimeoutAWS, this.defaultTimeoutServerlessFramework].includes( + lambdaFunction.Timeout + ) && !this.SLS.getFunctionConfig(shortenedName).timeout + ); } async run() { diff --git a/src/services/serverless.js b/src/services/serverless.js index 4c1558b4..483365f5 100644 --- a/src/services/serverless.js +++ b/src/services/serverless.js @@ -20,6 +20,10 @@ class Serverless { } } + getFunctionConfig(functionName) { + return this.config.functions[functionName]; + } + getStage() { if (typeof this.config !== "object") { return "dev"; diff --git a/src/utils/abbreviateFunction.js b/src/utils/abbreviateFunction.js new file mode 100644 index 00000000..3a7fb4eb --- /dev/null +++ b/src/utils/abbreviateFunction.js @@ -0,0 +1,7 @@ +function abbreviateFunction(fullFuncName, stackName) { + return fullFuncName.replace(`${stackName}-`, ""); +} + +module.exports = { + abbreviateFunction, +}; From ef41ad59d6e4263ba42ed64a0d70ae23b869f783 Mon Sep 17 00:00:00 2001 From: mansurpasha Date: Tue, 19 May 2020 10:37:57 +0100 Subject: [PATCH 2/2] Make false positive check work with bad yml files --- .../best_practices/no-default-memory/index.js | 2 +- .../no-default-timeout/index.js | 2 +- src/services/serverless.js | 21 ++++++++++++++++++- 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/src/guardian/rules/best_practices/no-default-memory/index.js b/src/guardian/rules/best_practices/no-default-memory/index.js index 12cf6181..25055a1a 100644 --- a/src/guardian/rules/best_practices/no-default-memory/index.js +++ b/src/guardian/rules/best_practices/no-default-memory/index.js @@ -23,7 +23,7 @@ class NoDefaultMemory { ); return ( lambdaFunction.MemorySize === this.defaultMemory && - !this.SLS.getFunctionConfig(shortenedName).memorySize + !this.SLS.getMemorySize(shortenedName) ); } diff --git a/src/guardian/rules/best_practices/no-default-timeout/index.js b/src/guardian/rules/best_practices/no-default-timeout/index.js index e33d7a3b..f30e59e1 100644 --- a/src/guardian/rules/best_practices/no-default-timeout/index.js +++ b/src/guardian/rules/best_practices/no-default-timeout/index.js @@ -25,7 +25,7 @@ class NoDefaultTimeout { return ( [this.defaultTimeoutAWS, this.defaultTimeoutServerlessFramework].includes( lambdaFunction.Timeout - ) && !this.SLS.getFunctionConfig(shortenedName).timeout + ) && !this.SLS.getTimeout(shortenedName) ); } diff --git a/src/services/serverless.js b/src/services/serverless.js index 483365f5..7a325e31 100644 --- a/src/services/serverless.js +++ b/src/services/serverless.js @@ -21,7 +21,26 @@ class Serverless { } getFunctionConfig(functionName) { - return this.config.functions[functionName]; + if (this.config && this.config.functions) { + return this.config.functions[functionName]; + } + return undefined; + } + + getTimeout(functionName) { + const config = this.getFunctionConfig(functionName); + if (config && config.timeout) { + return config.timeout; + } + return undefined; + } + + getMemorySize(functionName) { + const config = this.getFunctionConfig(functionName); + if (config && config.memorySize) { + return config.memorySize; + } + return undefined; } getStage() {