From 80f1c7b809044a2c297058b9c1fbd902bc32991f Mon Sep 17 00:00:00 2001 From: nmccready Date: Sun, 26 May 2024 21:41:21 -0400 Subject: [PATCH] fix: moved cft-utils out to @znemz/cft-utils to seperate concerns --- .eslintrc.js | 2 +- index.js | 4 +- package.json | 7 +- t/tests/applyTags.yml | 4 +- workspaces/utils/README.md | 39 ----- workspaces/utils/bin/taggableResourceMap.js | 7 - workspaces/utils/bin/taggableResources.js | 7 - workspaces/utils/debug.js | 3 - workspaces/utils/package.json | 48 ------- workspaces/utils/src/index.js | 5 - workspaces/utils/src/resources/index.js | 3 - workspaces/utils/src/resources/taggable.js | 134 ------------------ .../utils/src/resources/taggable.test.js | 18 --- 13 files changed, 7 insertions(+), 274 deletions(-) delete mode 100644 workspaces/utils/README.md delete mode 100755 workspaces/utils/bin/taggableResourceMap.js delete mode 100755 workspaces/utils/bin/taggableResources.js delete mode 100644 workspaces/utils/debug.js delete mode 100644 workspaces/utils/package.json delete mode 100644 workspaces/utils/src/index.js delete mode 100644 workspaces/utils/src/resources/index.js delete mode 100755 workspaces/utils/src/resources/taggable.js delete mode 100755 workspaces/utils/src/resources/taggable.test.js diff --git a/.eslintrc.js b/.eslintrc.js index 17ccd2e..5972865 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -26,7 +26,7 @@ module.exports = { }, overrides: [ { - files: ['t/**/*.js', 'workspaces/**/*.test.js'], + files: ['t/**/*.js'], plugins: ['mocha'], env: { mocha: true, diff --git a/index.js b/index.js index 5e7f109..233e324 100644 --- a/index.js +++ b/index.js @@ -10,12 +10,12 @@ const { addProxyToClient } = require('aws-sdk-v3-proxy'); const pathParse = require('path-parse'); const deepMerge = require('deepmerge'); -const { isTaggableResource } = require('@cfn-include/utils/src/resources/taggable'); +const { isTaggableResource } = require('@znemz/cft-utils/src/resources/taggable'); const request = require('./lib/request'); const PromiseExt = require('./lib/promise'); -const S3 = (opts = {}) => addProxyToClient(new S3Client(opts)); +const S3 = (opts = {}) => addProxyToClient(new S3Client(opts), { throwOnNoProxy: false }); const s3 = S3(); const yaml = require('./lib/yaml'); diff --git a/package.json b/package.json index 89d5a61..c051099 100644 --- a/package.json +++ b/package.json @@ -30,23 +30,20 @@ "bin/", "lib/" ], - "workspaces": [ - "workspaces/*" - ], "scripts": { "better-audit": "better-npm-audit audit", "lint": "eslint .", "lint:fix": "eslint . --fix", "prepare": "sort-package-json", "serve": "serve ./t/fixtures -l 9999", - "test": "npm run test:this && npm run test --workspaces", + "test": "npm run test:this", "test:this": "run-p -r serve test:run", "test:run": "sleep 1 && mocha --timeout 20000 --bail t/include.js t/cli.js t/replaceEnv.js" }, "dependencies": { "@aws-sdk/client-cloudformation": "^3", "@aws-sdk/client-s3": "^3", - "@cfn-include/utils": "0.0.4", + "@znemz/cft-utils": "0.1.0", "@znemz/sort-object": "^3.0.4", "aws-sdk-v3-proxy": "2.1.2", "bluebird": "^3.7.2", diff --git a/t/tests/applyTags.yml b/t/tests/applyTags.yml index 188b9e3..f35f6e4 100644 --- a/t/tests/applyTags.yml +++ b/t/tests/applyTags.yml @@ -38,7 +38,7 @@ applyTags: Url: https://example.com ClientIdList: - !Ref RoleOne - # NOTE: This test could fail in future updates to @cfn-include/utils and aws-cdk-lib + # NOTE: This test could fail in future updates to @znemz/cft-utils and aws-cdk-lib # Where resources become taggable upon aws-cdk-lib updates. If it becomes taggable and it wasn't # thats a good thing. output: @@ -127,7 +127,7 @@ applyTags: Url: https://example.com ClientIdList: - !Ref RoleOne - # NOTE: This test could fail in future updates to @cfn-include/utils and aws-cdk-lib + # NOTE: This test could fail in future updates to @znemz/cft-utils and aws-cdk-lib # Where resources become taggable upon aws-cdk-lib updates. If it becomes taggable and it wasn't # thats a good thing. output: diff --git a/workspaces/utils/README.md b/workspaces/utils/README.md deleted file mode 100644 index ff91017..0000000 --- a/workspaces/utils/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# cft-utils - -This projects goal is to provide information and capabilities of what AWS Cloudformation -actually provides. There are many missing gaps and this library intends to fill them. The -original goal of this library is to identify all AWS Resources which are actually Taggable via -a Cloudformation Template. - -Note: the first time the library is run it processes the aws-cd-lib for taggable resources. This -is then cached inside of `./src/cache/*.json` . - -## install - -`npm i --save @cfn-include/utils` - -## SDK - -```js -const lib = require('@cfn-include/utils'); -(async () => - console.log(await lib.resources.taggable.getResources()) - console.log(await lib.resources.taggable.getResourceMap()) - - await lib.resources.taggable.isTaggableResource('AWS::IAM::Role') // true -)(); -``` - -## CLI Tools - -```bash -$ ./bin/taggableResourceMap.js -{"AWS::AccessAnalyzer::Analyzer":true,"AWS::ACMPCA::CertificateAuthority":true,"AWS::AmazonMQ::Broker":true,"AWS::AmazonMQ::Configuration":true,"AWS::Amplify::App":true,"AWS::Amplify::Branch":true,"AWS::AmplifyUIBuilder::Component":true,"AWS::AmplifyUIBuilder::Form":true,"AWS::AmplifyUIBuilder::Theme":true,"AWS::ApiGatewayV2::Api":true,"AWS::ApiGatewayV2::DomainName":true,"AWS::ApiGatewayV2::Stage":true,"AWS::ApiGatewayV2::VpcLink":true,"AWS::AppConfig::Extension":true, -... more items -``` - -```bash -$ ./bin/taggableResources.js -["AWS::AccessAnalyzer::Analyzer","AWS::ACMPCA::CertificateAuthority","AWS::AmazonMQ::Broker","AWS::AmazonMQ::Configuration","AWS::Amplify::App","AWS::Amplify::Branch","AWS::AmplifyUIBuilder::Component","AWS::AmplifyUIBuilder::Form","AWS::AmplifyUIBuilder::Theme", -... more items -``` diff --git a/workspaces/utils/bin/taggableResourceMap.js b/workspaces/utils/bin/taggableResourceMap.js deleted file mode 100755 index 62c9718..0000000 --- a/workspaces/utils/bin/taggableResourceMap.js +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env node -const taggable = require('../src/resources/taggable'); - -(async () => { - const _map = await taggable.getResourceMap(); - process.stdout.write(`${JSON.stringify(_map)}\n`); -})(); diff --git a/workspaces/utils/bin/taggableResources.js b/workspaces/utils/bin/taggableResources.js deleted file mode 100755 index 7649889..0000000 --- a/workspaces/utils/bin/taggableResources.js +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env node -const taggable = require('../src/resources/taggable'); - -(async () => { - const resouces = await taggable.getResources(); - process.stdout.write(`${JSON.stringify(resouces)}\n`); -})(); diff --git a/workspaces/utils/debug.js b/workspaces/utils/debug.js deleted file mode 100644 index c0bbbb8..0000000 --- a/workspaces/utils/debug.js +++ /dev/null @@ -1,3 +0,0 @@ -const { name } = require('./package.json'); - -module.exports = require('debug-fabulous').spawnable(name); diff --git a/workspaces/utils/package.json b/workspaces/utils/package.json deleted file mode 100644 index 5e1d861..0000000 --- a/workspaces/utils/package.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "name": "@cfn-include/utils", - "version": "0.0.4", - "description": "AWS CFT Utilities to fill the gaps for Cloud Formation", - "keywords": [ - "cft", - "aws", - "cloudformation" - ], - "homepage": "https://github.com/monken/cfn-include/workspaces/utils#readme", - "bugs": { - "url": "https://github.com/monken/cfn-include/issues" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/monken/cfn-include.git" - }, - "author": "Nicholas McCready", - "main": "src/index.js", - "bin": { - "taggableResourceMap.js": "./bin/taggableResourceMap.js", - "taggableResources.js": "./bin/taggableResources.js" - }, - "files": [ - "src/**/*.js", - "src/**/*.json", - "*.js", - "!commitlint.config.js", - "!jest*.js", - "!.*.js" - ], - "scripts": { - "lint:js": "eslint .", - "prepack": "./bin/taggableResourceMap.js && ./bin/taggableResources.js", - "prepare": "skip-npm-task -t prepare sort-package-json", - "test": "mocha --timeout 20000 --bail ./src/**/*.test.js", - "unused:dependencies": "depcheck --ignore-bin-package --ignores @znemz/skip-npm-task,sort-package-json" - }, - "dependencies": { - "@znemz/skip-npm-task": "0.1.0", - "aws-cdk-lib": "2", - "debug-fabulous": "2.0.2", - "globby": "11.1.0" - }, - "devDependencies": { - "depcheck": "1.4.6" - } -} diff --git a/workspaces/utils/src/index.js b/workspaces/utils/src/index.js deleted file mode 100644 index 4971cc0..0000000 --- a/workspaces/utils/src/index.js +++ /dev/null @@ -1,5 +0,0 @@ -const resources = require('./resources'); - -module.exports = { - resources, -}; diff --git a/workspaces/utils/src/resources/index.js b/workspaces/utils/src/resources/index.js deleted file mode 100644 index acc83ae..0000000 --- a/workspaces/utils/src/resources/index.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - taggable: require('./taggable'), -}; diff --git a/workspaces/utils/src/resources/taggable.js b/workspaces/utils/src/resources/taggable.js deleted file mode 100755 index 43c134c..0000000 --- a/workspaces/utils/src/resources/taggable.js +++ /dev/null @@ -1,134 +0,0 @@ -const path = require('path'); -const fs = require('fs/promises'); -const globby = require('globby'); - -const cdkDir = path.dirname(require.resolve('aws-cdk-lib')); -const cachePath = path.join(__dirname, '..', 'cache'); - -/* - * @returns {Promise} - * - * Returns list of taggable resources from a cache file - * or from reading the aws-cdk-lib ITaggable Resources - */ -const getResources = async (skipCachePull = false) => { - // use cached list if it exists in ${cachePath}/taggable.json - const cacheFile = path.join(cachePath, 'cft_taggable_resources.json'); - let taggableResources; - if (!skipCachePull) { - taggableResources = await getCachedFile(cacheFile); - if (taggableResources) { - return taggableResources; - } - } - // cache miss, generate list of taggable resources - taggableResources = await getResourcesFromAwsCdk(); - await mkCacheDir(); - await fs.writeFile(cacheFile, JSON.stringify(taggableResources, null, 2)); - return taggableResources; -}; - -/* - * @returns {Promise} - * - * Matches comments of an aws-* inside aws-cdk-lib - * resource file "*generated.d.ts" definition - * looking for @cloudformationResource and ITaggable - */ -const getResourcesFromAwsCdk = async () => { - const globPaths = [ - path.join(cdkDir, 'aws-*', 'lib', '*generated.d.ts'), - `!${path.join(cdkDir, 'aws-*', 'lib', 'index.d.ts')}`, - ]; - const paths = await globby(globPaths); - const nestedResourceNames = await Promise.all( - paths.map((file) => fileToTaggableResourceNames(file)) - ); - return nestedResourceNames.flat(); -}; - -const getResourceMap = async (skipCachePull = false) => { - const cacheFile = path.join(cachePath, 'cft_taggable_resource_map.json'); - let resTagMap; - if (!skipCachePull) { - resTagMap = await getCachedFile(cacheFile); - if (resTagMap) { - return resTagMap; - } - } - resTagMap = {}; - const resources = await getResources(skipCachePull); - // use cached map - if (Object.keys(resTagMap).length > 0) { - return resTagMap; - } - - for (const resName of resources) { - resTagMap[resName] = true; - } - // cache it - await mkCacheDir(); - await fs.writeFile(cacheFile, JSON.stringify(resTagMap, null, 2)); - return resTagMap; -}; - -const isTaggableResource = async (resourceName) => { - const resMp = await getResourceMap(); - return Boolean(resMp[resourceName]); -}; - -/* - * @param {string} file - * @returns {Promise} - * - * Matches comments of an aws-* resource file d.ts file definition - * looking for @cloudformationResource and ITaggable - */ -async function fileToTaggableResourceNames(file) { - const taggableResources = []; - const data = (await fs.readFile(file)).toString(); - // console.log(file); - const matches = [...data.matchAll(/.*@cloudformationResource\s(.*)(\s.*){4}(ITaggable)/gm)]; - if (matches?.length >= 0) { - for (const match of matches) { - taggableResources.push(match[1]); - } - } - return taggableResources; -} - -/* - * @param {string} cacheFile - * @returns {Promise} - * - */ -async function getCachedFile(cacheFile) { - try { - const data = await fs.readFile(cacheFile); - const cached = JSON.parse(data.toString()); - if (cached && cached.length > 0) { - return cached; - } - } catch (e) { - // do nothing - } -} - -async function mkCacheDir() { - try { - await fs.access(cachePath); - } catch (e) { - try { - await fs.mkdir(cachePath, { recursive: true }); - } catch (e2) { - // --force - } - } -} - -module.exports = { - getResources, - getResourceMap, - getResourcesFromAwsCdk, - isTaggableResource, -}; diff --git a/workspaces/utils/src/resources/taggable.test.js b/workspaces/utils/src/resources/taggable.test.js deleted file mode 100755 index 1ba5f01..0000000 --- a/workspaces/utils/src/resources/taggable.test.js +++ /dev/null @@ -1,18 +0,0 @@ -const taggable = require('./taggable'); -const assert = require('assert'); - -describe(taggable.isTaggableResource.name, () => { - ['AWS::IAM::Role'].forEach((resourceName) => { - it(`${resourceName} is taggable`, async () => { - const isTag = await taggable.isTaggableResource(resourceName); - assert.ok(isTag); - }); - }); - - ['AWS::IAM::Policy', 'AWS::IAM::ManagedPolicy'].forEach((resourceName) => { - it(`${resourceName} is NOT taggable`, async () => { - const isTag = await taggable.isTaggableResource(resourceName); - assert.ok(!isTag); - }); - }); -});