91 | ```
92 |
93 | _Note:_ for PROFILE_NAME, substitute the name of an AWS CLI profile that contains appropriate credentials for deploying in your preferred region.
94 |
95 | ## Sample Scenario (Enabling CloudWatch logging on Elasticsearch domain)
96 |
97 | The default deployment uses opinionated values as setup in [solution manifest file](./source/resources/lib/manifest.json). In this scenario let's say we want to enable CloudWatch logging for ES domain.
98 |
99 | You would need to update the **ESDomain** resource in cl-primary-stack.ts as below:
100 |
101 | ```
102 | logging: {
103 | slowSearchLogEnabled: true,
104 | appLogEnabled: true,
105 | slowIndexLogEnabled: true,
106 | },
107 | ```
108 |
109 | ## File structure
110 |
111 | Centralized Logging on AWS solution consists of:
112 |
113 | - cdk constructs to generate needed resources
114 | - helper for bootstrapping purposes like creating CloudWatch Logs Destinations
115 | - transformer to translate kinesis data stream records into Elasticsearch documents
116 |
117 |
118 | |-config_files [ config files for prettier, eslint etc. ]
119 | |-architecture.png [ solution architecture diagram ]
120 | |-source/
121 | |dashboard.ndjson [ sample dashboard for demo ]
122 | |run-unit-test.sh [ script to run unit tests ]
123 | |-resources
124 | |-bin/
125 | |-app.ts [ entry point for CDK app ]
126 | |-__tests__/ [ unit tests for CDK constructs ]
127 | |-lib/
128 | |-cl-demo-ec2-construct.ts [ CDK construct for demo web server resource ]
129 | |-cl-demo-stack.ts [ CDK construct for demo stack]
130 | |-cl-jumpbox-construct.ts [ CDK construct for windows jumpbox resource ]
131 | |-cl-primary-stack.ts [ CDK construct for primary stack and related resources ]
132 | |-utils.ts [ utilities for generic functionalities across CDK constructs ]
133 | |-manifest.json [ manifest file for CDK resources ]
134 | |-config_files [ tsconfig, jest.config.js, package.json etc. ]
135 | |-services/
136 | |-@aws-solutions/utils/ [ library with generic utility functions for microservice ]
137 | |-helper/ [ lambda backed helper custom resource to help with solution launch/update/delete ]
138 | |-transformer/ [ microservice to translate kinesis records into es documents ]
139 |
140 |
141 | ## License
142 |
143 | See license [here](./LICENSE.txt)
144 |
145 |
146 | ---
147 |
148 | Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
149 |
150 | Licensed under the Apache License Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at
151 |
152 | ```
153 | http://www.apache.org/licenses/LICENSE-2.0
154 | ```
155 |
156 | or in the ["license"](./LICENSE.txt) file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions and limitations under the License.
157 |
--------------------------------------------------------------------------------
/architecture.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-solutions/aws-centralized-logging/e4e4ea88fb64141ffe59e2d2c75775b6513ae4af/architecture.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "aws-centralized-logging",
3 | "version": "4.0.6",
4 | "description": "Centralized Logging on AWS",
5 | "scripts": {
6 | "lint": "./node_modules/eslint/bin/eslint.js . --ext .ts",
7 | "prettier-format": "./node_modules/prettier/bin-prettier.js --config .prettierrc.yml '**/*.ts' --write",
8 | "build:helper": "cd source/services/helper && npm run build:all",
9 | "build:transformer": "cd source/services/transformer && npm run build:all",
10 | "build": "npm run build:helper && npm run build:transformer",
11 | "test": "cd source && chmod +x run-unit-tests.sh && ./run-unit-tests.sh"
12 | },
13 | "author": "aws-solutions",
14 | "license": "Apache-2.0",
15 | "devDependencies": {
16 | "@types/node": "^20.3.1",
17 | "@types/uuid": "^9.0.1",
18 | "@typescript-eslint/eslint-plugin": "^6.8.0",
19 | "@typescript-eslint/parser": "^6.8.0",
20 | "eslint": "^8.43.0",
21 | "eslint-config-prettier": "^9.0.0",
22 | "eslint-plugin-prettier": "^5.0.1",
23 | "prettier": "^3.0.3",
24 | "typescript": "^5.1.3",
25 | "aws-cdk": "^2.68.0"
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/source/dashboard.ndjson:
--------------------------------------------------------------------------------
1 | {"attributes":{"fields":"[{\"name\":\"@log_group\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"@log_group.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"@log_group\"}}},{\"name\":\"@log_stream\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":2,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"@log_stream.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"@log_stream\"}}},{\"name\":\"@message\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"@message.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"@message\"}}},{\"name\":\"@owner\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"@owner.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"@owner\"}}},{\"name\":\"_id\",\"type\":\"string\",\"esTypes\":[\"_id\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"_index\",\"type\":\"string\",\"esTypes\":[\"_index\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"_score\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"_source\",\"type\":\"_source\",\"esTypes\":[\"_source\"],\"count\":0,\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"_type\",\"type\":\"string\",\"esTypes\":[\"_type\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"account_id\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"account_id.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"account_id\"}}},{\"name\":\"action\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"action.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"action\"}}},{\"name\":\"additionalEventData.AuthenticationMethod\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"additionalEventData.AuthenticationMethod.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"additionalEventData.AuthenticationMethod\"}}},{\"name\":\"additionalEventData.CipherSuite\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"additionalEventData.CipherSuite.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"additionalEventData.CipherSuite\"}}},{\"name\":\"additionalEventData.LoginTo\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"additionalEventData.LoginTo.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"additionalEventData.LoginTo\"}}},{\"name\":\"additionalEventData.MFAUsed\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"additionalEventData.MFAUsed.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"additionalEventData.MFAUsed\"}}},{\"name\":\"additionalEventData.MobileVersion\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"additionalEventData.MobileVersion.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"additionalEventData.MobileVersion\"}}},{\"name\":\"additionalEventData.SignatureVersion\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"additionalEventData.SignatureVersion.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"additionalEventData.SignatureVersion\"}}},{\"name\":\"additionalEventData.bytesTransferredIn\",\"type\":\"number\",\"esTypes\":[\"long\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"additionalEventData.bytesTransferredOut\",\"type\":\"number\",\"esTypes\":[\"long\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"additionalEventData.x-amz-id-2\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"additionalEventData.x-amz-id-2.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"additionalEventData.x-amz-id-2\"}}},{\"name\":\"agent\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"agent.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"agent\"}}},{\"name\":\"apiVersion\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"apiVersion.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"apiVersion\"}}},{\"name\":\"authuser\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"authuser.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"authuser\"}}},{\"name\":\"awsRegion\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"awsRegion.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"awsRegion\"}}},{\"name\":\"bytes\",\"type\":\"number\",\"esTypes\":[\"long\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"date\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"date.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"date\"}}},{\"name\":\"dstaddr\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"dstaddr.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"dstaddr\"}}},{\"name\":\"dstport\",\"type\":\"number\",\"esTypes\":[\"long\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"end\",\"type\":\"number\",\"esTypes\":[\"long\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"errorCode\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"errorCode.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"errorCode\"}}},{\"name\":\"errorMessage\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"errorMessage.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"errorMessage\"}}},{\"name\":\"eventCategory\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"eventCategory.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"eventCategory\"}}},{\"name\":\"eventID\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"eventID.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"eventID\"}}},{\"name\":\"eventName\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"eventName.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"eventName\"}}},{\"name\":\"eventSource\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"eventSource.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"eventSource\"}}},{\"name\":\"eventTime\",\"type\":\"date\",\"esTypes\":[\"date\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"eventType\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"eventType.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"eventType\"}}},{\"name\":\"eventVersion\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"eventVersion.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"eventVersion\"}}},{\"name\":\"host\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"host.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"host\"}}},{\"name\":\"id\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"id.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"id\"}}},{\"name\":\"ident\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"ident.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"ident\"}}},{\"name\":\"interface_id\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"interface_id.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"interface_id\"}}},{\"name\":\"log_status\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"log_status.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"log_status\"}}},{\"name\":\"managementEvent\",\"type\":\"boolean\",\"esTypes\":[\"boolean\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"packets\",\"type\":\"number\",\"esTypes\":[\"long\"],\"count\":2,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"protocol\",\"type\":\"number\",\"esTypes\":[\"long\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"readOnly\",\"type\":\"boolean\",\"esTypes\":[\"boolean\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"recipientAccountId\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"recipientAccountId.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"recipientAccountId\"}}},{\"name\":\"referrer\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"referrer.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"referrer\"}}},{\"name\":\"request\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"request.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"request\"}}},{\"name\":\"requestID\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"requestID.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"requestID\"}}},{\"name\":\"requestParameters\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"requestParameters.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"requestParameters\"}}},{\"name\":\"resources.ARN\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"resources.ARN.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"resources.ARN\"}}},{\"name\":\"resources.accountId\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"resources.accountId.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"resources.accountId\"}}},{\"name\":\"resources.type\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"resources.type.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"resources.type\"}}},{\"name\":\"responseElements\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"responseElements.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"responseElements\"}}},{\"name\":\"serviceEventDetails.snapshotId\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"serviceEventDetails.snapshotId.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"serviceEventDetails.snapshotId\"}}},{\"name\":\"sessionCredentialFromConsole\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"sessionCredentialFromConsole.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"sessionCredentialFromConsole\"}}},{\"name\":\"sharedEventID\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"sharedEventID.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"sharedEventID\"}}},{\"name\":\"sourceIPAddress\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"sourceIPAddress.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"sourceIPAddress\"}}},{\"name\":\"srcaddr\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":3,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"srcaddr.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"srcaddr\"}}},{\"name\":\"srcport\",\"type\":\"number\",\"esTypes\":[\"long\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"start\",\"type\":\"number\",\"esTypes\":[\"long\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"status\",\"type\":\"number\",\"esTypes\":[\"long\"],\"count\":2,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"timestamp\",\"type\":\"date\",\"esTypes\":[\"date\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"tlsDetails.cipherSuite\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"tlsDetails.cipherSuite.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"tlsDetails.cipherSuite\"}}},{\"name\":\"tlsDetails.clientProvidedHostHeader\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"tlsDetails.clientProvidedHostHeader.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"tlsDetails.clientProvidedHostHeader\"}}},{\"name\":\"tlsDetails.tlsVersion\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"tlsDetails.tlsVersion.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"tlsDetails.tlsVersion\"}}},{\"name\":\"type\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"type.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"type\"}}},{\"name\":\"userAgent\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"userAgent.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"userAgent\"}}},{\"name\":\"userIdentity.accessKeyId\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"userIdentity.accessKeyId.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"userIdentity.accessKeyId\"}}},{\"name\":\"userIdentity.accountId\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"userIdentity.accountId.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"userIdentity.accountId\"}}},{\"name\":\"userIdentity.arn\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"userIdentity.arn.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"userIdentity.arn\"}}},{\"name\":\"userIdentity.identityProvider\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"userIdentity.identityProvider.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"userIdentity.identityProvider\"}}},{\"name\":\"userIdentity.invokedBy\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"userIdentity.invokedBy.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"userIdentity.invokedBy\"}}},{\"name\":\"userIdentity.principalId\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"userIdentity.principalId.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"userIdentity.principalId\"}}},{\"name\":\"userIdentity.sessionContext.attributes.creationDate\",\"type\":\"date\",\"esTypes\":[\"date\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"userIdentity.sessionContext.attributes.mfaAuthenticated\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"userIdentity.sessionContext.attributes.mfaAuthenticated.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"userIdentity.sessionContext.attributes.mfaAuthenticated\"}}},{\"name\":\"userIdentity.sessionContext.ec2RoleDelivery\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"userIdentity.sessionContext.ec2RoleDelivery.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"userIdentity.sessionContext.ec2RoleDelivery\"}}},{\"name\":\"userIdentity.sessionContext.sessionIssuer.accountId\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"userIdentity.sessionContext.sessionIssuer.accountId.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"userIdentity.sessionContext.sessionIssuer.accountId\"}}},{\"name\":\"userIdentity.sessionContext.sessionIssuer.arn\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"userIdentity.sessionContext.sessionIssuer.arn.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"userIdentity.sessionContext.sessionIssuer.arn\"}}},{\"name\":\"userIdentity.sessionContext.sessionIssuer.principalId\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"userIdentity.sessionContext.sessionIssuer.principalId.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"userIdentity.sessionContext.sessionIssuer.principalId\"}}},{\"name\":\"userIdentity.sessionContext.sessionIssuer.type\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"userIdentity.sessionContext.sessionIssuer.type.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"userIdentity.sessionContext.sessionIssuer.type\"}}},{\"name\":\"userIdentity.sessionContext.sessionIssuer.userName\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"userIdentity.sessionContext.sessionIssuer.userName.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"userIdentity.sessionContext.sessionIssuer.userName\"}}},{\"name\":\"userIdentity.type\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"userIdentity.type.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"userIdentity.type\"}}},{\"name\":\"userIdentity.userName\",\"type\":\"string\",\"esTypes\":[\"text\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"userIdentity.userName.keyword\",\"type\":\"string\",\"esTypes\":[\"keyword\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true,\"subType\":{\"multi\":{\"parent\":\"userIdentity.userName\"}}},{\"name\":\"version\",\"type\":\"number\",\"esTypes\":[\"long\"],\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true}]","timeFieldName":"timestamp","title":"cwl*"},"id":"b72dad40-4d4c-11ec-bcce-3f4b1c5e311c","migrationVersion":{"index-pattern":"7.6.0"},"references":[],"type":"index-pattern","updated_at":"2021-11-24T18:57:13.928Z","version":"WzE4NywxXQ=="}
2 | {"attributes":{"columns":["_source"],"description":"","hits":0,"kibanaSavedObjectMeta":{"searchSourceJSON":"{\"highlightAll\":true,\"version\":true,\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}"},"sort":[],"title":"CW-All Data","version":1},"id":"b9abbab0-4d4e-11ec-9168-077f704f5d1a","migrationVersion":{"search":"7.4.0"},"references":[{"id":"b72dad40-4d4c-11ec-bcce-3f4b1c5e311c","name":"kibanaSavedObjectMeta.searchSourceJSON.index","type":"index-pattern"}],"type":"search","updated_at":"2021-11-24T17:48:25.946Z","version":"WzE2MCwxXQ=="}
3 | {"attributes":{"description":"","kibanaSavedObjectMeta":{"searchSourceJSON":"{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}"},"savedSearchRefName":"search_0","title":"Top 10 Api Sources","uiStateJSON":"{}","version":1,"visState":"{\"type\":\"pie\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"eventSource.keyword\",\"orderBy\":\"_key\",\"order\":\"desc\",\"size\":10,\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\"}}],\"params\":{\"type\":\"pie\",\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"isDonut\":true,\"labels\":{\"show\":false,\"values\":true,\"last_level\":true,\"truncate\":100}},\"title\":\"Top 10 Api Sources\"}"},"id":"6bcabb50-4d55-11ec-b460-5772f5062857","migrationVersion":{"visualization":"7.7.0"},"references":[{"id":"b9abbab0-4d4e-11ec-9168-077f704f5d1a","name":"search_0","type":"search"}],"type":"visualization","updated_at":"2021-11-24T18:36:21.765Z","version":"WzE3NywxXQ=="}
4 | {"attributes":{"description":"","kibanaSavedObjectMeta":{"searchSourceJSON":"{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}"},"savedSearchRefName":"search_0","title":"Top 10 Access Key Ids","uiStateJSON":"{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}","version":1,"visState":"{\"type\":\"table\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"userIdentity.accessKeyId.keyword\",\"orderBy\":\"1\",\"order\":\"desc\",\"size\":10,\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"customLabel\":\"UserIdentity AccessKeyId\"}}],\"params\":{\"perPage\":10,\"showPartialRows\":false,\"showMetricsAtAllLevels\":false,\"sort\":{\"columnIndex\":null,\"direction\":null},\"showTotal\":false,\"totalFunc\":\"sum\",\"percentageCol\":\"Count\"},\"title\":\"Top 10 Access Key Ids\"}"},"id":"db311a70-4d55-11ec-b460-5772f5062857","migrationVersion":{"visualization":"7.7.0"},"references":[{"id":"b9abbab0-4d4e-11ec-9168-077f704f5d1a","name":"search_0","type":"search"}],"type":"visualization","updated_at":"2021-11-24T18:39:28.663Z","version":"WzE3OSwxXQ=="}
5 | {"attributes":{"description":"","kibanaSavedObjectMeta":{"searchSourceJSON":"{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}"},"savedSearchRefName":"search_0","title":"Top 10 Account Ids","uiStateJSON":"{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}","version":1,"visState":"{\"type\":\"table\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"account_id.keyword\",\"orderBy\":\"1\",\"order\":\"desc\",\"size\":10,\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"customLabel\":\"Account Id\"}}],\"params\":{\"perPage\":10,\"showPartialRows\":false,\"showMetricsAtAllLevels\":false,\"sort\":{\"columnIndex\":null,\"direction\":null},\"showTotal\":false,\"totalFunc\":\"sum\",\"percentageCol\":\"\",\"row\":false},\"title\":\"Top 10 Account Ids\"}"},"id":"34196b10-4d56-11ec-bcce-3f4b1c5e311c","migrationVersion":{"visualization":"7.7.0"},"references":[{"id":"b9abbab0-4d4e-11ec-9168-077f704f5d1a","name":"search_0","type":"search"}],"type":"visualization","updated_at":"2021-11-24T18:41:57.824Z","version":"WzE4MSwxXQ=="}
6 | {"attributes":{"description":"","kibanaSavedObjectMeta":{"searchSourceJSON":"{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}"},"savedSearchRefName":"search_0","title":"Top 10 AWS Regions","uiStateJSON":"{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}","version":1,"visState":"{\"type\":\"table\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"awsRegion.keyword\",\"orderBy\":\"1\",\"order\":\"desc\",\"size\":10,\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"customLabel\":\"AWS Region\"}}],\"params\":{\"perPage\":10,\"showPartialRows\":false,\"showMetricsAtAllLevels\":false,\"sort\":{\"columnIndex\":null,\"direction\":null},\"showTotal\":false,\"totalFunc\":\"sum\",\"percentageCol\":\"\"},\"title\":\"Top 10 AWS Regions\"}"},"id":"65287840-4d56-11ec-afa8-9fe54e15bce6","migrationVersion":{"visualization":"7.7.0"},"references":[{"id":"b9abbab0-4d4e-11ec-9168-077f704f5d1a","name":"search_0","type":"search"}],"type":"visualization","updated_at":"2021-11-24T18:43:20.131Z","version":"WzE4MywxXQ=="}
7 | {"attributes":{"description":"","kibanaSavedObjectMeta":{"searchSourceJSON":"{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}"},"savedSearchRefName":"search_0","title":"PacketCount By Source","uiStateJSON":"{\"vis\":{\"params\":{\"sort\":{\"columnIndex\":null,\"direction\":null}}}}","version":1,"visState":"{\"type\":\"table\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{\"customLabel\":\"Packet Count\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"bucket\",\"params\":{\"field\":\"srcaddr.keyword\",\"orderBy\":\"1\",\"order\":\"desc\",\"size\":5,\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\",\"customLabel\":\"Source Address\"}}],\"params\":{\"perPage\":10,\"showPartialRows\":false,\"showMetricsAtAllLevels\":false,\"sort\":{\"columnIndex\":null,\"direction\":null},\"showTotal\":false,\"totalFunc\":\"sum\",\"percentageCol\":\"Packet Count\"},\"title\":\"PacketCount By Source\"}"},"id":"ba1bc520-4d4f-11ec-9168-077f704f5d1a","migrationVersion":{"visualization":"7.7.0"},"references":[{"id":"b9abbab0-4d4e-11ec-9168-077f704f5d1a","name":"search_0","type":"search"}],"type":"visualization","updated_at":"2021-11-24T18:26:49.602Z","version":"WzE3NCwxXQ=="}
8 | {"attributes":{"description":"","kibanaSavedObjectMeta":{"searchSourceJSON":"{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}"},"savedSearchRefName":"search_0","title":"PacketStatus By Source","uiStateJSON":"{}","version":1,"visState":"{\"type\":\"pie\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"sum\",\"schema\":\"metric\",\"params\":{\"field\":\"packets\"}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"srcaddr.keyword\",\"orderBy\":\"1\",\"order\":\"desc\",\"size\":10,\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"action.keyword\",\"orderBy\":\"1\",\"order\":\"desc\",\"size\":2,\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\"}}],\"params\":{\"type\":\"pie\",\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"isDonut\":true,\"labels\":{\"show\":false,\"values\":true,\"last_level\":false,\"truncate\":100}},\"title\":\"PacketStatus By Source\"}"},"id":"9b8ab670-4d59-11ec-b460-5772f5062857","migrationVersion":{"visualization":"7.7.0"},"references":[{"id":"b9abbab0-4d4e-11ec-9168-077f704f5d1a","name":"search_0","type":"search"}],"type":"visualization","updated_at":"2021-11-24T19:06:19.863Z","version":"WzE4OCwxXQ=="}
9 | {"attributes":{"description":"","kibanaSavedObjectMeta":{"searchSourceJSON":"{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}"},"savedSearchRefName":"search_0","title":"PacketsStatus","uiStateJSON":"{}","version":1,"visState":"{\"type\":\"area\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"sum\",\"schema\":\"metric\",\"params\":{\"field\":\"packets\"}},{\"id\":\"3\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"group\",\"params\":{\"field\":\"action.keyword\",\"orderBy\":\"1\",\"order\":\"desc\",\"size\":5,\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"date_histogram\",\"schema\":\"segment\",\"params\":{\"field\":\"timestamp\",\"timeRange\":{\"from\":\"now-15m\",\"to\":\"now\"},\"useNormalizedEsInterval\":true,\"scaleMetricValues\":false,\"interval\":\"auto\",\"drop_partials\":false,\"min_doc_count\":1,\"extended_bounds\":{}}}],\"params\":{\"type\":\"line\",\"grid\":{\"categoryLines\":false},\"categoryAxes\":[{\"id\":\"CategoryAxis-1\",\"type\":\"category\",\"position\":\"bottom\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\"},\"labels\":{\"show\":true,\"filter\":true,\"truncate\":100},\"title\":{}}],\"valueAxes\":[{\"id\":\"ValueAxis-1\",\"name\":\"LeftAxis-1\",\"type\":\"value\",\"position\":\"left\",\"show\":true,\"style\":{},\"scale\":{\"type\":\"linear\",\"mode\":\"normal\"},\"labels\":{\"show\":true,\"rotate\":0,\"filter\":false,\"truncate\":100},\"title\":{\"text\":\"Sum of packets\"}}],\"seriesParams\":[{\"show\":true,\"type\":\"area\",\"mode\":\"normal\",\"data\":{\"label\":\"Sum of packets\",\"id\":\"1\"},\"valueAxis\":\"ValueAxis-1\",\"drawLinesBetweenPoints\":true,\"lineWidth\":2,\"interpolate\":\"linear\",\"showCircles\":true}],\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"times\":[],\"addTimeMarker\":false,\"labels\":{},\"thresholdLine\":{\"show\":false,\"value\":10,\"width\":1,\"style\":\"full\",\"color\":\"#E7664C\"}},\"title\":\"PacketsStatus\"}"},"id":"b840c6c0-4d53-11ec-b460-5772f5062857","migrationVersion":{"visualization":"7.7.0"},"references":[{"id":"b9abbab0-4d4e-11ec-9168-077f704f5d1a","name":"search_0","type":"search"}],"type":"visualization","updated_at":"2021-11-24T18:24:11.052Z","version":"WzE3MSwxXQ=="}
10 | {"attributes":{"description":"","kibanaSavedObjectMeta":{"searchSourceJSON":"{\"query\":{\"query\":\"\",\"language\":\"kuery\"},\"filter\":[]}"},"savedSearchRefName":"search_0","title":"HttpStatus","uiStateJSON":"{}","version":1,"visState":"{\"type\":\"pie\",\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{\"customLabel\":\"\"}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"status\",\"orderBy\":\"1\",\"order\":\"desc\",\"size\":5,\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\"}}],\"params\":{\"type\":\"pie\",\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"isDonut\":true,\"labels\":{\"show\":true,\"values\":true,\"last_level\":true,\"truncate\":100}},\"title\":\"HttpStatus\"}"},"id":"993088e0-4d50-11ec-9168-077f704f5d1a","migrationVersion":{"visualization":"7.7.0"},"references":[{"id":"b9abbab0-4d4e-11ec-9168-077f704f5d1a","name":"search_0","type":"search"}],"type":"visualization","updated_at":"2021-11-24T18:01:50.446Z","version":"WzE2NSwxXQ=="}
11 | {"attributes":{"description":"","hits":0,"kibanaSavedObjectMeta":{"searchSourceJSON":"{\"query\":{\"language\":\"kuery\",\"query\":\"\"},\"filter\":[]}"},"optionsJSON":"{\"hidePanelTitles\":false,\"useMargins\":true}","panelsJSON":"[{\"version\":\"7.7.0\",\"gridData\":{\"x\":0,\"y\":0,\"w\":24,\"h\":15,\"i\":\"ecd19bb6-5b50-4b36-8fdc-d9caeae8bbcc\"},\"panelIndex\":\"ecd19bb6-5b50-4b36-8fdc-d9caeae8bbcc\",\"embeddableConfig\":{},\"panelRefName\":\"panel_0\"},{\"version\":\"7.7.0\",\"gridData\":{\"x\":24,\"y\":0,\"w\":24,\"h\":15,\"i\":\"f1bc3f1f-2812-4018-9698-3bc9ccfb5994\"},\"panelIndex\":\"f1bc3f1f-2812-4018-9698-3bc9ccfb5994\",\"embeddableConfig\":{},\"panelRefName\":\"panel_1\"},{\"version\":\"7.7.0\",\"gridData\":{\"x\":0,\"y\":15,\"w\":24,\"h\":10,\"i\":\"bd12ad1c-9733-46ef-80e4-5ed0f068cba4\"},\"panelIndex\":\"bd12ad1c-9733-46ef-80e4-5ed0f068cba4\",\"embeddableConfig\":{},\"panelRefName\":\"panel_2\"},{\"version\":\"7.7.0\",\"gridData\":{\"x\":24,\"y\":15,\"w\":24,\"h\":10,\"i\":\"3c196825-7884-4c8d-93d1-76bdb6e3b069\"},\"panelIndex\":\"3c196825-7884-4c8d-93d1-76bdb6e3b069\",\"embeddableConfig\":{},\"panelRefName\":\"panel_3\"},{\"version\":\"7.7.0\",\"gridData\":{\"x\":0,\"y\":40,\"w\":24,\"h\":15,\"i\":\"09bb01d6-687d-4e90-88d5-1b2d8178cb81\"},\"panelIndex\":\"09bb01d6-687d-4e90-88d5-1b2d8178cb81\",\"embeddableConfig\":{},\"panelRefName\":\"panel_4\"},{\"version\":\"7.7.0\",\"gridData\":{\"x\":24,\"y\":25,\"w\":24,\"h\":15,\"i\":\"bb313830-deaf-4c10-b665-8fcb474093ed\"},\"panelIndex\":\"bb313830-deaf-4c10-b665-8fcb474093ed\",\"embeddableConfig\":{},\"panelRefName\":\"panel_5\"},{\"version\":\"7.7.0\",\"gridData\":{\"x\":0,\"y\":25,\"w\":24,\"h\":15,\"i\":\"f2fe6aa5-aed5-4a6e-a50a-47d304d0fc4b\"},\"panelIndex\":\"f2fe6aa5-aed5-4a6e-a50a-47d304d0fc4b\",\"embeddableConfig\":{\"title\":\"PacketsStatus\",\"colors\":{\"ACCEPT\":\"#64B0C8\",\"REJECT\":\"#BF1B00\"},\"vis\":{\"colors\":{\"ACCEPT\":\"#447EBC\",\"REJECT\":\"#BF1B00\"}}},\"title\":\"PacketsStatus\",\"panelRefName\":\"panel_6\"},{\"version\":\"7.7.0\",\"gridData\":{\"x\":24,\"y\":40,\"w\":24,\"h\":15,\"i\":\"8d1e6b81-61dc-4bf2-8e0c-d4d8e8a06bd4\"},\"panelIndex\":\"8d1e6b81-61dc-4bf2-8e0c-d4d8e8a06bd4\",\"embeddableConfig\":{},\"panelRefName\":\"panel_7\"}]","refreshInterval":{"pause":true,"value":0},"timeFrom":"now-15m","timeRestore":true,"timeTo":"now","title":"Basic","version":1},"id":"056abf40-4d5a-11ec-b460-5772f5062857","migrationVersion":{"dashboard":"7.3.0"},"references":[{"id":"6bcabb50-4d55-11ec-b460-5772f5062857","name":"panel_0","type":"visualization"},{"id":"db311a70-4d55-11ec-b460-5772f5062857","name":"panel_1","type":"visualization"},{"id":"34196b10-4d56-11ec-bcce-3f4b1c5e311c","name":"panel_2","type":"visualization"},{"id":"65287840-4d56-11ec-afa8-9fe54e15bce6","name":"panel_3","type":"visualization"},{"id":"ba1bc520-4d4f-11ec-9168-077f704f5d1a","name":"panel_4","type":"visualization"},{"id":"9b8ab670-4d59-11ec-b460-5772f5062857","name":"panel_5","type":"visualization"},{"id":"b840c6c0-4d53-11ec-b460-5772f5062857","name":"panel_6","type":"visualization"},{"id":"993088e0-4d50-11ec-9168-077f704f5d1a","name":"panel_7","type":"visualization"}],"type":"dashboard","updated_at":"2021-11-24T20:20:00.325Z","version":"WzE5NSwxXQ=="}
12 | {"exportedCount":11,"missingRefCount":0,"missingReferences":[]}
--------------------------------------------------------------------------------
/source/resources/README.md:
--------------------------------------------------------------------------------
1 | # Centralized Logging on AWS CDK Project
2 |
3 | The `cdk.json` file tells the CDK Toolkit how to execute your app.
4 |
5 | ## Useful commands
6 |
7 | - `npm run build` compile typescript to js
8 | - `npm run watch` watch for changes and compile
9 | - `npm run test` perform the jest unit tests
10 | - `cdk deploy` deploy this stack to your default AWS account/region
11 | - `cdk diff` compare deployed stack with current state
12 | - `cdk synth` emits the synthesized CloudFormation template
13 |
--------------------------------------------------------------------------------
/source/resources/__tests__/cl.test.ts:
--------------------------------------------------------------------------------
1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | import "@aws-cdk/assert/jest";
5 | import { CLPrimary } from "../lib/cl-primary-stack";
6 | import { App, Stack } from "aws-cdk-lib";
7 |
8 | describe("==Primary Stack Tests==", () => {
9 | const app = new App();
10 | const stack: Stack = new CLPrimary(app, "CL-PrimaryStack");
11 |
12 | describe("Test resources", () => {
13 | test("snapshot test", () => {
14 | expect(stack).toMatchSnapshot();
15 | });
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/source/resources/__tests__/utils.test.ts:
--------------------------------------------------------------------------------
1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | import "@aws-cdk/assert/jest";
5 | import { App, Stack } from "aws-cdk-lib";
6 | import * as s3 from "aws-cdk-lib/aws-s3";
7 |
8 | import { applyCfnNagSuppressRules } from "../lib/utils";
9 | import { ResourcePart } from "@aws-cdk/assert";
10 |
11 | test("validate cfn_nag suppressions are added", () => {
12 | const app = new App();
13 | const stack = new Stack(app, "TestStack");
14 |
15 | const cfnBucket = new s3.CfnBucket(stack, "TestBucket");
16 |
17 | // Add individual suppression
18 | applyCfnNagSuppressRules(cfnBucket, [
19 | {
20 | id: "W1",
21 | reason: "This should be ignored",
22 | },
23 | ]);
24 | expect(stack).toHaveResourceLike(
25 | "AWS::S3::Bucket",
26 | {
27 | Metadata: {
28 | cfn_nag: {
29 | rules_to_suppress: [
30 | {
31 | id: "W1",
32 | reason: "This should be ignored",
33 | },
34 | ],
35 | },
36 | },
37 | },
38 | ResourcePart.CompleteDefinition
39 | );
40 |
41 | // Add multiple suppressions (one of which is an overwrite)
42 | applyCfnNagSuppressRules(cfnBucket, [
43 | {
44 | id: "W1",
45 | reason: "Reason for warning 1",
46 | },
47 | {
48 | id: "W2",
49 | reason: "Reason for warning 2",
50 | },
51 | {
52 | id: "W3",
53 | reason: "Reason for warning 3",
54 | },
55 | ]);
56 |
57 | expect(stack).toHaveResource("AWS::S3::Bucket");
58 |
59 | expect(stack).toHaveResourceLike(
60 | "AWS::S3::Bucket",
61 | {
62 | Metadata: {
63 | cfn_nag: {
64 | rules_to_suppress: [
65 | {
66 | id: "W1",
67 | reason: "Reason for warning 1",
68 | },
69 | {
70 | id: "W2",
71 | reason: "Reason for warning 2",
72 | },
73 | {
74 | id: "W3",
75 | reason: "Reason for warning 3",
76 | },
77 | ],
78 | },
79 | },
80 | },
81 | ResourcePart.CompleteDefinition
82 | );
83 | });
84 |
--------------------------------------------------------------------------------
/source/resources/bin/app.ts:
--------------------------------------------------------------------------------
1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | import { App, DefaultStackSynthesizer } from "aws-cdk-lib";
5 | import { CLPrimary } from "../lib/cl-primary-stack";
6 |
7 | const app = new App();
8 |
9 | new CLPrimary(app, "CL-PrimaryStack", {
10 | synthesizer: new DefaultStackSynthesizer({
11 | generateBootstrapVersionRule: false,
12 | }),
13 | });
14 |
--------------------------------------------------------------------------------
/source/resources/cdk.json:
--------------------------------------------------------------------------------
1 | {
2 | "app": "npx ts-node bin/app.ts",
3 | "context": {
4 | "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/source/resources/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | // Automatically clear mock calls and instances between every test
3 | clearMocks: false,
4 |
5 | // The directory where Jest should output its coverage files
6 | coverageDirectory: "coverage",
7 |
8 | // An array of regexp pattern strings used to skip coverage collection
9 | coveragePathIgnorePatterns: ["/node_modules/"],
10 |
11 | // An object that configures minimum threshold enforcement for coverage results
12 | coverageThreshold: {
13 | global: {
14 | // branches: 80,
15 | functions: 80,
16 | lines: 80,
17 | statements: 80,
18 | },
19 | },
20 |
21 | // An array of directory names to be searched recursively up from the requiring module's location
22 | moduleDirectories: ["node_modules"],
23 |
24 | // An array of file extensions your modules use
25 | moduleFileExtensions: ["ts", "json", "jsx", "js", "tsx", "node"],
26 |
27 | // Automatically reset mock state between every test
28 | resetMocks: true,
29 |
30 | // The glob patterns Jest uses to detect test files
31 | testMatch: ["**/?(*.)+(spec|test).[t]s?(x)"],
32 |
33 | // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
34 | testPathIgnorePatterns: ["/node_modules/"],
35 |
36 | // A map from regular expressions to paths to transformers
37 | transform: {
38 | "^.+\\.(t|j)sx?$": "ts-jest",
39 | },
40 |
41 | // Indicates whether each individual test should be reported during the run
42 | verbose: true,
43 |
44 | coverageReporters: ["text", ["lcov", { projectRoot: "../../" }]],
45 |
46 | // This option allows the use of a custom results processor.
47 | testResultsProcessor: "jest-sonar-reporter",
48 | };
49 |
--------------------------------------------------------------------------------
/source/resources/lib/cl-demo-ec2-construct.ts:
--------------------------------------------------------------------------------
1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | /**
5 | * @description
6 | * This is EC2 construct for WebServer resource
7 | * @author @aws-solutions
8 | */
9 |
10 | import { Stack, RemovalPolicy, CfnResource } from "aws-cdk-lib";
11 | import { Construct } from "constructs";
12 | import {
13 | Vpc,
14 | Instance,
15 | InstanceType,
16 | InitFile,
17 | InitService,
18 | InitServiceRestartHandle,
19 | CloudFormationInit,
20 | MachineImage,
21 | AmazonLinuxVirt,
22 | AmazonLinuxGeneration,
23 | AmazonLinuxCpuType,
24 | SecurityGroup,
25 | Peer,
26 | Port,
27 | InitPackage,
28 | } from "aws-cdk-lib/aws-ec2";
29 | import {
30 | LogGroup,
31 | RetentionDays,
32 | CfnSubscriptionFilter,
33 | } from "aws-cdk-lib/aws-logs";
34 | import { Effect, PolicyStatement } from "aws-cdk-lib/aws-iam";
35 | import manifest from "./manifest.json";
36 | import { cfn_suppress_rules, applyCfnNagSuppressRules } from "./utils";
37 |
38 | /**
39 | * @interface
40 | * @description web server interface
41 | */
42 | interface IEC2Demo {
43 | /**
44 | * @description destination arn for log streaming
45 | * @type {string}
46 | */
47 | destination: string;
48 | /**
49 | * @description vpc for creating demo resources
50 | * @type {Vpc}
51 | */
52 | demoVpc: Vpc;
53 | }
54 | /**
55 | * @class
56 | * @description web server resources construct
57 | * @property {string} region of deployment
58 | */
59 | export class EC2Demo extends Construct {
60 | readonly region: string;
61 | readonly publicIp: string;
62 | constructor(scope: Construct, id: string, props: IEC2Demo) {
63 | super(scope, id);
64 |
65 | const stack = Stack.of(this);
66 |
67 | this.region = stack.region; // Returns the AWS::Region for this stack (or the literal value if known)
68 |
69 | /**
70 | * @description security group for web server
71 | * @type {SecurityGroup}
72 | */
73 | const demoSg: SecurityGroup = new SecurityGroup(this, "DemoSG", {
74 | vpc: props.demoVpc,
75 | });
76 | demoSg.addIngressRule(Peer.anyIpv4(), Port.tcp(80), "allow HTTP traffic");
77 | // cfn_nag suppress rule
78 | applyCfnNagSuppressRules(demoSg.node.defaultChild as CfnResource, [
79 | cfn_suppress_rules.W5,
80 | cfn_suppress_rules.W2,
81 | cfn_suppress_rules.W9,
82 | cfn_suppress_rules.W40,
83 | ]);
84 |
85 | /**
86 | * @description log group for web server
87 | * @type {LogGroup}
88 | */
89 | const ec2Lg: LogGroup = new LogGroup(this, "EC2LogGroup", {
90 | removalPolicy: RemovalPolicy.DESTROY,
91 | retention: RetentionDays.ONE_WEEK,
92 | });
93 |
94 | const handle: InitServiceRestartHandle = new InitServiceRestartHandle();
95 |
96 | /**
97 | * @description cloudformation init configuration for web server
98 | * @type {CloudFormationInit}
99 | */
100 | const init: CloudFormationInit = CloudFormationInit.fromElements(
101 | InitPackage.yum("httpd", { serviceRestartHandles: [handle] }),
102 | InitPackage.yum("php", { serviceRestartHandles: [handle] }),
103 | InitPackage.yum("amazon-cloudwatch-agent", {
104 | serviceRestartHandles: [handle],
105 | }),
106 | InitFile.fromObject("/tmp/cw-config.json", { //NOSONAR
107 | agent: {
108 | run_as_user: "root",
109 | },
110 | logs: {
111 | logs_collected: {
112 | files: {
113 | collect_list: [
114 | {
115 | file_path: "/var/log/httpd/access_log",
116 | log_group_name: ec2Lg.logGroupName,
117 | log_stream_name: "{instance_id}/apache.log",
118 | timezone: "UTC",
119 | },
120 | ],
121 | },
122 | },
123 | },
124 | }),
125 | InitFile.fromString(
126 | "/var/www/html/index.php",
127 | `AWS CloudFormation sample PHP application';
129 | ?>`,
130 | {
131 | mode: "000644",
132 | owner: "apache",
133 | group: "apache",
134 | serviceRestartHandles: [handle],
135 | }
136 | ),
137 | InitService.enable("httpd", {
138 | enabled: true,
139 | ensureRunning: true,
140 | serviceRestartHandle: handle,
141 | })
142 | );
143 |
144 | /**
145 | * @description web server instance
146 | * @type {Instance}
147 | */
148 | const demoEC2: Instance = new Instance(this, "DemoEC2", {
149 | vpc: props.demoVpc,
150 | instanceType: new InstanceType(manifest.jumpboxInstanceType),
151 | machineImage: MachineImage.latestAmazonLinux({
152 | virtualization: AmazonLinuxVirt.HVM,
153 | generation: AmazonLinuxGeneration.AMAZON_LINUX_2,
154 | cpuType: AmazonLinuxCpuType.X86_64,
155 | }),
156 | init: init,
157 | allowAllOutbound: true,
158 | securityGroup: demoSg,
159 | requireImdsv2: true,
160 | });
161 |
162 | demoEC2.addUserData(
163 | "/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a stop",
164 | "/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/tmp/cw-config.json -s",
165 | "curl 127.0.0.1"
166 | );
167 | demoEC2.addToRolePolicy(
168 | new PolicyStatement({
169 | effect: Effect.ALLOW,
170 | sid: "LogWrite",
171 | actions: ["logs:Create*", "logs:PutLogEvents"],
172 | resources: [ec2Lg.logGroupArn],
173 | })
174 | );
175 | this.publicIp = demoEC2.instancePublicIp;
176 |
177 | new CfnSubscriptionFilter(this, "WebServerSubscription", {
178 | destinationArn: props.destination,
179 | filterPattern:
180 | "[host, ident, authuser, date, request, status, bytes, referrer, agent]",
181 | logGroupName: ec2Lg.logGroupName,
182 | });
183 |
184 | applyCfnNagSuppressRules(ec2Lg.node.findChild("Resource") as CfnResource, [
185 | cfn_suppress_rules.W84,
186 | ]);
187 | }
188 | }
189 |
--------------------------------------------------------------------------------
/source/resources/lib/cl-demo-stack.ts:
--------------------------------------------------------------------------------
1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | /**
5 | * @description
6 | * Demo Stack for Centralized Logging on AWS
7 | * @author @aws-solutions
8 | */
9 |
10 | import {
11 | CfnMapping,
12 | CfnOutput,
13 | CfnParameter,
14 | CfnResource,
15 | Fn,
16 | NestedStack,
17 | NestedStackProps,
18 | RemovalPolicy,
19 | Stack
20 | } from "aws-cdk-lib";
21 | import { Construct } from "constructs";
22 | import {
23 | FlowLog,
24 | FlowLogDestination,
25 | FlowLogResourceType,
26 | FlowLogTrafficType,
27 | SubnetType,
28 | Vpc
29 | } from "aws-cdk-lib/aws-ec2";
30 | import { Effect, PolicyStatement, Role, ServicePrincipal } from "aws-cdk-lib/aws-iam";
31 | import { CfnSubscriptionFilter, LogGroup, RetentionDays } from "aws-cdk-lib/aws-logs";
32 | import { Trail } from "aws-cdk-lib/aws-cloudtrail";
33 | import { BlockPublicAccess, Bucket, BucketEncryption } from "aws-cdk-lib/aws-s3";
34 | import { EC2Demo } from "./cl-demo-ec2-construct";
35 | import { applyCfnNagSuppressRules, cfn_suppress_rules } from "./utils";
36 | import manifest from "./manifest.json";
37 |
38 | /**
39 | * @class
40 | * @description demo stack
41 | * @property {string} account id
42 | * @property {string} region of deployment
43 | */
44 | export class CLDemo extends NestedStack {
45 | readonly account: string;
46 | readonly region: string;
47 | /**
48 | * @constructor
49 | * @param {Construct} scope parent of the construct
50 | * @param {string} id unique identifier for the object
51 | * @param {NestedStackProps} props props for the construct
52 | */
53 | constructor(scope: Construct, id: string, props?: NestedStackProps) {
54 | super(scope, id, props);
55 | const stack = Stack.of(this);
56 |
57 | this.account = stack.account; // Returns the AWS::AccountId for this stack (or the literal value if known)
58 | this.region = stack.region; // Returns the AWS::Region for this stack (or the literal value if known)
59 |
60 | //=============================================================================================
61 | // Parameters
62 | //=============================================================================================
63 | /**
64 | * @description parameter for CW Logs Destination Arn
65 | * @type {CfnParameter}
66 | */
67 | const cwLogsDestinationArn: CfnParameter = new CfnParameter(
68 | this,
69 | "CWDestinationParm",
70 | {
71 | type: "String",
72 | }
73 | );
74 |
75 | //=============================================================================================
76 | // Metadata
77 | //=============================================================================================
78 | this.templateOptions.metadata = {
79 | "AWS::CloudFormation::Interface": {
80 | ParameterGroups: [
81 | {
82 | Label: { default: "Destination Configuration" },
83 | Parameters: [cwLogsDestinationArn.logicalId],
84 | },
85 | ],
86 | ParameterLabels: {
87 | [cwLogsDestinationArn.logicalId]: {
88 | default: "CloudWatch Logs Destination Arn for Log Streaming",
89 | },
90 | },
91 | },
92 | };
93 |
94 | this.templateOptions.description = `(${manifest.solutionId}D) - The AWS CloudFormation template for deployment of the ${manifest.solutionName}. Version ${manifest.solutionVersion}`;
95 | this.templateOptions.templateFormatVersion = manifest.templateVersion;
96 |
97 | //=============================================================================================
98 | // Map
99 | //=============================================================================================
100 | new CfnMapping(this, "EC2", {
101 | mapping: { Instance: { Type: "t3.micro" } },
102 | });
103 |
104 | new CfnMapping(this, "FilterPatternLookup", {
105 | mapping: {
106 | Common: {
107 | Pattern:
108 | "[host, ident, authuser, date, request, status, bytes, referrer, agent]",
109 | },
110 | CloudTrail: {
111 | Pattern: "",
112 | },
113 | FlowLogs: {
114 | Pattern:
115 | '[version, account_id, interface_id, srcaddr != "-", dstaddr != "-", srcport != "-", dstport != "-", protocol, packets, bytes, start, end, action, log_status]',
116 | },
117 | Lambda: {
118 | Pattern: '[timestamp=*Z, request_id="*-*", event]',
119 | },
120 | SpaceDelimited: {
121 | Pattern: "[]",
122 | },
123 | Other: {
124 | Pattern: "",
125 | },
126 | },
127 | });
128 |
129 | //=============================================================================================
130 | // Resources
131 | //=============================================================================================
132 |
133 | /**
134 | * @description demo vpc with 1 public subnet
135 | * @type {Vpc}
136 | */
137 | const demoVPC: Vpc = new Vpc(this, "DemoVPC", {
138 | cidr: "10.0.1.0/26", //NOSONAR
139 | natGateways: 0,
140 | vpnGateway: false,
141 | subnetConfiguration: [
142 | {
143 | cidrMask: 28,
144 | name: "PublicSubnet",
145 | subnetType: SubnetType.PUBLIC,
146 | },
147 | ],
148 | });
149 | demoVPC.applyRemovalPolicy(RemovalPolicy.DESTROY);
150 | demoVPC.publicSubnets.forEach((subnet) => {
151 | applyCfnNagSuppressRules(subnet.node.defaultChild as CfnResource, [
152 | cfn_suppress_rules.W33,
153 | ]);
154 | });
155 |
156 | //===================
157 | // FlowLog resources
158 | //===================
159 | /**
160 | * @description log group for VPC flow logs
161 | * @type {LogGroup}
162 | */
163 | const flowLg: LogGroup = new LogGroup(this, "VPCFlowLogGroup", {
164 | removalPolicy: RemovalPolicy.DESTROY,
165 | retention: RetentionDays.ONE_WEEK,
166 | });
167 |
168 | /**
169 | * @description iam role for flow logs
170 | * @type {Role}
171 | */
172 | const flowRole: Role = new Role(this, "flowRole", {
173 | assumedBy: new ServicePrincipal("vpc-flow-logs.amazonaws.com"),
174 | });
175 |
176 | /**
177 | * @description demo flow logs
178 | * @type {FlowLog}
179 | */
180 | new FlowLog(this, "DemoFlowLog", {
181 | resourceType: FlowLogResourceType.fromVpc(demoVPC),
182 | trafficType: FlowLogTrafficType.ALL,
183 | destination: FlowLogDestination.toCloudWatchLogs(flowLg, flowRole),
184 | });
185 |
186 | new CfnSubscriptionFilter(this, "FlowLogSubscription", {
187 | destinationArn: cwLogsDestinationArn.valueAsString,
188 | filterPattern: Fn.findInMap("FilterPatternLookup", "FlowLogs", "Pattern"),
189 | logGroupName: flowLg.logGroupName,
190 | });
191 |
192 | //====================
193 | // WebServer resources
194 | //====================
195 | /**
196 | * @description ec2 web server resources
197 | * @type {EC2Demo}
198 | */
199 | const ec2: EC2Demo = new EC2Demo(this, "WebServer", {
200 | destination: cwLogsDestinationArn.valueAsString,
201 | demoVpc: demoVPC,
202 | });
203 |
204 | //=====================
205 | // CloudTrail resources
206 | //=====================
207 | /**
208 | * @description log group for CloudTrail
209 | * @type {LogGroup}
210 | */
211 | const cloudtrailLg: LogGroup = new LogGroup(this, "CloudTrailLogGroup", {
212 | removalPolicy: RemovalPolicy.DESTROY,
213 | retention: RetentionDays.ONE_WEEK,
214 | });
215 |
216 | /**
217 | * @description bucket for CloudTrail
218 | * @type {Bucket}
219 | */
220 | const trailBucket: Bucket = new Bucket(this, "TrailBucket", { //NOSONAR
221 | encryption: BucketEncryption.S3_MANAGED,
222 | enforceSSL: true,
223 | blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
224 | });
225 | trailBucket.addToResourcePolicy(
226 | new PolicyStatement({
227 | effect: Effect.ALLOW,
228 | principals: [new ServicePrincipal("cloudtrail.amazonaws.com")],
229 | sid: "CloudTrailRead",
230 | actions: ["s3:GetBucketAcl"],
231 | resources: [trailBucket.bucketArn],
232 | })
233 | );
234 | trailBucket.addToResourcePolicy(
235 | new PolicyStatement({
236 | effect: Effect.ALLOW,
237 | principals: [new ServicePrincipal("cloudtrail.amazonaws.com")],
238 | sid: "CloudTrailWrite",
239 | actions: ["s3:PutObject"],
240 | resources: [`${trailBucket.bucketArn}/AWSLogs/${this.account}/*`],
241 | })
242 | );
243 |
244 | /**
245 | * @description demo trail
246 | * @type {Trail}
247 | */
248 | new Trail(this, "demoTrail", {
249 | bucket: trailBucket,
250 | cloudWatchLogGroup: cloudtrailLg,
251 | isMultiRegionTrail: false,
252 | sendToCloudWatchLogs: true,
253 | includeGlobalServiceEvents: true,
254 | });
255 |
256 | new CfnSubscriptionFilter(this, "CloudTrailSubscription", {
257 | destinationArn: cwLogsDestinationArn.valueAsString,
258 | filterPattern: Fn.findInMap(
259 | "FilterPatternLookup",
260 | "CloudTrail",
261 | "Pattern"
262 | ),
263 | logGroupName: cloudtrailLg.logGroupName,
264 | });
265 |
266 | //=============================================================================================
267 | // cfn_nag suppress rules
268 | //=============================================================================================
269 | applyCfnNagSuppressRules(trailBucket.node.defaultChild as CfnResource, [
270 | cfn_suppress_rules.W35,
271 | ]);
272 |
273 | applyCfnNagSuppressRules(flowLg.node.findChild("Resource") as CfnResource, [
274 | cfn_suppress_rules.W84,
275 | ]);
276 |
277 | applyCfnNagSuppressRules(
278 | cloudtrailLg.node.findChild("Resource") as CfnResource,
279 | [cfn_suppress_rules.W84]
280 | );
281 |
282 | //=============================================================================================
283 | // Output
284 | //=============================================================================================
285 | new CfnOutput(this, "Destination Arn", {
286 | description: "CloudWatch Logs destination arn",
287 | value: cwLogsDestinationArn.valueAsString,
288 | });
289 |
290 | new CfnOutput(this, "URL", {
291 | description: "URL for demo web server",
292 | value: `http://${ec2.publicIp}`,
293 | });
294 | }
295 | }
296 |
--------------------------------------------------------------------------------
/source/resources/lib/cl-jumpbox-construct.ts:
--------------------------------------------------------------------------------
1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | /**
5 | * @description
6 | * This is Jumpbox construct for Centralized Logging on AWS Solution
7 | * @author @aws-solutions
8 | */
9 |
10 | import { Stack, CfnCondition, CfnResource } from "aws-cdk-lib";
11 | import { Construct } from "constructs";
12 | import {
13 | Instance,
14 | InstanceType,
15 | MachineImage,
16 | WindowsVersion,
17 | Vpc,
18 | SecurityGroup,
19 | ISubnet,
20 | Port,
21 | Peer,
22 | } from "aws-cdk-lib/aws-ec2";
23 | import manifest from "./manifest.json";
24 | import { applyCfnNagSuppressRules, cfn_suppress_rules } from "./utils";
25 |
26 | interface IJumpbox {
27 | /**
28 | * @description vpc to launch jumpbox
29 | * @type {Vpc}
30 | */
31 | vpc: Vpc;
32 | /**
33 | * @description public subnets to launch jumpbox
34 | * @type {ISubnet[]}
35 | */
36 | subnets: ISubnet[];
37 | /**
38 | * @description ssh key for jumpbox
39 | * @type {string}
40 | */
41 | keyname: string;
42 | /**
43 | * @description deploy jumpbox
44 | * @type {CfnCondition}
45 | */
46 | deploy: CfnCondition;
47 | }
48 | /**
49 | * @class
50 | * @description web server resources construct
51 | * @property {string} region of deployment
52 | */
53 | export class Jumpbox extends Construct {
54 | readonly region: string;
55 | constructor(scope: Construct, id: string, props: IJumpbox) {
56 | super(scope, id);
57 |
58 | const stack = Stack.of(this);
59 |
60 | this.region = stack.region; // Returns the AWS::Region for this stack (or the literal value if known)
61 |
62 | //=========================================================================
63 | // Resource
64 | //=========================================================================
65 | /**
66 | * @description security group for jumpbox
67 | * @type {SecurityGroup}
68 | */
69 | const sg: SecurityGroup = new SecurityGroup(this, "JumpboxSG", {
70 | vpc: props.vpc,
71 | allowAllOutbound: false,
72 | });
73 | sg.addEgressRule(Peer.anyIpv4(), Port.tcp(80), "allow outbound https");
74 | sg.addEgressRule(Peer.anyIpv4(), Port.tcp(443), "allow outbound https");
75 | applyCfnNagSuppressRules(sg.node.defaultChild as CfnResource, [
76 | cfn_suppress_rules.W5,
77 | ]);
78 | (sg.node.defaultChild as CfnResource).cfnOptions.condition = props.deploy;
79 |
80 | /**
81 | * @description jumpbox instance
82 | * @type {Instance}
83 | */
84 | const jumpbox: Instance = new Instance(this, "JumpboxEC2", {
85 | vpc: props.vpc,
86 | instanceType: new InstanceType(manifest.jumpboxInstanceType),
87 | machineImage: MachineImage.latestWindows(
88 | WindowsVersion.WINDOWS_SERVER_2019_ENGLISH_FULL_BASE
89 | ),
90 | securityGroup: sg,
91 | vpcSubnets: { subnets: props.subnets },
92 | keyName: props.keyname,
93 | requireImdsv2: true,
94 | });
95 | (jumpbox.node.defaultChild as CfnResource).cfnOptions.condition =
96 | props.deploy;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/source/resources/lib/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "solutionId": "SO0009",
3 | "metricsEndpoint": "https://metrics.awssolutionsbuilder.com/generic",
4 | "solutionName": "%%SOLUTION_NAME%%",
5 | "templateVersion": "2010-09-09",
6 | "solutionVersion": "%%VERSION%%",
7 | "sendMetric": "Yes",
8 | "streamName": "CL-KinesisStream",
9 | "firehoseName": "CL-Firehose",
10 | "cwDestinationName": "CL-Destination",
11 | "firehosePolicy": "CL-Firehose-Policy",
12 | "jumpboxInstanceType": "t3.micro",
13 | "esdomain": {
14 | "vpcCIDR": "10.0.0.0/16",
15 | "masterNodes": 3
16 | },
17 | "kinesisDataStream": {
18 | "shard": 1,
19 | "retentionInHrs": 24
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/source/resources/lib/resource-retention-aspect.ts:
--------------------------------------------------------------------------------
1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | import { CfnResource, IAspect } from "aws-cdk-lib";
5 | import { IConstruct } from "constructs";
6 | import { applyRetentionPolicy } from "./utils";
7 |
8 | /**
9 | * @description cdk aspect to apply deletion policy
10 | */
11 | export class ResourceRetentionAspect implements IAspect {
12 | public visit(node: IConstruct) {
13 | if (node instanceof CfnResource) {
14 | applyRetentionPolicy(node);
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/source/resources/lib/utils.ts:
--------------------------------------------------------------------------------
1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | /**
5 | * @description
6 | * Utils for cdk constructs
7 | * @author @aws-solutions
8 | */
9 |
10 | import { Resource, CfnResource, RemovalPolicy } from "aws-cdk-lib";
11 |
12 | interface CfnNagSuppression {
13 | id: string;
14 | reason: string;
15 | }
16 |
17 | export function applyRetentionPolicy(resource: Resource | CfnResource) {
18 | if (resource) {
19 | if (resource instanceof Resource)
20 | resource = resource.node.defaultChild as CfnResource;
21 | resource.applyRemovalPolicy(RemovalPolicy.RETAIN);
22 | }
23 | }
24 |
25 | export function applyDependsOn(
26 | dependee: Resource | CfnResource,
27 | parent: Resource
28 | ) {
29 | if (dependee) {
30 | if (dependee instanceof Resource)
31 | dependee = dependee.node.defaultChild as CfnResource;
32 | dependee.addDependency(parent.node.defaultChild as CfnResource);
33 | }
34 | }
35 |
36 | export function applyCfnNagSuppressRules(
37 | resource: CfnResource,
38 | suppressions: CfnNagSuppression[]
39 | ) {
40 | let rules = [];
41 |
42 | if (suppressions instanceof Array)
43 | for (const suppression of suppressions) {
44 | rules.push({ id: suppression.id, reason: suppression.reason });
45 | }
46 |
47 | if (resource.cfnOptions.metadata?.cfn_nag) {
48 | // If the CfnResource already contains some suppressions, we don't want to erase them.
49 | const existingRules =
50 | resource.cfnOptions.metadata.cfn_nag.rules_to_suppress;
51 | rules = [...existingRules, ...rules];
52 | }
53 |
54 | // It's possible that multiple constructs try to add the same suppression.
55 | // We only keep one occurrence (last) of each.
56 | // Based on https://stackoverflow.com/a/56768137
57 | const uniqueRules = [
58 | ...new Map(rules.map((rule) => [rule.id, rule])).values(),
59 | ];
60 |
61 | resource.cfnOptions.metadata = {
62 | cfn_nag: {
63 | rules_to_suppress: uniqueRules,
64 | },
65 | };
66 | }
67 |
68 | /**
69 | * @description common cfn_nag suppress rules
70 | */
71 | export const cfn_suppress_rules: { [key: string]: CfnNagSuppression } = {
72 | W2: {
73 | id: "W2",
74 | reason: "Security group is a demo resource, allows CIDR open to world",
75 | },
76 | W5: {
77 | id: "W5",
78 | reason: "Security group allows outbound traffic for http[s]",
79 | },
80 | W9: {
81 | id: "W9",
82 | reason:
83 | "Security group is a demo web server, inbound access needed, CIDR not /32",
84 | },
85 | W11: {
86 | id: "W11",
87 | reason: "Cognito actions do not allow resource level permissions",
88 | },
89 | W12: {
90 | id: "W12",
91 | reason: "* needed, actions do no support resource level permissions",
92 | },
93 | W28: {
94 | id: "W28",
95 | reason: "OpenSearch service uses customer provided domain name",
96 | },
97 | W33: {
98 | id: "W33",
99 | reason: "Subnet allows public ip for jumpbox and demo web server",
100 | },
101 | W35: {
102 | id: "W35",
103 | reason:
104 | "Access logging disabled on the bucket as its a logging bucket or a demo resource",
105 | },
106 | W40: {
107 | id: "W40",
108 | reason:
109 | "Security group is a demo resource, egress with allow all IP Protocol",
110 | },
111 | W51: {
112 | id: "W51",
113 | reason: "Bucket allows permissions for log delivery",
114 | },
115 | W58: {
116 | id: "W58",
117 | reason:
118 | "CloudWatch logs write permissions added with managed role AWSLambdaBasicExecutionRole",
119 | },
120 | W76: {
121 | id: "W76",
122 | reason: "IAM policy verified",
123 | },
124 | W84: {
125 | id: "W84",
126 | reason:
127 | "Log group is encrypted using the CloudWatch server-side encryption keys (AWS Managed Keys)",
128 | },
129 | W89: {
130 | id: "W89",
131 | reason:
132 | "Not a valid use case for Lambda functions to be deployed inside a VPC",
133 | },
134 | W92: {
135 | id: "W92",
136 | reason: "Not a valid use case for Lambda reserved concurrency",
137 | },
138 | };
139 |
--------------------------------------------------------------------------------
/source/resources/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "centralized-logging",
3 | "version": "4.0.2",
4 | "license": "Apache-2.0",
5 | "bin": {
6 | "app": "bin/app.js"
7 | },
8 | "scripts": {
9 | "pretest": "npm ci",
10 | "test": "./node_modules/jest/bin/jest.js --coverage ./__tests__",
11 | "cdk-bootstrap": "./node_modules/aws-cdk/bin/cdk bootstrap",
12 | "cdk-deploy": "./node_modules/aws-cdk/bin/cdk deploy",
13 | "cdk-destroy": "./node_modules/aws-cdk/bin/cdk destroy",
14 | "cdk-synth": "./node_modules/aws-cdk/bin/cdk synth",
15 | "coverage": "npm ci && ./node_modules/jest/bin/jest.js --coverage ./__tests__"
16 | },
17 | "devDependencies": {
18 | "@aws-cdk/assert": "^2.68.0",
19 | "@types/jest": "^29.5.2",
20 | "@types/node": "^20.3.1",
21 | "aws-cdk": "^2.85.0",
22 | "jest": "^29.5.0",
23 | "jest-sonar-reporter": "^2.0.0",
24 | "ts-node": "^10.9.1",
25 | "ts-jest": "^29.0.5",
26 | "typescript": "^5.1.3"
27 | },
28 | "jestSonar": {
29 | "reportPath": "coverage",
30 | "reportFile": "cdk-resources-test-report.xml",
31 | "indent": 4
32 | },
33 | "overrides": {
34 | "semver": "^7.5.3"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/source/resources/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Basic Options */
4 | "target": "ES2018" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
5 | "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
6 | "lib": [
7 | "DOM",
8 | "ES2018"
9 | ] /* Specify library files to be included in the compilation. */,
10 | "declaration": false /* Generates corresponding '.d.ts' file. */,
11 | "noEmit": true,
12 | "outDir": "./dist",
13 | "types": ["jest", "node"],
14 | "removeComments": true /* Do not emit comments to output. */,
15 | "resolveJsonModule": true /* Allows importing modules with a ‘.json’ extension */,
16 | /* Strict Type-Checking Options */
17 | "strict": true /* Enable all strict type-checking options. */,
18 | "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
19 | "strictNullChecks": true /* Enable strict null checks. */,
20 | "strictFunctionTypes": true /* Enable strict checking of function types. */,
21 | "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */,
22 | "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */,
23 | "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */,
24 | /* Additional Checks */
25 | "noUnusedLocals": true /* Report errors on unused locals. */,
26 | "noUnusedParameters": true /* Report errors on unused parameters. */,
27 | "noImplicitReturns": true /* Report error when not all code paths in function return a value. */,
28 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */,
29 |
30 | /* Module Resolution Options */
31 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
32 |
33 | /* Experimental Options */
34 | "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */,
35 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
36 |
37 | /* Advanced Options */
38 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
39 | },
40 | "exclude": ["cdk.out", "node_modules"]
41 | }
42 |
--------------------------------------------------------------------------------
/source/run-unit-tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # This assumes all of the OS-level configuration has been completed and git repo has already been cloned
4 | #
5 | # This script should be run from the source directory
6 | # cd source
7 | # ./run-unit-tests.sh
8 | #
9 |
10 | ["$DEBUG" == 'true' ] && set -x
11 | set -e
12 |
13 | # Get reference for all important folders
14 | source_dir="$PWD"
15 | resource_dir="$source_dir/resources"
16 | services_dir="$source_dir/services"
17 |
18 | echo "------------------------------------------------------------------------------"
19 | echo "[Pre-Test] build binaries"
20 | echo "------------------------------------------------------------------------------"
21 | cd $services_dir/transformer
22 | npm run build:all
23 |
24 | cd $services_dir/helper
25 | npm run build:all
26 |
27 | echo "------------------------------------------------------------------------------"
28 | echo "[Test] Resources"
29 | echo "------------------------------------------------------------------------------"
30 | cd $resource_dir
31 | npm run test -- -u
32 |
33 | echo "------------------------------------------------------------------------------"
34 | echo "[Test] helper"
35 | echo "------------------------------------------------------------------------------"
36 | cd $services_dir/helper
37 | npm run test
38 |
39 | echo "------------------------------------------------------------------------------"
40 | echo "[Test] transformer"
41 | echo "------------------------------------------------------------------------------"
42 | cd $services_dir/transformer
43 | npm run test
44 |
45 |
--------------------------------------------------------------------------------
/source/services/@aws-solutions/utils/logger.ts:
--------------------------------------------------------------------------------
1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | // SPDX-License-Identifier: Apache-2.0
3 | /**
4 | * {
5 | emerg: 0,
6 | alert: 1,
7 | crit: 2,
8 | error: 3,
9 | warning: 4,
10 | notice: 5,
11 | info: 6,
12 | debug: 7
13 | }
14 | */
15 | import { createLogger, transports, format } from "winston";
16 | const { combine, timestamp, printf } = format;
17 |
18 | /*
19 | * Formatting the output as desired
20 | */
21 | const myFormat = printf(({ level, label, message }) => {
22 | const _level = level.toUpperCase();
23 | if (label) return `[${_level}] [${label}] ${message}`;
24 | else return `[${_level}] ${message}`;
25 | });
26 |
27 | export const logger = createLogger({
28 | format: combine(
29 | //
30 | // Order is important here, the formats are called in the
31 | // order they are passed to combine.
32 | //
33 | timestamp(),
34 | myFormat
35 | ),
36 |
37 | transports: [
38 | //cw logs transport channel
39 | new transports.Console({
40 | level: process.env.LOG_LEVEL,
41 | handleExceptions: true, //handle uncaught exceptions
42 | //format: format.splat()
43 | }),
44 | ],
45 | });
46 |
--------------------------------------------------------------------------------
/source/services/@aws-solutions/utils/metric.ts:
--------------------------------------------------------------------------------
1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | // SPDX-License-Identifier: Apache-2.0
3 | import got from "got";
4 | import { logger } from "./logger";
5 |
6 | const metricsEndpoint = process.env.METRICS_ENDPOINT;
7 | const awsRegion = process.env.AWS_REGION;
8 | const solutionId = process.env.SOLUTION_ID;
9 | const solutionVersion = process.env.SOLUTION_VERSION;
10 |
11 | export const sendDeploymentMetrics = async (
12 | properties: { [p: string]: string },
13 | requestType: string
14 | ): Promise<{ [key: string]: unknown }> => {
15 | logger.debug({
16 | label: "sendDeploymentMetrics",
17 | message: `Sending deployment metrics`,
18 | });
19 |
20 | const stack = process.env.STACK;
21 | const clusterSize = process.env.CLUSTER_SIZE;
22 |
23 | if (!stack || !clusterSize)
24 | throw new Error("Missing mandatory environment variable");
25 |
26 | const eventType = `Solution${requestType}`;
27 | const data = {
28 | Event: eventType,
29 | ClusterSize: clusterSize,
30 | Stack: stack,
31 | };
32 |
33 | // SolutionUuid cannot be passed as environment variable in this case,
34 | // because it is generated after deployment of the Lambda Function
35 | const uuid = properties.SolutionUuid;
36 | const metric = await sendToAwsSolutionsEngineeringTeam(uuid, data);
37 |
38 | return {
39 | Data: metric,
40 | };
41 | };
42 |
43 | export async function sendUsageMetrics(totalItemSize: number) {
44 | logger.info({
45 | label: "sendUsageMetrics",
46 | message: `Sending metrics for indexed data. totalItemSize: ${totalItemSize}`,
47 | });
48 | const data = {
49 | TotalItemSize: `${totalItemSize}`,
50 | };
51 |
52 | const uuid = process.env.UUID;
53 |
54 | await sendToAwsSolutionsEngineeringTeam(uuid, data);
55 | }
56 |
57 | async function sendToAwsSolutionsEngineeringTeam(
58 | uuid: string,
59 | data: { [p: string]: string }
60 | ) {
61 | const metric = {
62 | Solution: solutionId,
63 | UUID: uuid,
64 | TimeStamp: new Date().toISOString().replace("T", " ").replace("Z", ""), // Date and time instant in a java.sql.Timestamp compatible format,
65 | Data: {
66 | ...data,
67 | Version: solutionVersion,
68 | Region: awsRegion,
69 | },
70 | };
71 | try {
72 | await got(metricsEndpoint, {
73 | method: "POST",
74 | headers: {
75 | "Content-Type": "application/json",
76 | "Content-Length": "" + JSON.stringify(metric).length,
77 | },
78 | body: JSON.stringify(metric),
79 | });
80 | logger.debug(`Metric sent: ${JSON.stringify(metric)}`);
81 | } catch (error) {
82 | logger.error(
83 | `error occurred while sending metric: ${(error as Error).message}`
84 | );
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/source/services/@aws-solutions/utils/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "util",
3 | "version": "1.0.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "util",
9 | "version": "1.0.0",
10 | "license": "Apache-2.0",
11 | "dependencies": {
12 | "got": "11.8.5",
13 | "winston": "^3.8.1"
14 | },
15 | "devDependencies": {
16 | "@types/node": "^20.3.1",
17 | "ts-node": "^10.8.2",
18 | "typescript": "^5.1.3"
19 | }
20 | },
21 | "node_modules/@colors/colors": {
22 | "version": "1.6.0",
23 | "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz",
24 | "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==",
25 | "engines": {
26 | "node": ">=0.1.90"
27 | }
28 | },
29 | "node_modules/@cspotcode/source-map-support": {
30 | "version": "0.8.1",
31 | "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz",
32 | "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==",
33 | "dev": true,
34 | "dependencies": {
35 | "@jridgewell/trace-mapping": "0.3.9"
36 | },
37 | "engines": {
38 | "node": ">=12"
39 | }
40 | },
41 | "node_modules/@dabh/diagnostics": {
42 | "version": "2.0.3",
43 | "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz",
44 | "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==",
45 | "dependencies": {
46 | "colorspace": "1.1.x",
47 | "enabled": "2.0.x",
48 | "kuler": "^2.0.0"
49 | }
50 | },
51 | "node_modules/@jridgewell/resolve-uri": {
52 | "version": "3.1.1",
53 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
54 | "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
55 | "dev": true,
56 | "engines": {
57 | "node": ">=6.0.0"
58 | }
59 | },
60 | "node_modules/@jridgewell/sourcemap-codec": {
61 | "version": "1.4.15",
62 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
63 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
64 | "dev": true
65 | },
66 | "node_modules/@jridgewell/trace-mapping": {
67 | "version": "0.3.9",
68 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz",
69 | "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==",
70 | "dev": true,
71 | "dependencies": {
72 | "@jridgewell/resolve-uri": "^3.0.3",
73 | "@jridgewell/sourcemap-codec": "^1.4.10"
74 | }
75 | },
76 | "node_modules/@sindresorhus/is": {
77 | "version": "4.6.0",
78 | "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
79 | "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==",
80 | "engines": {
81 | "node": ">=10"
82 | },
83 | "funding": {
84 | "url": "https://github.com/sindresorhus/is?sponsor=1"
85 | }
86 | },
87 | "node_modules/@szmarczak/http-timer": {
88 | "version": "4.0.6",
89 | "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz",
90 | "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==",
91 | "dependencies": {
92 | "defer-to-connect": "^2.0.0"
93 | },
94 | "engines": {
95 | "node": ">=10"
96 | }
97 | },
98 | "node_modules/@tsconfig/node10": {
99 | "version": "1.0.9",
100 | "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz",
101 | "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==",
102 | "dev": true
103 | },
104 | "node_modules/@tsconfig/node12": {
105 | "version": "1.0.11",
106 | "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz",
107 | "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==",
108 | "dev": true
109 | },
110 | "node_modules/@tsconfig/node14": {
111 | "version": "1.0.3",
112 | "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz",
113 | "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==",
114 | "dev": true
115 | },
116 | "node_modules/@tsconfig/node16": {
117 | "version": "1.0.4",
118 | "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz",
119 | "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==",
120 | "dev": true
121 | },
122 | "node_modules/@types/cacheable-request": {
123 | "version": "6.0.3",
124 | "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz",
125 | "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==",
126 | "dependencies": {
127 | "@types/http-cache-semantics": "*",
128 | "@types/keyv": "^3.1.4",
129 | "@types/node": "*",
130 | "@types/responselike": "^1.0.0"
131 | }
132 | },
133 | "node_modules/@types/http-cache-semantics": {
134 | "version": "4.0.3",
135 | "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz",
136 | "integrity": "sha512-V46MYLFp08Wf2mmaBhvgjStM3tPa+2GAdy/iqoX+noX1//zje2x4XmrIU0cAwyClATsTmahbtoQ2EwP7I5WSiA=="
137 | },
138 | "node_modules/@types/keyv": {
139 | "version": "3.1.4",
140 | "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz",
141 | "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==",
142 | "dependencies": {
143 | "@types/node": "*"
144 | }
145 | },
146 | "node_modules/@types/node": {
147 | "version": "20.8.7",
148 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.7.tgz",
149 | "integrity": "sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==",
150 | "dependencies": {
151 | "undici-types": "~5.25.1"
152 | }
153 | },
154 | "node_modules/@types/responselike": {
155 | "version": "1.0.2",
156 | "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.2.tgz",
157 | "integrity": "sha512-/4YQT5Kp6HxUDb4yhRkm0bJ7TbjvTddqX7PZ5hz6qV3pxSo72f/6YPRo+Mu2DU307tm9IioO69l7uAwn5XNcFA==",
158 | "dependencies": {
159 | "@types/node": "*"
160 | }
161 | },
162 | "node_modules/@types/triple-beam": {
163 | "version": "1.3.4",
164 | "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.4.tgz",
165 | "integrity": "sha512-HlJjF3wxV4R2VQkFpKe0YqJLilYNgtRtsqqZtby7RkVsSs+i+vbyzjtUwpFEdUCKcrGzCiEJE7F/0mKjh0sunA=="
166 | },
167 | "node_modules/acorn": {
168 | "version": "8.10.0",
169 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
170 | "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
171 | "dev": true,
172 | "bin": {
173 | "acorn": "bin/acorn"
174 | },
175 | "engines": {
176 | "node": ">=0.4.0"
177 | }
178 | },
179 | "node_modules/acorn-walk": {
180 | "version": "8.2.0",
181 | "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
182 | "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
183 | "dev": true,
184 | "engines": {
185 | "node": ">=0.4.0"
186 | }
187 | },
188 | "node_modules/arg": {
189 | "version": "4.1.3",
190 | "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz",
191 | "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==",
192 | "dev": true
193 | },
194 | "node_modules/async": {
195 | "version": "3.2.4",
196 | "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz",
197 | "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ=="
198 | },
199 | "node_modules/cacheable-lookup": {
200 | "version": "5.0.4",
201 | "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz",
202 | "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==",
203 | "engines": {
204 | "node": ">=10.6.0"
205 | }
206 | },
207 | "node_modules/cacheable-request": {
208 | "version": "7.0.4",
209 | "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz",
210 | "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==",
211 | "dependencies": {
212 | "clone-response": "^1.0.2",
213 | "get-stream": "^5.1.0",
214 | "http-cache-semantics": "^4.0.0",
215 | "keyv": "^4.0.0",
216 | "lowercase-keys": "^2.0.0",
217 | "normalize-url": "^6.0.1",
218 | "responselike": "^2.0.0"
219 | },
220 | "engines": {
221 | "node": ">=8"
222 | }
223 | },
224 | "node_modules/clone-response": {
225 | "version": "1.0.3",
226 | "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz",
227 | "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==",
228 | "dependencies": {
229 | "mimic-response": "^1.0.0"
230 | },
231 | "funding": {
232 | "url": "https://github.com/sponsors/sindresorhus"
233 | }
234 | },
235 | "node_modules/color": {
236 | "version": "3.2.1",
237 | "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz",
238 | "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==",
239 | "dependencies": {
240 | "color-convert": "^1.9.3",
241 | "color-string": "^1.6.0"
242 | }
243 | },
244 | "node_modules/color-convert": {
245 | "version": "1.9.3",
246 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
247 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
248 | "dependencies": {
249 | "color-name": "1.1.3"
250 | }
251 | },
252 | "node_modules/color-name": {
253 | "version": "1.1.3",
254 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
255 | "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
256 | },
257 | "node_modules/color-string": {
258 | "version": "1.9.1",
259 | "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz",
260 | "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==",
261 | "dependencies": {
262 | "color-name": "^1.0.0",
263 | "simple-swizzle": "^0.2.2"
264 | }
265 | },
266 | "node_modules/colorspace": {
267 | "version": "1.1.4",
268 | "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz",
269 | "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==",
270 | "dependencies": {
271 | "color": "^3.1.3",
272 | "text-hex": "1.0.x"
273 | }
274 | },
275 | "node_modules/create-require": {
276 | "version": "1.1.1",
277 | "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
278 | "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
279 | "dev": true
280 | },
281 | "node_modules/decompress-response": {
282 | "version": "6.0.0",
283 | "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
284 | "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
285 | "dependencies": {
286 | "mimic-response": "^3.1.0"
287 | },
288 | "engines": {
289 | "node": ">=10"
290 | },
291 | "funding": {
292 | "url": "https://github.com/sponsors/sindresorhus"
293 | }
294 | },
295 | "node_modules/decompress-response/node_modules/mimic-response": {
296 | "version": "3.1.0",
297 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
298 | "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
299 | "engines": {
300 | "node": ">=10"
301 | },
302 | "funding": {
303 | "url": "https://github.com/sponsors/sindresorhus"
304 | }
305 | },
306 | "node_modules/defer-to-connect": {
307 | "version": "2.0.1",
308 | "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
309 | "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==",
310 | "engines": {
311 | "node": ">=10"
312 | }
313 | },
314 | "node_modules/diff": {
315 | "version": "4.0.2",
316 | "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
317 | "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
318 | "dev": true,
319 | "engines": {
320 | "node": ">=0.3.1"
321 | }
322 | },
323 | "node_modules/enabled": {
324 | "version": "2.0.0",
325 | "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz",
326 | "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ=="
327 | },
328 | "node_modules/end-of-stream": {
329 | "version": "1.4.4",
330 | "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
331 | "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
332 | "dependencies": {
333 | "once": "^1.4.0"
334 | }
335 | },
336 | "node_modules/fecha": {
337 | "version": "4.2.3",
338 | "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz",
339 | "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw=="
340 | },
341 | "node_modules/fn.name": {
342 | "version": "1.1.0",
343 | "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz",
344 | "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw=="
345 | },
346 | "node_modules/get-stream": {
347 | "version": "5.2.0",
348 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
349 | "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
350 | "dependencies": {
351 | "pump": "^3.0.0"
352 | },
353 | "engines": {
354 | "node": ">=8"
355 | },
356 | "funding": {
357 | "url": "https://github.com/sponsors/sindresorhus"
358 | }
359 | },
360 | "node_modules/got": {
361 | "version": "11.8.5",
362 | "resolved": "https://registry.npmjs.org/got/-/got-11.8.5.tgz",
363 | "integrity": "sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==",
364 | "dependencies": {
365 | "@sindresorhus/is": "^4.0.0",
366 | "@szmarczak/http-timer": "^4.0.5",
367 | "@types/cacheable-request": "^6.0.1",
368 | "@types/responselike": "^1.0.0",
369 | "cacheable-lookup": "^5.0.3",
370 | "cacheable-request": "^7.0.2",
371 | "decompress-response": "^6.0.0",
372 | "http2-wrapper": "^1.0.0-beta.5.2",
373 | "lowercase-keys": "^2.0.0",
374 | "p-cancelable": "^2.0.0",
375 | "responselike": "^2.0.0"
376 | },
377 | "engines": {
378 | "node": ">=10.19.0"
379 | },
380 | "funding": {
381 | "url": "https://github.com/sindresorhus/got?sponsor=1"
382 | }
383 | },
384 | "node_modules/http-cache-semantics": {
385 | "version": "4.1.1",
386 | "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
387 | "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ=="
388 | },
389 | "node_modules/http2-wrapper": {
390 | "version": "1.0.3",
391 | "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz",
392 | "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==",
393 | "dependencies": {
394 | "quick-lru": "^5.1.1",
395 | "resolve-alpn": "^1.0.0"
396 | },
397 | "engines": {
398 | "node": ">=10.19.0"
399 | }
400 | },
401 | "node_modules/inherits": {
402 | "version": "2.0.4",
403 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
404 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
405 | },
406 | "node_modules/is-arrayish": {
407 | "version": "0.3.2",
408 | "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
409 | "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="
410 | },
411 | "node_modules/is-stream": {
412 | "version": "2.0.1",
413 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
414 | "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
415 | "engines": {
416 | "node": ">=8"
417 | },
418 | "funding": {
419 | "url": "https://github.com/sponsors/sindresorhus"
420 | }
421 | },
422 | "node_modules/json-buffer": {
423 | "version": "3.0.1",
424 | "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
425 | "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
426 | },
427 | "node_modules/keyv": {
428 | "version": "4.5.4",
429 | "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
430 | "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
431 | "dependencies": {
432 | "json-buffer": "3.0.1"
433 | }
434 | },
435 | "node_modules/kuler": {
436 | "version": "2.0.0",
437 | "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz",
438 | "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A=="
439 | },
440 | "node_modules/logform": {
441 | "version": "2.6.0",
442 | "resolved": "https://registry.npmjs.org/logform/-/logform-2.6.0.tgz",
443 | "integrity": "sha512-1ulHeNPp6k/LD8H91o7VYFBng5i1BDE7HoKxVbZiGFidS1Rj65qcywLxX+pVfAPoQJEjRdvKcusKwOupHCVOVQ==",
444 | "dependencies": {
445 | "@colors/colors": "1.6.0",
446 | "@types/triple-beam": "^1.3.2",
447 | "fecha": "^4.2.0",
448 | "ms": "^2.1.1",
449 | "safe-stable-stringify": "^2.3.1",
450 | "triple-beam": "^1.3.0"
451 | },
452 | "engines": {
453 | "node": ">= 12.0.0"
454 | }
455 | },
456 | "node_modules/lowercase-keys": {
457 | "version": "2.0.0",
458 | "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
459 | "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
460 | "engines": {
461 | "node": ">=8"
462 | }
463 | },
464 | "node_modules/make-error": {
465 | "version": "1.3.6",
466 | "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz",
467 | "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==",
468 | "dev": true
469 | },
470 | "node_modules/mimic-response": {
471 | "version": "1.0.1",
472 | "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
473 | "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
474 | "engines": {
475 | "node": ">=4"
476 | }
477 | },
478 | "node_modules/ms": {
479 | "version": "2.1.3",
480 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
481 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
482 | },
483 | "node_modules/normalize-url": {
484 | "version": "6.1.0",
485 | "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz",
486 | "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==",
487 | "engines": {
488 | "node": ">=10"
489 | },
490 | "funding": {
491 | "url": "https://github.com/sponsors/sindresorhus"
492 | }
493 | },
494 | "node_modules/once": {
495 | "version": "1.4.0",
496 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
497 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
498 | "dependencies": {
499 | "wrappy": "1"
500 | }
501 | },
502 | "node_modules/one-time": {
503 | "version": "1.0.0",
504 | "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz",
505 | "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==",
506 | "dependencies": {
507 | "fn.name": "1.x.x"
508 | }
509 | },
510 | "node_modules/p-cancelable": {
511 | "version": "2.1.1",
512 | "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz",
513 | "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==",
514 | "engines": {
515 | "node": ">=8"
516 | }
517 | },
518 | "node_modules/pump": {
519 | "version": "3.0.0",
520 | "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
521 | "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
522 | "dependencies": {
523 | "end-of-stream": "^1.1.0",
524 | "once": "^1.3.1"
525 | }
526 | },
527 | "node_modules/quick-lru": {
528 | "version": "5.1.1",
529 | "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz",
530 | "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==",
531 | "engines": {
532 | "node": ">=10"
533 | },
534 | "funding": {
535 | "url": "https://github.com/sponsors/sindresorhus"
536 | }
537 | },
538 | "node_modules/readable-stream": {
539 | "version": "3.6.2",
540 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
541 | "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
542 | "dependencies": {
543 | "inherits": "^2.0.3",
544 | "string_decoder": "^1.1.1",
545 | "util-deprecate": "^1.0.1"
546 | },
547 | "engines": {
548 | "node": ">= 6"
549 | }
550 | },
551 | "node_modules/resolve-alpn": {
552 | "version": "1.2.1",
553 | "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz",
554 | "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g=="
555 | },
556 | "node_modules/responselike": {
557 | "version": "2.0.1",
558 | "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz",
559 | "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==",
560 | "dependencies": {
561 | "lowercase-keys": "^2.0.0"
562 | },
563 | "funding": {
564 | "url": "https://github.com/sponsors/sindresorhus"
565 | }
566 | },
567 | "node_modules/safe-buffer": {
568 | "version": "5.2.1",
569 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
570 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
571 | "funding": [
572 | {
573 | "type": "github",
574 | "url": "https://github.com/sponsors/feross"
575 | },
576 | {
577 | "type": "patreon",
578 | "url": "https://www.patreon.com/feross"
579 | },
580 | {
581 | "type": "consulting",
582 | "url": "https://feross.org/support"
583 | }
584 | ]
585 | },
586 | "node_modules/safe-stable-stringify": {
587 | "version": "2.4.3",
588 | "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz",
589 | "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==",
590 | "engines": {
591 | "node": ">=10"
592 | }
593 | },
594 | "node_modules/simple-swizzle": {
595 | "version": "0.2.2",
596 | "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
597 | "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==",
598 | "dependencies": {
599 | "is-arrayish": "^0.3.1"
600 | }
601 | },
602 | "node_modules/stack-trace": {
603 | "version": "0.0.10",
604 | "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
605 | "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==",
606 | "engines": {
607 | "node": "*"
608 | }
609 | },
610 | "node_modules/string_decoder": {
611 | "version": "1.3.0",
612 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
613 | "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
614 | "dependencies": {
615 | "safe-buffer": "~5.2.0"
616 | }
617 | },
618 | "node_modules/text-hex": {
619 | "version": "1.0.0",
620 | "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz",
621 | "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg=="
622 | },
623 | "node_modules/triple-beam": {
624 | "version": "1.4.1",
625 | "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz",
626 | "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==",
627 | "engines": {
628 | "node": ">= 14.0.0"
629 | }
630 | },
631 | "node_modules/ts-node": {
632 | "version": "10.9.1",
633 | "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz",
634 | "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==",
635 | "dev": true,
636 | "dependencies": {
637 | "@cspotcode/source-map-support": "^0.8.0",
638 | "@tsconfig/node10": "^1.0.7",
639 | "@tsconfig/node12": "^1.0.7",
640 | "@tsconfig/node14": "^1.0.0",
641 | "@tsconfig/node16": "^1.0.2",
642 | "acorn": "^8.4.1",
643 | "acorn-walk": "^8.1.1",
644 | "arg": "^4.1.0",
645 | "create-require": "^1.1.0",
646 | "diff": "^4.0.1",
647 | "make-error": "^1.1.1",
648 | "v8-compile-cache-lib": "^3.0.1",
649 | "yn": "3.1.1"
650 | },
651 | "bin": {
652 | "ts-node": "dist/bin.js",
653 | "ts-node-cwd": "dist/bin-cwd.js",
654 | "ts-node-esm": "dist/bin-esm.js",
655 | "ts-node-script": "dist/bin-script.js",
656 | "ts-node-transpile-only": "dist/bin-transpile.js",
657 | "ts-script": "dist/bin-script-deprecated.js"
658 | },
659 | "peerDependencies": {
660 | "@swc/core": ">=1.2.50",
661 | "@swc/wasm": ">=1.2.50",
662 | "@types/node": "*",
663 | "typescript": ">=2.7"
664 | },
665 | "peerDependenciesMeta": {
666 | "@swc/core": {
667 | "optional": true
668 | },
669 | "@swc/wasm": {
670 | "optional": true
671 | }
672 | }
673 | },
674 | "node_modules/typescript": {
675 | "version": "5.2.2",
676 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
677 | "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
678 | "dev": true,
679 | "bin": {
680 | "tsc": "bin/tsc",
681 | "tsserver": "bin/tsserver"
682 | },
683 | "engines": {
684 | "node": ">=14.17"
685 | }
686 | },
687 | "node_modules/undici-types": {
688 | "version": "5.25.3",
689 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz",
690 | "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA=="
691 | },
692 | "node_modules/util-deprecate": {
693 | "version": "1.0.2",
694 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
695 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
696 | },
697 | "node_modules/v8-compile-cache-lib": {
698 | "version": "3.0.1",
699 | "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz",
700 | "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==",
701 | "dev": true
702 | },
703 | "node_modules/winston": {
704 | "version": "3.11.0",
705 | "resolved": "https://registry.npmjs.org/winston/-/winston-3.11.0.tgz",
706 | "integrity": "sha512-L3yR6/MzZAOl0DsysUXHVjOwv8mKZ71TrA/41EIduGpOOV5LQVodqN+QdQ6BS6PJ/RdIshZhq84P/fStEZkk7g==",
707 | "dependencies": {
708 | "@colors/colors": "^1.6.0",
709 | "@dabh/diagnostics": "^2.0.2",
710 | "async": "^3.2.3",
711 | "is-stream": "^2.0.0",
712 | "logform": "^2.4.0",
713 | "one-time": "^1.0.0",
714 | "readable-stream": "^3.4.0",
715 | "safe-stable-stringify": "^2.3.1",
716 | "stack-trace": "0.0.x",
717 | "triple-beam": "^1.3.0",
718 | "winston-transport": "^4.5.0"
719 | },
720 | "engines": {
721 | "node": ">= 12.0.0"
722 | }
723 | },
724 | "node_modules/winston-transport": {
725 | "version": "4.6.0",
726 | "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.6.0.tgz",
727 | "integrity": "sha512-wbBA9PbPAHxKiygo7ub7BYRiKxms0tpfU2ljtWzb3SjRjv5yl6Ozuy/TkXf00HTAt+Uylo3gSkNwzc4ME0wiIg==",
728 | "dependencies": {
729 | "logform": "^2.3.2",
730 | "readable-stream": "^3.6.0",
731 | "triple-beam": "^1.3.0"
732 | },
733 | "engines": {
734 | "node": ">= 12.0.0"
735 | }
736 | },
737 | "node_modules/wrappy": {
738 | "version": "1.0.2",
739 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
740 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
741 | },
742 | "node_modules/yn": {
743 | "version": "3.1.1",
744 | "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz",
745 | "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==",
746 | "dev": true,
747 | "engines": {
748 | "node": ">=6"
749 | }
750 | }
751 | }
752 | }
753 |
--------------------------------------------------------------------------------
/source/services/@aws-solutions/utils/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "util",
3 | "version": "1.0.0",
4 | "description": "utility for aws-solutions",
5 | "license": "Apache-2.0",
6 | "scripts": {
7 | "build:ts": "npx tsc --project ./tsconfig.json"
8 | },
9 | "dependencies": {
10 | "got": "11.8.5",
11 | "winston": "^3.8.1"
12 | },
13 | "devDependencies": {
14 | "ts-node": "^10.8.2",
15 | "typescript": "^5.1.3",
16 | "@types/node": "^20.3.1"
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/source/services/@aws-solutions/utils/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "noEmit": false
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/source/services/helper/PromiseConstructor.d.ts:
--------------------------------------------------------------------------------
1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | // SPDX-License-Identifier: Apache-2.0
3 | export interface PromiseResolution {
4 | status: "fulfilled";
5 | value: T;
6 | }
7 |
8 | export interface PromiseRejection {
9 | status: "rejected";
10 | reason: E;
11 | }
12 |
13 | export type PromiseResult =
14 | | PromiseResolution
15 | | PromiseRejection;
16 |
17 | export type PromiseList = {
18 | [P in keyof T]: Promise;
19 | };
20 |
21 | export type PromiseResultList = {
22 | [P in keyof T]: PromiseResult;
23 | };
24 |
25 | declare global {
26 | interface PromiseConstructor {
27 | allSettled(): Promise<[]>;
28 | allSettled(
29 | list: PromiseList
30 | ): Promise>;
31 | allSettled(iterable: Iterable): Promise>>;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/source/services/helper/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | // SPDX-License-Identifier: Apache-2.0
3 | import { v4 as uuidv4 } from "uuid";
4 | import { logger } from "logger";
5 | import { CloudWatchLogs, EC2, IAM } from "aws-sdk";
6 | import {
7 | Context,
8 | CloudFormationCustomResourceEvent,
9 | CloudFormationCustomResourceUpdateEvent,
10 | } from "aws-lambda";
11 | import { sendDeploymentMetrics } from "metric";
12 |
13 | const awsClients = {
14 | ec2: "2016-11-15",
15 | cwLogs: "2014-03-28",
16 | iam: "2010-05-08",
17 | };
18 |
19 | interface IResponse {
20 | responseData: { [key: string]: unknown };
21 | status: string;
22 | }
23 |
24 | export const handler = async (
25 | event: CloudFormationCustomResourceEvent,
26 | context: Context
27 | ) => {
28 | logger.debug({
29 | label: "helper",
30 | message: `received event: ${JSON.stringify(event)}`,
31 | });
32 |
33 | const properties = event.ResourceProperties;
34 |
35 | /**
36 | * handle UUID
37 | */
38 | if (
39 | event.ResourceType === "Custom::CreateUUID" &&
40 | event.RequestType === "Create"
41 | ) {
42 | const { responseData, status } = createUUID();
43 | return responseBody(event, context.logStreamName, status, responseData);
44 | }
45 |
46 | /**
47 | * handle ES Service role
48 | */
49 | if (
50 | event.ResourceType === "Custom::CreateESServiceRole" &&
51 | event.RequestType === "Create"
52 | ) {
53 | const { responseData, status } = await createESRole();
54 | return responseBody(event, context.logStreamName, status, responseData);
55 | }
56 |
57 | /**
58 | * handle launch data
59 | */
60 | if (
61 | event.ResourceType === "Custom::LaunchData" &&
62 | process.env.SEND_METRIC === "Yes"
63 | ) {
64 | const responseData = await sendDeploymentMetrics(
65 | properties,
66 | event.RequestType
67 | );
68 | return responseBody(event, context.logStreamName, "SUCCESS", responseData);
69 | }
70 |
71 | /**
72 | * handle CW destinations
73 | */
74 | if (event.ResourceType === "Custom::CWDestination") {
75 | const { responseData, status } = await crudDestinations(
76 | properties,
77 | event.RequestType
78 | );
79 | return responseBody(event, context.logStreamName, status, responseData);
80 | }
81 |
82 | /**
83 | * default
84 | */
85 | // send response to custom resource
86 | return responseBody(event, context.logStreamName, "SUCCESS", {
87 | Data: "no data",
88 | });
89 | };
90 |
91 | /**
92 | * @description create UUID for customer deployment
93 | * @returns
94 | */
95 | const createUUID = (): IResponse => {
96 | const responseData = { UUID: uuidv4() };
97 | const status = "SUCCESS";
98 | logger.info({
99 | label: "helper/createUUID",
100 | message: `uuid create: ${responseData.UUID}`,
101 | });
102 | return { responseData, status };
103 | };
104 |
105 | /**
106 | * @description create ES service linked role
107 | * @returns
108 | */
109 |
110 | const createESRole = async (): Promise => {
111 | const iam = new IAM({
112 | apiVersion: awsClients.iam,
113 | customUserAgent: process.env.CUSTOM_SDK_USER_AGENT,
114 | });
115 |
116 | let responseData: {
117 | [key: string]: string;
118 | } = { Data: "no data" };
119 | let status = "SUCCESS";
120 |
121 | await iam
122 | .createServiceLinkedRole({ AWSServiceName: "es.amazonaws.com" })
123 | .promise()
124 | .catch((e) => {
125 | logger.error({
126 | label: "helper/createESRole",
127 | message: e,
128 | });
129 | if ((e as Error).name !== "InvalidInput") {
130 | // InvalidInput ES service linked role already exists
131 | responseData = {
132 | Error:
133 | "failed to create ES service linked role, please see in cw logs for more details",
134 | };
135 | status = "FAILED";
136 | }
137 | return { responseData, status };
138 | });
139 | logger.info({
140 | label: "helper/createESRole",
141 | message: `es service linked role created`,
142 | });
143 | return { responseData, status };
144 | };
145 |
146 | /**
147 | * @description crud for cw destinations
148 | * @returns
149 | */
150 | const crudDestinations = async (
151 | properties: any,
152 | requestType: string
153 | ): Promise => {
154 | let responseData: {
155 | [key: string]: string;
156 | } = { Data: "no data" };
157 | let status = "SUCCESS";
158 | try {
159 | const allRegions = await getRegions();
160 |
161 | // delete destinations
162 | if (requestType === "Delete")
163 | await deleteDestination(properties.DestinationName, allRegions);
164 | // create/update destinations
165 | else {
166 | let spokeRegions = properties.Regions;
167 | logger.debug({
168 | label: "helper/CWDestination",
169 | message: `Regions to ${requestType} CloudWatch destinations: ${spokeRegions}`,
170 | });
171 | if (spokeRegions[0] === "All") {
172 | spokeRegions = allRegions;
173 | }
174 | await putDestination(
175 | spokeRegions,
176 | allRegions,
177 | properties.DestinationName,
178 | properties.Role,
179 | properties.DataStream,
180 | properties.SpokeAccounts
181 | );
182 | }
183 | } catch (e) {
184 | logger.error({
185 | label: "helper/CWDestination",
186 | message: e,
187 | });
188 | responseData = {
189 | Error: `failed to ${requestType} CW destinations, please see in cw logs for more details`,
190 | };
191 | status = "FAILED";
192 | }
193 | return { responseData, status };
194 | };
195 |
196 | /**
197 | * @description get list of ec2 regions
198 | */
199 | async function getRegions(): Promise {
200 | logger.info({
201 | label: "helper/getRegions",
202 | message: `getting ec2 regions`,
203 | });
204 | try {
205 | const ec2 = new EC2({
206 | apiVersion: awsClients.ec2,
207 | customUserAgent: process.env.CUSTOM_SDK_USER_AGENT,
208 | });
209 | const _r = await ec2.describeRegions().promise();
210 | if (!_r.Regions) throw new Error("failed to describe regions");
211 |
212 | const regions = _r.Regions.map((region) => {
213 | return region.RegionName;
214 | });
215 | logger.debug({
216 | label: "helper/getRegions",
217 | message: `${JSON.stringify({ regions: regions })}`,
218 | });
219 | return regions;
220 | } catch (e) {
221 | logger.error({
222 | label: "helper/getRegions",
223 | message: e,
224 | });
225 | throw new Error("error in getting regions");
226 | }
227 | }
228 |
229 | /**
230 | * @description create cw destinations
231 | * @param {string[]} regions - regions for spokes
232 | * @param {string} destinationName - cw logs destination name
233 | * @param {string} roleArn - ARN of IAM role that grants CloudWatch Logs permissions to call the Amazon Kinesis PutRecord operation on the destination stream
234 | * @param {string} kinesisStreamArn - The ARN of an Amazon Kinesis stream to which to deliver matching log events
235 | * @param {string[]} spokeAccnts - list of spoke account ids
236 | */
237 | async function putDestination(
238 | regions: string[],
239 | awsRegions: string[],
240 | destinationName: string,
241 | roleArn: string,
242 | kinesisStreamArn: string,
243 | spokeAccnts: string[]
244 | ) {
245 | logger.info({
246 | label: "helper/putDestination",
247 | message: `putting cw logs destinations for spokes`,
248 | });
249 | try {
250 | // check if provided region list is valid
251 | const regionValid = await areRegionsValid(regions, awsRegions);
252 | if (regionValid) {
253 | await deleteDestination(destinationName, regions);
254 | await Promise.all(
255 | regions.map(async (region) => {
256 | logger.debug({
257 | label: "helper/putDestination",
258 | message: `creating cw logs destination in ${region}`,
259 | });
260 |
261 | const cwLogs = new CloudWatchLogs({
262 | apiVersion: awsClients.cwLogs,
263 | region: region,
264 | customUserAgent: process.env.CUSTOM_SDK_USER_AGENT,
265 | });
266 |
267 | //put destination
268 | const dest: CloudWatchLogs.PutDestinationResponse = await cwLogs
269 | .putDestination({
270 | destinationName: destinationName,
271 | roleArn: roleArn,
272 | targetArn: kinesisStreamArn,
273 | })
274 | .promise();
275 |
276 | // put access policy
277 | const accessPolicy = {
278 | Version: "2012-10-17",
279 | Statement: [
280 | {
281 | Sid: "AllowSpokesSubscribe",
282 | Effect: "Allow",
283 | Principal: {
284 | AWS: spokeAccnts,
285 | },
286 | Action: "logs:PutSubscriptionFilter",
287 | Resource: dest.destination?.arn,
288 | },
289 | ],
290 | };
291 | await cwLogs
292 | .putDestinationPolicy({
293 | destinationName: destinationName,
294 | accessPolicy: JSON.stringify(accessPolicy), // for spoke accounts as principals
295 | })
296 | .promise();
297 | logger.debug({
298 | label: "helper/putDestinations",
299 | message: `cw logs destination created in ${region}`,
300 | });
301 | })
302 | );
303 | logger.info({
304 | label: "helper/putDestinations",
305 | message: `All cw logs destinations created`,
306 | });
307 | } else {
308 | throw new Error("invalid regions");
309 | }
310 | } catch (e) {
311 | logger.error({
312 | label: "helper/putDestination",
313 | message: e,
314 | });
315 | throw new Error("error in creating cw log destination");
316 | }
317 | }
318 |
319 | /**
320 | * @description delete cw destinations
321 | * @param {string} destinationName - cw logs destination name
322 | */
323 | async function deleteDestination(destinationName: string, regions: string[]) {
324 | logger.info({
325 | label: "helper/deleteDestination",
326 | message: `deleting cw logs destinations `,
327 | });
328 | await Promise.allSettled(
329 | regions.map(async (region) => {
330 | const cwLogs = new CloudWatchLogs({
331 | apiVersion: awsClients.cwLogs,
332 | region: region,
333 | customUserAgent: process.env.CUSTOM_SDK_USER_AGENT,
334 | });
335 | await cwLogs
336 | .deleteDestination({ destinationName: destinationName })
337 | .promise()
338 | .then(() => {
339 | logger.debug({
340 | label: "helper/deleteDestination",
341 | message: `cw logs destination deleted in ${region}`,
342 | });
343 | })
344 | .catch((e) => {
345 | logger.warn({
346 | label: `helper/deleteDestination`,
347 | message: `${region}: ${(e as Error).message}`,
348 | });
349 | });
350 | })
351 | );
352 | logger.info({
353 | label: "helper/deleteDestinations",
354 | message: `All cw logs destinations deleted`,
355 | });
356 | }
357 |
358 | /**
359 | * @description check if region list is valid
360 | * @param {string[]} regions - region list for spokes
361 | */
362 | async function areRegionsValid(regions: string[], awsRegions: string[]) {
363 | logger.debug({
364 | label: "helper/areRegionsValid",
365 | message: `checking if region parameter is valid`,
366 | });
367 |
368 | if (!(awsRegions instanceof Array)) throw new Error("no regions found");
369 | try {
370 | await Promise.all(
371 | regions.map((region) => {
372 | if (!awsRegions.includes(region))
373 | throw new Error("invalid region provided");
374 | })
375 | );
376 | return true;
377 | } catch (e) {
378 | logger.error({
379 | label: "helper/areRegionsValid",
380 | message: `${(e as Error).message}`,
381 | });
382 | return false;
383 | }
384 | }
385 |
386 | const responseBody = async (
387 | event: CloudFormationCustomResourceEvent,
388 | logStreamName: string,
389 | responseStatus: string,
390 | responseData: any
391 | ) => {
392 | const responseBody = {
393 | Status: responseStatus,
394 | Reason: `${JSON.stringify(responseData)}`,
395 | PhysicalResourceId:
396 | (event as CloudFormationCustomResourceUpdateEvent).PhysicalResourceId ||
397 | logStreamName,
398 | StackId: event.StackId,
399 | RequestId: event.RequestId,
400 | LogicalResourceId: event.LogicalResourceId,
401 | Data: responseData,
402 | };
403 |
404 | logger.debug({
405 | label: "helper/responseBody",
406 | message: `Response Body: ${JSON.stringify(responseBody)}`,
407 | });
408 |
409 | if (responseStatus === "FAILED") {
410 | throw new Error(responseBody.Data.Error);
411 | } else return responseBody;
412 | };
413 |
--------------------------------------------------------------------------------
/source/services/helper/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cl-helper",
3 | "version": "4.0.2",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "cl-helper",
9 | "version": "4.0.2",
10 | "hasInstallScript": true,
11 | "license": "Apache-2.0",
12 | "dependencies": {
13 | "aws-sdk": "^2.1354.0",
14 | "uuid": "^9.0.0"
15 | },
16 | "devDependencies": {
17 | "@types/aws-lambda": "^8.10.114",
18 | "@types/node": "^20.3.1",
19 | "@types/uuid": "^9.0.2",
20 | "typescript": "^5.1.3"
21 | }
22 | },
23 | "node_modules/@types/aws-lambda": {
24 | "version": "8.10.125",
25 | "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.125.tgz",
26 | "integrity": "sha512-Vqw/WMlV4O1fJT6capim01v7VLDZkcX1n6Yhb52E7IfnMqYbNfwHfyDV8rRN42NLBtdDvfaqcCqs2K0fr5ljZw==",
27 | "dev": true
28 | },
29 | "node_modules/@types/node": {
30 | "version": "20.8.7",
31 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.7.tgz",
32 | "integrity": "sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==",
33 | "dev": true,
34 | "dependencies": {
35 | "undici-types": "~5.25.1"
36 | }
37 | },
38 | "node_modules/@types/uuid": {
39 | "version": "9.0.6",
40 | "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.6.tgz",
41 | "integrity": "sha512-BT2Krtx4xaO6iwzwMFUYvWBWkV2pr37zD68Vmp1CDV196MzczBRxuEpD6Pr395HAgebC/co7hOphs53r8V7jew==",
42 | "dev": true
43 | },
44 | "node_modules/available-typed-arrays": {
45 | "version": "1.0.5",
46 | "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
47 | "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
48 | "engines": {
49 | "node": ">= 0.4"
50 | },
51 | "funding": {
52 | "url": "https://github.com/sponsors/ljharb"
53 | }
54 | },
55 | "node_modules/aws-sdk": {
56 | "version": "2.1477.0",
57 | "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1477.0.tgz",
58 | "integrity": "sha512-DLsrKosrKRe5P1E+BcJAVpOXkma4oUOrcyBUridDmUhdf9k3jj5dnL1roFuDpTmNDDhK8a1tUgY3wmXoKQtv7A==",
59 | "dependencies": {
60 | "buffer": "4.9.2",
61 | "events": "1.1.1",
62 | "ieee754": "1.1.13",
63 | "jmespath": "0.16.0",
64 | "querystring": "0.2.0",
65 | "sax": "1.2.1",
66 | "url": "0.10.3",
67 | "util": "^0.12.4",
68 | "uuid": "8.0.0",
69 | "xml2js": "0.5.0"
70 | },
71 | "engines": {
72 | "node": ">= 10.0.0"
73 | }
74 | },
75 | "node_modules/aws-sdk/node_modules/uuid": {
76 | "version": "8.0.0",
77 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz",
78 | "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==",
79 | "bin": {
80 | "uuid": "dist/bin/uuid"
81 | }
82 | },
83 | "node_modules/base64-js": {
84 | "version": "1.5.1",
85 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
86 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
87 | "funding": [
88 | {
89 | "type": "github",
90 | "url": "https://github.com/sponsors/feross"
91 | },
92 | {
93 | "type": "patreon",
94 | "url": "https://www.patreon.com/feross"
95 | },
96 | {
97 | "type": "consulting",
98 | "url": "https://feross.org/support"
99 | }
100 | ]
101 | },
102 | "node_modules/buffer": {
103 | "version": "4.9.2",
104 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
105 | "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
106 | "dependencies": {
107 | "base64-js": "^1.0.2",
108 | "ieee754": "^1.1.4",
109 | "isarray": "^1.0.0"
110 | }
111 | },
112 | "node_modules/call-bind": {
113 | "version": "1.0.4",
114 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.4.tgz",
115 | "integrity": "sha512-e68w37XfAb5fL5M3NTxqKLcXRUkL2/kFlQjQjE/8jvPMBKmO5ZDycRkS/DrZRXjegOzwWzEwW88m+8r+D0PUUA==",
116 | "dependencies": {
117 | "function-bind": "^1.1.2",
118 | "get-intrinsic": "^1.2.1",
119 | "set-function-length": "^1.1.0"
120 | },
121 | "funding": {
122 | "url": "https://github.com/sponsors/ljharb"
123 | }
124 | },
125 | "node_modules/define-data-property": {
126 | "version": "1.1.1",
127 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz",
128 | "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==",
129 | "dependencies": {
130 | "get-intrinsic": "^1.2.1",
131 | "gopd": "^1.0.1",
132 | "has-property-descriptors": "^1.0.0"
133 | },
134 | "engines": {
135 | "node": ">= 0.4"
136 | }
137 | },
138 | "node_modules/events": {
139 | "version": "1.1.1",
140 | "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
141 | "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==",
142 | "engines": {
143 | "node": ">=0.4.x"
144 | }
145 | },
146 | "node_modules/for-each": {
147 | "version": "0.3.3",
148 | "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
149 | "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
150 | "dependencies": {
151 | "is-callable": "^1.1.3"
152 | }
153 | },
154 | "node_modules/function-bind": {
155 | "version": "1.1.2",
156 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
157 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
158 | "funding": {
159 | "url": "https://github.com/sponsors/ljharb"
160 | }
161 | },
162 | "node_modules/get-intrinsic": {
163 | "version": "1.2.1",
164 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
165 | "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
166 | "dependencies": {
167 | "function-bind": "^1.1.1",
168 | "has": "^1.0.3",
169 | "has-proto": "^1.0.1",
170 | "has-symbols": "^1.0.3"
171 | },
172 | "funding": {
173 | "url": "https://github.com/sponsors/ljharb"
174 | }
175 | },
176 | "node_modules/gopd": {
177 | "version": "1.0.1",
178 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
179 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
180 | "dependencies": {
181 | "get-intrinsic": "^1.1.3"
182 | },
183 | "funding": {
184 | "url": "https://github.com/sponsors/ljharb"
185 | }
186 | },
187 | "node_modules/has": {
188 | "version": "1.0.4",
189 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz",
190 | "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==",
191 | "engines": {
192 | "node": ">= 0.4.0"
193 | }
194 | },
195 | "node_modules/has-property-descriptors": {
196 | "version": "1.0.0",
197 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
198 | "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
199 | "dependencies": {
200 | "get-intrinsic": "^1.1.1"
201 | },
202 | "funding": {
203 | "url": "https://github.com/sponsors/ljharb"
204 | }
205 | },
206 | "node_modules/has-proto": {
207 | "version": "1.0.1",
208 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
209 | "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
210 | "engines": {
211 | "node": ">= 0.4"
212 | },
213 | "funding": {
214 | "url": "https://github.com/sponsors/ljharb"
215 | }
216 | },
217 | "node_modules/has-symbols": {
218 | "version": "1.0.3",
219 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
220 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
221 | "engines": {
222 | "node": ">= 0.4"
223 | },
224 | "funding": {
225 | "url": "https://github.com/sponsors/ljharb"
226 | }
227 | },
228 | "node_modules/has-tostringtag": {
229 | "version": "1.0.0",
230 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
231 | "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
232 | "dependencies": {
233 | "has-symbols": "^1.0.2"
234 | },
235 | "engines": {
236 | "node": ">= 0.4"
237 | },
238 | "funding": {
239 | "url": "https://github.com/sponsors/ljharb"
240 | }
241 | },
242 | "node_modules/ieee754": {
243 | "version": "1.1.13",
244 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
245 | "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
246 | },
247 | "node_modules/inherits": {
248 | "version": "2.0.4",
249 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
250 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
251 | },
252 | "node_modules/is-arguments": {
253 | "version": "1.1.1",
254 | "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
255 | "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
256 | "dependencies": {
257 | "call-bind": "^1.0.2",
258 | "has-tostringtag": "^1.0.0"
259 | },
260 | "engines": {
261 | "node": ">= 0.4"
262 | },
263 | "funding": {
264 | "url": "https://github.com/sponsors/ljharb"
265 | }
266 | },
267 | "node_modules/is-callable": {
268 | "version": "1.2.7",
269 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
270 | "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
271 | "engines": {
272 | "node": ">= 0.4"
273 | },
274 | "funding": {
275 | "url": "https://github.com/sponsors/ljharb"
276 | }
277 | },
278 | "node_modules/is-generator-function": {
279 | "version": "1.0.10",
280 | "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
281 | "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
282 | "dependencies": {
283 | "has-tostringtag": "^1.0.0"
284 | },
285 | "engines": {
286 | "node": ">= 0.4"
287 | },
288 | "funding": {
289 | "url": "https://github.com/sponsors/ljharb"
290 | }
291 | },
292 | "node_modules/is-typed-array": {
293 | "version": "1.1.12",
294 | "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz",
295 | "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==",
296 | "dependencies": {
297 | "which-typed-array": "^1.1.11"
298 | },
299 | "engines": {
300 | "node": ">= 0.4"
301 | },
302 | "funding": {
303 | "url": "https://github.com/sponsors/ljharb"
304 | }
305 | },
306 | "node_modules/isarray": {
307 | "version": "1.0.0",
308 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
309 | "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
310 | },
311 | "node_modules/jmespath": {
312 | "version": "0.16.0",
313 | "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz",
314 | "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==",
315 | "engines": {
316 | "node": ">= 0.6.0"
317 | }
318 | },
319 | "node_modules/punycode": {
320 | "version": "1.3.2",
321 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
322 | "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw=="
323 | },
324 | "node_modules/querystring": {
325 | "version": "0.2.0",
326 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
327 | "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==",
328 | "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.",
329 | "engines": {
330 | "node": ">=0.4.x"
331 | }
332 | },
333 | "node_modules/sax": {
334 | "version": "1.2.1",
335 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
336 | "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA=="
337 | },
338 | "node_modules/set-function-length": {
339 | "version": "1.1.1",
340 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz",
341 | "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==",
342 | "dependencies": {
343 | "define-data-property": "^1.1.1",
344 | "get-intrinsic": "^1.2.1",
345 | "gopd": "^1.0.1",
346 | "has-property-descriptors": "^1.0.0"
347 | },
348 | "engines": {
349 | "node": ">= 0.4"
350 | }
351 | },
352 | "node_modules/typescript": {
353 | "version": "5.2.2",
354 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
355 | "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
356 | "dev": true,
357 | "bin": {
358 | "tsc": "bin/tsc",
359 | "tsserver": "bin/tsserver"
360 | },
361 | "engines": {
362 | "node": ">=14.17"
363 | }
364 | },
365 | "node_modules/undici-types": {
366 | "version": "5.25.3",
367 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz",
368 | "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==",
369 | "dev": true
370 | },
371 | "node_modules/url": {
372 | "version": "0.10.3",
373 | "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz",
374 | "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==",
375 | "dependencies": {
376 | "punycode": "1.3.2",
377 | "querystring": "0.2.0"
378 | }
379 | },
380 | "node_modules/util": {
381 | "version": "0.12.5",
382 | "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
383 | "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==",
384 | "dependencies": {
385 | "inherits": "^2.0.3",
386 | "is-arguments": "^1.0.4",
387 | "is-generator-function": "^1.0.7",
388 | "is-typed-array": "^1.1.3",
389 | "which-typed-array": "^1.1.2"
390 | }
391 | },
392 | "node_modules/uuid": {
393 | "version": "9.0.1",
394 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
395 | "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
396 | "funding": [
397 | "https://github.com/sponsors/broofa",
398 | "https://github.com/sponsors/ctavan"
399 | ],
400 | "bin": {
401 | "uuid": "dist/bin/uuid"
402 | }
403 | },
404 | "node_modules/which-typed-array": {
405 | "version": "1.1.13",
406 | "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz",
407 | "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==",
408 | "dependencies": {
409 | "available-typed-arrays": "^1.0.5",
410 | "call-bind": "^1.0.4",
411 | "for-each": "^0.3.3",
412 | "gopd": "^1.0.1",
413 | "has-tostringtag": "^1.0.0"
414 | },
415 | "engines": {
416 | "node": ">= 0.4"
417 | },
418 | "funding": {
419 | "url": "https://github.com/sponsors/ljharb"
420 | }
421 | },
422 | "node_modules/xml2js": {
423 | "version": "0.5.0",
424 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
425 | "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
426 | "dependencies": {
427 | "sax": ">=0.6.0",
428 | "xmlbuilder": "~11.0.0"
429 | },
430 | "engines": {
431 | "node": ">=4.0.0"
432 | }
433 | },
434 | "node_modules/xmlbuilder": {
435 | "version": "11.0.1",
436 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
437 | "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
438 | "engines": {
439 | "node": ">=4.0"
440 | }
441 | }
442 | }
443 | }
444 |
--------------------------------------------------------------------------------
/source/services/helper/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cl-helper",
3 | "version": "4.0.2",
4 | "description": "helper function for Centralized Logging on AWS solution",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"nothing to do\"",
8 | "watch": "npx tsc -w",
9 | "preinstall": "cd ../@aws-solutions/utils && npm ci --production",
10 | "build:clean": "rm -rf ./node_modules && rm -rf ./dist",
11 | "build:ts": "npx tsc --project ./tsconfig.json",
12 | "build:copy": "cp -r ./node_modules ./dist/helper && cp -r ../@aws-solutions/utils/node_modules/* ./dist/helper/node_modules/ && cp ./dist/@aws-solutions/utils/*.js ./dist/helper/",
13 | "build:zip": "cd ./dist/helper && zip -r cl-helper.zip .",
14 | "build:all": "npm run build:clean && npm ci && npm run build:ts && npm prune --production && npm run build:copy && npm run build:zip"
15 | },
16 | "author": "aws-solutions",
17 | "license": "Apache-2.0",
18 | "dependencies": {
19 | "uuid": "^9.0.0",
20 | "aws-sdk": "^2.1354.0"
21 | },
22 | "devDependencies": {
23 | "typescript": "^5.1.3",
24 | "@types/uuid": "^9.0.2",
25 | "@types/node": "^20.3.1",
26 | "@types/aws-lambda": "^8.10.114"
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/source/services/helper/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "./dist",
5 | "noEmit": false,
6 | "baseUrl": ".",
7 | "paths": {
8 | "logger": ["../@aws-solutions/utils/logger"],
9 | "metric": ["../@aws-solutions/utils/metric"]
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/source/services/transformer/PromiseConstructor.d.ts:
--------------------------------------------------------------------------------
1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | // SPDX-License-Identifier: Apache-2.0
3 | export interface PromiseResolution {
4 | status: "fulfilled";
5 | value: T;
6 | }
7 |
8 | export interface PromiseRejection {
9 | status: "rejected";
10 | reason: E;
11 | }
12 |
13 | export type PromiseResult =
14 | | PromiseResolution
15 | | PromiseRejection;
16 |
17 | export type PromiseList = {
18 | [P in keyof T]: Promise;
19 | };
20 |
21 | export type PromiseResultList = {
22 | [P in keyof T]: PromiseResult;
23 | };
24 |
25 | declare global {
26 | interface PromiseConstructor {
27 | allSettled(): Promise<[]>;
28 | allSettled(
29 | list: PromiseList
30 | ): Promise>;
31 | allSettled(iterable: Iterable): Promise>>;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/source/services/transformer/index.ts:
--------------------------------------------------------------------------------
1 | // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 | // SPDX-License-Identifier: Apache-2.0
3 |
4 | import zlib from "zlib";
5 | import { Firehose } from "aws-sdk";
6 | import { Record } from "aws-sdk/clients/firehose";
7 | import { logger } from "logger";
8 | import { sendUsageMetrics } from "metric";
9 |
10 | /**
11 | * @description interface for log event
12 | * @property {string} id for the log event
13 | * @property {number} timestamp for the log event
14 | * @property {string} message stringified log event
15 | * @property {any} extractedFields inferred fields from the event
16 | */
17 | interface ILogEvent {
18 | id: string;
19 | timestamp: number;
20 | message: string;
21 | extractedFields: any;
22 | }
23 |
24 | /**
25 | * @description interface for log event
26 | * @property {any[]} Records kinesis records from the data stream
27 | */
28 | interface IEvent {
29 | Records: [
30 | {
31 | kinesis: {
32 | kinesisSchemaVersion: string;
33 | partitionKey: string;
34 | sequenceNumber: string;
35 | data: string;
36 | approximateArrivalTimestamp: number;
37 | };
38 | eventSource: string;
39 | eventVersion: string;
40 | eventID: string;
41 | eventName: string;
42 | invokeIdentityArn: string;
43 | awsRegion: string;
44 | eventSourceARN: string;
45 | }
46 | ];
47 | }
48 |
49 | /**
50 | * @description transform log events into es documents
51 | * @param {ILogEvent} logEvent - log event to transform into es document
52 | * @param {string} owner - account id of the owner
53 | * @param {string} logGroup - log group originating the event
54 | * @param {string} logStream - log stream originating the event
55 | */
56 | function transform(
57 | logEvent: ILogEvent,
58 | owner: string,
59 | logGroup: string,
60 | logStream: string
61 | ) {
62 | const source = buildSource(logEvent.message, logEvent.extractedFields);
63 | if ("requestParameters" in source)
64 | source["requestParameters"] = JSON.stringify(source["requestParameters"]);
65 | if ("responseElements" in source)
66 | source["responseElements"] = JSON.stringify(source["responseElements"]);
67 | if ("apiVersion" in source) source["apiVersion"] = "" + source["apiVersion"];
68 | if ("account_id" in source) source["account_id"] = "" + source["account_id"];
69 | source["timestamp"] = new Date(1 * logEvent.timestamp).toISOString();
70 | source["id"] = logEvent.id;
71 | source["type"] = "CloudWatchLogs";
72 | source["@message"] = logEvent.message;
73 | source["@owner"] = owner;
74 | source["@log_group"] = logGroup;
75 | source["@log_stream"] = logStream;
76 |
77 | return source;
78 | }
79 |
80 | /**
81 | * @description building source for log events
82 | * @param message - log event
83 | * @param extractedFields - fields in the log event
84 | */
85 | function buildSource(message: string, extractedFields: any) {
86 | if (extractedFields) {
87 | logger.debug({
88 | label: "handler",
89 | message: `extractedFields: ${extractedFields} `,
90 | });
91 | const source: { [key: string]: any } = {};
92 |
93 | for (const key in extractedFields) {
94 | if (extractedFields[key]) {
95 | const value = extractedFields[key];
96 | if (isNumeric(value)) {
97 | source[key] = 1 * value;
98 | continue;
99 | }
100 |
101 | const _jsonSubString = extractJson(value);
102 | if (_jsonSubString !== null) {
103 | source["$" + key] = JSON.parse(_jsonSubString);
104 | }
105 |
106 | source[key] = value;
107 | }
108 | }
109 |
110 | return source;
111 | }
112 |
113 | logger.debug({
114 | label: "handler",
115 | message: `message: ${message} `,
116 | });
117 | const jsonSubString = extractJson(message);
118 | if (jsonSubString !== null) {
119 | return JSON.parse(jsonSubString);
120 | }
121 |
122 | return {};
123 | }
124 |
125 | /**
126 | * @description extracting json from log event
127 | * @param {string} message - log event
128 | */
129 | function extractJson(message: string) {
130 | const jsonStart = message.indexOf("{");
131 | if (jsonStart < 0) return null;
132 | const jsonSubString = message.substring(jsonStart);
133 | return isValidJson(jsonSubString) ? jsonSubString : null;
134 | }
135 |
136 | /**
137 | * @description checking if extracted field has valid JSON
138 | * @param {string} message - log event
139 | */
140 | function isValidJson(message: string) {
141 | try {
142 | JSON.parse(message);
143 | } catch (e) {
144 | return false;
145 | }
146 | return true;
147 | }
148 |
149 | /**
150 | * @description checking if extracted field has numeric value
151 | * @param n - extracted field to test for numeric value
152 | */
153 | function isNumeric(n: any) {
154 | return !isNaN(parseFloat(n)) && isFinite(n);
155 | }
156 |
157 | function createRecordsFromEvents(
158 | logEvents: ILogEvent[],
159 | owner: string,
160 | logGroup: string,
161 | logStream: string
162 | ) {
163 | const records: Record[] = [];
164 | logEvents.forEach((event: ILogEvent) => {
165 | const transformedEvent = transform(event, owner, logGroup, logStream);
166 | logger.debug({
167 | label: "createRecordsFromEvents",
168 | message: `transformed event: ${JSON.stringify(transformedEvent)}`,
169 | });
170 | records.push({
171 | Data: Buffer.from(JSON.stringify(transformedEvent)),
172 | });
173 | });
174 | logger.info({
175 | label: "createRecordsFromEvents",
176 | message: "records created from log events",
177 | });
178 | return records;
179 | }
180 |
181 | async function putRecords(records: Record[]) {
182 | logger.debug({
183 | label: "putRecords",
184 | message: "records put on firehose",
185 | });
186 | const params = {
187 | DeliveryStreamName: "" + process.env.DELIVERY_STREAM /* required */,
188 | Records: records,
189 | };
190 | const firehose = new Firehose({
191 | customUserAgent: process.env.CUSTOM_SDK_USER_AGENT,
192 | });
193 | await firehose.putRecordBatch(params).promise();
194 |
195 | if (process.env.SEND_METRIC === "Yes") {
196 | const recordLengths = records.map((it) => (it.Data as Buffer).byteLength);
197 | const summedItemSize = recordLengths.reduce((sum, next) => {
198 | return sum + next;
199 | }, 0);
200 | await sendUsageMetrics(summedItemSize);
201 | }
202 | }
203 |
204 | exports.handler = async (event: IEvent) => {
205 | logger.debug({
206 | label: "handler",
207 | message: `event: ${JSON.stringify(event)}`,
208 | });
209 | await Promise.allSettled(
210 | event.Records.map(async (r) => {
211 | try {
212 | const buffer = Buffer.from(r.kinesis.data, "base64");
213 | let decompressed;
214 | try {
215 | decompressed = zlib.gunzipSync(buffer);
216 | } catch (e) {
217 | logger.error({
218 | label: "handler",
219 | message: `error in reading data: ${JSON.stringify(e)} `,
220 | });
221 | throw new Error("error in decompressing data");
222 | }
223 | const payload = JSON.parse(decompressed.toString());
224 | logger.debug({ label: "handler", message: JSON.stringify(payload) });
225 |
226 | // CONTROL_MESSAGE are sent by CWL to check if the subscription is reachable.
227 | // They do not contain actual data.
228 | if (payload.messageType === "CONTROL_MESSAGE") {
229 | return;
230 | } else if (payload.messageType === "DATA_MESSAGE") {
231 | const records = createRecordsFromEvents(
232 | payload.logEvents,
233 | payload.owner,
234 | payload.logGroup,
235 | payload.logStream
236 | );
237 | const chunkSize = 500;
238 | for (let i = 0; i < records.length; i += chunkSize) {
239 | const chunk = records.slice(i, i + chunkSize);
240 | await putRecords(chunk);
241 | logger.info({
242 | label: "handler",
243 | message: `#${i}: ${chunk.length} records put success`,
244 | });
245 | }
246 | } else {
247 | return;
248 | }
249 | } catch (e) {
250 | logger.error({
251 | label: "handler",
252 | message: e,
253 | });
254 | }
255 | })
256 | );
257 | };
258 |
--------------------------------------------------------------------------------
/source/services/transformer/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cl-transformer",
3 | "version": "4.0.2",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "cl-transformer",
9 | "version": "4.0.2",
10 | "hasInstallScript": true,
11 | "license": "Apache-2.0",
12 | "dependencies": {
13 | "aws-sdk": "^2.1354.0"
14 | },
15 | "devDependencies": {
16 | "@types/node": "^20.3.1",
17 | "@types/uuid": "^9.0.2",
18 | "typescript": "^5.1.3"
19 | }
20 | },
21 | "node_modules/@types/node": {
22 | "version": "20.8.7",
23 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.7.tgz",
24 | "integrity": "sha512-21TKHHh3eUHIi2MloeptJWALuCu5H7HQTdTrWIFReA8ad+aggoX+lRes3ex7/FtpC+sVUpFMQ+QTfYr74mruiQ==",
25 | "dev": true,
26 | "dependencies": {
27 | "undici-types": "~5.25.1"
28 | }
29 | },
30 | "node_modules/@types/uuid": {
31 | "version": "9.0.6",
32 | "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.6.tgz",
33 | "integrity": "sha512-BT2Krtx4xaO6iwzwMFUYvWBWkV2pr37zD68Vmp1CDV196MzczBRxuEpD6Pr395HAgebC/co7hOphs53r8V7jew==",
34 | "dev": true
35 | },
36 | "node_modules/available-typed-arrays": {
37 | "version": "1.0.5",
38 | "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
39 | "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
40 | "engines": {
41 | "node": ">= 0.4"
42 | },
43 | "funding": {
44 | "url": "https://github.com/sponsors/ljharb"
45 | }
46 | },
47 | "node_modules/aws-sdk": {
48 | "version": "2.1477.0",
49 | "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1477.0.tgz",
50 | "integrity": "sha512-DLsrKosrKRe5P1E+BcJAVpOXkma4oUOrcyBUridDmUhdf9k3jj5dnL1roFuDpTmNDDhK8a1tUgY3wmXoKQtv7A==",
51 | "dependencies": {
52 | "buffer": "4.9.2",
53 | "events": "1.1.1",
54 | "ieee754": "1.1.13",
55 | "jmespath": "0.16.0",
56 | "querystring": "0.2.0",
57 | "sax": "1.2.1",
58 | "url": "0.10.3",
59 | "util": "^0.12.4",
60 | "uuid": "8.0.0",
61 | "xml2js": "0.5.0"
62 | },
63 | "engines": {
64 | "node": ">= 10.0.0"
65 | }
66 | },
67 | "node_modules/base64-js": {
68 | "version": "1.5.1",
69 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
70 | "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
71 | "funding": [
72 | {
73 | "type": "github",
74 | "url": "https://github.com/sponsors/feross"
75 | },
76 | {
77 | "type": "patreon",
78 | "url": "https://www.patreon.com/feross"
79 | },
80 | {
81 | "type": "consulting",
82 | "url": "https://feross.org/support"
83 | }
84 | ]
85 | },
86 | "node_modules/buffer": {
87 | "version": "4.9.2",
88 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
89 | "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
90 | "dependencies": {
91 | "base64-js": "^1.0.2",
92 | "ieee754": "^1.1.4",
93 | "isarray": "^1.0.0"
94 | }
95 | },
96 | "node_modules/call-bind": {
97 | "version": "1.0.4",
98 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.4.tgz",
99 | "integrity": "sha512-e68w37XfAb5fL5M3NTxqKLcXRUkL2/kFlQjQjE/8jvPMBKmO5ZDycRkS/DrZRXjegOzwWzEwW88m+8r+D0PUUA==",
100 | "dependencies": {
101 | "function-bind": "^1.1.2",
102 | "get-intrinsic": "^1.2.1",
103 | "set-function-length": "^1.1.0"
104 | },
105 | "funding": {
106 | "url": "https://github.com/sponsors/ljharb"
107 | }
108 | },
109 | "node_modules/define-data-property": {
110 | "version": "1.1.1",
111 | "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz",
112 | "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==",
113 | "dependencies": {
114 | "get-intrinsic": "^1.2.1",
115 | "gopd": "^1.0.1",
116 | "has-property-descriptors": "^1.0.0"
117 | },
118 | "engines": {
119 | "node": ">= 0.4"
120 | }
121 | },
122 | "node_modules/events": {
123 | "version": "1.1.1",
124 | "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
125 | "integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw==",
126 | "engines": {
127 | "node": ">=0.4.x"
128 | }
129 | },
130 | "node_modules/for-each": {
131 | "version": "0.3.3",
132 | "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
133 | "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
134 | "dependencies": {
135 | "is-callable": "^1.1.3"
136 | }
137 | },
138 | "node_modules/function-bind": {
139 | "version": "1.1.2",
140 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
141 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
142 | "funding": {
143 | "url": "https://github.com/sponsors/ljharb"
144 | }
145 | },
146 | "node_modules/get-intrinsic": {
147 | "version": "1.2.1",
148 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
149 | "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
150 | "dependencies": {
151 | "function-bind": "^1.1.1",
152 | "has": "^1.0.3",
153 | "has-proto": "^1.0.1",
154 | "has-symbols": "^1.0.3"
155 | },
156 | "funding": {
157 | "url": "https://github.com/sponsors/ljharb"
158 | }
159 | },
160 | "node_modules/gopd": {
161 | "version": "1.0.1",
162 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
163 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
164 | "dependencies": {
165 | "get-intrinsic": "^1.1.3"
166 | },
167 | "funding": {
168 | "url": "https://github.com/sponsors/ljharb"
169 | }
170 | },
171 | "node_modules/has": {
172 | "version": "1.0.4",
173 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.4.tgz",
174 | "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==",
175 | "engines": {
176 | "node": ">= 0.4.0"
177 | }
178 | },
179 | "node_modules/has-property-descriptors": {
180 | "version": "1.0.0",
181 | "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
182 | "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
183 | "dependencies": {
184 | "get-intrinsic": "^1.1.1"
185 | },
186 | "funding": {
187 | "url": "https://github.com/sponsors/ljharb"
188 | }
189 | },
190 | "node_modules/has-proto": {
191 | "version": "1.0.1",
192 | "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
193 | "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
194 | "engines": {
195 | "node": ">= 0.4"
196 | },
197 | "funding": {
198 | "url": "https://github.com/sponsors/ljharb"
199 | }
200 | },
201 | "node_modules/has-symbols": {
202 | "version": "1.0.3",
203 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
204 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
205 | "engines": {
206 | "node": ">= 0.4"
207 | },
208 | "funding": {
209 | "url": "https://github.com/sponsors/ljharb"
210 | }
211 | },
212 | "node_modules/has-tostringtag": {
213 | "version": "1.0.0",
214 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
215 | "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
216 | "dependencies": {
217 | "has-symbols": "^1.0.2"
218 | },
219 | "engines": {
220 | "node": ">= 0.4"
221 | },
222 | "funding": {
223 | "url": "https://github.com/sponsors/ljharb"
224 | }
225 | },
226 | "node_modules/ieee754": {
227 | "version": "1.1.13",
228 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
229 | "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
230 | },
231 | "node_modules/inherits": {
232 | "version": "2.0.4",
233 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
234 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
235 | },
236 | "node_modules/is-arguments": {
237 | "version": "1.1.1",
238 | "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
239 | "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==",
240 | "dependencies": {
241 | "call-bind": "^1.0.2",
242 | "has-tostringtag": "^1.0.0"
243 | },
244 | "engines": {
245 | "node": ">= 0.4"
246 | },
247 | "funding": {
248 | "url": "https://github.com/sponsors/ljharb"
249 | }
250 | },
251 | "node_modules/is-callable": {
252 | "version": "1.2.7",
253 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz",
254 | "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==",
255 | "engines": {
256 | "node": ">= 0.4"
257 | },
258 | "funding": {
259 | "url": "https://github.com/sponsors/ljharb"
260 | }
261 | },
262 | "node_modules/is-generator-function": {
263 | "version": "1.0.10",
264 | "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
265 | "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
266 | "dependencies": {
267 | "has-tostringtag": "^1.0.0"
268 | },
269 | "engines": {
270 | "node": ">= 0.4"
271 | },
272 | "funding": {
273 | "url": "https://github.com/sponsors/ljharb"
274 | }
275 | },
276 | "node_modules/is-typed-array": {
277 | "version": "1.1.12",
278 | "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz",
279 | "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==",
280 | "dependencies": {
281 | "which-typed-array": "^1.1.11"
282 | },
283 | "engines": {
284 | "node": ">= 0.4"
285 | },
286 | "funding": {
287 | "url": "https://github.com/sponsors/ljharb"
288 | }
289 | },
290 | "node_modules/isarray": {
291 | "version": "1.0.0",
292 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
293 | "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="
294 | },
295 | "node_modules/jmespath": {
296 | "version": "0.16.0",
297 | "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz",
298 | "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==",
299 | "engines": {
300 | "node": ">= 0.6.0"
301 | }
302 | },
303 | "node_modules/punycode": {
304 | "version": "1.3.2",
305 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
306 | "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw=="
307 | },
308 | "node_modules/querystring": {
309 | "version": "0.2.0",
310 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
311 | "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==",
312 | "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.",
313 | "engines": {
314 | "node": ">=0.4.x"
315 | }
316 | },
317 | "node_modules/sax": {
318 | "version": "1.2.1",
319 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
320 | "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA=="
321 | },
322 | "node_modules/set-function-length": {
323 | "version": "1.1.1",
324 | "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz",
325 | "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==",
326 | "dependencies": {
327 | "define-data-property": "^1.1.1",
328 | "get-intrinsic": "^1.2.1",
329 | "gopd": "^1.0.1",
330 | "has-property-descriptors": "^1.0.0"
331 | },
332 | "engines": {
333 | "node": ">= 0.4"
334 | }
335 | },
336 | "node_modules/typescript": {
337 | "version": "5.2.2",
338 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
339 | "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
340 | "dev": true,
341 | "bin": {
342 | "tsc": "bin/tsc",
343 | "tsserver": "bin/tsserver"
344 | },
345 | "engines": {
346 | "node": ">=14.17"
347 | }
348 | },
349 | "node_modules/undici-types": {
350 | "version": "5.25.3",
351 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz",
352 | "integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA==",
353 | "dev": true
354 | },
355 | "node_modules/url": {
356 | "version": "0.10.3",
357 | "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz",
358 | "integrity": "sha512-hzSUW2q06EqL1gKM/a+obYHLIO6ct2hwPuviqTTOcfFVc61UbfJ2Q32+uGL/HCPxKqrdGB5QUwIe7UqlDgwsOQ==",
359 | "dependencies": {
360 | "punycode": "1.3.2",
361 | "querystring": "0.2.0"
362 | }
363 | },
364 | "node_modules/util": {
365 | "version": "0.12.5",
366 | "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
367 | "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==",
368 | "dependencies": {
369 | "inherits": "^2.0.3",
370 | "is-arguments": "^1.0.4",
371 | "is-generator-function": "^1.0.7",
372 | "is-typed-array": "^1.1.3",
373 | "which-typed-array": "^1.1.2"
374 | }
375 | },
376 | "node_modules/uuid": {
377 | "version": "8.0.0",
378 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz",
379 | "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==",
380 | "bin": {
381 | "uuid": "dist/bin/uuid"
382 | }
383 | },
384 | "node_modules/which-typed-array": {
385 | "version": "1.1.13",
386 | "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz",
387 | "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==",
388 | "dependencies": {
389 | "available-typed-arrays": "^1.0.5",
390 | "call-bind": "^1.0.4",
391 | "for-each": "^0.3.3",
392 | "gopd": "^1.0.1",
393 | "has-tostringtag": "^1.0.0"
394 | },
395 | "engines": {
396 | "node": ">= 0.4"
397 | },
398 | "funding": {
399 | "url": "https://github.com/sponsors/ljharb"
400 | }
401 | },
402 | "node_modules/xml2js": {
403 | "version": "0.5.0",
404 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
405 | "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
406 | "dependencies": {
407 | "sax": ">=0.6.0",
408 | "xmlbuilder": "~11.0.0"
409 | },
410 | "engines": {
411 | "node": ">=4.0.0"
412 | }
413 | },
414 | "node_modules/xmlbuilder": {
415 | "version": "11.0.1",
416 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
417 | "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
418 | "engines": {
419 | "node": ">=4.0"
420 | }
421 | }
422 | }
423 | }
424 |
--------------------------------------------------------------------------------
/source/services/transformer/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cl-transformer",
3 | "version": "4.0.2",
4 | "description": "transformer lambda for Centralized Logging on AWS solution",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"nothing to do\"",
8 | "watch": "npx tsc -w",
9 | "preinstall": "cd ../@aws-solutions/utils && npm ci --production",
10 | "build:clean": "rm -rf ./node_modules && rm -rf ./dist",
11 | "build:ts": "npx tsc --project ./tsconfig.json",
12 | "build:copy": "cp -r ./node_modules ./dist/transformer && cp -r ../@aws-solutions/utils/node_modules/* ./dist/transformer/node_modules/ && cp -r ./dist/@aws-solutions/utils/*.js ./dist/transformer/",
13 | "build:zip": "cd ./dist/transformer && zip -r cl-transformer.zip .",
14 | "build:all": "npm run build:clean && npm ci && npm run build:ts && npm prune --production && npm run build:copy && npm run build:zip"
15 | },
16 | "author": "aws-solutions",
17 | "license": "Apache-2.0",
18 | "dependencies": {
19 | "aws-sdk": "^2.1354.0"
20 | },
21 | "devDependencies": {
22 | "typescript": "^5.1.3",
23 | "@types/uuid": "^9.0.2",
24 | "@types/node": "^20.3.1"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/source/services/transformer/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "./dist",
5 | "noEmit": false,
6 | "baseUrl": ".",
7 | "paths": {
8 | "logger": ["../@aws-solutions/utils/logger"],
9 | "metric": ["../@aws-solutions/utils/metric"]
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/source/services/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | /* Basic Options */
4 | "target": "ES2018" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
5 | "module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
6 | "lib": [
7 | "DOM",
8 | "ES2018"
9 | ] /* Specify library files to be included in the compilation. */,
10 | "declaration": false /* Generates corresponding '.d.ts' file. */,
11 | "noEmit": true,
12 | "removeComments": true /* Do not emit comments to output. */,
13 | "resolveJsonModule": true /* Allows importing modules with a ‘.json’ extension */,
14 | /* Strict Type-Checking Options */
15 | "strict": true /* Enable all strict type-checking options. */,
16 | "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
17 | // "strictNullChecks": true /* Enable strict null checks. */,
18 | "strictFunctionTypes": true /* Enable strict checking of function types. */,
19 | "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */,
20 | "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */,
21 | "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */,
22 |
23 | /* Additional Checks */
24 | "noUnusedLocals": true /* Report errors on unused locals. */,
25 | "noUnusedParameters": true /* Report errors on unused parameters. */,
26 | "noImplicitReturns": true /* Report error when not all code paths in function return a value. */,
27 | "noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */,
28 |
29 | /* Module Resolution Options */
30 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
31 |
32 | /* Experimental Options */
33 | "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */,
34 | // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
35 |
36 | /* Advanced Options */
37 | "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
38 | },
39 | "typedocOptions": {
40 | "includes": "./services/",
41 | "exclude": ["**/*+(.d.ts|.test.ts|node_modules)"],
42 | "mode": "modules",
43 | "externalPattern": ["**/resources/**", "**/deployment/**"],
44 | "excludeExternals": true,
45 | "ignoreCompilerErrors": true,
46 | "out": "docs",
47 | "includeVersion": true,
48 | "readMe": "./README.md"
49 | }
50 | }
51 |
--------------------------------------------------------------------------------