diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/aws-cdk-transformer-integ.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/aws-cdk-transformer-integ.assets.json deleted file mode 100644 index 6c25b4b9f23f8..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/aws-cdk-transformer-integ.assets.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "version": "44.0.0", - "files": { - "37ae336b32dc0e038026d4a4101695bde95c06108b0ef900b3c62973025af77d": { - "displayName": "aws-cdk-transformer-integ Template", - "source": { - "path": "aws-cdk-transformer-integ.template.json", - "packaging": "file" - }, - "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "37ae336b32dc0e038026d4a4101695bde95c06108b0ef900b3c62973025af77d.json", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" - } - } - } - }, - "dockerImages": {} -} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/aws-cdk-transformer-integ.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/aws-cdk-transformer-integ.template.json deleted file mode 100644 index f4f71cf1bbf53..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/aws-cdk-transformer-integ.template.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "Resources": { - "MyLogGroup5C0DAD85": { - "Type": "AWS::Logs::LogGroup", - "Properties": { - "RetentionInDays": 731 - }, - "UpdateReplacePolicy": "Retain", - "DeletionPolicy": "Retain" - }, - "MyLogGroupResourceTransformer00531468": { - "Type": "AWS::Logs::Transformer", - "Properties": { - "LogGroupIdentifier": { - "Ref": "MyLogGroup5C0DAD85" - }, - "TransformerConfig": [ - { - "ParseJSON": { - "Source": "customField" - } - }, - { - "AddKeys": { - "Entries": [ - { - "Key": "test_key1", - "OverwriteIfExists": true, - "Value": "test_value1" - }, - { - "Key": "test_key2", - "OverwriteIfExists": false, - "Value": "test_value2" - }, - { - "Key": "test_key3", - "OverwriteIfExists": false, - "Value": "test_value3" - } - ] - } - } - ] - } - } - }, - "Parameters": { - "BootstrapVersion": { - "Type": "AWS::SSM::Parameter::Value", - "Default": "/cdk-bootstrap/hnb659fds/version", - "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" - } - }, - "Rules": { - "CheckBootstrapVersion": { - "Assertions": [ - { - "Assert": { - "Fn::Not": [ - { - "Fn::Contains": [ - [ - "1", - "2", - "3", - "4", - "5" - ], - { - "Ref": "BootstrapVersion" - } - ] - } - ] - }, - "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." - } - ] - } - } -} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/cdk.out deleted file mode 100644 index b3a26d44a5f73..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/cdk.out +++ /dev/null @@ -1 +0,0 @@ -{"version":"44.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/integ.json deleted file mode 100644 index 50064d6172409..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/integ.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "version": "44.0.0", - "testCases": { - "transformer-create/DefaultTest": { - "stacks": [ - "aws-cdk-transformer-integ" - ], - "assertionStack": "transformer-create/DefaultTest/DeployAssert", - "assertionStackName": "transformercreateDefaultTestDeployAssertB915E804" - } - }, - "minimumCliVersion": "2.1019.2" -} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/manifest.json deleted file mode 100644 index 1d72f17f193c5..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/manifest.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "version": "44.0.0", - "artifacts": { - "aws-cdk-transformer-integ.assets": { - "type": "cdk:asset-manifest", - "properties": { - "file": "aws-cdk-transformer-integ.assets.json", - "requiresBootstrapStackVersion": 6, - "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" - } - }, - "aws-cdk-transformer-integ": { - "type": "aws:cloudformation:stack", - "environment": "aws://unknown-account/unknown-region", - "properties": { - "templateFile": "aws-cdk-transformer-integ.template.json", - "terminationProtection": false, - "validateOnSynth": false, - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", - "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/37ae336b32dc0e038026d4a4101695bde95c06108b0ef900b3c62973025af77d.json", - "requiresBootstrapStackVersion": 6, - "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", - "additionalDependencies": [ - "aws-cdk-transformer-integ.assets" - ], - "lookupRole": { - "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", - "requiresBootstrapStackVersion": 8, - "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" - } - }, - "dependencies": [ - "aws-cdk-transformer-integ.assets" - ], - "metadata": { - "/aws-cdk-transformer-integ/MyLogGroup": [ - { - "type": "aws:cdk:analytics:construct", - "data": "*" - }, - { - "type": "warning", - "data": "Transformers can only be created for log groups in the Standard log class. Ensure that your log group is using the Standard log class." - } - ], - "/aws-cdk-transformer-integ/MyLogGroup/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "MyLogGroup5C0DAD85" - } - ], - "/aws-cdk-transformer-integ/MyLogGroup/ResourceTransformer": [ - { - "type": "aws:cdk:logicalId", - "data": "MyLogGroupResourceTransformer00531468" - } - ], - "/aws-cdk-transformer-integ/BootstrapVersion": [ - { - "type": "aws:cdk:logicalId", - "data": "BootstrapVersion" - } - ], - "/aws-cdk-transformer-integ/CheckBootstrapVersion": [ - { - "type": "aws:cdk:logicalId", - "data": "CheckBootstrapVersion" - } - ] - }, - "displayName": "aws-cdk-transformer-integ" - }, - "transformercreateDefaultTestDeployAssertB915E804.assets": { - "type": "cdk:asset-manifest", - "properties": { - "file": "transformercreateDefaultTestDeployAssertB915E804.assets.json", - "requiresBootstrapStackVersion": 6, - "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" - } - }, - "transformercreateDefaultTestDeployAssertB915E804": { - "type": "aws:cloudformation:stack", - "environment": "aws://unknown-account/unknown-region", - "properties": { - "templateFile": "transformercreateDefaultTestDeployAssertB915E804.template.json", - "terminationProtection": false, - "validateOnSynth": false, - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", - "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", - "requiresBootstrapStackVersion": 6, - "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", - "additionalDependencies": [ - "transformercreateDefaultTestDeployAssertB915E804.assets" - ], - "lookupRole": { - "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", - "requiresBootstrapStackVersion": 8, - "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" - } - }, - "dependencies": [ - "transformercreateDefaultTestDeployAssertB915E804.assets" - ], - "metadata": { - "/transformer-create/DefaultTest/DeployAssert/BootstrapVersion": [ - { - "type": "aws:cdk:logicalId", - "data": "BootstrapVersion" - } - ], - "/transformer-create/DefaultTest/DeployAssert/CheckBootstrapVersion": [ - { - "type": "aws:cdk:logicalId", - "data": "CheckBootstrapVersion" - } - ] - }, - "displayName": "transformer-create/DefaultTest/DeployAssert" - }, - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - } - }, - "minimumCliVersion": "2.1019.2" -} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/transformercreateDefaultTestDeployAssertB915E804.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/transformercreateDefaultTestDeployAssertB915E804.assets.json deleted file mode 100644 index 82dcb23a9b5cb..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/transformercreateDefaultTestDeployAssertB915E804.assets.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "version": "44.0.0", - "files": { - "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { - "displayName": "transformercreateDefaultTestDeployAssertB915E804 Template", - "source": { - "path": "transformercreateDefaultTestDeployAssertB915E804.template.json", - "packaging": "file" - }, - "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" - } - } - } - }, - "dockerImages": {} -} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/transformercreateDefaultTestDeployAssertB915E804.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/transformercreateDefaultTestDeployAssertB915E804.template.json deleted file mode 100644 index ad9d0fb73d1dd..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/transformercreateDefaultTestDeployAssertB915E804.template.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "Parameters": { - "BootstrapVersion": { - "Type": "AWS::SSM::Parameter::Value", - "Default": "/cdk-bootstrap/hnb659fds/version", - "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" - } - }, - "Rules": { - "CheckBootstrapVersion": { - "Assertions": [ - { - "Assert": { - "Fn::Not": [ - { - "Fn::Contains": [ - [ - "1", - "2", - "3", - "4", - "5" - ], - { - "Ref": "BootstrapVersion" - } - ] - } - ] - }, - "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." - } - ] - } - } -} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/tree.json deleted file mode 100644 index 5305c03452288..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.js.snapshot/tree.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"tree-0.1","tree":{"id":"App","path":"","constructInfo":{"fqn":"aws-cdk-lib.App","version":"0.0.0"},"children":{"aws-cdk-transformer-integ":{"id":"aws-cdk-transformer-integ","path":"aws-cdk-transformer-integ","constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"},"children":{"MyLogGroup":{"id":"MyLogGroup","path":"aws-cdk-transformer-integ/MyLogGroup","constructInfo":{"fqn":"aws-cdk-lib.aws_logs.LogGroup","version":"0.0.0","metadata":["*"]},"children":{"Resource":{"id":"Resource","path":"aws-cdk-transformer-integ/MyLogGroup/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_logs.CfnLogGroup","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::Logs::LogGroup","aws:cdk:cloudformation:props":{"retentionInDays":731}}},"Transformer":{"id":"Transformer","path":"aws-cdk-transformer-integ/MyLogGroup/Transformer","constructInfo":{"fqn":"aws-cdk-lib.aws_logs.Transformer","version":"0.0.0","metadata":[]}},"ResourceTransformer":{"id":"ResourceTransformer","path":"aws-cdk-transformer-integ/MyLogGroup/ResourceTransformer","constructInfo":{"fqn":"aws-cdk-lib.aws_logs.CfnTransformer","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::Logs::Transformer","aws:cdk:cloudformation:props":{"logGroupIdentifier":{"Ref":"MyLogGroup5C0DAD85"},"transformerConfig":[{"parseJson":{"source":"customField"}},{"addKeys":{"entries":[{"overwriteIfExists":true,"key":"test_key1","value":"test_value1"},{"overwriteIfExists":false,"key":"test_key2","value":"test_value2"},{"overwriteIfExists":false,"key":"test_key3","value":"test_value3"}]}}]}}}}},"BootstrapVersion":{"id":"BootstrapVersion","path":"aws-cdk-transformer-integ/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"aws-cdk-transformer-integ/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}}},"transformer-create":{"id":"transformer-create","path":"transformer-create","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTest","version":"0.0.0"},"children":{"DefaultTest":{"id":"DefaultTest","path":"transformer-create/DefaultTest","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTestCase","version":"0.0.0"},"children":{"Default":{"id":"Default","path":"transformer-create/DefaultTest/Default","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}},"DeployAssert":{"id":"DeployAssert","path":"transformer-create/DefaultTest/DeployAssert","constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"},"children":{"BootstrapVersion":{"id":"BootstrapVersion","path":"transformer-create/DefaultTest/DeployAssert/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"transformer-create/DefaultTest/DeployAssert/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}}}}}}},"Tree":{"id":"Tree","path":"Tree","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}}}}} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.ts deleted file mode 100644 index f3007e883e19c..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.loggroup-transformer.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { IntegTest } from '@aws-cdk/integ-tests-alpha'; -import { App, Stack, StackProps } from 'aws-cdk-lib'; -import { JsonMutatorType, LogGroup, ParserProcessorType, ParserProcessor, JsonMutatorProcessor } from 'aws-cdk-lib/aws-logs'; - -class TransformerIntegStack extends Stack { - constructor(scope: App, id: string, props?: StackProps) { - super(scope, id, props); - - const logGroup = new LogGroup(this, 'MyLogGroup'); - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - jsonOptions: { source: 'customField' }, - }); - - const addKeysProcesor = new JsonMutatorProcessor({ - type: JsonMutatorType.ADD_KEYS, - addKeysOptions: { - entries: [ - { key: 'test_key1', value: 'test_value1', overwriteIfExists: true }, - { key: 'test_key2', value: 'test_value2' }, - { key: 'test_key3', value: 'test_value3', overwriteIfExists: false }, - ], - }, - }); - - logGroup.addTransformer('Transformer', { - transformerName: 'MyTransformer', - transformerConfig: [jsonParser, addKeysProcesor], - }); - } -} - -const app = new App(); -const testCase = new TransformerIntegStack(app, 'aws-cdk-transformer-integ'); -new IntegTest(app, 'transformer-create', { - testCases: [testCase], -}); diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/aws-cdk-transformer-integ.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/aws-cdk-transformer-integ.assets.json deleted file mode 100644 index 609b1580809ba..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/aws-cdk-transformer-integ.assets.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "version": "44.0.0", - "files": { - "98ed9e9f12479f2bfbf981dcddb16d222c19274f2c84a93301e254e9f2560d64": { - "displayName": "aws-cdk-transformer-integ Template", - "source": { - "path": "aws-cdk-transformer-integ.template.json", - "packaging": "file" - }, - "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "98ed9e9f12479f2bfbf981dcddb16d222c19274f2c84a93301e254e9f2560d64.json", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" - } - } - } - }, - "dockerImages": {} -} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/aws-cdk-transformer-integ.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/aws-cdk-transformer-integ.template.json deleted file mode 100644 index 2f8afcee0161d..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/aws-cdk-transformer-integ.template.json +++ /dev/null @@ -1,61 +0,0 @@ -{ - "Resources": { - "MyLogGroup5C0DAD85": { - "Type": "AWS::Logs::LogGroup", - "Properties": { - "RetentionInDays": 731 - }, - "UpdateReplacePolicy": "Retain", - "DeletionPolicy": "Retain" - }, - "ResourceTransformer": { - "Type": "AWS::Logs::Transformer", - "Properties": { - "LogGroupIdentifier": { - "Ref": "MyLogGroup5C0DAD85" - }, - "TransformerConfig": [ - { - "ParseJSON": { - "Source": "customField" - } - } - ] - } - } - }, - "Parameters": { - "BootstrapVersion": { - "Type": "AWS::SSM::Parameter::Value", - "Default": "/cdk-bootstrap/hnb659fds/version", - "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" - } - }, - "Rules": { - "CheckBootstrapVersion": { - "Assertions": [ - { - "Assert": { - "Fn::Not": [ - { - "Fn::Contains": [ - [ - "1", - "2", - "3", - "4", - "5" - ], - { - "Ref": "BootstrapVersion" - } - ] - } - ] - }, - "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." - } - ] - } - } -} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/cdk.out deleted file mode 100644 index b3a26d44a5f73..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/cdk.out +++ /dev/null @@ -1 +0,0 @@ -{"version":"44.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/integ.json deleted file mode 100644 index 50064d6172409..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/integ.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "version": "44.0.0", - "testCases": { - "transformer-create/DefaultTest": { - "stacks": [ - "aws-cdk-transformer-integ" - ], - "assertionStack": "transformer-create/DefaultTest/DeployAssert", - "assertionStackName": "transformercreateDefaultTestDeployAssertB915E804" - } - }, - "minimumCliVersion": "2.1019.2" -} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/manifest.json deleted file mode 100644 index 4f7ef1b8d5e14..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/manifest.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "version": "44.0.0", - "artifacts": { - "aws-cdk-transformer-integ.assets": { - "type": "cdk:asset-manifest", - "properties": { - "file": "aws-cdk-transformer-integ.assets.json", - "requiresBootstrapStackVersion": 6, - "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" - } - }, - "aws-cdk-transformer-integ": { - "type": "aws:cloudformation:stack", - "environment": "aws://unknown-account/unknown-region", - "properties": { - "templateFile": "aws-cdk-transformer-integ.template.json", - "terminationProtection": false, - "validateOnSynth": false, - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", - "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/98ed9e9f12479f2bfbf981dcddb16d222c19274f2c84a93301e254e9f2560d64.json", - "requiresBootstrapStackVersion": 6, - "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", - "additionalDependencies": [ - "aws-cdk-transformer-integ.assets" - ], - "lookupRole": { - "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", - "requiresBootstrapStackVersion": 8, - "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" - } - }, - "dependencies": [ - "aws-cdk-transformer-integ.assets" - ], - "metadata": { - "/aws-cdk-transformer-integ/MyLogGroup": [ - { - "type": "aws:cdk:analytics:construct", - "data": "*" - }, - { - "type": "warning", - "data": "Transformers can only be created for log groups in the Standard log class. Ensure that your log group is using the Standard log class." - } - ], - "/aws-cdk-transformer-integ/MyLogGroup/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "MyLogGroup5C0DAD85" - } - ], - "/aws-cdk-transformer-integ/ResourceTransformer": [ - { - "type": "aws:cdk:logicalId", - "data": "ResourceTransformer" - } - ], - "/aws-cdk-transformer-integ/BootstrapVersion": [ - { - "type": "aws:cdk:logicalId", - "data": "BootstrapVersion" - } - ], - "/aws-cdk-transformer-integ/CheckBootstrapVersion": [ - { - "type": "aws:cdk:logicalId", - "data": "CheckBootstrapVersion" - } - ] - }, - "displayName": "aws-cdk-transformer-integ" - }, - "transformercreateDefaultTestDeployAssertB915E804.assets": { - "type": "cdk:asset-manifest", - "properties": { - "file": "transformercreateDefaultTestDeployAssertB915E804.assets.json", - "requiresBootstrapStackVersion": 6, - "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" - } - }, - "transformercreateDefaultTestDeployAssertB915E804": { - "type": "aws:cloudformation:stack", - "environment": "aws://unknown-account/unknown-region", - "properties": { - "templateFile": "transformercreateDefaultTestDeployAssertB915E804.template.json", - "terminationProtection": false, - "validateOnSynth": false, - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", - "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", - "requiresBootstrapStackVersion": 6, - "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", - "additionalDependencies": [ - "transformercreateDefaultTestDeployAssertB915E804.assets" - ], - "lookupRole": { - "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", - "requiresBootstrapStackVersion": 8, - "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" - } - }, - "dependencies": [ - "transformercreateDefaultTestDeployAssertB915E804.assets" - ], - "metadata": { - "/transformer-create/DefaultTest/DeployAssert/BootstrapVersion": [ - { - "type": "aws:cdk:logicalId", - "data": "BootstrapVersion" - } - ], - "/transformer-create/DefaultTest/DeployAssert/CheckBootstrapVersion": [ - { - "type": "aws:cdk:logicalId", - "data": "CheckBootstrapVersion" - } - ] - }, - "displayName": "transformer-create/DefaultTest/DeployAssert" - }, - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - } - } - }, - "minimumCliVersion": "2.1019.2" -} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/transformercreateDefaultTestDeployAssertB915E804.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/transformercreateDefaultTestDeployAssertB915E804.assets.json deleted file mode 100644 index 82dcb23a9b5cb..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/transformercreateDefaultTestDeployAssertB915E804.assets.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "version": "44.0.0", - "files": { - "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { - "displayName": "transformercreateDefaultTestDeployAssertB915E804 Template", - "source": { - "path": "transformercreateDefaultTestDeployAssertB915E804.template.json", - "packaging": "file" - }, - "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" - } - } - } - }, - "dockerImages": {} -} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/transformercreateDefaultTestDeployAssertB915E804.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/transformercreateDefaultTestDeployAssertB915E804.template.json deleted file mode 100644 index ad9d0fb73d1dd..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/transformercreateDefaultTestDeployAssertB915E804.template.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "Parameters": { - "BootstrapVersion": { - "Type": "AWS::SSM::Parameter::Value", - "Default": "/cdk-bootstrap/hnb659fds/version", - "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" - } - }, - "Rules": { - "CheckBootstrapVersion": { - "Assertions": [ - { - "Assert": { - "Fn::Not": [ - { - "Fn::Contains": [ - [ - "1", - "2", - "3", - "4", - "5" - ], - { - "Ref": "BootstrapVersion" - } - ] - } - ] - }, - "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." - } - ] - } - } -} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/tree.json deleted file mode 100644 index 504740fdc2807..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.js.snapshot/tree.json +++ /dev/null @@ -1 +0,0 @@ -{"version":"tree-0.1","tree":{"id":"App","path":"","constructInfo":{"fqn":"aws-cdk-lib.App","version":"0.0.0"},"children":{"aws-cdk-transformer-integ":{"id":"aws-cdk-transformer-integ","path":"aws-cdk-transformer-integ","constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"},"children":{"MyLogGroup":{"id":"MyLogGroup","path":"aws-cdk-transformer-integ/MyLogGroup","constructInfo":{"fqn":"aws-cdk-lib.aws_logs.LogGroup","version":"0.0.0","metadata":["*"]},"children":{"Resource":{"id":"Resource","path":"aws-cdk-transformer-integ/MyLogGroup/Resource","constructInfo":{"fqn":"aws-cdk-lib.aws_logs.CfnLogGroup","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::Logs::LogGroup","aws:cdk:cloudformation:props":{"retentionInDays":731}}}}},"Transformer":{"id":"Transformer","path":"aws-cdk-transformer-integ/Transformer","constructInfo":{"fqn":"aws-cdk-lib.aws_logs.Transformer","version":"0.0.0","metadata":[]}},"ResourceTransformer":{"id":"ResourceTransformer","path":"aws-cdk-transformer-integ/ResourceTransformer","constructInfo":{"fqn":"aws-cdk-lib.aws_logs.CfnTransformer","version":"0.0.0"},"attributes":{"aws:cdk:cloudformation:type":"AWS::Logs::Transformer","aws:cdk:cloudformation:props":{"logGroupIdentifier":{"Ref":"MyLogGroup5C0DAD85"},"transformerConfig":[{"parseJson":{"source":"customField"}}]}}},"BootstrapVersion":{"id":"BootstrapVersion","path":"aws-cdk-transformer-integ/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"aws-cdk-transformer-integ/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}}},"transformer-create":{"id":"transformer-create","path":"transformer-create","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTest","version":"0.0.0"},"children":{"DefaultTest":{"id":"DefaultTest","path":"transformer-create/DefaultTest","constructInfo":{"fqn":"@aws-cdk/integ-tests-alpha.IntegTestCase","version":"0.0.0"},"children":{"Default":{"id":"Default","path":"transformer-create/DefaultTest/Default","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}},"DeployAssert":{"id":"DeployAssert","path":"transformer-create/DefaultTest/DeployAssert","constructInfo":{"fqn":"aws-cdk-lib.Stack","version":"0.0.0"},"children":{"BootstrapVersion":{"id":"BootstrapVersion","path":"transformer-create/DefaultTest/DeployAssert/BootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnParameter","version":"0.0.0"}},"CheckBootstrapVersion":{"id":"CheckBootstrapVersion","path":"transformer-create/DefaultTest/DeployAssert/CheckBootstrapVersion","constructInfo":{"fqn":"aws-cdk-lib.CfnRule","version":"0.0.0"}}}}}}}},"Tree":{"id":"Tree","path":"Tree","constructInfo":{"fqn":"constructs.Construct","version":"10.4.2"}}}}} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.ts deleted file mode 100644 index fa9090827a613..0000000000000 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-logs/test/integ.transformer.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { IntegTest } from '@aws-cdk/integ-tests-alpha'; -import { App, Stack, StackProps } from 'aws-cdk-lib'; -import { LogGroup, ParserProcessorType, ParserProcessor, Transformer } from 'aws-cdk-lib/aws-logs'; - -class TransformerIntegStack extends Stack { - constructor(scope: App, id: string, props?: StackProps) { - super(scope, id, props); - - const logGroup = new LogGroup(this, 'MyLogGroup'); - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - jsonOptions: { source: 'customField' }, - }); - - new Transformer(this, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser], - }); - } -} - -const app = new App(); -const testCase = new TransformerIntegStack(app, 'aws-cdk-transformer-integ'); -new IntegTest(app, 'transformer-create', { - testCases: [testCase], -}); diff --git a/packages/aws-cdk-lib/aws-logs/README.md b/packages/aws-cdk-lib/aws-logs/README.md index 96337e258b03b..65e3c26a008e9 100644 --- a/packages/aws-cdk-lib/aws-logs/README.md +++ b/packages/aws-cdk-lib/aws-logs/README.md @@ -481,67 +481,6 @@ new logs.LogGroup(this, 'LogGroup', { }); ``` -## Transformer - -A log transformer enables transforming log events into a different format, making them easier -to process and analyze. You can transform logs from different sources into standardized formats -that contain relevant, source-specific information. Transformations are performed at the time of log ingestion. -Transformers support several types of processors which can be chained into a processing pipeline (subject to some restrictions, see [Usage Limits](#usage-limits)). - -### Processor Types - -1. **Parser Processors**: Parse string log events into structured log events. These are configurable parsers created using `ParserProcessor`, and support conversion to a format like Json, extracting fields from CSV input, converting vended sources to [OCSF](https://schema.ocsf.io/1.1.0/) format, regex parsing using Grok patterns or key-value parsing. Refer [configurable parsers](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CloudWatch-Logs-Transformation-Processors.html#CloudWatch-Logs-Transformation-Configurable) for more examples. - -2. **Vended Log Parsers**: Parse log events from vended sources into structured log events. These are created using `VendedLogParser`, and support conversion from sources such as AWS WAF, PostGres, Route53, CloudFront and VPC. These parsers are not configurable, meaning these can be added to the pipeline but do not accept any properties or configurations. Refer [vended log parsers](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CloudWatch-Logs-Transformation-Processors.html#CloudWatch-Logs-Transformation-BuiltIn) for more examples. - -3. **String Mutators**: Perform operations on string values in a field of a log event and are created using `StringMutatorProcessor`. These can be used to format string values in the log event such as changing case, removing trailing whitespaces or extracting values from a string field by splitting the string or regex backreferences. Refer [string mutators](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CloudWatch-Logs-Transformation-Processors.html#CloudWatch-Logs-Transformation-StringMutate) for more examples. - -4. **JSON Mutators**: Perform operation on JSON log events and are created using `JsonMutatorProcessor`. These processors can be used to enrich log events by adding new fields, deleting, moving, renaming fields, copying values to other fields or converting a list of key-value pairs to a map. Refer [JSON mutators](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CloudWatch-Logs-Transformation-Processors.html#CloudWatch-Logs-Transformation-JSONMutate) for more examples. - -5. **Data Converters**: Convert the data into different formats and are created using `DataConverterProcessor`. These can be used to convert values in a field to datatypes such as integers, string, double and boolean or to convert dates and times to different formats. Refer [datatype processors](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CloudWatch-Logs-Transformation-Processors.html#CloudWatch-Logs-Transformation-Datatype) for more examples. - -### Usage Limits - -- A transformer can have a maximum of 20 processors -- At least one parser-type processor is required -- Maximum of 5 parser-type processors allowed -- AWS vended log parser (if used) must be the first processor -- Only one parseToOcsf processor, one grok processor, one addKeys processor, and one copyValue processor allowed per transformer -- Transformers can only be used with log groups in the Standard log class - -Example: - -```ts - -// Create a log group -const logGroup = new logs.LogGroup(this, 'MyLogGroup'); - -// Create a JSON parser processor -const jsonParser = new logs.ParserProcessor({ - type: logs.ParserProcessorType.JSON -}); - -// Create a processor to add keys -const addKeysProcessor = new logs.JsonMutatorProcessor({ - type: logs.JsonMutatorType.ADD_KEYS, - addKeysOptions: { - entries: [{ - key: 'metadata.transformed_in', - value: 'CloudWatchLogs' - }] - } -}); - -// Create a transformer with these processors -new logs.Transformer(this, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser, addKeysProcessor] -}); -``` - -For more details on CloudWatch Logs transformation processors, refer to the [AWS documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CloudWatch-Logs-Transformation-Processors.html). - ## Notes Be aware that Log Group ARNs will always have the string `:*` appended to diff --git a/packages/aws-cdk-lib/aws-logs/lib/index.ts b/packages/aws-cdk-lib/aws-logs/lib/index.ts index 43dbbbe189eea..19981d33d8e7d 100644 --- a/packages/aws-cdk-lib/aws-logs/lib/index.ts +++ b/packages/aws-cdk-lib/aws-logs/lib/index.ts @@ -9,7 +9,6 @@ export * from './policy'; export * from './query-definition'; export * from './data-protection-policy'; export * from './field-index-policy'; -export * from './transformer'; // AWS::Logs CloudFormation Resources: export * from './logs.generated'; diff --git a/packages/aws-cdk-lib/aws-logs/lib/log-group.ts b/packages/aws-cdk-lib/aws-logs/lib/log-group.ts index 27916e9ba5698..e3d660cabf9ab 100644 --- a/packages/aws-cdk-lib/aws-logs/lib/log-group.ts +++ b/packages/aws-cdk-lib/aws-logs/lib/log-group.ts @@ -7,7 +7,6 @@ import { MetricFilter } from './metric-filter'; import { FilterPattern, IFilterPattern } from './pattern'; import { ResourcePolicy } from './policy'; import { ILogSubscriptionDestination, SubscriptionFilter } from './subscription-filter'; -import { IProcessor, Transformer } from './transformer'; import * as cloudwatch from '../../aws-cloudwatch'; import * as iam from '../../aws-iam'; import * as kms from '../../aws-kms'; @@ -53,14 +52,6 @@ export interface ILogGroup extends iam.IResourceWithPolicy { */ addMetricFilter(id: string, props: MetricFilterOptions): MetricFilter; - /** - * Create a new Transformer on this Log Group - * - * @param id Unique identifier for the construct in its parent - * @param props Properties for creating the Transformer - */ - addTransformer(id: string, props: TransformerOptions): Transformer; - /** * Extract a metric from structured log events in the LogGroup * @@ -179,19 +170,6 @@ abstract class LogGroupBase extends Resource implements ILogGroup { }); } - /** - * Create a new Transformer on this Log Group - * - * @param id Unique identifier for the construct in its parent - * @param props Properties for creating the Transformer - */ - public addTransformer(id: string, props: TransformerOptions): Transformer { - return new Transformer(this, id, { - logGroup: this, - ...props, - }); - } - /** * Extract a metric from structured log events in the LogGroup * @@ -813,13 +791,3 @@ export interface MetricFilterOptions { */ readonly filterName?: string; } - -/** - * Properties for Transformer created from LogGroup. - */ -export interface TransformerOptions { - /** Name of the transformer. */ - readonly transformerName: string; - /** List of processors in a transformer */ - readonly transformerConfig: Array; -} diff --git a/packages/aws-cdk-lib/aws-logs/lib/transformer.ts b/packages/aws-cdk-lib/aws-logs/lib/transformer.ts deleted file mode 100644 index f4c37234bb7d5..0000000000000 --- a/packages/aws-cdk-lib/aws-logs/lib/transformer.ts +++ /dev/null @@ -1,1336 +0,0 @@ -/** - * Generated TypeScript code for L2 Construct Design: AWS Logs Transformer - * - * This file contains TypeScript definitions for the AWS Logs Transformer L2 Construct. - * - * A log transformer enables transforming log events into a different format, making them easier - * to process and analyze. You can also transform logs from different sources into standardized formats - * that contain relevant, source-specific information. - * - * After you create a transformer, CloudWatch performs the transformations at the time of log ingestion. - * You can then refer to the transformed versions of the logs during operations such as - * querying with CloudWatch Logs Insights or creating metric filters or subscription filters. - * - * Resource Structure: - * - AWS::Logs::Transformer: Interface (ITransformer) directly implemented by concrete classes (Transformer) - * This follows a direct implementation pattern where concrete classes implement the interface directly without a shared base class. - */ - -import { Construct } from 'constructs'; -import { CfnTransformer } from '.'; -import { ILogGroup } from './log-group'; -import { Resource, Token, ValidationError, UnscopedValidationError } from '../../core'; -import { propertyInjectable } from '../../core/lib/prop-injectable'; - -/** - * Valid data types for type conversion in the TypeConverter processor. - * Used to specify the target data type for field conversion. - */ -export enum TypeConverterType { - /** Convert value to boolean type */ - BOOLEAN = 'boolean', - /** Convert value to integer type */ - INTEGER = 'integer', - /** Convert value to double (floating point) type */ - DOUBLE = 'double', - /** Convert value to string type */ - STRING = 'string', -} - -/** - * Standard datetime formats for the DateTimeConverter processor. - * Provides common format patterns for date/time conversion. - */ -export enum DateTimeFormat { - /** ISO 8601 format (yyyy-MM-ddTHH:mm:ssZ) */ - ISO_8601 = 'yyyy-MM-dd\'T\'HH:mm:ss\'Z\'', - /** Unix timestamp (seconds since epoch) */ - UNIX_TIMESTAMP = 'epoch', - /** Custom format specified by the targetFormat parameter */ - CUSTOM = 'custom', -} - -/** - * Valid delimiter characters for CSV processor. - * Defines the character used to separate each column in CSV data. - */ -export enum DelimiterCharacter { - /** Comma character */ - COMMA = ',', - /** Tab character */ - TAB = '\t', - /** Space character */ - SPACE = ' ', - /** Semicolon character */ - SEMICOLON = ';', - /** Pipe character */ - PIPE = '|', -} - -/** - * Valid quote characters for CSV processor. - * Defines the character used as a text qualifier for a single column of data. - */ -export enum QuoteCharacter { - /** Double quote character (default) */ - DOUBLE_QUOTE = '"', - /** Single quote character */ - SINGLE_QUOTE = '\'', -} - -/** - * Valid field delimiters for ParseKeyValue processor. - * Defines the delimiter string used between key-value pairs in the original log events. - */ -export enum KeyValuePairDelimiter { - /** Ampersand character (default) */ - AMPERSAND = '&', - /** Semicolon character */ - SEMICOLON = ';', - /** Space character */ - SPACE = ' ', - /** Newline character */ - NEWLINE = '\n', -} - -/** - * Valid key-value delimiters for ParseKeyValue processor. - * Defines the delimiter string to use between the key and value in each pair. - */ -export enum KeyValueDelimiter { - /** Equal sign (default) */ - EQUAL = '=', - /** Colon character */ - COLON = ':', -} - -/** - * Types of event sources supported to convert to OCSF format. - */ -export enum OCSFSourceType { - /** Log events from CloudTrail */ - CLOUD_TRAIL = 'CloudTrail', - /** Log events from Route53Resolver */ - ROUTE53_RESOLVER = 'Route53Resolver', - /** Log events from VPCFlow */ - VPC_FLOW = 'VPCFlow', - /** Log events from EKSAudit */ - EKS_AUDIT = 'EKSAudit', - /** Log events from AWSWAF */ - AWS_WAF = 'AWSWAF', -} - -/** - * OCSF Schema versions supported by transformers. - */ -export enum OCSFVersion { - /** - * OCSF schema version 1.1. - * @see https://schema.ocsf.io/1.1.0/ - */ - V1_1 = 'V1.1', -} - -/** - * Types of configurable parser processors. - * Defines the various parser types that can be used to process log events. - */ -export enum ParserProcessorType { - /** Parse log entries as JSON */ - JSON, - /** Parse log entries as key-value pairs */ - KEY_VALUE, - /** Parse log entries in CSV format */ - CSV, - /** Parse log entries using Grok patterns */ - GROK, - /** Parse logs to OCSF format */ - OCSF, -} - -/** - * Types of AWS vended logs with built-in parsers. - * AWS provides specialized parsers for common log formats produced by various AWS services. - */ -export enum VendedLogType { - /** Parse CloudFront logs */ - CLOUDFRONT, - /** Parse VPC flow logs */ - VPC, - /** Parse AWS WAF logs */ - WAF, - /** Parse Route 53 logs */ - ROUTE53, - /** Parse PostgreSQL logs */ - POSTGRES, -} - -/** - * Types of string mutation operations. - * Defines various operations that can be performed to modify string values in log events. - */ -export enum StringMutatorType { - /** Convert strings to lowercase */ - LOWER_CASE, - /** Convert strings to uppercase */ - UPPER_CASE, - /** Trim whitespace from strings */ - TRIM, - /** Split strings by delimiter */ - SPLIT, - /** Replace substrings in strings */ - SUBSTITUTE, -} - -/** - * Types of JSON mutation operations. - * Defines operations that can be performed to modify the JSON structure of log events. - */ -export enum JsonMutatorType { - /** Add new keys to the log event */ - ADD_KEYS, - /** Delete keys from the log event */ - DELETE_KEYS, - /** Move keys to different locations */ - MOVE_KEYS, - /** Rename keys in the log event */ - RENAME_KEYS, - /** Copy values between keys */ - COPY_VALUE, - /** Convert a list to a map */ - LIST_TO_MAP, -} - -/** - * Types of data conversion operations. - * Defines operations that can convert data from one format to another. - */ -export enum DataConverterType { - /** Convert data types */ - TYPE_CONVERTER, - /** Convert datetime formats */ - DATETIME_CONVERTER, -} - -/** - * Processor to parse events from CloudTrail, Route53Resolver, VPCFlow, EKSAudit and AWSWAF into OCSF V1.1 format. - */ -export interface ParseToOCSFProperty { - /** - * Path to the field in the log event that will be parsed. Use dot notation to access child fields. - * @default '@message' - */ - readonly source?: string; - - /** - * Type of input log event source to convert to OCSF format. - */ - readonly eventSource: OCSFSourceType; - - /** - * Version of OCSF schema to convert to. - */ - readonly ocsfVersion: OCSFVersion; -} - -/** - * This processor parses log events that are in JSON format. It can extract JSON key-value pairs and place them - * under a destination that you specify. - * Additionally, because you must have at least one parse-type processor in a transformer, you can use ParseJSON as that - * processor for JSON-format logs, so that you can also apply other processors, such as mutate processors, to these logs. - * For more information about this processor including examples, see parseJSON in the CloudWatch Logs User Guide. - */ -export interface ParseJSONProperty { - /** - * Path to the field in the log event that will be parsed. Use dot notation to access child fields. - * @default '@message' - */ - readonly source?: string; - /** - * The location to put the parsed key value pair into. - * @default - Placed under root of log event - */ - readonly destination?: string; -} - -/** - * This processor parses a specified field in the original log event into key-value pairs. - * For more information about this processor including examples, see parseKeyValue in the CloudWatch Logs User Guide. - */ -export interface ParseKeyValueProperty { - /** - * Path to the field in the log event that will be parsed. Use dot notation to access child fields. - * @default '@message' - */ - readonly source?: string; - /** - * The destination field to put the extracted key-value pairs into. - * @default - Places at the root of the JSON input. - */ - readonly destination?: string; - /** - * The field delimiter string that is used between key-value pairs in the original log events. - * @default KeyValuePairDelimiter.AMPERSAND - */ - readonly fieldDelimiter?: KeyValuePairDelimiter; - /** - * The delimiter string to use between the key and value in each pair in the transformed log event. - * @default KeyValueDelimiter.EQUAL - */ - readonly keyValueDelimiter?: KeyValueDelimiter; - /** - * If you want to add a prefix to all transformed keys, specify it here. - * @default - No prefix is added to the keys. - */ - readonly keyPrefix?: string; - /** - * A value to insert into the value field in the result, when a key-value pair is not successfully split. - * @default - No values is inserted when split is not successful. - */ - readonly nonMatchValue?: string; - /** - * Specifies whether to overwrite the value if the destination key already exists. - * @default false - */ - readonly overwriteIfExists?: boolean; -} - -/** - * Copy Value processor, copies values from source to target for each entry. - */ -export interface CopyValueProperty { - /** - * List of sources and target to copy. - */ - readonly entries: Array; -} - -/** - * The CSV processor parses comma-separated values (CSV) from the log events into columns. - * For more information about this processor including examples, see csv in the CloudWatch Logs User Guide. - */ -export interface CsvProperty { - /** - * Character used as a text qualifier for a single column of data. - * @default QuoteCharacter.DOUBLE_QUOTE - */ - readonly quoteCharacter?: QuoteCharacter; - /** - * Character used to separate each column in the original comma-separated value log event. - * @default DelimiterCharacter.COMMA - */ - readonly delimiter?: DelimiterCharacter; - /** - * The path to the field in the log event that has the comma separated values to be parsed. - * @default '@message' - */ - readonly source?: string; - /** - * An array of names to use for the columns in the transformed log event. - * @default - Column names ([column_1, column_2 ...]) are used - */ - readonly columns?: Array; -} - -/** - * This processor converts a datetime string into a format that you specify. - * For more information about this processor including examples, see datetimeConverter in the CloudWatch Logs User Guide. - */ -export interface DateTimeConverterProperty { - /** - * The key to apply the date conversion to. - */ - readonly source: string; - - /** - * The JSON field to store the result in. - */ - readonly target: string; - - /** - * The datetime format to use for the converted data in the target field. - * @default "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" - */ - readonly targetFormat?: string; - - /** - * A list of patterns to match against the source field. - */ - readonly matchPatterns: Array; - - /** - * The time zone of the source field. - * @default UTC - */ - readonly sourceTimezone?: string; - - /** - * The time zone of the target field. - * @default UTC - */ - readonly targetTimezone?: string; - - /** - * The locale of the source field. - */ - readonly locale: string; -} - -/** - * This processor uses pattern matching to parse and structure unstructured data. This processor can also extract fields from log messages. - * For more information about this processor including examples, see grok in the CloudWatch Logs User Guide. - */ -export interface GrokProperty { - /** - * The path to the field in the log event that you want to parse. - * @default '@message' - */ - readonly source?: string; - - /** - * The grok pattern to match against the log event. For a list of supported grok patterns, - * see Supported grok patterns in the CloudWatch Logs User Guide. - */ - readonly match: string; -} - -/** - * This processor takes a list of objects that contain key fields, and converts them into a map of target keys. - * For more information about this processor including examples, see listToMap in the CloudWatch Logs User Guide. - */ -export interface ListToMapProperty { - /** - * The key in the log event that has a list of objects that will be converted to a map. - */ - readonly source: string; - - /** - * The key of the field to be extracted as keys in the generated map. - */ - readonly key: string; - - /** - * If this is specified, the values that you specify in this parameter will be extracted from the source objects - * and put into the values of the generated map. - * @default - Original objects in the source list will be put into the values of the generated map - */ - readonly valueKey?: string; - - /** - * The key of the field that will hold the generated map. - * @default - Stored at the root of the log event - */ - readonly target?: string; - - /** - * A Boolean value to indicate whether the list will be flattened into single items. - * @default false - */ - readonly flatten?: boolean; - - /** - * If you set flatten to true, use flattenedElement to specify which element, first or last, to keep. - * You must specify this parameter if flatten is true. - * @default - Must be specified if flatten is true and if flatten is false, has no effect - */ - readonly flattenedElement?: string; -} - -/** - * This processor adds new key-value pairs to the log event. - * For more information about this processor including examples, see addKeys in the CloudWatch Logs User Guide. - */ -export interface AddKeysProperty { - /** - * An array of objects, where each object contains information about one key to add to the log event. - */ - readonly entries: Array; -} - -/** - * This processor adds new key-value pairs to the log event. - * For more information about this processor including examples, see addKeys in the CloudWatch Logs User Guide. - */ -export interface ProcessorDeleteKeysProperty { - /** - * A list of keys to delete - */ - readonly withKeys: Array; -} - -/** - * This processor copies values within a log event. - * You can also use this processor to add metadata to log events by copying values from metadata keys. - * For more information about this processor including examples, see copyValue in the CloudWatch Logs User Guide. - */ -export interface CopyValueProperty { - /** - * An array of CopyValueEntry objects, where each object contains information about one field value to copy. - */ - readonly entries: Array; -} - -/** - * This processor moves a key from one field to another. The original key is deleted. - * For more information about this processor including examples, see moveKeys in the CloudWatch Logs User Guide. - */ -export interface MoveKeysProperty { - /** - * An array of objects, where each object contains information about one key to move. - */ - readonly entries: Array; -} - -/** - * Use this processor to rename keys in a log event. - * For more information about this processor including examples, see renameKeys in the CloudWatch Logs User Guide. - */ -export interface RenameKeysProperty { - /** - * An array of RenameKeyEntry objects, where each object contains information about one key to rename. - */ - readonly entries: Array; -} - -/** - * Use this processor to split a field into an array of strings using a delimiting character. - * For more information about this processor including examples, see splitString in the CloudWatch Logs User Guide. - */ -export interface SplitStringProperty { - /** - * An array of SplitStringEntry objects, where each object contains information about one field to split. - */ - readonly entries: Array; -} - -/** - * This processor matches a key's value against a regular expression and replaces all matches with a replacement string. - * For more information about this processor including examples, see substituteString in the CloudWatch Logs User Guide. - */ -export interface SubstituteStringProperty { - /** - * An array of objects, where each object contains information about one key to match and replace. - */ - readonly entries: Array; -} - -/** - * Use this processor to convert a value type associated with the specified key to the specified type. - * It's a casting processor that changes the types of the specified fields. - * For more information about this processor including examples, see typeConverter in the CloudWatch Logs User Guide. - */ -export interface TypeConverterProperty { - /** - * An array of TypeConverterEntry objects, where each object contains information about one field to change the type of. - */ - readonly entries: Array; -} - -/** - * Interface representing a single processor in a CloudWatch Logs transformer. - * A log transformer is a series of processors, where each processor applies one type of transformation - * to the log events. The processors work one after another, in the order that they are listed, like a pipeline. - */ -export interface IProcessor { - /** - * Returns the L1 processor configuration - * @internal - */ - _render(): any; -} - -/** Base properties for all processor types */ -export interface BaseProcessorProps { -} - -/** Properties for creating configurable parser processors */ -export interface ParserProcessorProps extends BaseProcessorProps { - /** The type of parser processor */ - readonly type: ParserProcessorType; - /** - * Options for JSON parser. Required when type is JSON. - * @default - No JSON parser is created if props not set - */ - readonly jsonOptions?: ParseJSONProperty; - /** - * Options for key-value parser. Required when type is KEY_VALUE. - * @default - No key-value parser is created if props not set - */ - readonly keyValueOptions?: ParseKeyValueProperty; - /** - * Options for CSV parser. Required when type is CSV. - * @default - No CSV parser is created if props not set - */ - readonly csvOptions?: CsvProperty; - /** - * Options for Grok parser. Required when type is GROK. - * @default - No Grok parser is created if props not set - */ - readonly grokOptions?: GrokProperty; - /** - * Options for ParseToOCSF parser. Required when type is set to OCSF - * @default - no OCSF parser is created. - */ - readonly parseToOCSFOptions?: ParseToOCSFProperty; -} - -/** Properties for creating AWS vended log parsers */ -export interface VendedLogParserProps extends BaseProcessorProps { - /** The type of AWS vended log to parse */ - readonly logType: VendedLogType; - /** - * Source field to parse. - * @default @message - */ - readonly source?: string; -} - -/** Properties for creating string mutator processors */ -export interface StringMutatorProps extends BaseProcessorProps { - /** The type of string mutation operation */ - readonly type: StringMutatorType; - /** - * Keys for strings to convert to lowercase. Required when type is LOWER_CASE. - * @default - No lowercase processor is created if props not set - */ - readonly lowerCaseKeys?: Array; - /** - * Keys for strings to convert to uppercase. Required when type is UPPER_CASE. - * @default - No uppercase processor is created if props not set - */ - readonly upperCaseKeys?: Array; - /** - * Keys for strings to trim. Required when type is TRIM. - * @default - No trim processor is created if props not set - */ - readonly trimKeys?: Array; - /** - * Options for string splitting. Required when type is SPLIT. - * @default - No string splitting processor is created if props not set - */ - readonly splitOptions?: SplitStringProperty; - /** - * Options for string substitution. Required when type is SUBSTITUTE. - * @default - No string substitution processor is created if props not set - */ - readonly substituteOptions?: SubstituteStringProperty; -} - -/** Properties for creating JSON mutator processors */ -export interface JsonMutatorProps extends BaseProcessorProps { - /** The type of JSON mutation operation */ - readonly type: JsonMutatorType; - /** - * Options for adding keys. Required when type is ADD_KEYS. - * @default - No adding keys processor is created if props not set - */ - readonly addKeysOptions?: AddKeysProperty; - /** - * Keys to delete. Required when type is DELETE_KEYS. - * @default - No delete key processor is created if props not set - */ - readonly deleteKeysOptions?: ProcessorDeleteKeysProperty; - /** - * Options for moving keys. Required when type is MOVE_KEYS. - * @default - No move key processor is created if props not set - */ - readonly moveKeysOptions?: MoveKeysProperty; - /** - * Options for renaming keys. Required when type is RENAME_KEYS. - * @default - No rename key processor is created if props not set - */ - readonly renameKeysOptions?: RenameKeysProperty; - /** - * Options for copying values. Required when type is COPY_VALUE. - * @default - No copy value processor is created if props not set - */ - readonly copyValueOptions?: CopyValueProperty; - /** - * Options for converting lists to maps. Required when type is LIST_TO_MAP. - * @default - No list-to-map processor is created if props not set - */ - readonly listToMapOptions?: ListToMapProperty; -} - -/** Properties for creating data converter processors */ -export interface DataConverterProps extends BaseProcessorProps { - /** The type of data conversion operation */ - readonly type: DataConverterType; - /** - * Options for type conversion. Required when type is TYPE_CONVERTER. - * @default - No type convertor processor is created if not set - */ - readonly typeConverterOptions?: TypeConverterProperty; - /** - * Options for datetime conversion. Required when type is DATETIME_CONVERTER. - * @default - No date time converter processor is created if not set - */ - readonly dateTimeConverterOptions?: DateTimeConverterProperty; -} - -/** - * This object defines one key that will be added with the addKeys processor. - */ -export interface AddKeyEntryProperty { - /** - * The key of the new entry to be added to the log event. - */ - readonly key: string; - - /** - * The value of the new entry to be added to the log event. - */ - readonly value: string; - /** - * Specifies whether to overwrite the value if the key already exists. - * @default false - */ - readonly overwriteIfExists?: boolean; -} - -/** - * This object defines one value to be copied with the copyValue processor. - */ -export interface CopyValueEntryProperty { - /** - * The key to copy. - */ - readonly source: string; - - /** - * The key of the field to copy the value to. - */ - readonly target: string; - /** - * Specifies whether to overwrite the value if the target key already exists. - * @default false - */ - readonly overwriteIfExists?: boolean; -} - -/** - * This object defines one key that will be moved with the moveKey processor. - */ -export interface MoveKeyEntryProperty { - /** - * The key to move. - */ - readonly source: string; - - /** - * The key to move to. - */ - readonly target: string; - /** - * Specifies whether to overwrite the value if the target key already exists. - * @default false - */ - readonly overwriteIfExists?: boolean; -} - -/** - * This object defines one key that will be renamed with the renameKey processor. - */ -export interface RenameKeyEntryProperty { - /** - * The key to rename. - */ - readonly key: string; - - /** - * The string to use for the new key name. - */ - readonly renameTo: string; - - /** - * Whether to overwrite the target key if it already exists. - * @default false - */ - readonly overwriteIfExists?: boolean; -} - -/** - * This object defines one log field that will be split with the splitString processor. - */ -export interface SplitStringEntryProperty { - /** - * The key of the field to split. - */ - readonly source: string; - - /** The separator character to split the string on */ - readonly delimiter: DelimiterCharacter; -} - -/** - * This object defines one log field key that will be replaced using the substituteString processor. - */ -export interface SubstituteStringEntryProperty { - /** - * The key to modify. - */ - readonly source: string; - - /** - * The regular expression string to be replaced. - */ - readonly from: string; - - /** - * The string to be substituted for each match of from. - */ - readonly to: string; -} - -/** - * This object defines one value type that will be converted using the typeConverter processor. - */ -export interface TypeConverterEntryProperty { - /** - * The key with the value that is to be converted to a different type. - */ - readonly key: string; - - /** The data type to convert the field value to. */ - readonly type: TypeConverterType; -} - -/** - * The Resource properties for AWS::Logs::Transformer resource. This - * interface defines all configuration options for the CfnTransformer construct. - */ -export interface TransformerProps { - /** - * Name of the transformer. - */ - readonly transformerName: string; - /** Existing log group that you want to associate with this transformer. */ - readonly logGroup: ILogGroup; - /** List of processors in a transformer */ - readonly transformerConfig: Array; -} - -/** Parser processor for common data formats */ -export class ParserProcessor implements IProcessor { - /** The type of parser */ - type: ParserProcessorType; - /** Options for JSON parser */ - private jsonOptions?: ParseJSONProperty; - /** Options for key-value parser */ - private keyValueOptions?: ParseKeyValueProperty; - /** Options for CSV parser */ - private csvOptions?: CsvProperty; - /** Options for Grok parser */ - private grokOptions?: GrokProperty; - /** Options for OCSF parser */ - private parseToOCSFOptions?: ParseToOCSFProperty; - - /** Creates a new parser processor */ - constructor(props: ParserProcessorProps) { - this.type = props.type; - - switch (this.type) { - case ParserProcessorType.JSON: - // Apply default values for JSON options - this.jsonOptions = { - source: '@message', - ...props.jsonOptions, - }; - break; - - case ParserProcessorType.KEY_VALUE: - // Apply default values for key-value options - this.keyValueOptions = { - source: '@message', - fieldDelimiter: KeyValuePairDelimiter.AMPERSAND, - keyValueDelimiter: KeyValueDelimiter.EQUAL, - overwriteIfExists: false, - ...props.keyValueOptions, - }; - break; - - case ParserProcessorType.CSV: - // Apply default values for CSV options - this.csvOptions = { - source: '@message', - quoteCharacter: QuoteCharacter.DOUBLE_QUOTE, - delimiter: DelimiterCharacter.COMMA, - ...props.csvOptions, - }; - break; - - case ParserProcessorType.GROK: - if (!props.grokOptions || !props.grokOptions.match) { - throw new UnscopedValidationError('Match pattern is required for Grok parser'); - } - // Apply default values for Grok options - this.grokOptions = { - source: '@message', - ...props.grokOptions, - }; - break; - - case ParserProcessorType.OCSF: - if (!props.parseToOCSFOptions) { - throw new UnscopedValidationError('parseToOCSFOptions must be provided for type OCSF'); - } - this.parseToOCSFOptions = { - source: '@message', - ... props.parseToOCSFOptions, - }; - break; - - default: - throw new UnscopedValidationError(`Unsupported parser processor type: ${this.type}`); - } - } - - /** - * Returns the L1 processor configuration for this parser - * @internal - */ - public _render(): any { - switch (this.type) { - case ParserProcessorType.JSON: - return { parseJson: this.jsonOptions }; - case ParserProcessorType.KEY_VALUE: - return { parseKeyValue: this.keyValueOptions }; - case ParserProcessorType.CSV: - return { csv: this.csvOptions }; - case ParserProcessorType.GROK: - return { grok: this.grokOptions }; - case ParserProcessorType.OCSF: - return { parseToOcsf: this.parseToOCSFOptions }; - default: - throw new UnscopedValidationError(`Unsupported parser processor type: ${this.type}`); - } - } -} - -/** Parser processor for AWS vended logs */ -export class VendedLogParser implements IProcessor { - /** The type of AWS vended log */ - logType: VendedLogType; - - /** Creates a new vended log parser processor */ - constructor(props: VendedLogParserProps) { - this.logType = props.logType; - } - - /** - * Returns the L1 processor configuration for this vended log parser - * @internal - */ - public _render(): any { - switch (this.logType) { - case VendedLogType.CLOUDFRONT: - return { parseCloudfront: { } }; - case VendedLogType.VPC: - return { parseVpc: { } }; - case VendedLogType.WAF: - return { parseWaf: { } }; - case VendedLogType.ROUTE53: - return { parseRoute53: { } }; - case VendedLogType.POSTGRES: - return { parsePostgres: { } }; - default: - throw new UnscopedValidationError(`Unsupported vended log type: ${this.logType}`); - } - } -} - -/** Processor for string mutation operations */ -export class StringMutatorProcessor implements IProcessor { - /** The type of string mutation operation */ - type: StringMutatorType; - /** Keys for strings to convert to lowercase */ - private lowerCaseKeys?: Array; - /** Keys for strings to convert to uppercase */ - private upperCaseKeys?: Array; - /** Keys for strings to trim */ - private trimKeys?: Array; - /** Options for string splitting */ - private splitOptions?: SplitStringProperty; - /** Options for string substitution */ - private substituteOptions?: SubstituteStringProperty; - - /** Creates a new string mutator processor */ - constructor(props: StringMutatorProps) { - this.type = props.type; - - switch (this.type) { - case StringMutatorType.LOWER_CASE: - if (!props.lowerCaseKeys || props.lowerCaseKeys.length === 0) { - throw new UnscopedValidationError('lowerCaseKeys must be provided for LOWER_CASE string mutator'); - } - this.lowerCaseKeys = props.lowerCaseKeys; - break; - - case StringMutatorType.UPPER_CASE: - if (!props.upperCaseKeys || props.upperCaseKeys.length === 0) { - throw new UnscopedValidationError('upperCaseKeys must be provided for UPPER_CASE string mutator'); - } - this.upperCaseKeys = props.upperCaseKeys; - break; - - case StringMutatorType.TRIM: - if (!props.trimKeys || props.trimKeys.length === 0) { - throw new UnscopedValidationError('trimKeys must be provided for TRIM string mutator'); - } - this.trimKeys = props.trimKeys; - break; - - case StringMutatorType.SPLIT: - if (!props.splitOptions || !props.splitOptions.entries || props.splitOptions.entries.length === 0) { - throw new UnscopedValidationError('splitOptions must be provided for SPLIT string mutator'); - } - this.splitOptions = props.splitOptions; - break; - - case StringMutatorType.SUBSTITUTE: - if (!props.substituteOptions || !props.substituteOptions.entries || props.substituteOptions.entries.length === 0) { - throw new UnscopedValidationError('substituteOptions must be provided for SUBSTITUTE string mutator'); - } - this.substituteOptions = props.substituteOptions; - break; - - default: - throw new UnscopedValidationError(`Unsupported string mutator type: ${this.type}`); - } - } - - /** - * Returns the L1 processor configuration for this string mutator - * @internal - */ - public _render(): any { - switch (this.type) { - case StringMutatorType.LOWER_CASE: - return { lowerCaseString: { withKeys: this.lowerCaseKeys } }; - case StringMutatorType.UPPER_CASE: - return { upperCaseString: { withKeys: this.upperCaseKeys } }; - case StringMutatorType.TRIM: - return { trimString: { withKeys: this.trimKeys } }; - case StringMutatorType.SPLIT: - return { splitString: this.splitOptions }; - case StringMutatorType.SUBSTITUTE: - return { substituteString: this.substituteOptions }; - default: - throw new UnscopedValidationError(`Unsupported string mutator type: ${this.type}`); - } - } -} - -/** Processor for JSON mutation operations */ -export class JsonMutatorProcessor implements IProcessor { - /** The type of JSON mutation operation */ - type: JsonMutatorType; - /** Options for adding keys */ - private addKeysOptions?: AddKeysProperty; - /** Keys to delete */ - private deleteKeysOptions?: ProcessorDeleteKeysProperty; - /** Options for moving keys */ - private moveKeysOptions?: MoveKeysProperty; - /** Options for renaming keys */ - private renameKeysOptions?: RenameKeysProperty; - /** Options for copying values */ - private copyValueOptions?: CopyValueProperty; - /** Options for converting lists to maps */ - private listToMapOptions?: ListToMapProperty; - - /** Creates a new JSON mutator processor */ - constructor(props: JsonMutatorProps) { - this.type = props.type; - - switch (this.type) { - case JsonMutatorType.ADD_KEYS: - if (!props.addKeysOptions || !props.addKeysOptions.entries || props.addKeysOptions.entries.length === 0) { - throw new UnscopedValidationError('addKeysOptions must be provided for ADD_KEYS JSON mutator'); - } - this.addKeysOptions = { - entries: props.addKeysOptions.entries.map(entry => { return { overwriteIfExists: false, ...entry }; }), - }; - break; - - case JsonMutatorType.DELETE_KEYS: - if (!props.deleteKeysOptions || !props.deleteKeysOptions.withKeys || props.deleteKeysOptions.withKeys.length === 0) { - throw new UnscopedValidationError('deleteKeys must be provided for DELETE_KEYS JSON mutator'); - } - this.deleteKeysOptions = props.deleteKeysOptions; - break; - - case JsonMutatorType.MOVE_KEYS: - if (!props.moveKeysOptions || !props.moveKeysOptions.entries || props.moveKeysOptions.entries.length === 0) { - throw new UnscopedValidationError('moveKeysOptions must be provided for MOVE_KEYS JSON mutator'); - } - this.moveKeysOptions = { - entries: props.moveKeysOptions.entries.map(entry => { return { overwriteIfExists: false, ...entry }; }), - }; - break; - - case JsonMutatorType.RENAME_KEYS: - if (!props.renameKeysOptions || !props.renameKeysOptions.entries || props.renameKeysOptions.entries.length === 0) { - throw new UnscopedValidationError('renameKeysOptions must be provided for RENAME_KEYS JSON mutator'); - } - this.renameKeysOptions = { - entries: props.renameKeysOptions.entries.map(entry => { return { overwriteIfExists: false, ...entry }; }), - }; - break; - - case JsonMutatorType.COPY_VALUE: - if (!props.copyValueOptions || !props.copyValueOptions.entries || props.copyValueOptions.entries.length === 0) { - throw new UnscopedValidationError('copyValueOptions must be provided for COPY_VALUE JSON mutator'); - } - this.copyValueOptions = { - entries: props.copyValueOptions.entries.map(entry => { return { overwriteIfExists: false, ...entry }; }), - }; - break; - - case JsonMutatorType.LIST_TO_MAP: - if (!props.listToMapOptions || !props.listToMapOptions.source || !props.listToMapOptions.key) { - throw new UnscopedValidationError('listToMapOptions with source and key must be provided for LIST_TO_MAP JSON mutator'); - } - if (props.listToMapOptions.flatten && !props.listToMapOptions.flattenedElement) { - throw new UnscopedValidationError('listToMapOptions flattenedElement must be provided when flatten is true for LIST_TO_MAP JSON mutator'); - } - this.listToMapOptions = { - flatten: false, - ...props.listToMapOptions, - }; - break; - - default: - throw new UnscopedValidationError(`Unsupported JSON mutator type: ${this.type}`); - } - } - - /** - * Returns the L1 processor configuration for this JSON mutator - * @internal - */ - public _render(): any { - switch (this.type) { - case JsonMutatorType.ADD_KEYS: - return { addKeys: this.addKeysOptions }; - case JsonMutatorType.DELETE_KEYS: - return { deleteKeys: this.deleteKeysOptions }; - case JsonMutatorType.MOVE_KEYS: - return { moveKeys: this.moveKeysOptions }; - case JsonMutatorType.RENAME_KEYS: - return { renameKeys: this.renameKeysOptions }; - case JsonMutatorType.COPY_VALUE: - return { copyValue: this.copyValueOptions }; - case JsonMutatorType.LIST_TO_MAP: - return { listToMap: this.listToMapOptions }; - default: - throw new UnscopedValidationError(`Unsupported JSON mutator type: ${this.type}`); - } - } -} - -/** Processor for data conversion operations */ -export class DataConverterProcessor implements IProcessor { - /** The type of data conversion operation */ - type: DataConverterType; - /** Options for type conversion */ - private typeConverterOptions?: TypeConverterProperty; - /** Options for datetime conversion */ - private dateTimeConverterOptions?: DateTimeConverterProperty; - - /** Creates a new data converter processor */ - constructor(props: DataConverterProps) { - this.type = props.type; - - switch (this.type) { - case DataConverterType.TYPE_CONVERTER: - if (!props.typeConverterOptions || !props.typeConverterOptions.entries || props.typeConverterOptions.entries.length === 0) { - throw new UnscopedValidationError('typeConverterOptions must be provided for TYPE_CONVERTER data converter'); - } - this.typeConverterOptions = props.typeConverterOptions; - break; - - case DataConverterType.DATETIME_CONVERTER: - if (!props.dateTimeConverterOptions || !props.dateTimeConverterOptions.source || - !props.dateTimeConverterOptions.target || !props.dateTimeConverterOptions.matchPatterns) { - throw new UnscopedValidationError('dateTimeConverterOptions with source, target and matchPatterns must be provided for DATETIME_CONVERTER data converter'); - } - this.dateTimeConverterOptions = { - targetFormat: "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", - sourceTimezone: 'UTC', - targetTimezone: 'UTC', - ... props.dateTimeConverterOptions, - }; - break; - - default: - throw new UnscopedValidationError(`Unsupported data converter type: ${this.type}`); - } - } - - /** - * Returns the L1 processor configuration for this data converter - * @internal - */ - public _render(): any { - switch (this.type) { - case DataConverterType.TYPE_CONVERTER: - return { typeConverter: this.typeConverterOptions }; - case DataConverterType.DATETIME_CONVERTER: - return { dateTimeConverter: this.dateTimeConverterOptions }; - default: - throw new UnscopedValidationError(`Unsupported data converter type: ${this.type}`); - } - } -} - -/** Represent the L2 construct for the AWS::Logs::Transformer CloudFormation resource. */ -@propertyInjectable -export class Transformer extends Resource { - /** - * The property injection ID for this resource class. - * Used by the CDK frameworks for managing resource lifecycle. - */ - public static readonly PROPERTY_INJECTION_ID: string = 'aws-cdk-lib.aws-logs.Transformer'; - - /** The Transformer L2 construct that represents AWS::Logs::Transformer CFN resource. */ - constructor(scope: Construct, id: string, props: TransformerProps) { - super(scope, id, { - physicalName: props.transformerName, - }); - - // Validate the transformer configuration - this.validateProcessorCount(props.transformerConfig); - this.validateParserProcessors(props.transformerConfig); - this.validateUniqueProcessorTypes(props.transformerConfig); - this.validateLogGroupClass(props.logGroup); - - // Map the transformer configuration to the L1 CloudFormation resource - new CfnTransformer(scope, 'ResourceTransformer', { - logGroupIdentifier: props.logGroup.logGroupName, - transformerConfig: props.transformerConfig.map(processor => processor._render()), - }); - } - - /** - * @internal Validates that the number of processors doesn't exceed the AWS limit of 20 per transformer, and that at least - * one processor is provided. - */ - private validateProcessorCount(processors: Array): void { - // Skip validation if processors is a CDK token - if (Token.isUnresolved(processors)) { - return; - } - - // Validate the number of processors is between 1 and 20 inclusive - if (processors.length === 0) { - throw new ValidationError('At least one processor is required in a transformer', this); - } - - if (processors.length > 20) { - throw new ValidationError('A transformer cannot have more than 20 processors', this); - } - } - /** - * @internal Validates parser processor requirements: at least one parser-type processor is required, maximum of 5 - * parser-type processors allowed, and if including a vended log parser, it must be the first processor. - */ - private validateParserProcessors(processors: Array): void { - // Skip validation if processors is a CDK token - if (Token.isUnresolved(processors)) { - return; - } - // Validate first processor is a parser - if (! (processors.at(0) instanceof ParserProcessor || processors.at(0) instanceof VendedLogParser)) { - throw new ValidationError('First processor in a transformer must be a parser', this); - } - - // Identify parser-type processors (instances of ParserProcessor or VendedLogParser) - const parserProcessors = processors.filter( - p => p instanceof ParserProcessor || p instanceof VendedLogParser, - ); - - const vendedProcessors = processors.filter( - p => p instanceof VendedLogParser, - ); - - // Validate no more than 5 parser processors - if (parserProcessors.length > 5) { - throw new ValidationError('A transformer cannot have more than 5 parser-type processors', this); - } - - // Validate at most one vended parser processor exists - if (vendedProcessors.length > 1) { - throw new ValidationError('Only one vended log parser is allowed in a transformer', this); - } - - // Check if any vended log parser exists - const vendedLogParserIndex = processors.findIndex(p => p instanceof VendedLogParser); - - // If a vended log parser exists, ensure it's the first processor - if (vendedLogParserIndex > 0) { - throw new ValidationError('AWS vended log parser must be the first processor in a transformer', this); - } - } - /** - * @internal Validates that certain processor types appear at most once: only one grok processor, one addKeys processor, - * and one copyValue processor allowed. - */ - private validateUniqueProcessorTypes(processors: Array): void { - // Skip validation if processors is a CDK token - if (Token.isUnresolved(processors)) { - return; - } - - // Count occurrences of grok processors - const grokProcessors = processors.filter( - p => p instanceof ParserProcessor && (p as ParserProcessor).type === ParserProcessorType.GROK, - ); - if (grokProcessors.length > 1) { - throw new ValidationError('Only one grok processor is allowed in a transformer', this); - } - - // Count occurrences of addKeys processors - const addKeysProcessors = processors.filter( - p => p instanceof JsonMutatorProcessor && (p as JsonMutatorProcessor).type === JsonMutatorType.ADD_KEYS, - ); - if (addKeysProcessors.length > 1) { - throw new ValidationError('Only one addKeys processor is allowed in a transformer', this); - } - - // Count occurrences of copyValue processors - const copyValueProcessors = processors.filter( - p => p instanceof JsonMutatorProcessor && (p as JsonMutatorProcessor).type === JsonMutatorType.COPY_VALUE, - ); - if (copyValueProcessors.length > 1) { - throw new ValidationError('Only one copyValue processor is allowed in a transformer', this); - } - - // Count occurrences of copyValue processors - const parseToOcsfProcessors = processors.filter( - p => p instanceof ParserProcessor && (p as ParserProcessor).type === ParserProcessorType.OCSF, - ); - if (parseToOcsfProcessors.length > 1) { - throw new ValidationError('Only one parseToOCSF processor is allowed in a transformer', this); - } - if (parseToOcsfProcessors.length > 0) { - const parseToOcsfIndex = processors.findIndex(p => p instanceof ParserProcessor && (p as ParserProcessor).type === ParserProcessorType.OCSF); - if (parseToOcsfIndex != 0 ) { - throw new ValidationError('parseToOCSF processor must be the first processor in a transformer', this); - } - } - } - /** - * @internal Validates that the log group is in the Standard log class, as transformers can only be used with Standard log - * groups. - */ - private validateLogGroupClass(logGroup: ILogGroup): void { - // Since logGroupClass might not be directly accessible or might be a CDK token, - // we'll use a warning instead of validation error - // In an ideal implementation, we would check that: logGroup.logGroupClass === 'Standard' - // For now, add a warning to the node metadata - if (logGroup.node) { - logGroup.node.addMetadata('warning', 'Transformers can only be created for log groups in the Standard log class. ' + - 'Ensure that your log group is using the Standard log class.'); - } - } -} diff --git a/packages/aws-cdk-lib/aws-logs/test/loggroup.test.ts b/packages/aws-cdk-lib/aws-logs/test/loggroup.test.ts index 2871f6088e0ef..722c5ba301597 100644 --- a/packages/aws-cdk-lib/aws-logs/test/loggroup.test.ts +++ b/packages/aws-cdk-lib/aws-logs/test/loggroup.test.ts @@ -4,7 +4,7 @@ import * as iam from '../../aws-iam'; import * as kms from '../../aws-kms'; import { Bucket } from '../../aws-s3'; import { App, CfnParameter, Fn, RemovalPolicy, Stack } from '../../core'; -import { LogGroup, RetentionDays, LogGroupClass, DataProtectionPolicy, DataIdentifier, CustomDataIdentifier, ILogGroup, ILogSubscriptionDestination, FilterPattern, FieldIndexPolicy, ParserProcessor, ParserProcessorType, JsonMutatorType, JsonMutatorProcessor } from '../lib'; +import { LogGroup, RetentionDays, LogGroupClass, DataProtectionPolicy, DataIdentifier, CustomDataIdentifier, ILogGroup, ILogSubscriptionDestination, FilterPattern, FieldIndexPolicy } from '../lib'; describe('log group', () => { test('set kms key when provided', () => { @@ -1004,56 +1004,6 @@ describe('subscription filter', () => { }); }); -test('create a Add Key transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - const addKeysProcesor = new JsonMutatorProcessor({ - type: JsonMutatorType.ADD_KEYS, - addKeysOptions: { - entries: [ - { key: 'test_key1', value: 'test_value1', overwriteIfExists: true }, - { key: 'test_key2', value: 'test_value2' }, - { key: 'test_key3', value: 'test_value3', overwriteIfExists: false }, - ], - }, - }); - - // WHEN - - logGroup.addTransformer( - 'Transformer', - { - transformerName: 'MyTransformer', - transformerConfig: [jsonParser, addKeysProcesor], - }, - ); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [ - { - ParseJSON: { Source: '@message' }, - }, - { - AddKeys: { - Entries: [ - { Key: 'test_key1', Value: 'test_value1', OverwriteIfExists: true }, - { Key: 'test_key2', Value: 'test_value2', OverwriteIfExists: false }, - { Key: 'test_key3', Value: 'test_value3', OverwriteIfExists: false }, - ], - }, - }, - ], - }); -}); - function dataDrivenTests(cases: string[], body: (suffix: string) => void): void { for (let i = 0; i < cases.length; i++) { const args = cases[i]; // Need to capture inside loop for safe use inside closure. diff --git a/packages/aws-cdk-lib/aws-logs/test/transformer.test.ts b/packages/aws-cdk-lib/aws-logs/test/transformer.test.ts deleted file mode 100644 index d0941c60e903d..0000000000000 --- a/packages/aws-cdk-lib/aws-logs/test/transformer.test.ts +++ /dev/null @@ -1,1144 +0,0 @@ -import { Template } from '../../assertions'; -import { Stack } from '../../core'; -import { LogGroup, Transformer, ParserProcessor, JsonMutatorProcessor, VendedLogParser, StringMutatorProcessor, DataConverterProcessor, ParserProcessorType, JsonMutatorType, StringMutatorType, DelimiterCharacter, DataConverterType, TypeConverterType, QuoteCharacter, VendedLogType, OCSFSourceType, OCSFVersion } from '../lib'; - -describe('transformer', () => { - // Parser Processor tests - test('create a JSON parser transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - jsonOptions: { source: 'customField' }, - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [{ - ParseJSON: { Source: 'customField' }, - }], - }); - }); - - test('create a KeyValue parser transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const keyValueParser = new ParserProcessor({ - type: ParserProcessorType.KEY_VALUE, - keyValueOptions: { }, - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [keyValueParser], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [{ - ParseKeyValue: { - Source: '@message', - FieldDelimiter: '&', - KeyValueDelimiter: '=', - OverwriteIfExists: false, - }, - }], - }); - }); - - test('create a CSV parser transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const csvParser = new ParserProcessor({ - type: ParserProcessorType.CSV, - csvOptions: { - quoteCharacter: QuoteCharacter.SINGLE_QUOTE, - delimiter: DelimiterCharacter.PIPE, - }, - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [csvParser], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [{ - Csv: { - Source: '@message', - QuoteCharacter: "'", - Delimiter: '|', - }, - }], - }); - }); - - test('create a Grok parser transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const grokParser = new ParserProcessor({ - type: ParserProcessorType.GROK, - grokOptions: { source: 'customField', match: 'custom_grok_pattern' }, - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [grokParser], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [{ - Grok: { Source: 'customField', Match: 'custom_grok_pattern' }, - }], - }); - }); - - // Vended log sources tests - test('create a CloudFront parser transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const cloudFrontParser = new VendedLogParser({ - logType: VendedLogType.CLOUDFRONT, - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [cloudFrontParser], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [{ - ParseCloudfront: { }, - }], - }); - }); - - test('create a VPC parser transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const vpcParser = new VendedLogParser({ - logType: VendedLogType.VPC, - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [vpcParser], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [{ - ParseVPC: { }, - }], - }); - }); - - test('create a WAF parser transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const wafParser = new VendedLogParser({ - logType: VendedLogType.WAF, - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [wafParser], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [{ - ParseWAF: { }, - }], - }); - }); - - test('create a Route53 parser transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const route53Parser = new VendedLogParser({ - logType: VendedLogType.ROUTE53, - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [route53Parser], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [{ - ParseRoute53: { }, - }], - }); - }); - - test('create a PostGres parser transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const postGresParser = new VendedLogParser({ - logType: VendedLogType.POSTGRES, - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [postGresParser], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [{ - ParsePostgres: { }, - }], - }); - }); - - test('create a OCSF parser transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const ocsfParser = new ParserProcessor({ - type: ParserProcessorType.OCSF, - parseToOCSFOptions: { - eventSource: OCSFSourceType.CLOUD_TRAIL, - ocsfVersion: OCSFVersion.V1_1, - }, - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [ocsfParser], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [{ - ParseToOCSF: { - Source: '@message', - EventSource: 'CloudTrail', - OcsfVersion: 'V1.1', - }, - }], - }); - }); - - // Json Mutator tests - test('create a Add Key transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - const addKeysProcesor = new JsonMutatorProcessor({ - type: JsonMutatorType.ADD_KEYS, - addKeysOptions: { - entries: [ - { key: 'test_key1', value: 'test_value1', overwriteIfExists: true }, - { key: 'test_key2', value: 'test_value2' }, - { key: 'test_key3', value: 'test_value3', overwriteIfExists: false }, - ], - }, - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser, addKeysProcesor], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [ - { - ParseJSON: { Source: '@message' }, - }, - { - AddKeys: { - Entries: [ - { Key: 'test_key1', Value: 'test_value1', OverwriteIfExists: true }, - { Key: 'test_key2', Value: 'test_value2', OverwriteIfExists: false }, - { Key: 'test_key3', Value: 'test_value3', OverwriteIfExists: false }, - ], - }, - }, - ], - }); - }); - - test('create a Delete Key transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - const deleteKeysProcessor = new JsonMutatorProcessor({ - type: JsonMutatorType.DELETE_KEYS, - deleteKeysOptions: { - withKeys: ['test_delete_key1', 'test_delete_key2'], - }, - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser, deleteKeysProcessor], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [ - { - ParseJSON: { Source: '@message' }, - }, - { - DeleteKeys: { WithKeys: ['test_delete_key1', 'test_delete_key2'] }, - }, - ], - }); - }); - - test('create a Move Key transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - const moveKeysProcesor = new JsonMutatorProcessor({ - type: JsonMutatorType.MOVE_KEYS, - moveKeysOptions: { - entries: [ - { source: 'test_source1', target: 'test_target1', overwriteIfExists: true }, - { source: 'test_source2', target: 'test_target2' }, - { source: 'test_source3', target: 'test_target3', overwriteIfExists: false }, - ], - }, - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser, moveKeysProcesor], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [ - { - ParseJSON: { Source: '@message' }, - }, - { - MoveKeys: { - Entries: [ - { Source: 'test_source1', Target: 'test_target1', OverwriteIfExists: true }, - { Source: 'test_source2', Target: 'test_target2', OverwriteIfExists: false }, - { Source: 'test_source3', Target: 'test_target3', OverwriteIfExists: false }, - ], - }, - }, - ], - }); - }); - - test('create a Rename Key transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - const renameKeysProcessor = new JsonMutatorProcessor({ - type: JsonMutatorType.RENAME_KEYS, - renameKeysOptions: { - entries: [ - { key: 'test_key1', renameTo: 'test_rename1', overwriteIfExists: true }, - { key: 'test_key2', renameTo: 'test_rename2' }, - { key: 'test_key3', renameTo: 'test_rename3', overwriteIfExists: false }, - ], - }, - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser, renameKeysProcessor], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [ - { - ParseJSON: { Source: '@message' }, - }, - { - RenameKeys: { - Entries: [ - { Key: 'test_key1', RenameTo: 'test_rename1', OverwriteIfExists: true }, - { Key: 'test_key2', RenameTo: 'test_rename2', OverwriteIfExists: false }, - { Key: 'test_key3', RenameTo: 'test_rename3', OverwriteIfExists: false }, - ], - }, - }, - ], - }); - }); - - test('create a Copy Value transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - const copyValueProcessor = new JsonMutatorProcessor({ - type: JsonMutatorType.COPY_VALUE, - copyValueOptions: { - entries: [ - { source: 'test_source1', target: 'test_target1', overwriteIfExists: true }, - { source: 'test_source2', target: 'test_target2' }, - { source: 'test_source3', target: 'test_target3', overwriteIfExists: false }, - ], - }, - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser, copyValueProcessor], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [ - { - ParseJSON: { Source: '@message' }, - }, - { - CopyValue: { - Entries: [ - { Source: 'test_source1', Target: 'test_target1', OverwriteIfExists: true }, - { Source: 'test_source2', Target: 'test_target2', OverwriteIfExists: false }, - { Source: 'test_source3', Target: 'test_target3', OverwriteIfExists: false }, - ], - }, - }, - ], - }); - }); - - test('create a List To Map transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - const listToMapProcessor = new JsonMutatorProcessor({ - type: JsonMutatorType.LIST_TO_MAP, - listToMapOptions: { - source: 'test_source1', - key: 'test_key1', - }, - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser, listToMapProcessor], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [ - { - ParseJSON: { Source: '@message' }, - }, - { - ListToMap: { - Source: 'test_source1', - Key: 'test_key1', - Flatten: false, - }, - }, - ], - }); - }); - // String mutator tests - test('create LowerCase transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - const lowercaseProcessor = new StringMutatorProcessor({ - type: StringMutatorType.LOWER_CASE, - lowerCaseKeys: ['test_key1', 'test_key2'], - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser, lowercaseProcessor], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [ - { - ParseJSON: { Source: '@message' }, - }, - { - LowerCaseString: { WithKeys: ['test_key1', 'test_key2'] }, - }, - ], - }); - }); - - test('create UpperCase transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - const upperCaseProcessor = new StringMutatorProcessor({ - type: StringMutatorType.UPPER_CASE, - upperCaseKeys: ['test_key1', 'test_key2'], - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser, upperCaseProcessor], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [ - { - ParseJSON: { Source: '@message' }, - }, - { - UpperCaseString: { WithKeys: ['test_key1', 'test_key2'] }, - }, - ], - }); - }); - - test('create Trim transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - const trimStringProcessor = new StringMutatorProcessor({ - type: StringMutatorType.TRIM, - trimKeys: ['test_key1', 'test_key2'], - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser, trimStringProcessor], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [ - { - ParseJSON: { Source: '@message' }, - }, - { - TrimString: { WithKeys: ['test_key1', 'test_key2'] }, - }, - ], - }); - }); - - test('create Split transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - const splitStringProcessor = new StringMutatorProcessor({ - type: StringMutatorType.SPLIT, - splitOptions: { - entries: [ - { source: 'test_source1', delimiter: DelimiterCharacter.COMMA }, - { source: 'test_source2', delimiter: DelimiterCharacter.PIPE }, - { source: 'test_source3', delimiter: DelimiterCharacter.SEMICOLON }, - { source: 'test_source4', delimiter: DelimiterCharacter.SPACE }, - { source: 'test_source5', delimiter: DelimiterCharacter.TAB }, - ], - }, - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser, splitStringProcessor], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [ - { - ParseJSON: { Source: '@message' }, - }, - { - SplitString: { - Entries: [ - { Source: 'test_source1', Delimiter: ',' }, - { Source: 'test_source2', Delimiter: '|' }, - { Source: 'test_source3', Delimiter: ';' }, - { Source: 'test_source4', Delimiter: ' ' }, - { Source: 'test_source5', Delimiter: '\t' }, - ], - }, - }, - ], - }); - }); - - test('create SubstituteString transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - const substituteStringProcessor = new StringMutatorProcessor({ - type: StringMutatorType.SUBSTITUTE, - substituteOptions: { - entries: [ - { source: 'test_source1', from: 'test_from1', to: 'test_to1' }, - { source: 'test_source2', from: 'test_from2', to: 'test_to2' }, - { source: 'test_source3', from: 'test_from3', to: 'test_to3' }, - ], - }, - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser, substituteStringProcessor], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [ - { - ParseJSON: { Source: '@message' }, - }, - { - SubstituteString: { - Entries: [ - { Source: 'test_source1', From: 'test_from1', To: 'test_to1' }, - { Source: 'test_source2', From: 'test_from2', To: 'test_to2' }, - { Source: 'test_source3', From: 'test_from3', To: 'test_to3' }, - ], - }, - }, - ], - }); - }); - // Data Convertor Processors - test('create DateTime transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - const dateTimeProcessor = new DataConverterProcessor({ - type: DataConverterType.DATETIME_CONVERTER, - dateTimeConverterOptions: { - source: 'test_source1', - target: 'test_target1', - locale: 'en', - matchPatterns: ['EEEE dd. MMMM yyyy HH:mm:ss'], - targetFormat: 'yyyy-mm-dd', - targetTimezone: 'PDT', - }, - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser, dateTimeProcessor], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [ - { - ParseJSON: { Source: '@message' }, - }, - { - DateTimeConverter: { - Source: 'test_source1', - Target: 'test_target1', - Locale: 'en', - MatchPatterns: ['EEEE dd. MMMM yyyy HH:mm:ss'], - TargetFormat: 'yyyy-mm-dd', - TargetTimezone: 'PDT', - SourceTimezone: 'UTC', - }, - }, - ], - }); - }); - - test('create TypeConverter transformer against a log group', () => { - // GIVEN - const stack = new Stack(); - - // WHEN - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - const lowercaseProcessor = new DataConverterProcessor({ - type: DataConverterType.TYPE_CONVERTER, - typeConverterOptions: { - entries: [ - { key: 'test_key1', type: TypeConverterType.BOOLEAN }, - { key: 'test_key2', type: TypeConverterType.STRING }, - { key: 'test_key3', type: TypeConverterType.INTEGER }, - { key: 'test_key4', type: TypeConverterType.DOUBLE }, - ], - }, - }); - - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser, lowercaseProcessor], - }); - - // THEN - Template.fromStack(stack).hasResourceProperties('AWS::Logs::Transformer', { - LogGroupIdentifier: { Ref: 'awscdktestloggroup30AE39AB' }, - TransformerConfig: [ - { - ParseJSON: { Source: '@message' }, - }, - { - TypeConverter: { - Entries: [ - { Key: 'test_key1', Type: 'boolean' }, - { Key: 'test_key2', Type: 'string' }, - { Key: 'test_key3', Type: 'integer' }, - { Key: 'test_key4', Type: 'double' }, - ], - }, - }, - ], - }); - }); - // Transformer config validation tests - test('Transformer config with zero processors should fail', () => { - // GIVEN - const stack = new Stack(); - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - // THEN - expect( () => { - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [], - }, - ); - }).toThrow('At least one processor is required in a transformer'); - }); - - test('Transformer config with 21 processors should fail', () => { - // GIVEN - const stack = new Stack(); - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - const trimStringProcessor = new StringMutatorProcessor({ - type: StringMutatorType.TRIM, - trimKeys: ['test_key1', 'test_key2'], - }); - - // THEN - expect( () => { - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser, trimStringProcessor, - trimStringProcessor, trimStringProcessor, trimStringProcessor, - trimStringProcessor, trimStringProcessor, trimStringProcessor, - trimStringProcessor, trimStringProcessor, trimStringProcessor, - trimStringProcessor, trimStringProcessor, trimStringProcessor, - trimStringProcessor, trimStringProcessor, trimStringProcessor, - trimStringProcessor, trimStringProcessor, trimStringProcessor, - trimStringProcessor], - }, - ); - }).toThrow('A transformer cannot have more than 20 processors'); - }); - - test('Transformer config with a parser not as the first processor should fail', () => { - // GIVEN - const stack = new Stack(); - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - const trimStringProcessor = new StringMutatorProcessor({ - type: StringMutatorType.TRIM, - trimKeys: ['test_key1', 'test_key2'], - }); - - // THEN - expect( () => { - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [trimStringProcessor, jsonParser], - }, - ); - }).toThrow('First processor in a transformer must be a parser'); - }); - - test('Transformer config with more than 5 parser processors should fail', () => { - // GIVEN - const stack = new Stack(); - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - const cloudFrontParser = new VendedLogParser({ - logType: VendedLogType.CLOUDFRONT, - }); - - // THEN - expect( () => { - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [cloudFrontParser, jsonParser, jsonParser, jsonParser, jsonParser, jsonParser], - }, - ); - }).toThrow('A transformer cannot have more than 5 parser-type processors'); - }); - - test('Transformer config with more than 1 vended parser processors should fail', () => { - // GIVEN - const stack = new Stack(); - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const cloudFrontParser = new VendedLogParser({ - logType: VendedLogType.CLOUDFRONT, - }); - - // THEN - expect( () => { - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [cloudFrontParser, cloudFrontParser], - }, - ); - }).toThrow('Only one vended log parser is allowed in a transformer'); - }); - - test('Transformer config with vended parser processor not in first position should fail', () => { - // GIVEN - const stack = new Stack(); - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const cloudFrontParser = new VendedLogParser({ - logType: VendedLogType.CLOUDFRONT, - }); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - // THEN - expect( () => { - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser, cloudFrontParser], - }, - ); - }).toThrow('AWS vended log parser must be the first processor in a transformer'); - }); - - test('Transformer config more than one Grok parsers should fail', () => { - // GIVEN - const stack = new Stack(); - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const grokParser = new ParserProcessor({ - type: ParserProcessorType.GROK, - grokOptions: { source: 'customField', match: 'custom_grok_pattern' }, - }); - - // THEN - expect( () => { - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [grokParser, grokParser], - }, - ); - }).toThrow('Only one grok processor is allowed in a transformer'); - }); - - test('Transformer config with more than 1 AddKeys should fail', () => { - // GIVEN - const stack = new Stack(); - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const addKeysProcesor = new JsonMutatorProcessor({ - type: JsonMutatorType.ADD_KEYS, - addKeysOptions: { - entries: [{ key: 'test_key1', value: 'test_value1', overwriteIfExists: true }], - }, - }); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - // THEN - expect( () => { - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser, addKeysProcesor, addKeysProcesor], - }, - ); - }).toThrow('Only one addKeys processor is allowed in a transformer'); - }); - - test('Transformer config with more than one copy value processor should fail', () => { - // GIVEN - const stack = new Stack(); - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const copyValueProcessor = new JsonMutatorProcessor({ - type: JsonMutatorType.COPY_VALUE, - copyValueOptions: { - entries: [ - { source: 'test_source1', target: 'test_target1', overwriteIfExists: true }, - ], - }, - }); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - // THEN - expect( () => { - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser, copyValueProcessor, copyValueProcessor], - }, - ); - }).toThrow('Only one copyValue processor is allowed in a transformer'); - }); - - test('Transformer config with more than one parseToOcsf processor should fail', () => { - // GIVEN - const stack = new Stack(); - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const ocsfParser = new ParserProcessor({ - type: ParserProcessorType.OCSF, - parseToOCSFOptions: { - eventSource: OCSFSourceType.CLOUD_TRAIL, - ocsfVersion: OCSFVersion.V1_1, - }, - }); - - // THEN - expect( () => { - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [ocsfParser, ocsfParser], - }, - ); - }).toThrow('Only one parseToOCSF processor is allowed in a transformer'); - }); - - test('Transformer config with parseToOcsf not first should fail', () => { - // GIVEN - const stack = new Stack(); - const logGroup = new LogGroup(stack, 'aws_cdk_test_log_group'); - - const jsonParser = new ParserProcessor({ - type: ParserProcessorType.JSON, - }); - - const ocsfParser = new ParserProcessor({ - type: ParserProcessorType.OCSF, - parseToOCSFOptions: { - eventSource: OCSFSourceType.CLOUD_TRAIL, - ocsfVersion: OCSFVersion.V1_1, - }, - }); - - // THEN - expect( () => { - new Transformer(stack, 'Transformer', { - transformerName: 'MyTransformer', - logGroup: logGroup, - transformerConfig: [jsonParser, ocsfParser], - }, - ); - }).toThrow('parseToOCSF processor must be the first processor in a transformer'); - }); -});