sls-dev-tools
Version:
The Dev Tools for the Serverless World
196 lines (146 loc) • 6.24 kB
JavaScript
"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;