UNPKG

sls-dev-tools

Version:

The Dev Tools for the Serverless World

196 lines (146 loc) 6.24 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _chalk = _interopRequireDefault(require("chalk")); var _awsSdk = _interopRequireDefault(require("aws-sdk")); var _noDefaultMemory = _interopRequireDefault(require("./rules/best_practices/no-default-memory")); var _noDefaultTimeout = _interopRequireDefault(require("./rules/best_practices/no-default-timeout")); var _noMaxTimeout = _interopRequireDefault(require("./rules/best_practices/no-max-timeout")); var _noMaxMemory = _interopRequireDefault(require("./rules/best_practices/no-max-memory")); var _noIdenticalCode = _interopRequireDefault(require("./rules/best_practices/no-identical-code")); var _noSharedRoles = _interopRequireDefault(require("./rules/best_practices/no-shared-roles")); var _services = require("../services"); var _serverlessConfigParser = _interopRequireDefault(require("../services/severlessConfigParser/serverlessConfigParser")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const infoLog = _chalk.default.greenBright; const titleLog = _chalk.default.greenBright.underline.bold; const fail = _chalk.default.redBright; const failTitleLog = _chalk.default.redBright.underline.bold; class GuardianCI { constructor(program) { _awsSdk.default.config.credentials = (0, _services.getAWSCredentials)(program.profile, program); if (program.region) { _awsSdk.default.config.region = program.region; } this.exitCode = 0; if (!_awsSdk.default) { console.error("Invalid AWS SDK"); this.exitCode = 1; } if (!program.stackName) { console.error("Invalid Cloudformation Stack Name"); this.exitCode = 1; } this.AWS = _awsSdk.default; this.stackName = program.stackName; this.checksToRun = [_noDefaultMemory.default, _noDefaultTimeout.default, _noMaxTimeout.default, _noMaxMemory.default, _noIdenticalCode.default, _noSharedRoles.default]; this.failingChecks = []; this.resourceIDs = []; this.allFunctions = []; this.stackFunctions = []; if (program.slsDevToolsConfig) { this.config = program.slsDevToolsConfig.guardian; } if (this.config) { this.ignoreConfig = this.config.ignore; } this.SLS = new _serverlessConfigParser.default(program); } async getAllLambdaFunctions() { const lambda = new this.AWS.Lambda(); const allFunctions = (0, _services.getLambdaFunctions)(lambda); return allFunctions; } async getStackFunctionResouceIDs() { const cloudformation = new this.AWS.CloudFormation(); const stackResources = await (0, _services.getStackResources)(this.stackName, cloudformation); const lambdaFunctionResources = stackResources.StackResourceSummaries.filter(res => res.ResourceType === "AWS::Lambda::Function"); return lambdaFunctionResources.map(lambda => lambda.PhysicalResourceId); } async initResources() { this.resourceIDs = await this.getStackFunctionResouceIDs(); this.allFunctions = await this.getAllLambdaFunctions(); this.stackFunctions = this.allFunctions.filter(lambda => this.resourceIDs.includes(lambda.FunctionName)); } ignoreCheck(check) { if (this.ignoreConfig) { if (this.ignoreConfig[check.name] === true) { return true; } if (Date.parse(this.ignoreConfig[check.name]) > Date.now()) { return true; } } return false; } ignoreArns(check, stackFunctions) { if (this.ignoreConfig) { const arns = this.ignoreConfig[check.name]; if (arns instanceof Array) { return stackFunctions.filter(func => !arns.includes(func.FunctionArn)); } } return stackFunctions; } async runChecks() { console.log(_chalk.default.greenBright(` ‗‗‗‗‗‗‗‗‗‗‗‗‗‗‗†‗‗‗‗‗‗‗‗‗‗‗‗‗‗ ╿ ▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▔▔▔▔▔▔▔▓▔▔▔▔▔▔▔▓ ▓▁▁▁▁▁▁▁▓▁▁▁▁▁▁▁▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ╿ ╿ ▔ ▔ sls-dev-tools GUARDIAN `)); if (this.exitCode !== 0) { return; } console.group(titleLog(" > Running checks")); console.log("Analysing Resources..."); await this.initResources(); // 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, this.SLS); if (!this.ignoreCheck(check)) { const filteredStack = this.ignoreArns(check, this.stackFunctions); check.stackFunctions = filteredStack; const padCheckName = checkName => " ".repeat(20 - checkName.length); process.stdout.write(infoLog(` > ${check.name}...${padCheckName(check.name)}`)); // eslint-disable-next-line no-await-in-loop const checkResult = await check.run(); console.log(checkResult ? "✅" : "❌"); if (!checkResult) { this.failingChecks = [...this.failingChecks, check]; } console.groupEnd(); } } console.groupEnd(); if (this.failingChecks.length > 0) { console.group(_chalk.default.blueBright.underline(failTitleLog(" > Failing Checks"))); } let overallResult = true; this.failingChecks.forEach(failingCheck => { console.group(fail(`> ${failingCheck.name}`)); console.log(failingCheck.failureMessage); console.log(failingCheck.rulePage); console.table(failingCheck.failingResources); overallResult = false; console.groupEnd(); }); console.groupEnd(); if (!overallResult) { this.exitCode = 1; } // eslint-disable-next-line consistent-return return this.exitCode; } } var _default = GuardianCI; exports.default = _default;