diff --git a/CHANGELOG.md b/CHANGELOG.md index a5dc6f90..48256215 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,10 +7,14 @@ - A custom resource to retrieve the latest version of the ManagedRuleGroup and to check that the specified version is valid. - Typescript configuration files for WAF configurations - A Function to convert CdkRule to SdkRule - with the introduction of Typescript configuration and CDK interfaces, we now need to convert every CDK rule to an SDK rule to be able to use the [CheckCapacity API Call](https://docs.aws.amazon.com/waf/latest/APIReference/API_CheckCapacity.html). +- ManagedRuleGroupVersions to CloudFormation Output - Example Configurations 1. Example WAF Configuration againts: [OWASP Top Ten](https://owasp.org/www-project-top-ten/) 2. Example Configuration for Prerequisite Stack - Added TOOL_KIT_STACKNAME to TaskFile - To Specify The name of the bootstrap stack ([see Bootstrapping your AWS environment](https://docs.aws.amazon.com/cdk/v2/guide/cli.html#cli-bootstrap)). +- Migrate Script to migrate from json to ts Config (./values/migrate.ts) + - ts-node ./values/migrate.ts YOURJSON.json + ### Fixed - Allow sub-statements of IPSetReferenceStatements -> Allow IPSetReferenceStatement.ARN entries that reference an aws-firewall-factory controlled ipset (i.e. the name of the ipset) within AND, OR and NOT statements (as sub-statements). - Adjusted Function to generate Skeleton for WAF Config for Typescript configuration diff --git a/values/migrate.ts b/values/migrate.ts new file mode 100644 index 00000000..1b8745c8 --- /dev/null +++ b/values/migrate.ts @@ -0,0 +1,169 @@ +/* eslint-disable @typescript-eslint/no-unsafe-argument */ +/* eslint-disable @typescript-eslint/no-unsafe-call */ +/* eslint-disable @typescript-eslint/no-unsafe-member-access */ +/* eslint-disable @typescript-eslint/no-floating-promises */ +/* eslint-disable @typescript-eslint/restrict-plus-operands */ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/no-unsafe-return */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import util from "util"; +import fs from "fs"; +import path from "path"; +import { Config } from "../lib/types/config"; + +interface OldConfig { + General: any, + WebAcl: { + Name: string, + Scope: string, + Type: string, + IncludeMap: { + account: string[], + }, + PreProcess: { + ManagedRuleGroups: any[], + CustomRules: any[], + }, + PostProcess: { + ManagedRuleGroups: any[], + CustomRules: any[] + } + } +} + +async function findFile(inputFileName: string, currentPath = "."): Promise { + const files = await fs.promises.readdir(currentPath); + for (const file of files) { + const filePath = path.join(currentPath, file); + const stats = await fs.promises.stat(filePath); + + if (stats.isDirectory()) { + const foundPath = await findFile(inputFileName, filePath); + if (foundPath !== null) { + return foundPath; + } + } else if (file === inputFileName) { + return filePath; + } + } + return null; +} + +/** + * Function to transform property names into camel case like AWS needs it + * @param o object which property names has to be transformed to camel case + * @returns the object with the transformed property names in camel case + */ +// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types +function toAwsCamel(o: any): any { + let newO: any, origKey: any, newKey: any, value: any; + if (o instanceof Array) { + return o.map(function(value) { + if (typeof value === "object") { + value = toAwsCamel(value); + } + if(value === "aRN"){ + value = "arn"; + } + if(value === "iPSetReferenceStatement"){ + value = "ipSetReferenceStatement"; + } + return value; + }); + } else { + newO = {}; + for (origKey in o) { + if (Object.prototype.hasOwnProperty.call(o, origKey)) { + newKey = (origKey.charAt(0).toLowerCase() + origKey.slice(1) || origKey).toString(); + if(newKey === "aRN"){ + newKey = "arn"; + } + if(newKey === "iPSetReferenceStatement"){ + newKey = "ipSetReferenceStatement"; + } + value = o[origKey]; + if (value instanceof Array || (value !== null && value.constructor === Object)) { + value = toAwsCamel(value); + if(value === "aRN"){ + value = "arn"; + } + } + newO[newKey] = value; + } + } + } + return newO; +} + + +findFile(process.argv[2], ".").then((filePath) => { + if (filePath) { + const filePathWithoutExtension = filePath.substring(0, filePath.lastIndexOf(".")); + const requirePath = "./" + filePathWithoutExtension.substring(filePathWithoutExtension.indexOf("/")); + // eslint-disable-next-line @typescript-eslint/no-var-requires + const valuesFile = require(requirePath); + console.log(`🚀 Migrate Config: ${filePathWithoutExtension} to AWS Firewall Factory 4.0 schema...`); + const oldConfig: OldConfig = valuesFile ; + + const newConfig = { + General: oldConfig.General, + WebAcl: { + Name: oldConfig.WebAcl.Name, + Scope: oldConfig.WebAcl.Scope, + Type: oldConfig.WebAcl.Type, + IncludeMap: oldConfig.WebAcl.IncludeMap, + PreProcess: { + ManagedRuleGroups: oldConfig.WebAcl.PreProcess.ManagedRuleGroups ? toAwsCamel(oldConfig.WebAcl.PreProcess.ManagedRuleGroups) : undefined, + CustomRules: oldConfig.WebAcl.PreProcess.CustomRules ? toAwsCamel(oldConfig.WebAcl.PreProcess.CustomRules) : undefined + }, + PostProcess: { + ManagedRuleGroups: oldConfig.WebAcl.PostProcess.ManagedRuleGroups ? toAwsCamel(oldConfig.WebAcl.PostProcess.ManagedRuleGroups) : undefined, + CustomRules: oldConfig.WebAcl.PostProcess.CustomRules ? toAwsCamel(oldConfig.WebAcl.PostProcess.CustomRules) : undefined + } + } + } as Config; + + let priority = 100; + + if (newConfig.WebAcl.PreProcess.CustomRules) { + for (let i=0; i