From ae780e3482cde5c653b5834efeb2f6134af576ba Mon Sep 17 00:00:00 2001 From: Markus Date: Tue, 4 Feb 2025 08:11:44 +0100 Subject: [PATCH 01/12] chore: save work --- .projen/deps.json | 6 +- .projen/tasks.json | 4 +- .projenrc.js | 6 +- .tool-versions | 2 +- .vscode/settings.json | 11 + API.md | 937 +- lambda/README.md | 15 + ...arameter-binary-binary-true-true.json.snap | 17 + ...2-secret-binary-binary-true-true.json.snap | 17 + ...1-parametermulti-json-na-true-na.json.snap | 49 + ...2-parametermulti-yaml-na-true-na.json.snap | 49 + ...parametermulti-dotenv-na-true-na.json.snap | 21 + .../21-secret-json-json-true-true.json.snap | 17 + .../22-secret-json-binary-na-na.json.snap | 17 + .../23-secret-yaml-json-true-true.json.snap | 17 + .../24-secret-yaml-binary-na-na.json.snap | 17 + .../25-secret-dotenv-json-true-true.json.snap | 17 + .../26-secret-dotenv-binary-na-na.json.snap | 17 + lambda/__snapshots__/conversion_test.snap | 197 - lambda/__snapshots__/handler_common_test.snap | 7 - .../handler_parameter_raw_test.snap | 46 - .../handler_parameter_yaml_multi_test.snap | 126 - .../handler_secret_env_test.snap | 88 - .../handler_secret_json_test.snap | 284 - .../handler_secret_raw_test.snap | 44 - .../handler_secret_yaml_test.snap | 443 - lambda/__snapshots__/main_test.snap | 80 - lambda/conversion_test.go | 56 - .../01-parameter-binary-binary-true-true.json | 11 + .../02-secret-binary-binary-true-true.json | 10 + .../11-parametermulti-json-na-true-na.json | 10 + .../12-parametermulti-yaml-na-true-na.json | 10 + .../13-parametermulti-dotenv-na-true-na.json | 10 + .../events/21-secret-json-json-true-true.json | 10 + .../events/22-secret-json-binary-na-na.json | 10 + .../events/23-secret-yaml-json-true-true.json | 10 + .../events/24-secret-yaml-binary-na-na.json | 10 + .../25-secret-dotenv-json-true-true.json | 11 + .../events/26-secret-dotenv-binary-na-na.json | 10 + .../event_create_s3_parameter_raw_simple.json | 18 - ...vent_create_s3_parameter_yaml_complex.json | 21 - ...s3_parameter_yaml_complex_custom_keys.json | 21 - ...t_create_s3_secret_env_as_json_simple.json | 19 - .../event_create_s3_secret_env_simple.json | 19 - .../event_create_s3_secret_json_complex.json | 20 - ...nt_create_s3_secret_json_complex_flat.json | 20 - ...eate_s3_secret_json_complex_stringify.json | 20 - .../event_create_s3_secret_json_simple.json | 19 - .../event_create_s3_secret_raw_simple.json | 19 - ...create_s3_secret_yaml_as_json_complex.json | 21 - ...e_s3_secret_yaml_as_json_complex_flat.json | 21 - ..._create_s3_secret_yaml_as_json_simple.json | 20 - .../event_create_s3_secret_yaml_complex.json | 21 - ...nt_create_s3_secret_yaml_complex_flat.json | 21 - .../event_create_s3_secret_yaml_simple.json | 20 - lambda/events/event_delete.json | 8 - lambda/go.mod | 29 +- lambda/go.sum | 48 +- lambda/handle.go | 129 + lambda/handler_common_test.go | 15 - lambda/handler_parameter_raw_test.go | 15 - lambda/handler_parameter_yaml_multi_test.go | 23 - lambda/handler_secret_env_test.go | 22 - lambda/handler_secret_json_test.go | 73 - lambda/handler_secret_raw_test.go | 15 - lambda/handler_secret_yaml_test.go | 108 - lambda/internal/.DS_Store | Bin 0 -> 8196 bytes .../client/__snapshots__/s3_get_object.snap | 27 + .../__snapshots__/s3_get_object_etag.snap | 17 + .../s3_get_object_etag_not_found.snap | 17 + .../s3_get_object_reader_error.snap | 27 + .../secrets_manager_put_secret_value.snap | 12 + .../ssm_update_update_parameter.snap | 34 + lambda/internal/client/client.go | 126 + lambda/internal/client/client_test.go | 228 + lambda/internal/client/mock.go | 81 + .../data/__snapshots__/1.simple.flatten.snap | 12 + .../data/__snapshots__/1.simple.fromJson.snap | 12 + .../data/__snapshots__/1.simple.fromYaml.snap | 12 + .../__snapshots__/1.simple.stringify.snap | 12 + .../data/__snapshots__/1.simple.toJson.snap | 8 + .../__snapshots__/1.simple.toStringMap.snap | 8 + .../data/__snapshots__/1.simple.toYaml.snap | 7 + .../data/__snapshots__/2.nested.flatten.snap | 15 + .../data/__snapshots__/2.nested.fromJson.snap | 17 + .../data/__snapshots__/2.nested.fromYaml.snap | 17 + .../__snapshots__/2.nested.stringify.snap | 17 + .../data/__snapshots__/2.nested.toJson.snap | 13 + .../data/__snapshots__/2.nested.toYaml.snap | 11 + .../data/__snapshots__/3.array.flatten.snap | 15 + .../data/__snapshots__/3.array.fromJson.snap | 19 + .../data/__snapshots__/3.array.fromYaml.snap | 19 + .../data/__snapshots__/3.array.stringify.snap | 19 + .../data/__snapshots__/3.array.toJson.snap | 15 + .../data/__snapshots__/3.array.toYaml.snap | 10 + lambda/internal/data/data.go | 278 + lambda/internal/data/data_test.go | 274 + .../__snapshots__/invalid_empty.json.snap | 4 + .../__snapshots__/invalid_empty.json_err.snap | 5 + .../event/__snapshots__/valid_full.json.snap | 4 + .../__snapshots__/valid_full.json_err.snap | 5 + .../__snapshots__/valid_minimal.json.snap | 4 + .../__snapshots__/valid_minimal.json_err.snap | 5 + lambda/internal/event/config-schema.json | 83 + lambda/internal/event/event.go | 184 + lambda/internal/event/event_test.go | 43 + .../event/testdata/invalid_empty.json | 1 + .../internal/event/testdata/valid_full.json | 20 + .../event/testdata/valid_minimal.json | 8 + .../binary/sopsfile.enc-age.binary.snap | 18 + .../dotenv/encrypted-best-secret.env.snap | 6 + .../encrypted-best-secret.env.snap | 6 + .../json/sopsfile-complex.enc-age.json.snap | 38 + .../sops/__snapshots__/sops_test.snap | 44 + .../sopsfile-complex.enc-age.json.snap | 38 + .../sopsfile.enc-age.binary.snap | 18 + .../__snapshots__/sopsfile.enc-age.yaml.snap | 7 + .../yaml/sopsfile.enc-age.yaml.snap | 7 + lambda/internal/sops/sops.go | 77 + lambda/internal/sops/sops_test.go | 150 + lambda/main.go | 488 +- lambda/main_integration_test.go | 242 + lambda/main_test.go | 147 +- lambda/mocks.go | 181 - lambda/testhelper.go | 92 - package-lock.json | 11335 ---------------- package.json | 5 +- src/LambdaInterface.ts | 24 + src/MultiStringParameter.ts | 17 +- src/SopsSecret.ts | 13 +- src/SopsStringParameter.ts | 35 +- src/SopsSync.ts | 151 +- test/__snapshots__/permissions.test.ts.snap | 3 + .../SecretIntegrationAsset.assets.json | 12 +- .../SecretIntegrationAsset.template.json | 112 +- test/secret-asset.integ.ts | 18 +- .../SecretIntegrationInline.assets.json | 12 +- .../SecretIntegrationInline.template.json | 123 +- test/secret-inline.integ.ts | 17 +- .../SecretIntegrationAsset.assets.json | 12 +- .../SecretIntegrationAsset.template.json | 101 +- test/secret-manual.integ.ts | 19 +- .../SecretMultiKms.assets.json | 12 +- .../SecretMultiKms.template.json | 28 +- yarn.lock | 112 +- 145 files changed, 3886 insertions(+), 15103 deletions(-) create mode 100644 .vscode/settings.json create mode 100644 lambda/README.md create mode 100755 lambda/__snapshots__/01-parameter-binary-binary-true-true.json.snap create mode 100755 lambda/__snapshots__/02-secret-binary-binary-true-true.json.snap create mode 100755 lambda/__snapshots__/11-parametermulti-json-na-true-na.json.snap create mode 100755 lambda/__snapshots__/12-parametermulti-yaml-na-true-na.json.snap create mode 100755 lambda/__snapshots__/13-parametermulti-dotenv-na-true-na.json.snap create mode 100755 lambda/__snapshots__/21-secret-json-json-true-true.json.snap create mode 100755 lambda/__snapshots__/22-secret-json-binary-na-na.json.snap create mode 100755 lambda/__snapshots__/23-secret-yaml-json-true-true.json.snap create mode 100755 lambda/__snapshots__/24-secret-yaml-binary-na-na.json.snap create mode 100755 lambda/__snapshots__/25-secret-dotenv-json-true-true.json.snap create mode 100755 lambda/__snapshots__/26-secret-dotenv-binary-na-na.json.snap delete mode 100755 lambda/__snapshots__/conversion_test.snap delete mode 100755 lambda/__snapshots__/handler_common_test.snap delete mode 100755 lambda/__snapshots__/handler_parameter_raw_test.snap delete mode 100755 lambda/__snapshots__/handler_parameter_yaml_multi_test.snap delete mode 100755 lambda/__snapshots__/handler_secret_env_test.snap delete mode 100755 lambda/__snapshots__/handler_secret_json_test.snap delete mode 100755 lambda/__snapshots__/handler_secret_raw_test.snap delete mode 100755 lambda/__snapshots__/handler_secret_yaml_test.snap delete mode 100755 lambda/__snapshots__/main_test.snap delete mode 100644 lambda/conversion_test.go create mode 100644 lambda/events/01-parameter-binary-binary-true-true.json create mode 100644 lambda/events/02-secret-binary-binary-true-true.json create mode 100644 lambda/events/11-parametermulti-json-na-true-na.json create mode 100644 lambda/events/12-parametermulti-yaml-na-true-na.json create mode 100644 lambda/events/13-parametermulti-dotenv-na-true-na.json create mode 100644 lambda/events/21-secret-json-json-true-true.json create mode 100644 lambda/events/22-secret-json-binary-na-na.json create mode 100644 lambda/events/23-secret-yaml-json-true-true.json create mode 100644 lambda/events/24-secret-yaml-binary-na-na.json create mode 100644 lambda/events/25-secret-dotenv-json-true-true.json create mode 100644 lambda/events/26-secret-dotenv-binary-na-na.json delete mode 100644 lambda/events/event_create_s3_parameter_raw_simple.json delete mode 100644 lambda/events/event_create_s3_parameter_yaml_complex.json delete mode 100644 lambda/events/event_create_s3_parameter_yaml_complex_custom_keys.json delete mode 100644 lambda/events/event_create_s3_secret_env_as_json_simple.json delete mode 100644 lambda/events/event_create_s3_secret_env_simple.json delete mode 100644 lambda/events/event_create_s3_secret_json_complex.json delete mode 100644 lambda/events/event_create_s3_secret_json_complex_flat.json delete mode 100644 lambda/events/event_create_s3_secret_json_complex_stringify.json delete mode 100644 lambda/events/event_create_s3_secret_json_simple.json delete mode 100644 lambda/events/event_create_s3_secret_raw_simple.json delete mode 100644 lambda/events/event_create_s3_secret_yaml_as_json_complex.json delete mode 100644 lambda/events/event_create_s3_secret_yaml_as_json_complex_flat.json delete mode 100644 lambda/events/event_create_s3_secret_yaml_as_json_simple.json delete mode 100644 lambda/events/event_create_s3_secret_yaml_complex.json delete mode 100644 lambda/events/event_create_s3_secret_yaml_complex_flat.json delete mode 100644 lambda/events/event_create_s3_secret_yaml_simple.json delete mode 100644 lambda/events/event_delete.json create mode 100644 lambda/handle.go delete mode 100644 lambda/handler_common_test.go delete mode 100644 lambda/handler_parameter_raw_test.go delete mode 100644 lambda/handler_parameter_yaml_multi_test.go delete mode 100644 lambda/handler_secret_env_test.go delete mode 100644 lambda/handler_secret_json_test.go delete mode 100644 lambda/handler_secret_raw_test.go delete mode 100644 lambda/handler_secret_yaml_test.go create mode 100644 lambda/internal/.DS_Store create mode 100755 lambda/internal/client/__snapshots__/s3_get_object.snap create mode 100755 lambda/internal/client/__snapshots__/s3_get_object_etag.snap create mode 100755 lambda/internal/client/__snapshots__/s3_get_object_etag_not_found.snap create mode 100755 lambda/internal/client/__snapshots__/s3_get_object_reader_error.snap create mode 100755 lambda/internal/client/__snapshots__/secrets_manager_put_secret_value.snap create mode 100755 lambda/internal/client/__snapshots__/ssm_update_update_parameter.snap create mode 100644 lambda/internal/client/client.go create mode 100644 lambda/internal/client/client_test.go create mode 100644 lambda/internal/client/mock.go create mode 100755 lambda/internal/data/__snapshots__/1.simple.flatten.snap create mode 100755 lambda/internal/data/__snapshots__/1.simple.fromJson.snap create mode 100755 lambda/internal/data/__snapshots__/1.simple.fromYaml.snap create mode 100755 lambda/internal/data/__snapshots__/1.simple.stringify.snap create mode 100755 lambda/internal/data/__snapshots__/1.simple.toJson.snap create mode 100755 lambda/internal/data/__snapshots__/1.simple.toStringMap.snap create mode 100755 lambda/internal/data/__snapshots__/1.simple.toYaml.snap create mode 100755 lambda/internal/data/__snapshots__/2.nested.flatten.snap create mode 100755 lambda/internal/data/__snapshots__/2.nested.fromJson.snap create mode 100755 lambda/internal/data/__snapshots__/2.nested.fromYaml.snap create mode 100755 lambda/internal/data/__snapshots__/2.nested.stringify.snap create mode 100755 lambda/internal/data/__snapshots__/2.nested.toJson.snap create mode 100755 lambda/internal/data/__snapshots__/2.nested.toYaml.snap create mode 100755 lambda/internal/data/__snapshots__/3.array.flatten.snap create mode 100755 lambda/internal/data/__snapshots__/3.array.fromJson.snap create mode 100755 lambda/internal/data/__snapshots__/3.array.fromYaml.snap create mode 100755 lambda/internal/data/__snapshots__/3.array.stringify.snap create mode 100755 lambda/internal/data/__snapshots__/3.array.toJson.snap create mode 100755 lambda/internal/data/__snapshots__/3.array.toYaml.snap create mode 100644 lambda/internal/data/data.go create mode 100644 lambda/internal/data/data_test.go create mode 100755 lambda/internal/event/__snapshots__/invalid_empty.json.snap create mode 100755 lambda/internal/event/__snapshots__/invalid_empty.json_err.snap create mode 100755 lambda/internal/event/__snapshots__/valid_full.json.snap create mode 100755 lambda/internal/event/__snapshots__/valid_full.json_err.snap create mode 100755 lambda/internal/event/__snapshots__/valid_minimal.json.snap create mode 100755 lambda/internal/event/__snapshots__/valid_minimal.json_err.snap create mode 100644 lambda/internal/event/config-schema.json create mode 100644 lambda/internal/event/event.go create mode 100644 lambda/internal/event/event_test.go create mode 100644 lambda/internal/event/testdata/invalid_empty.json create mode 100644 lambda/internal/event/testdata/valid_full.json create mode 100644 lambda/internal/event/testdata/valid_minimal.json create mode 100755 lambda/internal/sops/__snapshots__/binary/sopsfile.enc-age.binary.snap create mode 100755 lambda/internal/sops/__snapshots__/dotenv/encrypted-best-secret.env.snap create mode 100755 lambda/internal/sops/__snapshots__/encrypted-best-secret.env.snap create mode 100755 lambda/internal/sops/__snapshots__/json/sopsfile-complex.enc-age.json.snap create mode 100755 lambda/internal/sops/__snapshots__/sops_test.snap create mode 100755 lambda/internal/sops/__snapshots__/sopsfile-complex.enc-age.json.snap create mode 100755 lambda/internal/sops/__snapshots__/sopsfile.enc-age.binary.snap create mode 100755 lambda/internal/sops/__snapshots__/sopsfile.enc-age.yaml.snap create mode 100755 lambda/internal/sops/__snapshots__/yaml/sopsfile.enc-age.yaml.snap create mode 100644 lambda/internal/sops/sops.go create mode 100644 lambda/internal/sops/sops_test.go create mode 100644 lambda/main_integration_test.go delete mode 100644 lambda/mocks.go delete mode 100644 lambda/testhelper.go delete mode 100644 package-lock.json create mode 100644 src/LambdaInterface.ts diff --git a/.projen/deps.json b/.projen/deps.json index c44b8d55..0630fc21 100644 --- a/.projen/deps.json +++ b/.projen/deps.json @@ -81,6 +81,10 @@ "version": "~5.6.0", "type": "build" }, + { + "name": "json-schema-to-typescript", + "type": "build" + }, { "name": "prettier", "type": "build" @@ -107,7 +111,7 @@ }, { "name": "aws-cdk-lib", - "version": "^2.144.0", + "version": "^2.177.0", "type": "peer" }, { diff --git a/.projen/tasks.json b/.projen/tasks.json index 862269d5..db4d0bb9 100644 --- a/.projen/tasks.json +++ b/.projen/tasks.json @@ -591,13 +591,13 @@ }, "steps": [ { - "exec": "npx npm-check-updates@16 --upgrade --target=minor --peer --no-deprecated --dep=dev,peer,prod,optional --filter=@types/jest,@types/node,eslint-config-prettier,eslint-import-resolver-typescript,eslint-plugin-import,eslint-plugin-prettier,jest,jsii-diff,jsii-pacmak,prettier,projen,ts-jest,ts-node,typescript,yaml" + "exec": "npx npm-check-updates@16 --upgrade --target=minor --peer --no-deprecated --dep=dev,peer,prod,optional --filter=@types/jest,@types/node,eslint-config-prettier,eslint-import-resolver-typescript,eslint-plugin-import,eslint-plugin-prettier,jest,jsii-diff,jsii-pacmak,json-schema-to-typescript,prettier,projen,ts-jest,ts-node,typescript,yaml" }, { "exec": "yarn install --check-files" }, { - "exec": "yarn upgrade @types/jest @types/node @typescript-eslint/eslint-plugin @typescript-eslint/parser aws-cdk commit-and-tag-version eslint-config-prettier eslint-import-resolver-typescript eslint-plugin-import eslint-plugin-prettier eslint jest jest-junit jsii-diff jsii-docgen jsii-pacmak jsii-rosetta jsii prettier projen ts-jest ts-node typescript yaml aws-cdk-lib constructs" + "exec": "yarn upgrade @types/jest @types/node @typescript-eslint/eslint-plugin @typescript-eslint/parser aws-cdk commit-and-tag-version eslint-config-prettier eslint-import-resolver-typescript eslint-plugin-import eslint-plugin-prettier eslint jest jest-junit jsii-diff jsii-docgen jsii-pacmak jsii-rosetta jsii json-schema-to-typescript prettier projen ts-jest ts-node typescript yaml aws-cdk-lib constructs" }, { "exec": "npx projen" diff --git a/.projenrc.js b/.projenrc.js index 506d2d60..1e088b42 100644 --- a/.projenrc.js +++ b/.projenrc.js @@ -2,7 +2,7 @@ const { awscdk } = require('projen'); const project = new awscdk.AwsCdkConstructLibrary({ author: 'Markus Siebert', authorAddress: 'markus.siebert@deutschebahn.com', - cdkVersion: '2.144.0', + cdkVersion: '2.177.0', stability: 'stable', homepage: 'https://constructs.dev/packages/cdk-sops-secrets', description: @@ -32,7 +32,9 @@ const project = new awscdk.AwsCdkConstructLibrary({ bundledDeps: ['yaml'], // deps: [], /* Runtime dependencies of this module. */, // description: undefined, /* The description is just a string that helps people understand the purpose of the package. */ - // devDeps: [], /* Build dependencies for this module. */ + devDeps: [ + 'json-schema-to-typescript', + ], /* Build dependencies for this module. */ integrationTestAutoDiscover: true, prettier: true, prettierOptions: { diff --git a/.tool-versions b/.tool-versions index 1f577776..bed478c6 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,3 +1,3 @@ -golang 1.23.1 +golang 1.23.5 yarn 1.22.19 nodejs 20.15.1 \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..233b8088 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,11 @@ +{ + "json.schemas": [ + { + "fileMatch": [ + "lambda/internal/event/testdata/*.json", + "lambda/events/*.json" + ], + "url": "./lambda/internal/event/config-schema.json" + } + ] +} \ No newline at end of file diff --git a/API.md b/API.md index a986522a..943f6712 100644 --- a/API.md +++ b/API.md @@ -885,9 +885,6 @@ Any object. | **Name** | **Type** | **Description** | | --- | --- | --- | | node | constructs.Node | The tree node. | -| converToJSON | boolean | Was the format converted to json? | -| flatten | boolean | Was the structure flattened? | -| stringifiedValues | boolean | Were the values stringified? | | versionId | string | The current versionId of the secret populated via this resource. | --- @@ -904,42 +901,6 @@ The tree node. --- -##### `converToJSON`Required - -```typescript -public readonly converToJSON: boolean; -``` - -- *Type:* boolean - -Was the format converted to json? - ---- - -##### `flatten`Required - -```typescript -public readonly flatten: boolean; -``` - -- *Type:* boolean - -Was the structure flattened? - ---- - -##### `stringifiedValues`Required - -```typescript -public readonly stringifiedValues: boolean; -``` - -- *Type:* boolean - -Were the values stringified? - ---- - ##### `versionId`Required ```typescript @@ -1006,7 +967,9 @@ new SopsSyncProvider(scope: Construct, id?: string, props?: SopsSyncProviderProp | considerWarningOnInvokeFunctionPermissions | A warning will be added to functions under the following conditions: - permissions that include `lambda:InvokeFunction` are added to the unqualified function. | | grantInvoke | Grant the given identity permissions to invoke this Lambda. | | grantInvokeCompositePrincipal | Grant multiple principals the ability to invoke this Lambda via CompositePrincipal. | +| grantInvokeLatestVersion | Grant the given identity permissions to invoke the $LATEST version or unqualified version of this Lambda. | | grantInvokeUrl | Grant the given identity permissions to invoke this Lambda Function URL. | +| grantInvokeVersion | Grant the given identity permissions to invoke the given version of this Lambda. | | metric | Return the given named metric for this Function. | | metricDuration | How long execution of this Lambda takes. | | metricErrors | How many invocations of this Lambda fail. | @@ -1015,6 +978,7 @@ new SopsSyncProvider(scope: Construct, id?: string, props?: SopsSyncProviderProp | addDependency | Using node.addDependency() does not work on this method as the underlying lambda function is modeled as a singleton across the stack. Use this method instead to declare dependencies. | | addEnvironment | Adds an environment variable to this Lambda function. | | addLayers | Adds one or more Lambda Layers to this Lambda function. | +| addMetadata | Use this method to write to the construct tree. | | dependOn | The SingletonFunction construct cannot be added as a dependency of another construct using node.addDependency(). Use this method instead to declare this as a dependency of another construct. | | addAgeKey | *No description.* | @@ -1207,6 +1171,20 @@ Grant multiple principals the ability to invoke this Lambda via CompositePrincip --- +##### `grantInvokeLatestVersion` + +```typescript +public grantInvokeLatestVersion(grantee: IGrantable): Grant +``` + +Grant the given identity permissions to invoke the $LATEST version or unqualified version of this Lambda. + +###### `grantee`Required + +- *Type:* aws-cdk-lib.aws_iam.IGrantable + +--- + ##### `grantInvokeUrl` ```typescript @@ -1221,6 +1199,26 @@ Grant the given identity permissions to invoke this Lambda Function URL. --- +##### `grantInvokeVersion` + +```typescript +public grantInvokeVersion(grantee: IGrantable, version: IVersion): Grant +``` + +Grant the given identity permissions to invoke the given version of this Lambda. + +###### `grantee`Required + +- *Type:* aws-cdk-lib.aws_iam.IGrantable + +--- + +###### `version`Required + +- *Type:* aws-cdk-lib.aws_lambda.IVersion + +--- + ##### `metric` ```typescript @@ -1369,6 +1367,34 @@ the layers to be added. --- +##### `addMetadata` + +```typescript +public addMetadata(type: string, data: any, options?: MetadataOptions): void +``` + +Use this method to write to the construct tree. + +The metadata entries are written to the Cloud Assembly Manifest if the `treeMetadata` property is specified in the props of the App that contains this Construct. + +###### `type`Required + +- *Type:* string + +--- + +###### `data`Required + +- *Type:* any + +--- + +###### `options`Optional + +- *Type:* constructs.MetadataOptions + +--- + ##### `dependOn` ```typescript @@ -1472,6 +1498,7 @@ Check whether the given construct is a Resource. | permissionsNode | constructs.Node | The construct node where permissions are attached. | | resourceArnsForGrantInvoke | string[] | The ARN(s) to put into the resource field of the generated IAM policy for grantInvoke(). | | role | aws-cdk-lib.aws_iam.IRole | The IAM role associated with this function. | +| constructName | string | The name of the singleton function. | | currentVersion | aws-cdk-lib.aws_lambda.Version | Returns a `lambda.Version` which represents the current version of this singleton Lambda function. A new version will be created every time the function's configuration changes. | | logGroup | aws-cdk-lib.aws_logs.ILogGroup | The LogGroup where the Lambda function's logs are made available. | | runtime | aws-cdk-lib.aws_lambda.Runtime | The runtime environment for the Lambda function. | @@ -1654,6 +1681,20 @@ Undefined if the function was imported without a role. --- +##### `constructName`Required + +```typescript +public readonly constructName: string; +``` + +- *Type:* string + +The name of the singleton function. + +It acts as a unique ID within its CDK stack. + +--- + ##### `currentVersion`Required ```typescript @@ -1718,10 +1759,7 @@ const multiStringParameterProps: MultiStringParameterProps = { ... } | **Name** | **Type** | **Description** | | --- | --- | --- | | autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | -| convertToJSON | boolean | Should the encrypted sops value should be converted to JSON? | -| flatten | boolean | Should the structure be flattened? | | flattenSeparator | string | If the structure should be flattened use the provided separator between keys. | -| parameterKeyPrefix | string | Add this prefix to parameter names. | | sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | | sopsFileFormat | string | The format of the sops file. | | sopsFilePath | string | The filepath to the sops file. | @@ -1729,19 +1767,12 @@ const multiStringParameterProps: MultiStringParameterProps = { ... } | sopsProvider | SopsSyncProvider | The custom resource provider to use. | | sopsS3Bucket | string | If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | | sopsS3Key | string | If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | -| stringifyValues | boolean | Shall all values be flattened? | | uploadType | UploadType | How should the secret be passed to the CustomResource? | -| allowedPattern | string | A regular expression used to validate the parameter value. | +| encryptionKey | aws-cdk-lib.aws_kms.IKey | *No description.* | | description | string | Information about the parameter that you want to add to the system. | -| parameterName | string | The name of the parameter. | -| simpleName | boolean | Indicates if the parameter name is a simple name (i.e. does not include "/" separators). | | tier | aws-cdk-lib.aws_ssm.ParameterTier | The tier of the string parameter. | -| stringValue | string | The value of the parameter. | -| dataType | aws-cdk-lib.aws_ssm.ParameterDataType | The data type of the parameter, such as `text` or `aws:ec2:image`. | -| type | aws-cdk-lib.aws_ssm.ParameterType | The type of the string parameter. | -| encryptionKey | aws-cdk-lib.aws_kms.IKey | *No description.* | -| keyPrefix | string | *No description.* | -| keySeparator | string | *No description.* | +| keyPrefix | string | The prefix used for all parameters. | +| keySeparator | string | The seperator used to seperate keys. | --- @@ -1758,38 +1789,6 @@ Should this construct automatically create IAM permissions? --- -##### `convertToJSON`Optional - -```typescript -public readonly convertToJSON: boolean; -``` - -- *Type:* boolean -- *Default:* true - -Should the encrypted sops value should be converted to JSON? - -Only JSON can be handled by cloud formations dynamic references. - ---- - -##### `flatten`Optional - -```typescript -public readonly flatten: boolean; -``` - -- *Type:* boolean -- *Default:* true - -Should the structure be flattened? - -The result will be a flat structure and all -object keys will be replaced with the full jsonpath as key. -This is usefull for dynamic references, as those don't support nested objects. - ---- - ##### `flattenSeparator`Optional ```typescript @@ -1797,24 +1796,12 @@ public readonly flattenSeparator: string; ``` - *Type:* string -- *Default:* '.' +- *Default:* undefined If the structure should be flattened use the provided separator between keys. --- -##### `parameterKeyPrefix`Optional - -```typescript -public readonly parameterKeyPrefix: string; -``` - -- *Type:* string - -Add this prefix to parameter names. - ---- - ##### `sopsAgeKey`Optional ```typescript @@ -1908,21 +1895,6 @@ If you want to pass the sops file via s3, you can specify the key inside the buc --- -##### `stringifyValues`Optional - -```typescript -public readonly stringifyValues: boolean; -``` - -- *Type:* boolean - -Shall all values be flattened? - -This is usefull for dynamic references, as there -are lookup errors for certain float types - ---- - ##### `uploadType`Optional ```typescript @@ -1936,19 +1908,13 @@ How should the secret be passed to the CustomResource? --- -##### `allowedPattern`Optional +##### `encryptionKey`Required ```typescript -public readonly allowedPattern: string; +public readonly encryptionKey: IKey; ``` -- *Type:* string -- *Default:* no validation is performed - -A regular expression used to validate the parameter value. - -For example, for String types with values restricted to -numbers, you can specify the following: ``^\d+$`` +- *Type:* aws-cdk-lib.aws_kms.IKey --- @@ -1965,203 +1931,320 @@ Information about the parameter that you want to add to the system. --- -##### `parameterName`Optional +##### `tier`Optional ```typescript -public readonly parameterName: string; +public readonly tier: ParameterTier; ``` -- *Type:* string -- *Default:* a name will be generated by CloudFormation +- *Type:* aws-cdk-lib.aws_ssm.ParameterTier +- *Default:* undefined -The name of the parameter. +The tier of the string parameter. --- -##### `simpleName`Optional +##### `keyPrefix`Optional ```typescript -public readonly simpleName: boolean; +public readonly keyPrefix: string; ``` -- *Type:* boolean -- *Default:* auto-detect based on `parameterName` - -Indicates if the parameter name is a simple name (i.e. does not include "/" separators). - -This is required only if `parameterName` is a token, which means we -are unable to detect if the name is simple or "path-like" for the purpose -of rendering SSM parameter ARNs. +- *Type:* string +- *Default:* '/' -If `parameterName` is not specified, `simpleName` must be `true` (or -undefined) since the name generated by AWS CloudFormation is always a -simple name. +The prefix used for all parameters. --- -##### `tier`Optional +##### `keySeparator`Optional ```typescript -public readonly tier: ParameterTier; +public readonly keySeparator: string; ``` -- *Type:* aws-cdk-lib.aws_ssm.ParameterTier -- *Default:* undefined +- *Type:* string +- *Default:* '/' -The tier of the string parameter. +The seperator used to seperate keys. --- -##### `stringValue`Required +### SopsCommonParameterProps + +The configuration options of the StringParameter. + +#### Initializer ```typescript -public readonly stringValue: string; -``` +import { SopsCommonParameterProps } from 'cdk-sops-secrets' -- *Type:* string +const sopsCommonParameterProps: SopsCommonParameterProps = { ... } +``` -The value of the parameter. +#### Properties -It may not reference another parameter and ``{{}}`` cannot be used in the value. +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | +| flattenSeparator | string | If the structure should be flattened use the provided separator between keys. | +| sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | +| sopsFileFormat | string | The format of the sops file. | +| sopsFilePath | string | The filepath to the sops file. | +| sopsKmsKey | aws-cdk-lib.aws_kms.IKey[] | The kmsKey used to encrypt the sops file. | +| sopsProvider | SopsSyncProvider | The custom resource provider to use. | +| sopsS3Bucket | string | If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | +| sopsS3Key | string | If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | +| uploadType | UploadType | How should the secret be passed to the CustomResource? | +| encryptionKey | aws-cdk-lib.aws_kms.IKey | *No description.* | +| description | string | Information about the parameter that you want to add to the system. | +| tier | aws-cdk-lib.aws_ssm.ParameterTier | The tier of the string parameter. | --- -##### `dataType`Optional +##### `autoGenerateIamPermissions`Optional ```typescript -public readonly dataType: ParameterDataType; +public readonly autoGenerateIamPermissions: boolean; ``` -- *Type:* aws-cdk-lib.aws_ssm.ParameterDataType -- *Default:* ParameterDataType.TEXT +- *Type:* boolean +- *Default:* true -The data type of the parameter, such as `text` or `aws:ec2:image`. +Should this construct automatically create IAM permissions? --- -##### ~~`type`~~Optional - -- *Deprecated:* - type will always be 'String' +##### `flattenSeparator`Optional ```typescript -public readonly type: ParameterType; +public readonly flattenSeparator: string; ``` -- *Type:* aws-cdk-lib.aws_ssm.ParameterType -- *Default:* ParameterType.STRING +- *Type:* string +- *Default:* undefined -The type of the string parameter. +If the structure should be flattened use the provided separator between keys. --- -##### `encryptionKey`Required +##### `sopsAgeKey`Optional ```typescript -public readonly encryptionKey: IKey; +public readonly sopsAgeKey: SecretValue; ``` -- *Type:* aws-cdk-lib.aws_kms.IKey +- *Type:* aws-cdk-lib.SecretValue + +The age key that should be used for encryption. --- -##### `keyPrefix`Optional +##### `sopsFileFormat`Optional ```typescript -public readonly keyPrefix: string; +public readonly sopsFileFormat: string; ``` - *Type:* string +- *Default:* The fileformat will be derived from the file ending + +The format of the sops file. --- -##### `keySeparator`Optional +##### `sopsFilePath`Optional ```typescript -public readonly keySeparator: string; +public readonly sopsFilePath: string; ``` - *Type:* string ---- - -### SopsSecretProps +The filepath to the sops file. -The configuration options of the SopsSecret. +--- -#### Initializer +##### `sopsKmsKey`Optional ```typescript -import { SopsSecretProps } from 'cdk-sops-secrets' - -const sopsSecretProps: SopsSecretProps = { ... } +public readonly sopsKmsKey: IKey[]; ``` -#### Properties +- *Type:* aws-cdk-lib.aws_kms.IKey[] +- *Default:* The key will be derived from the sops file -| **Name** | **Type** | **Description** | -| --- | --- | --- | -| description | string | An optional, human-friendly description of the secret. | -| encryptionKey | aws-cdk-lib.aws_kms.IKey | The customer-managed encryption key to use for encrypting the secret value. | -| generateSecretString | aws-cdk-lib.aws_secretsmanager.SecretStringGenerator | Configuration for how to generate a secret value. | -| removalPolicy | aws-cdk-lib.RemovalPolicy | Policy to apply when the secret is removed from this stack. | -| replicaRegions | aws-cdk-lib.aws_secretsmanager.ReplicaRegion[] | A list of regions where to replicate this secret. | -| secretName | string | A name for the secret. | -| secretObjectValue | {[ key: string ]: aws-cdk-lib.SecretValue} | Initial value for a JSON secret. | -| secretStringBeta1 | aws-cdk-lib.aws_secretsmanager.SecretStringValueBeta1 | Initial value for the secret. | -| secretStringValue | aws-cdk-lib.SecretValue | Initial value for the secret. | -| autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | -| convertToJSON | boolean | Should the encrypted sops value should be converted to JSON? | -| flatten | boolean | Should the structure be flattened? | -| flattenSeparator | string | If the structure should be flattened use the provided separator between keys. | -| parameterKeyPrefix | string | Add this prefix to parameter names. | -| sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | -| sopsFileFormat | string | The format of the sops file. | -| sopsFilePath | string | The filepath to the sops file. | -| sopsKmsKey | aws-cdk-lib.aws_kms.IKey[] | The kmsKey used to encrypt the sops file. | -| sopsProvider | SopsSyncProvider | The custom resource provider to use. | -| sopsS3Bucket | string | If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | -| sopsS3Key | string | If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | -| stringifyValues | boolean | Shall all values be flattened? | -| uploadType | UploadType | How should the secret be passed to the CustomResource? | +The kmsKey used to encrypt the sops file. + +Encrypt permissions +will be granted to the custom resource provider. --- -##### `description`Optional +##### `sopsProvider`Optional ```typescript -public readonly description: string; +public readonly sopsProvider: SopsSyncProvider; ``` -- *Type:* string -- *Default:* No description. +- *Type:* SopsSyncProvider +- *Default:* A new singleton provider will be created -An optional, human-friendly description of the secret. +The custom resource provider to use. + +If you don't specify any, a new +provider will be created - or if already exists within this stack - reused. --- -##### `encryptionKey`Optional +##### `sopsS3Bucket`Optional ```typescript -public readonly encryptionKey: IKey; +public readonly sopsS3Bucket: string; ``` -- *Type:* aws-cdk-lib.aws_kms.IKey -- *Default:* A default KMS key for the account and region is used. +- *Type:* string -The customer-managed encryption key to use for encrypting the secret value. +If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. --- -##### `generateSecretString`Optional +##### `sopsS3Key`Optional ```typescript -public readonly generateSecretString: SecretStringGenerator; +public readonly sopsS3Key: string; ``` -- *Type:* aws-cdk-lib.aws_secretsmanager.SecretStringGenerator -- *Default:* 32 characters with upper-case letters, lower-case letters, punctuation and numbers (at least one from each category), per the default values of ``SecretStringGenerator``. +- *Type:* string -Configuration for how to generate a secret value. +If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. + +--- + +##### `uploadType`Optional + +```typescript +public readonly uploadType: UploadType; +``` + +- *Type:* UploadType +- *Default:* INLINE + +How should the secret be passed to the CustomResource? + +--- + +##### `encryptionKey`Required + +```typescript +public readonly encryptionKey: IKey; +``` + +- *Type:* aws-cdk-lib.aws_kms.IKey + +--- + +##### `description`Optional + +```typescript +public readonly description: string; +``` + +- *Type:* string +- *Default:* none + +Information about the parameter that you want to add to the system. + +--- + +##### `tier`Optional + +```typescript +public readonly tier: ParameterTier; +``` + +- *Type:* aws-cdk-lib.aws_ssm.ParameterTier +- *Default:* undefined + +The tier of the string parameter. + +--- + +### SopsSecretProps + +The configuration options of the SopsSecret. + +#### Initializer + +```typescript +import { SopsSecretProps } from 'cdk-sops-secrets' + +const sopsSecretProps: SopsSecretProps = { ... } +``` + +#### Properties + +| **Name** | **Type** | **Description** | +| --- | --- | --- | +| description | string | An optional, human-friendly description of the secret. | +| encryptionKey | aws-cdk-lib.aws_kms.IKey | The customer-managed encryption key to use for encrypting the secret value. | +| generateSecretString | aws-cdk-lib.aws_secretsmanager.SecretStringGenerator | Configuration for how to generate a secret value. | +| removalPolicy | aws-cdk-lib.RemovalPolicy | Policy to apply when the secret is removed from this stack. | +| replicaRegions | aws-cdk-lib.aws_secretsmanager.ReplicaRegion[] | A list of regions where to replicate this secret. | +| secretName | string | A name for the secret. | +| secretObjectValue | {[ key: string ]: aws-cdk-lib.SecretValue} | Initial value for a JSON secret. | +| secretStringBeta1 | aws-cdk-lib.aws_secretsmanager.SecretStringValueBeta1 | Initial value for the secret. | +| secretStringValue | aws-cdk-lib.SecretValue | Initial value for the secret. | +| autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | +| flattenSeparator | string | If the structure should be flattened use the provided separator between keys. | +| sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | +| sopsFileFormat | string | The format of the sops file. | +| sopsFilePath | string | The filepath to the sops file. | +| sopsKmsKey | aws-cdk-lib.aws_kms.IKey[] | The kmsKey used to encrypt the sops file. | +| sopsProvider | SopsSyncProvider | The custom resource provider to use. | +| sopsS3Bucket | string | If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | +| sopsS3Key | string | If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | +| uploadType | UploadType | How should the secret be passed to the CustomResource? | +| rawOutput | boolean | Should the secret parsed and transformed to json? | + +--- + +##### `description`Optional + +```typescript +public readonly description: string; +``` + +- *Type:* string +- *Default:* No description. + +An optional, human-friendly description of the secret. + +--- + +##### `encryptionKey`Optional + +```typescript +public readonly encryptionKey: IKey; +``` + +- *Type:* aws-cdk-lib.aws_kms.IKey +- *Default:* A default KMS key for the account and region is used. + +The customer-managed encryption key to use for encrypting the secret value. + +--- + +##### `generateSecretString`Optional + +```typescript +public readonly generateSecretString: SecretStringGenerator; +``` + +- *Type:* aws-cdk-lib.aws_secretsmanager.SecretStringGenerator +- *Default:* 32 characters with upper-case letters, lower-case letters, punctuation and numbers (at least one from each category), per the default values of ``SecretStringGenerator``. + +Configuration for how to generate a secret value. Only one of `secretString` and `generateSecretString` can be provided. @@ -2312,38 +2395,6 @@ Should this construct automatically create IAM permissions? --- -##### `convertToJSON`Optional - -```typescript -public readonly convertToJSON: boolean; -``` - -- *Type:* boolean -- *Default:* true - -Should the encrypted sops value should be converted to JSON? - -Only JSON can be handled by cloud formations dynamic references. - ---- - -##### `flatten`Optional - -```typescript -public readonly flatten: boolean; -``` - -- *Type:* boolean -- *Default:* true - -Should the structure be flattened? - -The result will be a flat structure and all -object keys will be replaced with the full jsonpath as key. -This is usefull for dynamic references, as those don't support nested objects. - ---- - ##### `flattenSeparator`Optional ```typescript @@ -2351,24 +2402,12 @@ public readonly flattenSeparator: string; ``` - *Type:* string -- *Default:* '.' +- *Default:* undefined If the structure should be flattened use the provided separator between keys. --- -##### `parameterKeyPrefix`Optional - -```typescript -public readonly parameterKeyPrefix: string; -``` - -- *Type:* string - -Add this prefix to parameter names. - ---- - ##### `sopsAgeKey`Optional ```typescript @@ -2462,38 +2501,34 @@ If you want to pass the sops file via s3, you can specify the key inside the buc --- -##### `stringifyValues`Optional +##### `uploadType`Optional ```typescript -public readonly stringifyValues: boolean; +public readonly uploadType: UploadType; ``` -- *Type:* boolean - -Shall all values be flattened? +- *Type:* UploadType +- *Default:* INLINE -This is usefull for dynamic references, as there -are lookup errors for certain float types +How should the secret be passed to the CustomResource? --- -##### `uploadType`Optional +##### `rawOutput`Optional ```typescript -public readonly uploadType: UploadType; +public readonly rawOutput: boolean; ``` -- *Type:* UploadType -- *Default:* INLINE +- *Type:* boolean +- *Default:* true -How should the secret be passed to the CustomResource? +Should the secret parsed and transformed to json? --- ### SopsStringParameterProps -The configuration options of the StringParameter. - #### Initializer ```typescript @@ -2507,10 +2542,7 @@ const sopsStringParameterProps: SopsStringParameterProps = { ... } | **Name** | **Type** | **Description** | | --- | --- | --- | | autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | -| convertToJSON | boolean | Should the encrypted sops value should be converted to JSON? | -| flatten | boolean | Should the structure be flattened? | | flattenSeparator | string | If the structure should be flattened use the provided separator between keys. | -| parameterKeyPrefix | string | Add this prefix to parameter names. | | sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | | sopsFileFormat | string | The format of the sops file. | | sopsFilePath | string | The filepath to the sops file. | @@ -2518,17 +2550,11 @@ const sopsStringParameterProps: SopsStringParameterProps = { ... } | sopsProvider | SopsSyncProvider | The custom resource provider to use. | | sopsS3Bucket | string | If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | | sopsS3Key | string | If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | -| stringifyValues | boolean | Shall all values be flattened? | | uploadType | UploadType | How should the secret be passed to the CustomResource? | -| allowedPattern | string | A regular expression used to validate the parameter value. | +| encryptionKey | aws-cdk-lib.aws_kms.IKey | *No description.* | | description | string | Information about the parameter that you want to add to the system. | -| parameterName | string | The name of the parameter. | -| simpleName | boolean | Indicates if the parameter name is a simple name (i.e. does not include "/" separators). | | tier | aws-cdk-lib.aws_ssm.ParameterTier | The tier of the string parameter. | -| stringValue | string | The value of the parameter. | -| dataType | aws-cdk-lib.aws_ssm.ParameterDataType | The data type of the parameter, such as `text` or `aws:ec2:image`. | -| type | aws-cdk-lib.aws_ssm.ParameterType | The type of the string parameter. | -| encryptionKey | aws-cdk-lib.aws_kms.IKey | *No description.* | +| parameterName | string | The name of the parameter. | --- @@ -2545,38 +2571,6 @@ Should this construct automatically create IAM permissions? --- -##### `convertToJSON`Optional - -```typescript -public readonly convertToJSON: boolean; -``` - -- *Type:* boolean -- *Default:* true - -Should the encrypted sops value should be converted to JSON? - -Only JSON can be handled by cloud formations dynamic references. - ---- - -##### `flatten`Optional - -```typescript -public readonly flatten: boolean; -``` - -- *Type:* boolean -- *Default:* true - -Should the structure be flattened? - -The result will be a flat structure and all -object keys will be replaced with the full jsonpath as key. -This is usefull for dynamic references, as those don't support nested objects. - ---- - ##### `flattenSeparator`Optional ```typescript @@ -2584,24 +2578,12 @@ public readonly flattenSeparator: string; ``` - *Type:* string -- *Default:* '.' +- *Default:* undefined If the structure should be flattened use the provided separator between keys. --- -##### `parameterKeyPrefix`Optional - -```typescript -public readonly parameterKeyPrefix: string; -``` - -- *Type:* string - -Add this prefix to parameter names. - ---- - ##### `sopsAgeKey`Optional ```typescript @@ -2695,21 +2677,6 @@ If you want to pass the sops file via s3, you can specify the key inside the buc --- -##### `stringifyValues`Optional - -```typescript -public readonly stringifyValues: boolean; -``` - -- *Type:* boolean - -Shall all values be flattened? - -This is usefull for dynamic references, as there -are lookup errors for certain float types - ---- - ##### `uploadType`Optional ```typescript @@ -2723,19 +2690,13 @@ How should the secret be passed to the CustomResource? --- -##### `allowedPattern`Optional +##### `encryptionKey`Required ```typescript -public readonly allowedPattern: string; +public readonly encryptionKey: IKey; ``` -- *Type:* string -- *Default:* no validation is performed - -A regular expression used to validate the parameter value. - -For example, for String types with values restricted to -numbers, you can specify the following: ``^\d+$`` +- *Type:* aws-cdk-lib.aws_kms.IKey --- @@ -2752,40 +2713,6 @@ Information about the parameter that you want to add to the system. --- -##### `parameterName`Optional - -```typescript -public readonly parameterName: string; -``` - -- *Type:* string -- *Default:* a name will be generated by CloudFormation - -The name of the parameter. - ---- - -##### `simpleName`Optional - -```typescript -public readonly simpleName: boolean; -``` - -- *Type:* boolean -- *Default:* auto-detect based on `parameterName` - -Indicates if the parameter name is a simple name (i.e. does not include "/" separators). - -This is required only if `parameterName` is a token, which means we -are unable to detect if the name is simple or "path-like" for the purpose -of rendering SSM parameter ARNs. - -If `parameterName` is not specified, `simpleName` must be `true` (or -undefined) since the name generated by AWS CloudFormation is always a -simple name. - ---- - ##### `tier`Optional ```typescript @@ -2799,55 +2726,16 @@ The tier of the string parameter. --- -##### `stringValue`Required +##### `parameterName`Optional ```typescript -public readonly stringValue: string; +public readonly parameterName: string; ``` - *Type:* string +- *Default:* a name will be generated by CloudFormation -The value of the parameter. - -It may not reference another parameter and ``{{}}`` cannot be used in the value. - ---- - -##### `dataType`Optional - -```typescript -public readonly dataType: ParameterDataType; -``` - -- *Type:* aws-cdk-lib.aws_ssm.ParameterDataType -- *Default:* ParameterDataType.TEXT - -The data type of the parameter, such as `text` or `aws:ec2:image`. - ---- - -##### ~~`type`~~Optional - -- *Deprecated:* - type will always be 'String' - -```typescript -public readonly type: ParameterType; -``` - -- *Type:* aws-cdk-lib.aws_ssm.ParameterType -- *Default:* ParameterType.STRING - -The type of the string parameter. - ---- - -##### `encryptionKey`Required - -```typescript -public readonly encryptionKey: IKey; -``` - -- *Type:* aws-cdk-lib.aws_kms.IKey +The name of the parameter. --- @@ -2868,10 +2756,7 @@ const sopsSyncOptions: SopsSyncOptions = { ... } | **Name** | **Type** | **Description** | | --- | --- | --- | | autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | -| convertToJSON | boolean | Should the encrypted sops value should be converted to JSON? | -| flatten | boolean | Should the structure be flattened? | | flattenSeparator | string | If the structure should be flattened use the provided separator between keys. | -| parameterKeyPrefix | string | Add this prefix to parameter names. | | sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | | sopsFileFormat | string | The format of the sops file. | | sopsFilePath | string | The filepath to the sops file. | @@ -2879,7 +2764,6 @@ const sopsSyncOptions: SopsSyncOptions = { ... } | sopsProvider | SopsSyncProvider | The custom resource provider to use. | | sopsS3Bucket | string | If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | | sopsS3Key | string | If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | -| stringifyValues | boolean | Shall all values be flattened? | | uploadType | UploadType | How should the secret be passed to the CustomResource? | --- @@ -2897,38 +2781,6 @@ Should this construct automatically create IAM permissions? --- -##### `convertToJSON`Optional - -```typescript -public readonly convertToJSON: boolean; -``` - -- *Type:* boolean -- *Default:* true - -Should the encrypted sops value should be converted to JSON? - -Only JSON can be handled by cloud formations dynamic references. - ---- - -##### `flatten`Optional - -```typescript -public readonly flatten: boolean; -``` - -- *Type:* boolean -- *Default:* true - -Should the structure be flattened? - -The result will be a flat structure and all -object keys will be replaced with the full jsonpath as key. -This is usefull for dynamic references, as those don't support nested objects. - ---- - ##### `flattenSeparator`Optional ```typescript @@ -2936,24 +2788,12 @@ public readonly flattenSeparator: string; ``` - *Type:* string -- *Default:* '.' +- *Default:* undefined If the structure should be flattened use the provided separator between keys. --- -##### `parameterKeyPrefix`Optional - -```typescript -public readonly parameterKeyPrefix: string; -``` - -- *Type:* string - -Add this prefix to parameter names. - ---- - ##### `sopsAgeKey`Optional ```typescript @@ -3047,21 +2887,6 @@ If you want to pass the sops file via s3, you can specify the key inside the buc --- -##### `stringifyValues`Optional - -```typescript -public readonly stringifyValues: boolean; -``` - -- *Type:* boolean - -Shall all values be flattened? - -This is usefull for dynamic references, as there -are lookup errors for certain float types - ---- - ##### `uploadType`Optional ```typescript @@ -3092,10 +2917,7 @@ const sopsSyncProps: SopsSyncProps = { ... } | **Name** | **Type** | **Description** | | --- | --- | --- | | autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | -| convertToJSON | boolean | Should the encrypted sops value should be converted to JSON? | -| flatten | boolean | Should the structure be flattened? | | flattenSeparator | string | If the structure should be flattened use the provided separator between keys. | -| parameterKeyPrefix | string | Add this prefix to parameter names. | | sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | | sopsFileFormat | string | The format of the sops file. | | sopsFilePath | string | The filepath to the sops file. | @@ -3103,12 +2925,12 @@ const sopsSyncProps: SopsSyncProps = { ... } | sopsProvider | SopsSyncProvider | The custom resource provider to use. | | sopsS3Bucket | string | If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | | sopsS3Key | string | If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | -| stringifyValues | boolean | Shall all values be flattened? | | uploadType | UploadType | How should the secret be passed to the CustomResource? | -| encryptionKey | aws-cdk-lib.aws_kms.IKey | The encryption key used for encrypting the ssm parameter if `parameterName` is set. | -| parameterNames | string[] | The parameter names. | | resourceType | ResourceType | Will this Sync deploy a Secret or Parameter(s). | -| secret | aws-cdk-lib.aws_secretsmanager.ISecret | The secret that will be populated with the encrypted sops file content. | +| target | string | The target to populate with the sops file content. | +| encryptionKey | aws-cdk-lib.aws_kms.IKey | The encryption key used for encrypting the ssm parameter if `parameterName` is set. | +| parameterNames | string[] | *No description.* | +| secret | aws-cdk-lib.aws_secretsmanager.ISecret | *No description.* | --- @@ -3125,38 +2947,6 @@ Should this construct automatically create IAM permissions? --- -##### `convertToJSON`Optional - -```typescript -public readonly convertToJSON: boolean; -``` - -- *Type:* boolean -- *Default:* true - -Should the encrypted sops value should be converted to JSON? - -Only JSON can be handled by cloud formations dynamic references. - ---- - -##### `flatten`Optional - -```typescript -public readonly flatten: boolean; -``` - -- *Type:* boolean -- *Default:* true - -Should the structure be flattened? - -The result will be a flat structure and all -object keys will be replaced with the full jsonpath as key. -This is usefull for dynamic references, as those don't support nested objects. - ---- - ##### `flattenSeparator`Optional ```typescript @@ -3164,24 +2954,12 @@ public readonly flattenSeparator: string; ``` - *Type:* string -- *Default:* '.' +- *Default:* undefined If the structure should be flattened use the provided separator between keys. --- -##### `parameterKeyPrefix`Optional - -```typescript -public readonly parameterKeyPrefix: string; -``` - -- *Type:* string - -Add this prefix to parameter names. - ---- - ##### `sopsAgeKey`Optional ```typescript @@ -3275,69 +3053,66 @@ If you want to pass the sops file via s3, you can specify the key inside the buc --- -##### `stringifyValues`Optional +##### `uploadType`Optional ```typescript -public readonly stringifyValues: boolean; +public readonly uploadType: UploadType; ``` -- *Type:* boolean - -Shall all values be flattened? +- *Type:* UploadType +- *Default:* INLINE -This is usefull for dynamic references, as there -are lookup errors for certain float types +How should the secret be passed to the CustomResource? --- -##### `uploadType`Optional +##### `resourceType`Required ```typescript -public readonly uploadType: UploadType; +public readonly resourceType: ResourceType; ``` -- *Type:* UploadType -- *Default:* INLINE +- *Type:* ResourceType -How should the secret be passed to the CustomResource? +Will this Sync deploy a Secret or Parameter(s). --- -##### `encryptionKey`Optional +##### `target`Required ```typescript -public readonly encryptionKey: IKey; +public readonly target: string; ``` -- *Type:* aws-cdk-lib.aws_kms.IKey +- *Type:* string -The encryption key used for encrypting the ssm parameter if `parameterName` is set. +The target to populate with the sops file content. + +for secret, it's the name or arn of the secret +- for parameter, it's the name of the parameter +- for parameter multi, it's the prefix of the parameters --- -##### `parameterNames`Optional +##### `encryptionKey`Optional ```typescript -public readonly parameterNames: string[]; +public readonly encryptionKey: IKey; ``` -- *Type:* string[] - -The parameter names. +- *Type:* aws-cdk-lib.aws_kms.IKey -If set this creates encrypted SSM Parameters instead of a secret. +The encryption key used for encrypting the ssm parameter if `parameterName` is set. --- -##### `resourceType`Optional +##### `parameterNames`Optional ```typescript -public readonly resourceType: ResourceType; +public readonly parameterNames: string[]; ``` -- *Type:* ResourceType - -Will this Sync deploy a Secret or Parameter(s). +- *Type:* string[] --- @@ -3349,8 +3124,6 @@ public readonly secret: ISecret; - *Type:* aws-cdk-lib.aws_secretsmanager.ISecret -The secret that will be populated with the encrypted sops file content. - --- ### SopsSyncProviderProps @@ -3441,6 +3214,7 @@ Where to place the network interfaces within the VPC. | **Name** | **Description** | | --- | --- | | SECRET | *No description.* | +| SECRET_BINARY | *No description.* | | PARAMETER | *No description.* | | PARAMETER_MULTI | *No description.* | @@ -3451,6 +3225,11 @@ Where to place the network interfaces within the VPC. --- +##### `SECRET_BINARY` + +--- + + ##### `PARAMETER` --- diff --git a/lambda/README.md b/lambda/README.md new file mode 100644 index 00000000..8892d94f --- /dev/null +++ b/lambda/README.md @@ -0,0 +1,15 @@ +# Tested combinations + +| Test Case | Input Format | Output Format | Flatten | Stringify | Handling Type | Expected Behavior | +| --------- | ------------ | ------------- | ---------- | --------- | --------------- | -------------------------------------- | +| 01 | binary | binary | N/A | N/A | SECRET | No transformation, raw binary output | +| 02 | binary | binary | N/A | N/A | PARAMETER | No transformation, raw binary output | +| 11 | json | N/A | true (N/A) | true | PARAMETER_MULTI | Outputformat allways map[string]string | +| 12 | yaml | N/A | true (N/A) | true | PARAMETER_MULTI | Outputformat allways map[string]string | +| 13 | dotenv | N/A | true (N/A) | true | PARAMETER_MULTI | Outputformat allways map[string]string | +| 21 | json | json | true | true | SECRET | Stringified, Flattened JSON | +| 22 | json | binary | N/A | N/A | SECRET | RAW Input is output | +| 23 | yaml | json | true | true | SECRET | Stringified, Flattened JSON | +| 24 | yaml | binary | N/A | N/A | SECRET | RAW Input is output | +| 25 | dotenv | json | true | true | SECRET | Stringified, Flattened JSON | +| 26 | dotenv | binary | N/A | N/A | SECRET | RAW Input is output | diff --git a/lambda/__snapshots__/01-parameter-binary-binary-true-true.json.snap b/lambda/__snapshots__/01-parameter-binary-binary-true-true.json.snap new file mode 100755 index 00000000..403d7167 --- /dev/null +++ b/lambda/__snapshots__/01-parameter-binary-binary-true-true.json.snap @@ -0,0 +1,17 @@ + +[TestHandleRequestWithClients/01-parameter-binary-binary-true-true.json - 1] +main.getObjectCalls{ + "test-secrets/binary/sopsfile.enc-age.binary": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/binary/sopsfile.enc-age.binary"}, +} +main.getObjectEtagCalls{ + "test-secrets/binary/sopsfile.enc-age.binary": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/binary/sopsfile.enc-age.binary"}, +} +main.putParameterCalls{ + "01-parameter-binary-binary-true-true": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQDVd/OAdqlMznWINBDoyR+PESgQJlUptwnh/vzbgAaIuHl4gN7Q\nW2Jx06bKFgv8yAQ4ouR0EaPv43X1pWFUyE/vK4e2A4M28Ciriy5r2TiBx57EL7bA\nAiiCaEvpKx3uAtTgFYcdLdD5xYKUf51gymZ6wU8BBgYMkVlL5rpGmR7ddQIDAQAB\nAoGAaeEXG+6/RmNZFHeOs4eeaZ2+21PIBerNshSBYnX7x7CIP2bcHUhWadLq9W0+\nAOFMhrL00UU2pPOTPIYM4rqAOl5PvPeV4GNMvI+9/619p/ZNMbnvj43KqUtaPp1g\nJyT22CH4TqDC2io8S9xWxxh9AgvgOI/ekJ3h4PdYpmyVUXkCQQD6b1dkYhlgiy3u\nZ84L5WM+7vXG2ivA3N3T5eYJdsQFvlV6gNSqbKcxIR+cFK0RaRiWrd7U2IOM67RF\nYRvHNN0rAkEA2jZRXVjHjTZSuAVDMOA4cc6pgxOqByg14clWgRDtbueIMHNCYLJY\nbi5YE0kqzjSaH2WbeT7LX1q3S7amoN4f3wJBALw9ZrYYmrSbyRmTQyhj8raCTZF7\nujmMitzUyJVChVM/3uZm4fN8GivuluDuFaypj4brCDx6xl7taKJhvMx+quMCQF/C\nZoJoa2n05OgMpyfTvfFzl8AF6R+q7bpf+K47F3cL9CAO9JoqqdPwUoZkHXzQaLJO\njKPwgp8d2EJJrWX7FFECQQCRMPE4WsTCLXmVefZne7k000WPclZ4pIjggz1lpGgN\n23bwNOla1k4/B10btnEzNi16/b01Kf3K4hYaicd46sLH\n-----END RSA PRIVATE KEY-----", + }, +} +main.putSecretValueCalls{ +} +--- diff --git a/lambda/__snapshots__/02-secret-binary-binary-true-true.json.snap b/lambda/__snapshots__/02-secret-binary-binary-true-true.json.snap new file mode 100755 index 00000000..e9ae9bc0 --- /dev/null +++ b/lambda/__snapshots__/02-secret-binary-binary-true-true.json.snap @@ -0,0 +1,17 @@ + +[TestHandleRequestWithClients/02-secret-binary-binary-true-true.json - 1] +main.getObjectCalls{ + "test-secrets/binary/sopsfile.enc-age.binary": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/binary/sopsfile.enc-age.binary"}, +} +main.getObjectEtagCalls{ + "test-secrets/binary/sopsfile.enc-age.binary": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/binary/sopsfile.enc-age.binary"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "02-secret-binary-binary-true-true": map[string]interface {}{ + "secretContent": "-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQDVd/OAdqlMznWINBDoyR+PESgQJlUptwnh/vzbgAaIuHl4gN7Q\nW2Jx06bKFgv8yAQ4ouR0EaPv43X1pWFUyE/vK4e2A4M28Ciriy5r2TiBx57EL7bA\nAiiCaEvpKx3uAtTgFYcdLdD5xYKUf51gymZ6wU8BBgYMkVlL5rpGmR7ddQIDAQAB\nAoGAaeEXG+6/RmNZFHeOs4eeaZ2+21PIBerNshSBYnX7x7CIP2bcHUhWadLq9W0+\nAOFMhrL00UU2pPOTPIYM4rqAOl5PvPeV4GNMvI+9/619p/ZNMbnvj43KqUtaPp1g\nJyT22CH4TqDC2io8S9xWxxh9AgvgOI/ekJ3h4PdYpmyVUXkCQQD6b1dkYhlgiy3u\nZ84L5WM+7vXG2ivA3N3T5eYJdsQFvlV6gNSqbKcxIR+cFK0RaRiWrd7U2IOM67RF\nYRvHNN0rAkEA2jZRXVjHjTZSuAVDMOA4cc6pgxOqByg14clWgRDtbueIMHNCYLJY\nbi5YE0kqzjSaH2WbeT7LX1q3S7amoN4f3wJBALw9ZrYYmrSbyRmTQyhj8raCTZF7\nujmMitzUyJVChVM/3uZm4fN8GivuluDuFaypj4brCDx6xl7taKJhvMx+quMCQF/C\nZoJoa2n05OgMpyfTvfFzl8AF6R+q7bpf+K47F3cL9CAO9JoqqdPwUoZkHXzQaLJO\njKPwgp8d2EJJrWX7FFECQQCRMPE4WsTCLXmVefZne7k000WPclZ4pIjggz1lpGgN\n23bwNOla1k4/B10btnEzNi16/b01Kf3K4hYaicd46sLH\n-----END RSA PRIVATE KEY-----", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/11-parametermulti-json-na-true-na.json.snap b/lambda/__snapshots__/11-parametermulti-json-na-true-na.json.snap new file mode 100755 index 00000000..35ced433 --- /dev/null +++ b/lambda/__snapshots__/11-parametermulti-json-na-true-na.json.snap @@ -0,0 +1,49 @@ + +[TestHandleRequestWithClients/11-parametermulti-json-na-true-na.json - 1] +main.getObjectCalls{ + "test-secrets/json/sopsfile-complex.enc-age.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/json/sopsfile-complex.enc-age.json"}, +} +main.getObjectEtagCalls{ + "test-secrets/json/sopsfile-complex.enc-age.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/json/sopsfile-complex.enc-age.json"}, +} +main.putParameterCalls{ + "/11-parametermulti-json-na-true-na/and_now/some/0/basic": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "false", + }, + "/11-parametermulti-json-na-true-na/and_now/some/1/nested": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "12345", + }, + "/11-parametermulti-json-na-true-na/and_now/some/2/type": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "1.2345", + }, + "/11-parametermulti-json-na-true-na/and_now/some/3/tests": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "Finish!", + }, + "/11-parametermulti-json-na-true-na/some/deep/nested/arrays/0": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "with", + }, + "/11-parametermulti-json-na-true-na/some/deep/nested/arrays/1": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "several", + }, + "/11-parametermulti-json-na-true-na/some/deep/nested/arrays/2/values/and": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "objects", + }, + "/11-parametermulti-json-na-true-na/some/deep/nested/object": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "structure", + }, + "/11-parametermulti-json-na-true-na/some/notsodeep": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "struct", + }, +} +main.putSecretValueCalls{ +} +--- diff --git a/lambda/__snapshots__/12-parametermulti-yaml-na-true-na.json.snap b/lambda/__snapshots__/12-parametermulti-yaml-na-true-na.json.snap new file mode 100755 index 00000000..0e72ed0c --- /dev/null +++ b/lambda/__snapshots__/12-parametermulti-yaml-na-true-na.json.snap @@ -0,0 +1,49 @@ + +[TestHandleRequestWithClients/12-parametermulti-yaml-na-true-na.json - 1] +main.getObjectCalls{ + "test-secrets/yaml/sopsfile-complex.enc-age.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/yaml/sopsfile-complex.enc-age.yaml"}, +} +main.getObjectEtagCalls{ + "test-secrets/yaml/sopsfile-complex.enc-age.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/yaml/sopsfile-complex.enc-age.yaml"}, +} +main.putParameterCalls{ + "/12-parametermulti-yaml-na-true-true/and_now/some/0/basic": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "false", + }, + "/12-parametermulti-yaml-na-true-true/and_now/some/1/nested": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "12345", + }, + "/12-parametermulti-yaml-na-true-true/and_now/some/2/type": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "1.2345", + }, + "/12-parametermulti-yaml-na-true-true/and_now/some/3/tests": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "Finish!", + }, + "/12-parametermulti-yaml-na-true-true/some/deep/nested/arrays/0": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "with", + }, + "/12-parametermulti-yaml-na-true-true/some/deep/nested/arrays/1": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "several", + }, + "/12-parametermulti-yaml-na-true-true/some/deep/nested/arrays/2/values/and": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "objects", + }, + "/12-parametermulti-yaml-na-true-true/some/deep/nested/object": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "structure", + }, + "/12-parametermulti-yaml-na-true-true/some/notsodeep": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "struct", + }, +} +main.putSecretValueCalls{ +} +--- diff --git a/lambda/__snapshots__/13-parametermulti-dotenv-na-true-na.json.snap b/lambda/__snapshots__/13-parametermulti-dotenv-na-true-na.json.snap new file mode 100755 index 00000000..1d4df3ff --- /dev/null +++ b/lambda/__snapshots__/13-parametermulti-dotenv-na-true-na.json.snap @@ -0,0 +1,21 @@ + +[TestHandleRequestWithClients/13-parametermulti-dotenv-na-true-na.json - 1] +main.getObjectCalls{ + "test-secrets/dotenv/encrypted-best-secret.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/dotenv/encrypted-best-secret.env"}, +} +main.getObjectEtagCalls{ + "test-secrets/dotenv/encrypted-best-secret.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/dotenv/encrypted-best-secret.env"}, +} +main.putParameterCalls{ + "/13-parametermulti-dotenv-na-true-na/banane": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "yellow", + }, + "/13-parametermulti-dotenv-na-true-na/crypt": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "\"ajkscbuiuXA34%%&&=", + }, +} +main.putSecretValueCalls{ +} +--- diff --git a/lambda/__snapshots__/21-secret-json-json-true-true.json.snap b/lambda/__snapshots__/21-secret-json-json-true-true.json.snap new file mode 100755 index 00000000..545bab6b --- /dev/null +++ b/lambda/__snapshots__/21-secret-json-json-true-true.json.snap @@ -0,0 +1,17 @@ + +[TestHandleRequestWithClients/21-secret-json-json-true-true.json - 1] +main.getObjectCalls{ + "test-secrets/json/sopsfile-complex.enc-age.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/json/sopsfile-complex.enc-age.json"}, +} +main.getObjectEtagCalls{ + "test-secrets/json/sopsfile-complex.enc-age.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/json/sopsfile-complex.enc-age.json"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "21-secret-json-json-true-true": map[string]interface {}{ + "secretContent": "{\n \"and now.some[0].basic\": \"false\",\n \"and now.some[1].nested\": \"12345\",\n \"and now.some[2].type\": \"1.2345\",\n \"and now.some[3].tests\": \"Finish!\",\n \"some.deep.nested.arrays[0]\": \"with\",\n \"some.deep.nested.arrays[1]\": \"several\",\n \"some.deep.nested.arrays[2].values.and\": \"objects\",\n \"some.deep.nested.object\": \"structure\",\n \"some.notsodeep\": \"struct\"\n}", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/22-secret-json-binary-na-na.json.snap b/lambda/__snapshots__/22-secret-json-binary-na-na.json.snap new file mode 100755 index 00000000..4d63c6af --- /dev/null +++ b/lambda/__snapshots__/22-secret-json-binary-na-na.json.snap @@ -0,0 +1,17 @@ + +[TestHandleRequestWithClients/22-secret-json-binary-na-na.json - 1] +main.getObjectCalls{ + "test-secrets/json/sopsfile-complex.enc-age.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/json/sopsfile-complex.enc-age.json"}, +} +main.getObjectEtagCalls{ + "test-secrets/json/sopsfile-complex.enc-age.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/json/sopsfile-complex.enc-age.json"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "22-secret-json-binary-true-true": map[string]interface {}{ + "secretContent": "{\n\t\"some\": {\n\t\t\"deep\": {\n\t\t\t\"nested\": {\n\t\t\t\t\"object\": \"structure\",\n\t\t\t\t\"arrays\": [\n\t\t\t\t\t\"with\",\n\t\t\t\t\t\"several\",\n\t\t\t\t\t{\n\t\t\t\t\t\t\"values\": {\n\t\t\t\t\t\t\t\"and\": \"objects\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t},\n\t\t\"notsodeep\": \"struct\"\n\t},\n\t\"and now\": {\n\t\t\"some\": [\n\t\t\t{\n\t\t\t\t\"basic\": false\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"nested\": 12345\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"type\": 1.2345\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"tests\": \"Finish!\"\n\t\t\t}\n\t\t]\n\t}\n}", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/23-secret-yaml-json-true-true.json.snap b/lambda/__snapshots__/23-secret-yaml-json-true-true.json.snap new file mode 100755 index 00000000..bcc42659 --- /dev/null +++ b/lambda/__snapshots__/23-secret-yaml-json-true-true.json.snap @@ -0,0 +1,17 @@ + +[TestHandleRequestWithClients/23-secret-yaml-json-true-true.json - 1] +main.getObjectCalls{ + "test-secrets/yaml/sopsfile-complex.enc-age.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/yaml/sopsfile-complex.enc-age.yaml"}, +} +main.getObjectEtagCalls{ + "test-secrets/yaml/sopsfile-complex.enc-age.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/yaml/sopsfile-complex.enc-age.yaml"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "23-secret-yaml-json-true-true": map[string]interface {}{ + "secretContent": "{\n \"and now.some[0].basic\": \"false\",\n \"and now.some[1].nested\": \"12345\",\n \"and now.some[2].type\": \"1.2345\",\n \"and now.some[3].tests\": \"Finish!\",\n \"some.deep.nested.arrays[0]\": \"with\",\n \"some.deep.nested.arrays[1]\": \"several\",\n \"some.deep.nested.arrays[2].values.and\": \"objects\",\n \"some.deep.nested.object\": \"structure\",\n \"some.notsodeep\": \"struct\"\n}", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/24-secret-yaml-binary-na-na.json.snap b/lambda/__snapshots__/24-secret-yaml-binary-na-na.json.snap new file mode 100755 index 00000000..479e17c1 --- /dev/null +++ b/lambda/__snapshots__/24-secret-yaml-binary-na-na.json.snap @@ -0,0 +1,17 @@ + +[TestHandleRequestWithClients/24-secret-yaml-binary-na-na.json - 1] +main.getObjectCalls{ + "test-secrets/yaml/sopsfile-complex.enc-age.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/yaml/sopsfile-complex.enc-age.yaml"}, +} +main.getObjectEtagCalls{ + "test-secrets/yaml/sopsfile-complex.enc-age.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/yaml/sopsfile-complex.enc-age.yaml"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "24-secret-yaml-binary-na-na": map[string]interface {}{ + "secretContent": "some:\n deep:\n nested:\n object: structure\n arrays:\n - with\n - several\n - values:\n and: objects\n notsodeep: struct\nand now:\n some:\n - basic: false\n - nested: 12345\n - type: 1.2345\n - tests: Finish!\n", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/25-secret-dotenv-json-true-true.json.snap b/lambda/__snapshots__/25-secret-dotenv-json-true-true.json.snap new file mode 100755 index 00000000..20d2085d --- /dev/null +++ b/lambda/__snapshots__/25-secret-dotenv-json-true-true.json.snap @@ -0,0 +1,17 @@ + +[TestHandleRequestWithClients/25-secret-dotenv-json-true-true.json - 1] +main.getObjectCalls{ + "test-secrets/dotenv/encrypted-best-secret.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/dotenv/encrypted-best-secret.env"}, +} +main.getObjectEtagCalls{ + "test-secrets/dotenv/encrypted-best-secret.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/dotenv/encrypted-best-secret.env"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "25-secret-dotenv-json-true-true": map[string]interface {}{ + "secretContent": "{\n \"banane\": \"yellow\",\n \"crypt\": \"\\\"ajkscbuiuXA34%%\\u0026\\u0026=\"\n}", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/26-secret-dotenv-binary-na-na.json.snap b/lambda/__snapshots__/26-secret-dotenv-binary-na-na.json.snap new file mode 100755 index 00000000..83e4b854 --- /dev/null +++ b/lambda/__snapshots__/26-secret-dotenv-binary-na-na.json.snap @@ -0,0 +1,17 @@ + +[TestHandleRequestWithClients/26-secret-dotenv-binary-na-na.json - 1] +main.getObjectCalls{ + "test-secrets/dotenv/encrypted-best-secret.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/dotenv/encrypted-best-secret.env"}, +} +main.getObjectEtagCalls{ + "test-secrets/dotenv/encrypted-best-secret.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/dotenv/encrypted-best-secret.env"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "26-secret-dotenv-binary-true-true": map[string]interface {}{ + "secretContent": "banane=yellow\ncrypt=\"ajkscbuiuXA34%%&&=\n", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/conversion_test.snap b/lambda/__snapshots__/conversion_test.snap deleted file mode 100755 index 0d586cd3..00000000 --- a/lambda/__snapshots__/conversion_test.snap +++ /dev/null @@ -1,197 +0,0 @@ - -[Test_FromJSON - 1] ->>>Simple -map[string]interface {}{ - "key1": "value1", - "key2": float64(12345), - "key3": bool(false), -} ---- - -[Test_FromJSON - 2] ->>>Complex -map[string]interface {}{ - "and now": map[string]interface {}{ - "some": []interface {}{ - map[string]interface {}{ - "basic": bool(false), - }, - map[string]interface {}{ - "nested": float64(12345), - }, - map[string]interface {}{ - "type": float64(1.2345), - }, - map[string]interface {}{ - "tests": "Finish!", - }, - }, - }, - "some": map[string]interface {}{ - "deep": map[string]interface {}{ - "nested": map[string]interface {}{ - "arrays": []interface {}{ - "with", - "several", - map[string]interface {}{ - "values": map[string]interface {}{ - "and": "objects", - }, - }, - }, - "object": "structure", - }, - }, - "notsodeep": "struct", - }, -} ---- - -[Test_FromYAML - 1] ->>>Simple -map[string]interface {}{ - "key1": "value1", - "key2": int(12345), - "key3": bool(false), -} ---- - -[Test_FromYAML - 2] ->>>Complex -map[string]interface {}{ - "and now": map[string]interface {}{ - "some": []interface {}{ - map[string]interface {}{ - "basic": bool(false), - }, - map[string]interface {}{ - "nested": int(12345), - }, - map[string]interface {}{ - "type": float64(1.2345), - }, - map[string]interface {}{ - "tests": "Finish!", - }, - }, - }, - "some": map[string]interface {}{ - "deep": map[string]interface {}{ - "nested": map[string]interface {}{ - "arrays": []interface {}{ - "with", - "several", - map[string]interface {}{ - "values": map[string]interface {}{ - "and": "objects", - }, - }, - }, - "object": "structure", - }, - }, - "notsodeep": "struct", - }, -} ---- - -[Test_Flatten - 1] ->>>Simple -map[string]interface {}{ - "key1": "value1", - "key2": float64(12345), - "key3": bool(false), -} ---- - -[Test_Flatten - 2] ->>>Complex -map[string]interface {}{ - "and now.some[0].basic": bool(false), - "and now.some[1].nested": float64(12345), - "and now.some[2].type": float64(1.2345), - "and now.some[3].tests": "Finish!", - "some.deep.nested.arrays[0]": "with", - "some.deep.nested.arrays[1]": "several", - "some.deep.nested.arrays[2].values.and": "objects", - "some.deep.nested.object": "structure", - "some.notsodeep": "struct", -} ---- - -[Test_toJSON - 1] ->>>Simple -{ - "key1": "value1", - "key2": 12345, - "key3": false -} ---- - -[Test_toJSON - 2] ->>>Complex -{ - "and now": { - "some": [ - { - "basic": false - }, - { - "nested": 12345 - }, - { - "type": 1.2345 - }, - { - "tests": "Finish!" - } - ] - }, - "some": { - "deep": { - "nested": { - "arrays": [ - "with", - "several", - { - "values": { - "and": "objects" - } - } - ], - "object": "structure" - } - }, - "notsodeep": "struct" - } -} ---- - -[Test_toYAML - 1] ->>>Simple -key1: value1 -key2: 12345 -key3: false - ---- - -[Test_toYAML - 2] ->>>Complex -and now: - some: - - basic: false - - nested: 12345 - - type: 1.2345 - - tests: Finish! -some: - deep: - nested: - arrays: - - with - - several - - values: - and: objects - object: structure - notsodeep: struct - ---- diff --git a/lambda/__snapshots__/handler_common_test.snap b/lambda/__snapshots__/handler_common_test.snap deleted file mode 100755 index d684791a..00000000 --- a/lambda/__snapshots__/handler_common_test.snap +++ /dev/null @@ -1,7 +0,0 @@ - -[Test_FullWorkflow_Delete - 1] ->>>syncSopsToSecretsmanager - -map[string]interface {}{} -nil ---- diff --git a/lambda/__snapshots__/handler_parameter_raw_test.snap b/lambda/__snapshots__/handler_parameter_raw_test.snap deleted file mode 100755 index 46007613..00000000 --- a/lambda/__snapshots__/handler_parameter_raw_test.snap +++ /dev/null @@ -1,46 +0,0 @@ - -[Test_FullWorkflow_Create_S3_Parameter_RAW_Simple - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/binary/sopsfile.enc-age.binary", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_RAW_Simple - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/binary/sopsfile.enc-age.binary" -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_RAW_Simple - 3] ->>>SecretsManagerMockClient.PutParameterValue.Input -main.putParameterValueInputNotSecure{ - _: struct {}{}, - AllowedPattern: (*string)(nil), - DataType: (*string)(nil), - Description: (*string)(nil), - KeyId: &"", - Name: &"arn:aws:ssm:eu-central-1:123456789012:parameter/testsecret", - Overwrite: &bool(true), - Policies: (*string)(nil), - Tags: nil, - Tier: (*string)(nil), - Type: &"SecureString", - Value: &"-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQDVd/OAdqlMznWINBDoyR+PESgQJlUptwnh/vzbgAaIuHl4gN7Q\nW2Jx06bKFgv8yAQ4ouR0EaPv43X1pWFUyE/vK4e2A4M28Ciriy5r2TiBx57EL7bA\nAiiCaEvpKx3uAtTgFYcdLdD5xYKUf51gymZ6wU8BBgYMkVlL5rpGmR7ddQIDAQAB\nAoGAaeEXG+6/RmNZFHeOs4eeaZ2+21PIBerNshSBYnX7x7CIP2bcHUhWadLq9W0+\nAOFMhrL00UU2pPOTPIYM4rqAOl5PvPeV4GNMvI+9/619p/ZNMbnvj43KqUtaPp1g\nJyT22CH4TqDC2io8S9xWxxh9AgvgOI/ekJ3h4PdYpmyVUXkCQQD6b1dkYhlgiy3u\nZ84L5WM+7vXG2ivA3N3T5eYJdsQFvlV6gNSqbKcxIR+cFK0RaRiWrd7U2IOM67RF\nYRvHNN0rAkEA2jZRXVjHjTZSuAVDMOA4cc6pgxOqByg14clWgRDtbueIMHNCYLJY\nbi5YE0kqzjSaH2WbeT7LX1q3S7amoN4f3wJBALw9ZrYYmrSbyRmTQyhj8raCTZF7\nujmMitzUyJVChVM/3uZm4fN8GivuluDuFaypj4brCDx6xl7taKJhvMx+quMCQF/C\nZoJoa2n05OgMpyfTvfFzl8AF6R+q7bpf+K47F3cL9CAO9JoqqdPwUoZkHXzQaLJO\njKPwgp8d2EJJrWX7FFECQQCRMPE4WsTCLXmVefZne7k000WPclZ4pIjggz1lpGgN\n23bwNOla1k4/B10btnEzNi16/b01Kf3K4hYaicd46sLH\n-----END RSA PRIVATE KEY-----", -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_RAW_Simple - 4] ->>>syncSopsToSecretsmanager -arn:aws:arn:custom:sopssync:eu-central-1:123456789012:parameter/testsecret -map[string]interface {}{ - "ParameterName": "arn:aws:ssm:eu-central-1:123456789012:parameter/testsecret", - "Tier": &"Standard", - "Version": &int64(1), -} -nil ---- diff --git a/lambda/__snapshots__/handler_parameter_yaml_multi_test.snap b/lambda/__snapshots__/handler_parameter_yaml_multi_test.snap deleted file mode 100755 index 8826756e..00000000 --- a/lambda/__snapshots__/handler_parameter_yaml_multi_test.snap +++ /dev/null @@ -1,126 +0,0 @@ - -[Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex-parameters.enc-age.yaml", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex-parameters.enc-age.yaml" -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple - 3] ->>>SecretsManagerMockClient.PutParameterValue.Input -main.putParameterValueInputNotSecure{ - _: struct {}{}, - AllowedPattern: (*string)(nil), - DataType: (*string)(nil), - Description: (*string)(nil), - KeyId: &"", - Name: &"/foo/bar/key1", - Overwrite: &bool(true), - Policies: (*string)(nil), - Tags: nil, - Tier: (*string)(nil), - Type: &"SecureString", - Value: &"foo", -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple - 4] ->>>SecretsManagerMockClient.PutParameterValue.Input -main.putParameterValueInputNotSecure{ - _: struct {}{}, - AllowedPattern: (*string)(nil), - DataType: (*string)(nil), - Description: (*string)(nil), - KeyId: &"", - Name: &"/foo/bar/key2", - Overwrite: &bool(true), - Policies: (*string)(nil), - Tags: nil, - Tier: (*string)(nil), - Type: &"SecureString", - Value: &"bar", -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple - 5] ->>>syncSopsToSecretsmanager -arn:aws:arn:custom:sopssync:eu-central-1:123456789012:parameter/testsecret -map[string]interface {}{ - "Count": int(2), - "Prefix": "/", -} -nil ---- - -[Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple_custom_keys - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex-parameters.enc-age.yaml", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple_custom_keys - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex-parameters.enc-age.yaml" -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple_custom_keys - 3] ->>>SecretsManagerMockClient.PutParameterValue.Input -main.putParameterValueInputNotSecure{ - _: struct {}{}, - AllowedPattern: (*string)(nil), - DataType: (*string)(nil), - Description: (*string)(nil), - KeyId: &"", - Name: &"_foo.bar.key1", - Overwrite: &bool(true), - Policies: (*string)(nil), - Tags: nil, - Tier: (*string)(nil), - Type: &"SecureString", - Value: &"foo", -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple_custom_keys - 4] ->>>SecretsManagerMockClient.PutParameterValue.Input -main.putParameterValueInputNotSecure{ - _: struct {}{}, - AllowedPattern: (*string)(nil), - DataType: (*string)(nil), - Description: (*string)(nil), - KeyId: &"", - Name: &"_foo.bar.key2", - Overwrite: &bool(true), - Policies: (*string)(nil), - Tags: nil, - Tier: (*string)(nil), - Type: &"SecureString", - Value: &"bar", -} ---- - -[Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple_custom_keys - 5] ->>>syncSopsToSecretsmanager -arn:aws:arn:custom:sopssync:eu-central-1:123456789012:parameter/testsecret -map[string]interface {}{ - "Count": int(2), - "Prefix": "_", -} -nil ---- diff --git a/lambda/__snapshots__/handler_secret_env_test.snap b/lambda/__snapshots__/handler_secret_env_test.snap deleted file mode 100755 index 0488553e..00000000 --- a/lambda/__snapshots__/handler_secret_env_test.snap +++ /dev/null @@ -1,88 +0,0 @@ - -[Test_FullWorkflow_Create_S3_ENV_Simple - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/dotenv/encrypted-best-secret.env", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_ENV_Simple - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/dotenv/encrypted-best-secret.env" -} ---- - -[Test_FullWorkflow_Create_S3_ENV_Simple - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"banane=yellow\ncrypt=\"ajkscbuiuXA34%%&&=\n", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_ENV_Simple - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "6e5c42133fbe7c37503ffbd8e2c4dd792b6800a7aa022e5ee9d70892c3be4205", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_S3_ENV_as_JSON_Simple - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/dotenv/encrypted-best-secret.env", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_ENV_as_JSON_Simple - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/dotenv/encrypted-best-secret.env" -} ---- - -[Test_FullWorkflow_Create_S3_ENV_as_JSON_Simple - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"banane\": \"yellow\",\n \"crypt\": \"\\\"ajkscbuiuXA34%%\\u0026\\u0026=\"\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_ENV_as_JSON_Simple - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "853112768310b655f423f8e8338d83ca124ddfa16d70f60f0b82aeb3861744c5", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- diff --git a/lambda/__snapshots__/handler_secret_json_test.snap b/lambda/__snapshots__/handler_secret_json_test.snap deleted file mode 100755 index 83ca106c..00000000 --- a/lambda/__snapshots__/handler_secret_json_test.snap +++ /dev/null @@ -1,284 +0,0 @@ - -[Test_FullWorkflow_Create_S3_JSON_Simple - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/json/sopsfile.enc-age.json", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Simple - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/json/sopsfile.enc-age.json" -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Simple - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"key1\": \"value1\",\n \"key2\": 12345,\n \"key3\": false\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Simple - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "46b116fd9409581eb2623320d877cfa1f46cb2487bc3cd0672b1eb95554e65d3", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/json/sopsfile-complex.enc-age.json", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/json/sopsfile-complex.enc-age.json" -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"and now\": {\n \"some\": [\n {\n \"basic\": false\n },\n {\n \"nested\": 12345\n },\n {\n \"type\": 1.2345\n },\n {\n \"tests\": \"Finish!\"\n }\n ]\n },\n \"some\": {\n \"deep\": {\n \"nested\": {\n \"arrays\": [\n \"with\",\n \"several\",\n {\n \"values\": {\n \"and\": \"objects\"\n }\n }\n ],\n \"object\": \"structure\"\n }\n },\n \"notsodeep\": \"struct\"\n }\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "28e49c30b2d8af77e323b63c5c9e90ec2cf1385ab330eb674695ee065b1252f2", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex_StringifyValues - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/json/sopsfile-complex.enc-age.json", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex_StringifyValues - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/json/sopsfile-complex.enc-age.json" -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex_StringifyValues - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"and now\": {\n \"some\": [\n {\n \"basic\": \"false\"\n },\n {\n \"nested\": \"12345\"\n },\n {\n \"type\": \"1.2345\"\n },\n {\n \"tests\": \"Finish!\"\n }\n ]\n },\n \"some\": {\n \"deep\": {\n \"nested\": {\n \"arrays\": [\n \"with\",\n \"several\",\n {\n \"values\": {\n \"and\": \"objects\"\n }\n }\n ],\n \"object\": \"structure\"\n }\n },\n \"notsodeep\": \"struct\"\n }\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex_StringifyValues - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "ddc702937cbed1b68f84659094f8db7c862114642ae2a98baa43c42e16b256f4", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex_Flat - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/json/sopsfile-complex.enc-age.json", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex_Flat - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/json/sopsfile-complex.enc-age.json" -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex_Flat - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"and now.some[0].basic\": false,\n \"and now.some[1].nested\": 12345,\n \"and now.some[2].type\": 1.2345,\n \"and now.some[3].tests\": \"Finish!\",\n \"some.deep.nested.arrays[0]\": \"with\",\n \"some.deep.nested.arrays[1]\": \"several\",\n \"some.deep.nested.arrays[2].values.and\": \"objects\",\n \"some.deep.nested.object\": \"structure\",\n \"some.notsodeep\": \"struct\"\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_JSON_Complex_Flat - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "e9a8d3ab5715c1120faae25b669e5905a92fe4b261ae97eb1e65ad9ba52f9ee6", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_INLINE_JSON_Simple - 1] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"MyHash", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"key1\": \"value1\",\n \"key2\": 12345,\n \"key3\": false\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_INLINE_JSON_Simple - 2] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "46b116fd9409581eb2623320d877cfa1f46cb2487bc3cd0672b1eb95554e65d3", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_INLINE_JSON_Complex - 1] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"MyHash", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"and now\": {\n \"some\": [\n {\n \"basic\": false\n },\n {\n \"nested\": 12345\n },\n {\n \"type\": 1.2345\n },\n {\n \"tests\": \"Finish!\"\n }\n ]\n },\n \"some\": {\n \"deep\": {\n \"nested\": {\n \"arrays\": [\n \"with\",\n \"several\",\n {\n \"values\": {\n \"and\": \"objects\"\n }\n }\n ],\n \"object\": \"structure\"\n }\n },\n \"notsodeep\": \"struct\"\n }\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_INLINE_JSON_Complex - 2] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "28e49c30b2d8af77e323b63c5c9e90ec2cf1385ab330eb674695ee065b1252f2", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_INLINE_JSON_Complex_StringifyValues - 1] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"MyHash", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"and now\": {\n \"some\": [\n {\n \"basic\": \"false\"\n },\n {\n \"nested\": \"12345\"\n },\n {\n \"type\": \"1.2345\"\n },\n {\n \"tests\": \"Finish!\"\n }\n ]\n },\n \"some\": {\n \"deep\": {\n \"nested\": {\n \"arrays\": [\n \"with\",\n \"several\",\n {\n \"values\": {\n \"and\": \"objects\"\n }\n }\n ],\n \"object\": \"structure\"\n }\n },\n \"notsodeep\": \"struct\"\n }\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_INLINE_JSON_Complex_StringifyValues - 2] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "ddc702937cbed1b68f84659094f8db7c862114642ae2a98baa43c42e16b256f4", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_INLINE_JSON_Complex_Flat - 1] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"MyHash", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"and now.some[0].basic\": false,\n \"and now.some[1].nested\": 12345,\n \"and now.some[2].type\": 1.2345,\n \"and now.some[3].tests\": \"Finish!\",\n \"some.deep.nested.arrays[0]\": \"with\",\n \"some.deep.nested.arrays[1]\": \"several\",\n \"some.deep.nested.arrays[2].values.and\": \"objects\",\n \"some.deep.nested.object\": \"structure\",\n \"some.notsodeep\": \"struct\"\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_INLINE_JSON_Complex_Flat - 2] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "e9a8d3ab5715c1120faae25b669e5905a92fe4b261ae97eb1e65ad9ba52f9ee6", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- diff --git a/lambda/__snapshots__/handler_secret_raw_test.snap b/lambda/__snapshots__/handler_secret_raw_test.snap deleted file mode 100755 index 674c2da6..00000000 --- a/lambda/__snapshots__/handler_secret_raw_test.snap +++ /dev/null @@ -1,44 +0,0 @@ - -[Test_FullWorkflow_Create_S3_RAW_Simple - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/binary/sopsfile.enc-age.binary", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_RAW_Simple - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/binary/sopsfile.enc-age.binary" -} ---- - -[Test_FullWorkflow_Create_S3_RAW_Simple - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQDVd/OAdqlMznWINBDoyR+PESgQJlUptwnh/vzbgAaIuHl4gN7Q\nW2Jx06bKFgv8yAQ4ouR0EaPv43X1pWFUyE/vK4e2A4M28Ciriy5r2TiBx57EL7bA\nAiiCaEvpKx3uAtTgFYcdLdD5xYKUf51gymZ6wU8BBgYMkVlL5rpGmR7ddQIDAQAB\nAoGAaeEXG+6/RmNZFHeOs4eeaZ2+21PIBerNshSBYnX7x7CIP2bcHUhWadLq9W0+\nAOFMhrL00UU2pPOTPIYM4rqAOl5PvPeV4GNMvI+9/619p/ZNMbnvj43KqUtaPp1g\nJyT22CH4TqDC2io8S9xWxxh9AgvgOI/ekJ3h4PdYpmyVUXkCQQD6b1dkYhlgiy3u\nZ84L5WM+7vXG2ivA3N3T5eYJdsQFvlV6gNSqbKcxIR+cFK0RaRiWrd7U2IOM67RF\nYRvHNN0rAkEA2jZRXVjHjTZSuAVDMOA4cc6pgxOqByg14clWgRDtbueIMHNCYLJY\nbi5YE0kqzjSaH2WbeT7LX1q3S7amoN4f3wJBALw9ZrYYmrSbyRmTQyhj8raCTZF7\nujmMitzUyJVChVM/3uZm4fN8GivuluDuFaypj4brCDx6xl7taKJhvMx+quMCQF/C\nZoJoa2n05OgMpyfTvfFzl8AF6R+q7bpf+K47F3cL9CAO9JoqqdPwUoZkHXzQaLJO\njKPwgp8d2EJJrWX7FFECQQCRMPE4WsTCLXmVefZne7k000WPclZ4pIjggz1lpGgN\n23bwNOla1k4/B10btnEzNi16/b01Kf3K4hYaicd46sLH\n-----END RSA PRIVATE KEY-----", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_RAW_Simple - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "afe1e68ea88d603e524fc4854b2f33e8f56ce0cc80b539d21fddcbf82586fb38", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- diff --git a/lambda/__snapshots__/handler_secret_yaml_test.snap b/lambda/__snapshots__/handler_secret_yaml_test.snap deleted file mode 100755 index 9e19453e..00000000 --- a/lambda/__snapshots__/handler_secret_yaml_test.snap +++ /dev/null @@ -1,443 +0,0 @@ - -[Test_FullWorkflow_Create_S3_YAML_Simple - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile.enc-age.yaml", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_YAML_Simple - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile.enc-age.yaml" -} ---- - -[Test_FullWorkflow_Create_S3_YAML_Simple - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"key1: value1\nkey2: 12345\nkey3: false\n", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_YAML_Simple - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "656f2d935b86bfbefbd97f1c55c1578aef8d96c5647a6161e37f94fb34a84d61", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Simple - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile.enc-age.yaml", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Simple - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile.enc-age.yaml" -} ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Simple - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"key1\": \"value1\",\n \"key2\": 12345,\n \"key3\": false\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Simple - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "46b116fd9409581eb2623320d877cfa1f46cb2487bc3cd0672b1eb95554e65d3", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_S3_YAML_Complex - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex.enc-age.yaml", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_YAML_Complex - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex.enc-age.yaml" -} ---- - -[Test_FullWorkflow_Create_S3_YAML_Complex - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"and now:\n some:\n - basic: false\n - nested: 12345\n - type: 1.2345\n - tests: Finish!\nsome:\n deep:\n nested:\n arrays:\n - with\n - several\n - values:\n and: objects\n object: structure\n notsodeep: struct\n", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_YAML_Complex - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "99d08789c0db731bcf0f3a467759c84c11e1b18253f9d614be55c817a410e088", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Complex - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex.enc-age.yaml", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Complex - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex.enc-age.yaml" -} ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Complex - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"and now\": {\n \"some\": [\n {\n \"basic\": false\n },\n {\n \"nested\": 12345\n },\n {\n \"type\": 1.2345\n },\n {\n \"tests\": \"Finish!\"\n }\n ]\n },\n \"some\": {\n \"deep\": {\n \"nested\": {\n \"arrays\": [\n \"with\",\n \"several\",\n {\n \"values\": {\n \"and\": \"objects\"\n }\n }\n ],\n \"object\": \"structure\"\n }\n },\n \"notsodeep\": \"struct\"\n }\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Complex - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "28e49c30b2d8af77e323b63c5c9e90ec2cf1385ab330eb674695ee065b1252f2", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_S3_YAML_Complex_Flat - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex.enc-age.yaml", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_YAML_Complex_Flat - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex.enc-age.yaml" -} ---- - -[Test_FullWorkflow_Create_S3_YAML_Complex_Flat - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"and now.some[0].basic: false\nand now.some[1].nested: 12345\nand now.some[2].type: 1.2345\nand now.some[3].tests: Finish!\nsome.deep.nested.arrays[0]: with\nsome.deep.nested.arrays[1]: several\nsome.deep.nested.arrays[2].values.and: objects\nsome.deep.nested.object: structure\nsome.notsodeep: struct\n", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_YAML_Complex_Flat - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "9383dcb62f4f91358496ec0e473c605325cf76d5162b1432f3efaaac14e6d07f", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Complex_Flat - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex.enc-age.yaml", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Complex_Flat - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex.enc-age.yaml" -} ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Complex_Flat - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"and now.some[0].basic\": false,\n \"and now.some[1].nested\": 12345,\n \"and now.some[2].type\": 1.2345,\n \"and now.some[3].tests\": \"Finish!\",\n \"some.deep.nested.arrays[0]\": \"with\",\n \"some.deep.nested.arrays[1]\": \"several\",\n \"some.deep.nested.arrays[2].values.and\": \"objects\",\n \"some.deep.nested.object\": \"structure\",\n \"some.notsodeep\": \"struct\"\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_S3_YAML_as_JSON_Complex_Flat - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "e9a8d3ab5715c1120faae25b669e5905a92fe4b261ae97eb1e65ad9ba52f9ee6", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_INLINE_YAML_Simple - 1] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"MyHash", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"key1: value1\nkey2: 12345\nkey3: false\n", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_INLINE_YAML_Simple - 2] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "656f2d935b86bfbefbd97f1c55c1578aef8d96c5647a6161e37f94fb34a84d61", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Simple - 1] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"MyHash", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"key1\": \"value1\",\n \"key2\": 12345,\n \"key3\": false\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Simple - 2] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "46b116fd9409581eb2623320d877cfa1f46cb2487bc3cd0672b1eb95554e65d3", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_INLINE_YAML_Complex - 1] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"MyHash", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"and now:\n some:\n - basic: false\n - nested: 12345\n - type: 1.2345\n - tests: Finish!\nsome:\n deep:\n nested:\n arrays:\n - with\n - several\n - values:\n and: objects\n object: structure\n notsodeep: struct\n", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_INLINE_YAML_Complex - 2] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "99d08789c0db731bcf0f3a467759c84c11e1b18253f9d614be55c817a410e088", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Complex - 1] ->>>S3ApiMockClient.GetObjectAttributes.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex.enc-age.yaml", - ObjectAttributes: ["ETag"] -} ---- - -[Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Complex - 2] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/yaml/sopsfile-complex.enc-age.yaml" -} ---- - -[Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Complex - 3] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"some-32-character-long-string-ab", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"and now\": {\n \"some\": [\n {\n \"basic\": false\n },\n {\n \"nested\": 12345\n },\n {\n \"type\": 1.2345\n },\n {\n \"tests\": \"Finish!\"\n }\n ]\n },\n \"some\": {\n \"deep\": {\n \"nested\": {\n \"arrays\": [\n \"with\",\n \"several\",\n {\n \"values\": {\n \"and\": \"objects\"\n }\n }\n ],\n \"object\": \"structure\"\n }\n },\n \"notsodeep\": \"struct\"\n }\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Complex - 4] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "28e49c30b2d8af77e323b63c5c9e90ec2cf1385ab330eb674695ee065b1252f2", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_INLINE_YAML_Complex_Flat - 1] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"MyHash", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"and now.some[0].basic: false\nand now.some[1].nested: 12345\nand now.some[2].type: 1.2345\nand now.some[3].tests: Finish!\nsome.deep.nested.arrays[0]: with\nsome.deep.nested.arrays[1]: several\nsome.deep.nested.arrays[2].values.and: objects\nsome.deep.nested.object: structure\nsome.notsodeep: struct\n", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_INLINE_YAML_Complex_Flat - 2] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "9383dcb62f4f91358496ec0e473c605325cf76d5162b1432f3efaaac14e6d07f", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- - -[Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Complex_Flat - 1] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"MyHash", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - SecretString: &"{\n \"and now.some[0].basic\": false,\n \"and now.some[1].nested\": 12345,\n \"and now.some[2].type\": 1.2345,\n \"and now.some[3].tests\": \"Finish!\",\n \"some.deep.nested.arrays[0]\": \"with\",\n \"some.deep.nested.arrays[1]\": \"several\",\n \"some.deep.nested.arrays[2].values.and\": \"objects\",\n \"some.deep.nested.object\": \"structure\",\n \"some.notsodeep\": \"struct\"\n}", - VersionStages: nil, -} ---- - -[Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Complex_Flat - 2] ->>>syncSopsToSecretsmanager -arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret -map[string]interface {}{ - "ARN": "arn:custom:sopssync:eu-central-1:123456789012:secret:testsecret", - "Name": "dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - "VersionId": "e9a8d3ab5715c1120faae25b669e5905a92fe4b261ae97eb1e65ad9ba52f9ee6", - "VersionStages": []*string{ - &"dfb70680d326c245dbdd113d635caa16113e78b1eb8b7447f10eeb861e491724", - }, -} -nil ---- diff --git a/lambda/__snapshots__/main_test.snap b/lambda/__snapshots__/main_test.snap deleted file mode 100755 index eddfddd3..00000000 --- a/lambda/__snapshots__/main_test.snap +++ /dev/null @@ -1,80 +0,0 @@ - -[Test_GetS3FileContent - 1] ->>>S3MAnagerMockClient.Download.Input -{ - Bucket: "..", - Key: "../test-secrets/json/sopsfile.enc-age.json" -} ---- - -[Test_GetS3FileContent - 2] -{ - "key1": "ENC[AES256_GCM,data:ArSjC0Vd,iv:NFrIj1ekM2dU8JCU6NpmnHFmwcFaEQagCw/fxKV2b6A=,tag:GrGgeNmtqFuyiTjKJ/78kw==,type:str]", - "key2": "ENC[AES256_GCM,data:NeoandY=,iv:2oCcBk0R/XxvH/O+aaCIa7V9pFsy7dhCKZ70ebjc5Ds=,tag:GVZXUFFwbpMVY/KCLNENAQ==,type:float]", - "key3": "ENC[AES256_GCM,data:y4tBaNg=,iv:mHuYrtf0Ke/oHBcunpgdPpzaYkBx7UjMcOQgpmVc8/Q=,tag:cuEg2UE17Po6opfpH8ikog==,type:bool]", - "sops": { - "kms": null, - "gcp_kms": null, - "azure_kv": null, - "hc_vault": null, - "age": [ - { - "recipient": "age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBOWlAxekVNNXdjenV5cmdR\nZDlQU3N5WC9oeENUbUpYcWxkeU9kVS9TeUR3Cm5zbGhIL0J6WG9TWi9KR3ZUTVph\nblpiUDZtQklnWlRrSGZzTXlZN2Z6WjgKLS0tIDI3ZHNHR0NmWTMzdTg0dEtXcU93\nbEdNWndKdWROWGdLdHAwTGFtRGlsaDQKV7HJG629rPWDBY046Hxj4utxUkex3SwU\nVUQRX00p6r9ffc+iC5DGUm/KOketAHunO4Kn0uOS4WHg+Jg2Cwu72Q==\n-----END AGE ENCRYPTED FILE-----\n" - } - ], - "lastmodified": "2022-03-29T21:02:32Z", - "mac": "ENC[AES256_GCM,data:2vmzwW74OSJq18GEcScpMH76AWrhJdENlKw2vRzGrQfPixTNcrwJ0neTH+BvGKfR9OlLR2EZTheRphQ0Ikb4SdhfInoDjHo+0jXN7RQ4neTlko4j/YRVek61oePgAKAqcmvL2IhzRGO2VR8nDPuJuvRCmP5wOMOBkerydRKHeDc=,iv:NHWPNWDmuhekJUIJpC1cDJ51lLKTsXLE6dC4tpw/qSI=,tag:yV5ngRdIYZfUgj6ntsY5CQ==,type:str]", - "pgp": null, - "unencrypted_suffix": "_unencrypted", - "version": "3.7.2" - } -} ---- - -[Test_UpdateSecret - 1] ->>>SecretsManagerMockClient.PutSecretValue.Input -main.putSecretValueInputNotSecure{ - _: struct {}{}, - ClientRequestToken: &"4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2.yaml", - RotationToken: (*string)(nil), - SecretBinary: nil, - SecretId: &"arn:${Partition}:secretsmanager:${Region}:${Account}:secret:${SecretId}", - SecretString: &"some-secret-data", - VersionStages: nil, -} ---- - -[Test_UpdateSecret - 2] -{ - ARN: "arn:custom:sopssync:${Region}:${Account}:secret:${SecretId}", - Name: "ea44991f303ca1fc043cd129e135eb477c9f102e05eff7b06813202bda64638b", - VersionId: "90543d7645d7aa15732054e8a94dc5409278eb964a5dd9a53faeadb0cd849ca1", - VersionStages: ["ea44991f303ca1fc043cd129e135eb477c9f102e05eff7b06813202bda64638b"] -} ---- - -[Test_UpdateSSMParameter - 1] ->>>SecretsManagerMockClient.PutParameterValue.Input -main.putParameterValueInputNotSecure{ - _: struct {}{}, - AllowedPattern: (*string)(nil), - DataType: (*string)(nil), - Description: (*string)(nil), - KeyId: &"key", - Name: &"/foo/bar", - Overwrite: &bool(true), - Policies: (*string)(nil), - Tags: nil, - Tier: (*string)(nil), - Type: &"SecureString", - Value: &"some-secret-data", -} ---- - -[Test_UpdateSSMParameter - 2] -{ - Tier: "Standard", - Version: 1 -} ---- diff --git a/lambda/conversion_test.go b/lambda/conversion_test.go deleted file mode 100644 index cece3a80..00000000 --- a/lambda/conversion_test.go +++ /dev/null @@ -1,56 +0,0 @@ -package main - -import ( - "testing" - - "github.com/gkampitakis/go-snaps/snaps" -) - -func Test_FromJSON(t *testing.T) { - simpleStruct, err := fromJSON(ReadFile("../test-secrets/json/sopsfile.json")) - check(err) - snaps.MatchSnapshot(t, ">>>Simple", simpleStruct) - complexStruct, err := fromJSON(ReadFile("../test-secrets/json/sopsfile-complex.json")) - check(err) - snaps.MatchSnapshot(t, ">>>Complex", complexStruct) -} - -func Test_FromYAML(t *testing.T) { - simpleStruct, err := fromYAML(ReadFile("../test-secrets/yaml/sopsfile.yml")) - check(err) - snaps.MatchSnapshot(t, ">>>Simple", simpleStruct) - complexStruct, err := fromYAML(ReadFile("../test-secrets/yaml/sopsfile-complex.yml")) - check(err) - snaps.MatchSnapshot(t, ">>>Complex", complexStruct) -} - -func Test_Flatten(t *testing.T) { - simpleStruct, err := fromJSON(ReadFile("../test-secrets/json/sopsfile.json")) - check(err) - flattenedSimpleStruct := make(map[string]interface{}) - err = flatten("", simpleStruct, flattenedSimpleStruct, ".") - snaps.MatchSnapshot(t, ">>>Simple", flattenedSimpleStruct) - complexStruct, err := fromJSON(ReadFile("../test-secrets/json/sopsfile-complex.json")) - check(err) - flattenedComplexStruct := make(map[string]interface{}) - err = flatten("", complexStruct, flattenedComplexStruct, ".") - snaps.MatchSnapshot(t, ">>>Complex", flattenedComplexStruct) -} - -func Test_toJSON(t *testing.T) { - simpleJSON, err := toJSON(UnmarshalAny(ReadFile("../test-secrets/json/sopsfile.json"))) - check(err) - snaps.MatchSnapshot(t, ">>>Simple", string(simpleJSON)) - complexJSON, err := toJSON(UnmarshalAny(ReadFile("../test-secrets/json/sopsfile-complex.json"))) - check(err) - snaps.MatchSnapshot(t, ">>>Complex", string(complexJSON)) -} - -func Test_toYAML(t *testing.T) { - simpleJSON, err := toYAML(UnmarshalAny(ReadFile("../test-secrets/json/sopsfile.json"))) - check(err) - snaps.MatchSnapshot(t, ">>>Simple", string(simpleJSON)) - complexJSON, err := toYAML(UnmarshalAny(ReadFile("../test-secrets/json/sopsfile-complex.json"))) - check(err) - snaps.MatchSnapshot(t, ">>>Complex", string(complexJSON)) -} diff --git a/lambda/events/01-parameter-binary-binary-true-true.json b/lambda/events/01-parameter-binary-binary-true-true.json new file mode 100644 index 00000000..9dbec197 --- /dev/null +++ b/lambda/events/01-parameter-binary-binary-true-true.json @@ -0,0 +1,11 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "binary", + "Target": "01-parameter-binary-binary-true-true", + "ResourceType": "PARAMETER", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/binary/sopsfile.enc-age.binary" + }, + "ServiceToken": "arn:aws:lambda:eu-central-1:505755377845:function:SecretsManagerResourceHandler" + } \ No newline at end of file diff --git a/lambda/events/02-secret-binary-binary-true-true.json b/lambda/events/02-secret-binary-binary-true-true.json new file mode 100644 index 00000000..98a5e5c9 --- /dev/null +++ b/lambda/events/02-secret-binary-binary-true-true.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "binary", + "Target": "02-secret-binary-binary-true-true", + "ResourceType": "SECRET_BINARY", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/binary/sopsfile.enc-age.binary" + } + } \ No newline at end of file diff --git a/lambda/events/11-parametermulti-json-na-true-na.json b/lambda/events/11-parametermulti-json-na-true-na.json new file mode 100644 index 00000000..49431677 --- /dev/null +++ b/lambda/events/11-parametermulti-json-na-true-na.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "json", + "Target": "/11-parametermulti-json-na-true-na/", + "ResourceType": "PARAMETER_MULTI", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/json/sopsfile-complex.enc-age.json" + } +} \ No newline at end of file diff --git a/lambda/events/12-parametermulti-yaml-na-true-na.json b/lambda/events/12-parametermulti-yaml-na-true-na.json new file mode 100644 index 00000000..8565d2d8 --- /dev/null +++ b/lambda/events/12-parametermulti-yaml-na-true-na.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "yaml", + "Target": "/12-parametermulti-yaml-na-true-true/", + "ResourceType": "PARAMETER_MULTI", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/yaml/sopsfile-complex.enc-age.yaml" + } +} \ No newline at end of file diff --git a/lambda/events/13-parametermulti-dotenv-na-true-na.json b/lambda/events/13-parametermulti-dotenv-na-true-na.json new file mode 100644 index 00000000..9f58db0d --- /dev/null +++ b/lambda/events/13-parametermulti-dotenv-na-true-na.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "dotenv", + "Target": "/13-parametermulti-dotenv-na-true-na/", + "ResourceType": "PARAMETER_MULTI", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/dotenv/encrypted-best-secret.env" + } +} \ No newline at end of file diff --git a/lambda/events/21-secret-json-json-true-true.json b/lambda/events/21-secret-json-json-true-true.json new file mode 100644 index 00000000..8a5c85e1 --- /dev/null +++ b/lambda/events/21-secret-json-json-true-true.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "json", + "Target": "21-secret-json-json-true-true", + "ResourceType": "SECRET", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/json/sopsfile-complex.enc-age.json" + } +} \ No newline at end of file diff --git a/lambda/events/22-secret-json-binary-na-na.json b/lambda/events/22-secret-json-binary-na-na.json new file mode 100644 index 00000000..da081e08 --- /dev/null +++ b/lambda/events/22-secret-json-binary-na-na.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "json", + "Target": "22-secret-json-binary-true-true", + "ResourceType": "SECRET_BINARY", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/json/sopsfile-complex.enc-age.json" + } +} \ No newline at end of file diff --git a/lambda/events/23-secret-yaml-json-true-true.json b/lambda/events/23-secret-yaml-json-true-true.json new file mode 100644 index 00000000..ac968334 --- /dev/null +++ b/lambda/events/23-secret-yaml-json-true-true.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "yaml", + "Target": "23-secret-yaml-json-true-true", + "ResourceType": "SECRET", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/yaml/sopsfile-complex.enc-age.yaml" + } +} \ No newline at end of file diff --git a/lambda/events/24-secret-yaml-binary-na-na.json b/lambda/events/24-secret-yaml-binary-na-na.json new file mode 100644 index 00000000..ba4da962 --- /dev/null +++ b/lambda/events/24-secret-yaml-binary-na-na.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "yaml", + "Target": "24-secret-yaml-binary-na-na", + "ResourceType": "SECRET_BINARY", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/yaml/sopsfile-complex.enc-age.yaml" + } +} \ No newline at end of file diff --git a/lambda/events/25-secret-dotenv-json-true-true.json b/lambda/events/25-secret-dotenv-json-true-true.json new file mode 100644 index 00000000..1fc8e813 --- /dev/null +++ b/lambda/events/25-secret-dotenv-json-true-true.json @@ -0,0 +1,11 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "FlattenSeparator": ".", + "Format": "dotenv", + "Target": "25-secret-dotenv-json-true-true", + "ResourceType": "SECRET", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/dotenv/encrypted-best-secret.env" + } +} \ No newline at end of file diff --git a/lambda/events/26-secret-dotenv-binary-na-na.json b/lambda/events/26-secret-dotenv-binary-na-na.json new file mode 100644 index 00000000..6f38ef5e --- /dev/null +++ b/lambda/events/26-secret-dotenv-binary-na-na.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "dotenv", + "Target": "26-secret-dotenv-binary-true-true", + "ResourceType": "SECRET_BINARY", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/dotenv/encrypted-best-secret.env" + } +} \ No newline at end of file diff --git a/lambda/events/event_create_s3_parameter_raw_simple.json b/lambda/events/event_create_s3_parameter_raw_simple.json deleted file mode 100644 index 0309d8c2..00000000 --- a/lambda/events/event_create_s3_parameter_raw_simple.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "PARAMETER", - "ParameterName": "arn:aws:ssm:eu-central-1:123456789012:parameter/testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/binary/sopsfile.enc-age.binary" - }, - "Format": "binary", - "ConvertToJSON": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_parameter_yaml_complex.json b/lambda/events/event_create_s3_parameter_yaml_complex.json deleted file mode 100644 index b84319a1..00000000 --- a/lambda/events/event_create_s3_parameter_yaml_complex.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "PARAMETER_MULTI", - "ParameterName": "arn:aws:ssm:eu-central-1:123456789012:parameter/testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/yaml/sopsfile-complex-parameters.enc-age.yaml" - }, - "Format": "yaml", - "Flatten": "true", - "FlattenSeparator": "/", - "ParameterKeyPrefix": "/", - "ConvertToJSON": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_parameter_yaml_complex_custom_keys.json b/lambda/events/event_create_s3_parameter_yaml_complex_custom_keys.json deleted file mode 100644 index 893a909e..00000000 --- a/lambda/events/event_create_s3_parameter_yaml_complex_custom_keys.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "PARAMETER_MULTI", - "ParameterName": "arn:aws:ssm:eu-central-1:123456789012:parameter/testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/yaml/sopsfile-complex-parameters.enc-age.yaml" - }, - "Format": "yaml", - "Flatten": "true", - "FlattenSeparator": ".", - "ParameterKeyPrefix": "_", - "ConvertToJSON": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_env_as_json_simple.json b/lambda/events/event_create_s3_secret_env_as_json_simple.json deleted file mode 100644 index bc276b4c..00000000 --- a/lambda/events/event_create_s3_secret_env_as_json_simple.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/dotenv/encrypted-best-secret.env" - }, - "Format": "dotenv", - "ConvertToJSON": "true", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_env_simple.json b/lambda/events/event_create_s3_secret_env_simple.json deleted file mode 100644 index 9b1baf91..00000000 --- a/lambda/events/event_create_s3_secret_env_simple.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/dotenv/encrypted-best-secret.env" - }, - "Format": "dotenv", - "ConvertToJSON": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_json_complex.json b/lambda/events/event_create_s3_secret_json_complex.json deleted file mode 100644 index a94df6b3..00000000 --- a/lambda/events/event_create_s3_secret_json_complex.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/json/sopsfile-complex.enc-age.json" - }, - "Format": "json", - "Flatten": "false", - "StringifyValues": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_json_complex_flat.json b/lambda/events/event_create_s3_secret_json_complex_flat.json deleted file mode 100644 index 5a7286bc..00000000 --- a/lambda/events/event_create_s3_secret_json_complex_flat.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/json/sopsfile-complex.enc-age.json" - }, - "Format": "json", - "Flatten": "true", - "StringifyValues": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_json_complex_stringify.json b/lambda/events/event_create_s3_secret_json_complex_stringify.json deleted file mode 100644 index b08f818d..00000000 --- a/lambda/events/event_create_s3_secret_json_complex_stringify.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/json/sopsfile-complex.enc-age.json" - }, - "Format": "json", - "Flatten": "false", - "StringifyValues": "true", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_json_simple.json b/lambda/events/event_create_s3_secret_json_simple.json deleted file mode 100644 index 5d657957..00000000 --- a/lambda/events/event_create_s3_secret_json_simple.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/json/sopsfile.enc-age.json" - }, - "Format": "json", - "StringifyValues": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_raw_simple.json b/lambda/events/event_create_s3_secret_raw_simple.json deleted file mode 100644 index 8f85ba91..00000000 --- a/lambda/events/event_create_s3_secret_raw_simple.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/binary/sopsfile.enc-age.binary" - }, - "Format": "binary", - "ConvertToJSON": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_yaml_as_json_complex.json b/lambda/events/event_create_s3_secret_yaml_as_json_complex.json deleted file mode 100644 index 48801dad..00000000 --- a/lambda/events/event_create_s3_secret_yaml_as_json_complex.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/yaml/sopsfile-complex.enc-age.yaml" - }, - "Format": "yaml", - "ConvertToJSON": "true", - "Flatten": "false", - "StringifyValues": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_yaml_as_json_complex_flat.json b/lambda/events/event_create_s3_secret_yaml_as_json_complex_flat.json deleted file mode 100644 index 995f00ed..00000000 --- a/lambda/events/event_create_s3_secret_yaml_as_json_complex_flat.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/yaml/sopsfile-complex.enc-age.yaml" - }, - "Format": "yaml", - "ConvertToJSON": "true", - "Flatten": "true", - "StringifyValues": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_yaml_as_json_simple.json b/lambda/events/event_create_s3_secret_yaml_as_json_simple.json deleted file mode 100644 index 02420ea7..00000000 --- a/lambda/events/event_create_s3_secret_yaml_as_json_simple.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/yaml/sopsfile.enc-age.yaml" - }, - "Format": "yaml", - "ConvertToJSON": "true", - "StringifyValues": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_yaml_complex.json b/lambda/events/event_create_s3_secret_yaml_complex.json deleted file mode 100644 index a2e0403d..00000000 --- a/lambda/events/event_create_s3_secret_yaml_complex.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/yaml/sopsfile-complex.enc-age.yaml" - }, - "Format": "yaml", - "ConvertToJSON": "false", - "Flatten": "false", - "StringifyValues": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_yaml_complex_flat.json b/lambda/events/event_create_s3_secret_yaml_complex_flat.json deleted file mode 100644 index d7d8cc78..00000000 --- a/lambda/events/event_create_s3_secret_yaml_complex_flat.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/yaml/sopsfile-complex.enc-age.yaml" - }, - "Format": "yaml", - "ConvertToJSON": "false", - "Flatten": "true", - "StringifyValues": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_create_s3_secret_yaml_simple.json b/lambda/events/event_create_s3_secret_yaml_simple.json deleted file mode 100644 index 8fecbe62..00000000 --- a/lambda/events/event_create_s3_secret_yaml_simple.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "RequestType": "Create", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": { - "ResourceType": "SECRET", - "FlattenSeparator": ".", - "SecretARN": "arn:aws:secretsmanager:eu-central-1:123456789012:secret:testsecret", - "SopsS3File": { - "Bucket": "..", - "Key": "../test-secrets/yaml/sopsfile.enc-age.yaml" - }, - "Format": "yaml", - "ConvertToJSON": "false", - "StringifyValues": "false", - "SopsAgeKey": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - }, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/events/event_delete.json b/lambda/events/event_delete.json deleted file mode 100644 index 4d2c57d9..00000000 --- a/lambda/events/event_delete.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "RequestType": "Delete", - "LogicalResourceId": "LogicalResourceId", - "ResourceProperties": {}, - "ResourceType": "Custom::SOPS::Secret", - "RequestId": "RequestId", - "StackId": "StackId" -} diff --git a/lambda/go.mod b/lambda/go.mod index 417eaaf9..76024082 100644 --- a/lambda/go.mod +++ b/lambda/go.mod @@ -4,11 +4,16 @@ go 1.23 require ( github.com/aws/aws-lambda-go v1.47.0 - github.com/aws/aws-sdk-go v1.55.6 - github.com/aws/aws-sdk-go-v2 v1.34.0 + github.com/aws/aws-sdk-go-v2 v1.36.0 + github.com/aws/aws-sdk-go-v2/config v1.28.6 + github.com/aws/aws-sdk-go-v2/service/s3 v1.70.0 + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.16 + github.com/aws/aws-sdk-go-v2/service/ssm v1.56.10 github.com/getsops/sops/v3 v3.9.2 github.com/gkampitakis/go-snaps v0.5.9 - github.com/go-test/deep v1.1.1 + github.com/invopop/jsonschema v0.13.0 + github.com/kaptinlin/jsonschema v0.2.2 + github.com/stretchr/testify v1.10.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -35,12 +40,11 @@ require ( github.com/GoogleCloudPlatform/opentelemetry-operations-go/internal/resourcemapping v0.48.1 // indirect github.com/ProtonMail/go-crypto v1.1.3 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect - github.com/aws/aws-sdk-go-v2/config v1.28.6 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.17.47 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 // indirect github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.42 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.31 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.31 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.25 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 // indirect @@ -48,18 +52,20 @@ require ( github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.6 // indirect github.com/aws/aws-sdk-go-v2/service/kms v1.37.7 // indirect - github.com/aws/aws-sdk-go-v2/service/s3 v1.70.0 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.24.7 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.33.2 // indirect github.com/aws/smithy-go v1.22.2 // indirect + github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/blang/semver v3.5.1+incompatible // indirect + github.com/buger/jsonparser v1.1.1 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cloudflare/circl v1.4.0 // indirect github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.5 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/envoyproxy/go-control-plane v0.13.0 // indirect github.com/envoyproxy/protoc-gen-validate v1.1.0 // indirect github.com/fatih/color v1.18.0 // indirect @@ -70,6 +76,8 @@ require ( github.com/go-jose/go-jose/v4 v4.0.4 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-test/deep v1.1.1 // indirect + github.com/goccy/go-json v0.10.3 // indirect github.com/goccy/go-yaml v1.15.13 // indirect github.com/golang-jwt/jwt/v5 v5.2.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect @@ -78,6 +86,8 @@ require ( github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect github.com/googleapis/gax-go/v2 v2.14.0 // indirect + github.com/gotnospirit/makeplural v0.0.0-20180622080156-a5f48d94d976 // indirect + github.com/gotnospirit/messageformat v0.0.0-20221001023931-dfe49f1eb092 // indirect github.com/goware/prefixer v0.0.0-20160118172347-395022866408 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -89,11 +99,12 @@ require ( github.com/hashicorp/go-sockaddr v1.0.7 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/vault/api v1.15.0 // indirect - github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/kaptinlin/go-i18n v0.1.3 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/lib/pq v1.10.9 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/maruel/natural v1.1.1 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -103,6 +114,7 @@ require ( github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect @@ -112,6 +124,7 @@ require ( github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/sjson v1.2.5 // indirect github.com/urfave/cli v1.22.16 // indirect + github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/detectors/gcp v1.29.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.55.0 // indirect diff --git a/lambda/go.sum b/lambda/go.sum index 0f6344d2..5bd694ba 100644 --- a/lambda/go.sum +++ b/lambda/go.sum @@ -65,10 +65,8 @@ github.com/ProtonMail/go-crypto v1.1.3 h1:nRBOetoydLeUb4nHajyO2bKqMLfWQ/ZPwkXqXx github.com/ProtonMail/go-crypto v1.1.3/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/aws/aws-lambda-go v1.47.0 h1:0H8s0vumYx/YKs4sE7YM0ktwL2eWse+kfopsRI1sXVI= github.com/aws/aws-lambda-go v1.47.0/go.mod h1:dpMpZgvWx5vuQJfBt0zqBha60q7Dd7RfgJv23DymV8A= -github.com/aws/aws-sdk-go v1.55.6 h1:cSg4pvZ3m8dgYcgqB97MrcdjUmZ1BeMYKUxMMB89IPk= -github.com/aws/aws-sdk-go v1.55.6/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= -github.com/aws/aws-sdk-go-v2 v1.34.0 h1:9iyL+cjifckRGEVpRKZP3eIxVlL06Qk1Tk13vreaVQU= -github.com/aws/aws-sdk-go-v2 v1.34.0/go.mod h1:JgstGg0JjWU1KpVJjD5H0y0yyAIpSdKEq556EI6yOOM= +github.com/aws/aws-sdk-go-v2 v1.36.0 h1:b1wM5CcE65Ujwn565qcwgtOTT1aT4ADOHHgglKjG7fk= +github.com/aws/aws-sdk-go-v2 v1.36.0/go.mod h1:5PMILGVKiW32oDzjj6RU52yrNrDPUHcbZQYr1sM7qmM= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 h1:lL7IfaFzngfx0ZwUGOZdsFFnQ5uLvR0hWqqhyE7Q9M8= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7/go.mod h1:QraP0UcVlQJsmHfioCrveWOC1nbiWUl3ej08h4mXWoc= github.com/aws/aws-sdk-go-v2/config v1.28.6 h1:D89IKtGrs/I3QXOLNTH93NJYtDhm8SYa9Q5CsPShmyo= @@ -79,10 +77,10 @@ github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 h1:AmoU1pziydclFT/xRV+xXE github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21/go.mod h1:AjUdLYe4Tgs6kpH4Bv7uMZo7pottoyHMn4eTcIcneaY= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.42 h1:vEnk9vtjJ62OO2wOhEmgKMZgNcn1w0aF7XCiNXO5rK0= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.42/go.mod h1:GUOPbPJWRZsdt1OJ355upCrry4d3ZFgdX6rhT7gtkto= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 h1:s/fF4+yDQDoElYhfIVvSNyeCydfbuTKzhxSXDXCPasU= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25/go.mod h1:IgPfDv5jqFIzQSNbUEMoitNooSMXjRSDkhXv8jiROvU= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 h1:ZntTCl5EsYnhN/IygQEUugpdwbhdkom9uHcbCftiGgA= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25/go.mod h1:DBdPrgeocww+CSl1C8cEV8PN1mHMBhuCDLpXezyvWkE= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.31 h1:lWm9ucLSRFiI4dQQafLrEOmEDGry3Swrz0BIRdiHJqQ= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.31/go.mod h1:Huu6GG0YTfbPphQkDSo4dEGmQRTKb9k9G7RdtyQWxuI= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.31 h1:ACxDklUKKXb48+eg5ROZXi1vDgfMyfIA/WyvqHcHI0o= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.31/go.mod h1:yadnfsDwqXeVaohbGc/RaD287PuyRw2wugkh5ZL2J6k= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.25 h1:r67ps7oHCYnflpgDy2LZU0MAQtQbYIOqNNnqGO6xQkE= @@ -99,6 +97,10 @@ github.com/aws/aws-sdk-go-v2/service/kms v1.37.7 h1:dZmNIRtPUvtvUIIDVNpvtnJQ8N8I github.com/aws/aws-sdk-go-v2/service/kms v1.37.7/go.mod h1:vj8PlfJH9mnGeIzd6uMLPi5VgiqzGG7AZoe1kf1uTXM= github.com/aws/aws-sdk-go-v2/service/s3 v1.70.0 h1:HrHFR8RoS4l4EvodRMFcJMYQ8o3UhmALn2nbInXaxZA= github.com/aws/aws-sdk-go-v2/service/s3 v1.70.0/go.mod h1:sT/iQz8JK3u/5gZkT+Hmr7GzVZehUMkRZpOaAwYXeGY= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.16 h1:tIgXdHiHVELZm56dCK7fQ8c4gFMoz6AkhHksrxpmAFQ= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.34.16/go.mod h1:5WGcD7Mks8G/VNlpHp2ZwfP5pVIZp0zp8nauLU7NuLM= +github.com/aws/aws-sdk-go-v2/service/ssm v1.56.10 h1:GLRZnZtAxWIgROsRgVm8YPaAG0t9pUwaxrkda/g9JiU= +github.com/aws/aws-sdk-go-v2/service/ssm v1.56.10/go.mod h1:kh7898L3bN432TMBiRBe5Ua4IrUAaq1LwHhbqabeOOk= github.com/aws/aws-sdk-go-v2/service/sso v1.24.7 h1:rLnYAfXQ3YAccocshIH5mzNNwZBkBo+bP6EhIxak6Hw= github.com/aws/aws-sdk-go-v2/service/sso v1.24.7/go.mod h1:ZHtuQJ6t9A/+YDuxOLnbryAmITtr8UysSny3qcyvJTc= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6 h1:JnhTZR3PiYDNKlXy50/pNeix9aGMo6lLpXwJ1mw8MD4= @@ -107,8 +109,12 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.33.2 h1:s4074ZO1Hk8qv65GqNXqDjmkf4HS github.com/aws/aws-sdk-go-v2/service/sts v1.33.2/go.mod h1:mVggCnIWoM09jP71Wh+ea7+5gAp53q+49wDFs1SW5z8= github.com/aws/smithy-go v1.22.2 h1:6D9hW43xKFrRx/tXXfAlIZc4JI+yQe6snnWcQyxSyLQ= github.com/aws/smithy-go v1.22.2/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= +github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= +github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -173,6 +179,8 @@ github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U= github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= github.com/go-viper/mapstructure/v2 v2.2.1 h1:ZAaOCxANMuZx5RCeg0mBdEZk7DZasvvZIxtHqx8aGss= github.com/go-viper/mapstructure/v2 v2.2.1/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-yaml v1.15.13 h1:Xd87Yddmr2rC1SLLTm2MNDcTjeO/GYo0JGiww6gSTDg= github.com/goccy/go-yaml v1.15.13/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= @@ -216,6 +224,10 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.4 h1:XYIDZApgAnrN1c855gT github.com/googleapis/enterprise-certificate-proxy v0.3.4/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= github.com/googleapis/gax-go/v2 v2.14.0 h1:f+jMrjBPl+DL9nI4IQzLUxMq7XrAqFYB7hBPqMNIe8o= github.com/googleapis/gax-go/v2 v2.14.0/go.mod h1:lhBCnjdLrWRaPvLWhmc8IS24m9mr07qSYnHncrgo+zk= +github.com/gotnospirit/makeplural v0.0.0-20180622080156-a5f48d94d976 h1:b70jEaX2iaJSPZULSUxKtm73LBfsCrMsIlYCUgNGSIs= +github.com/gotnospirit/makeplural v0.0.0-20180622080156-a5f48d94d976/go.mod h1:ZGQeOwybjD8lkCjIyJfqR5LD2wMVHJ31d6GdPxoTsWY= +github.com/gotnospirit/messageformat v0.0.0-20221001023931-dfe49f1eb092 h1:c7gcNWTSr1gtLp6PyYi3wzvFCEcHJ4YRobDgqmIgf7Q= +github.com/gotnospirit/messageformat v0.0.0-20221001023931-dfe49f1eb092/go.mod h1:ZZAN4fkkful3l1lpJwF8JbW41ZiG9TwJ2ZlqzQovBNU= github.com/goware/prefixer v0.0.0-20160118172347-395022866408 h1:Y9iQJfEqnN3/Nce9cOegemcy/9Ai5k3huT6E80F3zaw= github.com/goware/prefixer v0.0.0-20160118172347-395022866408/go.mod h1:PE1ycukgRPJ7bJ9a1fdfQ9j8i/cEcRAoLZzbxYpNB/s= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -241,10 +253,13 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/vault/api v1.15.0 h1:O24FYQCWwhwKnF7CuSqP30S51rTV7vz1iACXE/pj5DA= github.com/hashicorp/vault/api v1.15.0/go.mod h1:+5YTO09JGn0u+b6ySD/LLVf8WkJCPLAL2Vkmrn2+CM8= -github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= +github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/kaptinlin/go-i18n v0.1.3 h1:Zmc2sp3N3eNxAPEiyfdbZgF+QF8LZdOdZNR1gHefUe4= +github.com/kaptinlin/go-i18n v0.1.3/go.mod h1:giU+qqtzFZ2U0ksKKVuSxtIFzBLkMA/vlKTeJDyyM2c= +github.com/kaptinlin/jsonschema v0.2.2 h1:aspDbCaqAJ/GSnzmtaSesC0+lnTOjLRamFB/k8mo60s= +github.com/kaptinlin/jsonschema v0.2.2/go.mod h1:HkWM5Yd1hA7K5nvRx/A67wQw/khr6b0/DHrP5CWgAbY= github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs= github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -255,6 +270,8 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -280,6 +297,8 @@ github.com/opencontainers/runc v1.1.14 h1:rgSuzbmgz5DUJjeSnw337TxDbRuqjs6iqQck/2 github.com/opencontainers/runc v1.1.14/go.mod h1:E4C2z+7BxR7GHXp0hAY53mek+x49X1LjPNeMTfRGvOA= github.com/ory/dockertest/v3 v3.11.0 h1:OiHcxKAvSDUwsEVh2BjxQQc/5EHz9n0va9awCtNGuyA= github.com/ory/dockertest/v3 v3.11.0/go.mod h1:VIPxS1gwT9NpPOrfD3rACs8Y9Z7yhzO4SB194iUDnUI= +github.com/pelletier/go-toml/v2 v2.2.1 h1:9TA9+T8+8CUCO2+WYnDLCgrYi9+omqKXyjDtosvtEhg= +github.com/pelletier/go-toml/v2 v2.2.1/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -313,6 +332,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE= +github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU= github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -325,6 +346,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/urfave/cli v1.22.16 h1:MH0k6uJxdwdeWQTwhSO42Pwr4YLrNLwBtg1MRgTqPdQ= github.com/urfave/cli v1.22.16/go.mod h1:EeJR6BKodywf4zciqrdw6hpCPk68JO9z5LazXZMn5Po= +github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= +github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= @@ -437,7 +460,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntN gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/lambda/handle.go b/lambda/handle.go new file mode 100644 index 00000000..ff25e7c8 --- /dev/null +++ b/lambda/handle.go @@ -0,0 +1,129 @@ +package main + +import ( + "fmt" + "log/slog" + "strings" + + "github.com/markussiebert/cdk-sops-secrets/internal/client" + "github.com/markussiebert/cdk-sops-secrets/internal/data" + "github.com/markussiebert/cdk-sops-secrets/internal/event" +) + +type BaseProps struct { + properties *event.SopsSyncResourcePropertys + clients client.AwsClient + secretDecryptedData *data.Data +} + +func handleSecret(props BaseProps) (physicalResourceID string, data map[string]interface{}, err error) { + logger := slog.With("Package", "main", "Function", "handleSecret") + var outData *[]byte + var outDataErr error + logger.Info("Handling secret data", "ResourceType", props.properties.ResourceType) + if props.properties.ResourceType == event.SECRET { + seperator := "." + if props.properties.FlattenSeparator != nil { + seperator = *props.properties.FlattenSeparator + } + logger.Info("Flattening secret data", "seperator", seperator) + if err := props.secretDecryptedData.Flatten(seperator); err != nil { + return props.properties.GeneratePhysicalResourceId(), nil, err + } + logger.Info("Stringifying secret data") + if err := props.secretDecryptedData.StringifyValues(); err != nil { + return props.properties.GeneratePhysicalResourceId(), nil, err + } + logger.Info("Converting secret data to JSON") + outData, outDataErr = props.secretDecryptedData.ToJSON() + } else { + logger.Info("Getting raw secret data") + outData, outDataErr = props.secretDecryptedData.GetRaw() + } + + if outDataErr != nil { + return props.properties.GeneratePhysicalResourceId(), nil, outDataErr + } + + putSecretValueResp, putSecretValueRespErr := props.clients.SecretsManagerPutSecretValue(*props.secretDecryptedData.Hash, props.properties.Target, outData) + if putSecretValueRespErr != nil { + return props.properties.GeneratePhysicalResourceId(), nil, putSecretValueRespErr + } + + logger.Info("Secret data updated", "ARN", *putSecretValueResp.ARN) + + return *putSecretValueResp.ARN, map[string]interface{}{ + "ARN": *putSecretValueResp.ARN, + "Name": *putSecretValueResp.Name, + "VersionStages": putSecretValueResp.VersionStages, + "VersionId": *putSecretValueResp.VersionId, + }, nil +} + +func handleParameterMulti(props BaseProps) (physicalResourceID string, data map[string]interface{}, err error) { + logger := slog.With("Package", "main", "Function", "handleParameterMulti") + seperator := "/" + if props.properties.FlattenSeparator != nil { + seperator = *props.properties.FlattenSeparator + } + logger.Info("Flattening secret data", "seperator", seperator) + if err := props.secretDecryptedData.Flatten(seperator); err != nil { + return props.properties.GeneratePhysicalResourceId(), nil, err + } + logger.Info("Converting secret data to map") + outData, outDataErr := props.secretDecryptedData.ToStringMap() + if outDataErr != nil { + return props.properties.GeneratePhysicalResourceId(), nil, outDataErr + } + if props.properties.EncryptionKey == nil { + return props.properties.GeneratePhysicalResourceId(), nil, fmt.Errorf("EncryptionKey must be set for PARAMETER_MULTI") + } + logger.Info("Writing secret data to parameter store") + for key, value := range outData { + // Ass we flatten array to [number] path notations, we have to fix this for parameter store + fixedKey := strings.ReplaceAll(key, "[", seperator) + fixedKey = strings.ReplaceAll(fixedKey, "]", seperator) + fixedKey = strings.TrimSuffix(fixedKey, seperator) + fixedKey = strings.ReplaceAll(fixedKey, seperator+seperator, seperator) + // Whitespaces are also not allowed, maybe more characters + fixedKey = strings.ReplaceAll(fixedKey, " ", "_") + // Prefix with Target + fixedKey = props.properties.Target + fixedKey + _, err := props.clients.SsmPutParameter(fixedKey, &value, *props.properties.EncryptionKey) + if err != nil { + return props.properties.GeneratePhysicalResourceId(), nil, fmt.Errorf("failed to update ssm parameter:\n%v", err) + } + logger.Info("Parameter written", "Parameter", fixedKey) + } + + logger.Info("Secret data updated", "ARN", props.properties.GeneratePhysicalResourceId()) + + return props.properties.GeneratePhysicalResourceId(), map[string]interface{}{ + "Prefix": props.properties.Target, + "Count": len(outData), + }, nil +} + +func handleParameter(props BaseProps) (physicalResourceID string, data map[string]interface{}, err error) { + logger := slog.With("Package", "main", "Function", "handleParameter") + logger.Info("Getting raw secret data") + outData, outDataErr := props.secretDecryptedData.GetRaw() + if outDataErr != nil { + return props.properties.GeneratePhysicalResourceId(), nil, outDataErr + } + if props.properties.EncryptionKey == nil { + return "", nil, fmt.Errorf("EncryptionKey must be set for PARAMETER") + } + putParameterResponse, putParameterResponseErr := props.clients.SsmPutParameter(props.properties.Target, outData, *props.properties.EncryptionKey) + if putParameterResponseErr != nil { + return props.properties.GeneratePhysicalResourceId(), nil, fmt.Errorf("failed to update ssm parameter:\n%v", err) + } + logger.Info("Parameter written", "Parameter", props.properties.Target) + + logger.Info("Secret data updated", "ARN", props.properties.GeneratePhysicalResourceId()) + return props.properties.GeneratePhysicalResourceId(), map[string]interface{}{ + "ParameterName": props.properties.Target, + "Version": putParameterResponse.Version, + "Tier": putParameterResponse.Tier, + }, nil +} diff --git a/lambda/handler_common_test.go b/lambda/handler_common_test.go deleted file mode 100644 index f099b424..00000000 --- a/lambda/handler_common_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package main - -import ( - "testing" - - "github.com/gkampitakis/go-snaps/snaps" -) - -func Test_FullWorkflow_Delete(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_delete.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} diff --git a/lambda/handler_parameter_raw_test.go b/lambda/handler_parameter_raw_test.go deleted file mode 100644 index f168a0be..00000000 --- a/lambda/handler_parameter_raw_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package main - -import ( - "testing" - - "github.com/gkampitakis/go-snaps/snaps" -) - -func Test_FullWorkflow_Create_S3_Parameter_RAW_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_parameter_raw_simple.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} diff --git a/lambda/handler_parameter_yaml_multi_test.go b/lambda/handler_parameter_yaml_multi_test.go deleted file mode 100644 index 96b54b50..00000000 --- a/lambda/handler_parameter_yaml_multi_test.go +++ /dev/null @@ -1,23 +0,0 @@ -package main - -import ( - "testing" - - "github.com/gkampitakis/go-snaps/snaps" -) - -func Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_parameter_yaml_complex.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_S3_Parameter_YAML_multi_Simple_custom_keys(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_parameter_yaml_complex_custom_keys.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} diff --git a/lambda/handler_secret_env_test.go b/lambda/handler_secret_env_test.go deleted file mode 100644 index 2a960979..00000000 --- a/lambda/handler_secret_env_test.go +++ /dev/null @@ -1,22 +0,0 @@ -package main - -import ( - "testing" - - "github.com/gkampitakis/go-snaps/snaps" -) - -func Test_FullWorkflow_Create_S3_ENV_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_env_simple.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_S3_ENV_as_JSON_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_env_as_json_simple.json") - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} diff --git a/lambda/handler_secret_json_test.go b/lambda/handler_secret_json_test.go deleted file mode 100644 index bfae4a2d..00000000 --- a/lambda/handler_secret_json_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package main - -import ( - "testing" - - "github.com/gkampitakis/go-snaps/snaps" -) - -func Test_FullWorkflow_Create_S3_JSON_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_json_simple.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_S3_JSON_Complex(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_json_complex.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_S3_JSON_Complex_StringifyValues(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_json_complex_stringify.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} -func Test_FullWorkflow_Create_S3_JSON_Complex_Flat(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_json_complex_flat.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_INLINE_JSON_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_json_simple.json") - event = fileToInline(event) - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_INLINE_JSON_Complex(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_json_complex.json") - event = fileToInline(event) - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_INLINE_JSON_Complex_StringifyValues(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_json_complex_stringify.json") - event = fileToInline(event) - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} -func Test_FullWorkflow_Create_INLINE_JSON_Complex_Flat(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_json_complex_flat.json") - event = fileToInline(event) - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} diff --git a/lambda/handler_secret_raw_test.go b/lambda/handler_secret_raw_test.go deleted file mode 100644 index a6bb8559..00000000 --- a/lambda/handler_secret_raw_test.go +++ /dev/null @@ -1,15 +0,0 @@ -package main - -import ( - "testing" - - "github.com/gkampitakis/go-snaps/snaps" -) - -func Test_FullWorkflow_Create_S3_RAW_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_raw_simple.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} diff --git a/lambda/handler_secret_yaml_test.go b/lambda/handler_secret_yaml_test.go deleted file mode 100644 index 4a6be298..00000000 --- a/lambda/handler_secret_yaml_test.go +++ /dev/null @@ -1,108 +0,0 @@ -package main - -import ( - "testing" - - "github.com/gkampitakis/go-snaps/snaps" -) - -func Test_FullWorkflow_Create_S3_YAML_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_simple.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_S3_YAML_as_JSON_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_as_json_simple.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_S3_YAML_Complex(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_complex.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_S3_YAML_as_JSON_Complex(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_as_json_complex.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_S3_YAML_Complex_Flat(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_complex_flat.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_S3_YAML_as_JSON_Complex_Flat(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_as_json_complex_flat.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_INLINE_YAML_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_simple.json") - event = fileToInline(event) - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Simple(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_as_json_simple.json") - event = fileToInline(event) - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_INLINE_YAML_Complex(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_complex.json") - event = fileToInline(event) - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Complex(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_as_json_complex.json") - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_INLINE_YAML_Complex_Flat(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_complex_flat.json") - event = fileToInline(event) - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} - -func Test_FullWorkflow_Create_INLINE_YAML_as_JSON_Complex_Flat(t *testing.T) { - mocks, ctx, event := prepareHandler(t, "events/event_create_s3_secret_yaml_as_json_complex_flat.json") - event = fileToInline(event) - - phys, data, err := mocks.syncSopsToSecretsmanager(ctx, event) - check(err) - snaps.MatchSnapshot(t, ">>>syncSopsToSecretsmanager", phys, data, err) -} diff --git a/lambda/internal/.DS_Store b/lambda/internal/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..411da647dd882e62aa8f9a9ed9a02845a8f44911 GIT binary patch literal 8196 zcmeHMU2GIp6u#edfti8Y+wxa-0&HlcSc+_s77GTpfBXbYk!@)y;5yqGV8V2!?#%9j zgxF|&QT&N7KB)NfYBc(wiA0S)!K>I9dC){ne9=Vo(U|DDb7z~j&<7J@NSK?VwsEOl$6v$1u~SR3`KmzfD9*lCict4a!N`W&JZ6y5ciDugo3DddVVHy zXUIvJ)CmF!0=FU{(kI0%X0ni(v(N9vN!JO&Z1!6yb*V**m#9nBrRvH28NZqj&9EHw znx*4H8}fa(Si3iiM;*Ib;4AukFEky`E=2*3Ws}Q^5y!LqYOi1RtRRZb%LY|bwE|yr z;X+4O_m1{VcW3rud*(v-wrqQ5`$Jt9FKX(_maV&v6wbO6p8tZJ1LF4ptDiTgOS32B z29-YfL87j)Hlgoo6Vmjh#_-V*y}+9)H0r_0(DA+Cs9g$37I;HIvpX>EdxuN5XdfB( z-SUJN6nNvf>5i9OGqihLH}5=U2cw~VE);iTfnN&yBF9mOVuh{1c{#9;*c9MY?0yOh zR?HhTv=5f8T)Sc8=4|KA-F^EG4o=tK*T5T_bbX8<@@?V2`SziM^!nzUgoka*cMPqu@w?r=% z|5&BxQ13144db|I=_}b(TX8_^CPNJv29PzFdi4(9x{V)aMJc@NY~=N`>Aa#IAfOV z!76bpw(ciuv|MBtK?9Z(`cWgHafoJdOgyf~vZ6UOuUcJiJZ9uoeqE)NalDE{e5Mtb zv{qYkZE|rUSX**gscE!7tzi$+KDeKqU^bg%=h-FpCcDhuXP>aI*j4s5yTN{7KeC_L z&+Iq$C;J;I)T03$jYy*v51xA6|%#e2Ad&+s|Ez*StwH<-rv_#HR#2mVr0$|7a4(x7mqNm;IJR9cm+(y8p0 z16OK^a%?W=ls%-+WIiQI{N+w@Z`QiyO%q3dVZXAQ>>sGa%vH!>BXLtOa|^n#1Krq(M=*fB*pCCm(jg3E1fv+k zII;8;PQyV70YX&pG^U8D&*C}a>C1Qpui|yQfy;O+X6%QEzXH#2@W5OS;>v6eR`Mm! z^}W+%t8sR&d!pT01nT7Dn#K8lVBzoocec~yX$b-e0(TVxNcHFYdud1uy>`V}J44qK zbcrJTrlgEQsEUr`B%|Xv$(cV4={`fQA|@BhDJjW9<$wPW5dY3i_Wxx6j|g~=R{sKd COcP`P literal 0 HcmV?d00001 diff --git a/lambda/internal/client/__snapshots__/s3_get_object.snap b/lambda/internal/client/__snapshots__/s3_get_object.snap new file mode 100755 index 00000000..712694b4 --- /dev/null +++ b/lambda/internal/client/__snapshots__/s3_get_object.snap @@ -0,0 +1,27 @@ + +[TestS3GetObject - 1] +&s3.GetObjectInput{ + Bucket: &"test-bucket", + Key: &"test-key", + ChecksumMode: "", + ExpectedBucketOwner: (*string)(nil), + IfMatch: (*string)(nil), + IfModifiedSince: (*time.Time)(nil), + IfNoneMatch: (*string)(nil), + IfUnmodifiedSince: (*time.Time)(nil), + PartNumber: (*int32)(nil), + Range: (*string)(nil), + RequestPayer: "", + ResponseCacheControl: (*string)(nil), + ResponseContentDisposition: (*string)(nil), + ResponseContentEncoding: (*string)(nil), + ResponseContentLanguage: (*string)(nil), + ResponseContentType: (*string)(nil), + ResponseExpires: (*time.Time)(nil), + SSECustomerAlgorithm: (*string)(nil), + SSECustomerKey: (*string)(nil), + SSECustomerKeyMD5: (*string)(nil), + VersionId: (*string)(nil), + noSmithyDocumentSerde: document.NoSerde{}, +} +--- diff --git a/lambda/internal/client/__snapshots__/s3_get_object_etag.snap b/lambda/internal/client/__snapshots__/s3_get_object_etag.snap new file mode 100755 index 00000000..f09de08f --- /dev/null +++ b/lambda/internal/client/__snapshots__/s3_get_object_etag.snap @@ -0,0 +1,17 @@ + +[TestS3GetObjectETAG - 1] +&s3.GetObjectAttributesInput{ + Bucket: &"test-bucket", + Key: &"test-key", + ObjectAttributes: {"ETag"}, + ExpectedBucketOwner: (*string)(nil), + MaxParts: (*int32)(nil), + PartNumberMarker: (*string)(nil), + RequestPayer: "", + SSECustomerAlgorithm: (*string)(nil), + SSECustomerKey: (*string)(nil), + SSECustomerKeyMD5: (*string)(nil), + VersionId: (*string)(nil), + noSmithyDocumentSerde: document.NoSerde{}, +} +--- diff --git a/lambda/internal/client/__snapshots__/s3_get_object_etag_not_found.snap b/lambda/internal/client/__snapshots__/s3_get_object_etag_not_found.snap new file mode 100755 index 00000000..f09de08f --- /dev/null +++ b/lambda/internal/client/__snapshots__/s3_get_object_etag_not_found.snap @@ -0,0 +1,17 @@ + +[TestS3GetObjectETAG - 1] +&s3.GetObjectAttributesInput{ + Bucket: &"test-bucket", + Key: &"test-key", + ObjectAttributes: {"ETag"}, + ExpectedBucketOwner: (*string)(nil), + MaxParts: (*int32)(nil), + PartNumberMarker: (*string)(nil), + RequestPayer: "", + SSECustomerAlgorithm: (*string)(nil), + SSECustomerKey: (*string)(nil), + SSECustomerKeyMD5: (*string)(nil), + VersionId: (*string)(nil), + noSmithyDocumentSerde: document.NoSerde{}, +} +--- diff --git a/lambda/internal/client/__snapshots__/s3_get_object_reader_error.snap b/lambda/internal/client/__snapshots__/s3_get_object_reader_error.snap new file mode 100755 index 00000000..712694b4 --- /dev/null +++ b/lambda/internal/client/__snapshots__/s3_get_object_reader_error.snap @@ -0,0 +1,27 @@ + +[TestS3GetObject - 1] +&s3.GetObjectInput{ + Bucket: &"test-bucket", + Key: &"test-key", + ChecksumMode: "", + ExpectedBucketOwner: (*string)(nil), + IfMatch: (*string)(nil), + IfModifiedSince: (*time.Time)(nil), + IfNoneMatch: (*string)(nil), + IfUnmodifiedSince: (*time.Time)(nil), + PartNumber: (*int32)(nil), + Range: (*string)(nil), + RequestPayer: "", + ResponseCacheControl: (*string)(nil), + ResponseContentDisposition: (*string)(nil), + ResponseContentEncoding: (*string)(nil), + ResponseContentLanguage: (*string)(nil), + ResponseContentType: (*string)(nil), + ResponseExpires: (*time.Time)(nil), + SSECustomerAlgorithm: (*string)(nil), + SSECustomerKey: (*string)(nil), + SSECustomerKeyMD5: (*string)(nil), + VersionId: (*string)(nil), + noSmithyDocumentSerde: document.NoSerde{}, +} +--- diff --git a/lambda/internal/client/__snapshots__/secrets_manager_put_secret_value.snap b/lambda/internal/client/__snapshots__/secrets_manager_put_secret_value.snap new file mode 100755 index 00000000..e169f774 --- /dev/null +++ b/lambda/internal/client/__snapshots__/secrets_manager_put_secret_value.snap @@ -0,0 +1,12 @@ + +[TestSecretsManagerPutSecretValue - 1] +&secretsmanager.PutSecretValueInput{ + SecretId: &"arn", + ClientRequestToken: &"hash", + RotationToken: (*string)(nil), + SecretBinary: nil, + SecretString: &"content", + VersionStages: nil, + noSmithyDocumentSerde: document.NoSerde{}, +} +--- diff --git a/lambda/internal/client/__snapshots__/ssm_update_update_parameter.snap b/lambda/internal/client/__snapshots__/ssm_update_update_parameter.snap new file mode 100755 index 00000000..9e392c3a --- /dev/null +++ b/lambda/internal/client/__snapshots__/ssm_update_update_parameter.snap @@ -0,0 +1,34 @@ + +[TestSsmUpdateUpdateParameter - 1] +&ssm.PutParameterInput{ + Name: &"parameter", + Value: &"content", + AllowedPattern: (*string)(nil), + DataType: (*string)(nil), + Description: (*string)(nil), + KeyId: &"key", + Overwrite: &bool(true), + Policies: (*string)(nil), + Tags: nil, + Tier: "", + Type: "SecureString", + noSmithyDocumentSerde: document.NoSerde{}, +} +--- + +[TestSsmPutParameter - 1] +&ssm.PutParameterInput{ + Name: &"parameter", + Value: &"content", + AllowedPattern: (*string)(nil), + DataType: (*string)(nil), + Description: (*string)(nil), + KeyId: &"key", + Overwrite: &bool(true), + Policies: (*string)(nil), + Tags: nil, + Tier: "", + Type: "SecureString", + noSmithyDocumentSerde: document.NoSerde{}, +} +--- diff --git a/lambda/internal/client/client.go b/lambda/internal/client/client.go new file mode 100644 index 00000000..5f90d995 --- /dev/null +++ b/lambda/internal/client/client.go @@ -0,0 +1,126 @@ +package client + +import ( + "bytes" + "context" + "fmt" + "log" + "log/slog" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/s3" + s3Types "github.com/aws/aws-sdk-go-v2/service/s3/types" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager" + "github.com/aws/aws-sdk-go-v2/service/ssm" + ssmTypes "github.com/aws/aws-sdk-go-v2/service/ssm/types" +) + +type S3Client interface { + GetObject(ctx context.Context, params *s3.GetObjectInput, optFns ...func(*s3.Options)) (*s3.GetObjectOutput, error) + GetObjectAttributes(ctx context.Context, params *s3.GetObjectAttributesInput, optFns ...func(*s3.Options)) (*s3.GetObjectAttributesOutput, error) +} + +type SecretsManagerClient interface { + PutSecretValue(ctx context.Context, params *secretsmanager.PutSecretValueInput, optFns ...func(*secretsmanager.Options)) (*secretsmanager.PutSecretValueOutput, error) +} + +type SsmClient interface { + PutParameter(ctx context.Context, params *ssm.PutParameterInput, optFns ...func(*ssm.Options)) (*ssm.PutParameterOutput, error) +} + +type AwsClient interface { + S3GetObject(file SopsS3File) (data []byte, err error) + S3GetObjectETAG(file SopsS3File) (*string, error) + SecretsManagerPutSecretValue(sopsHash string, secretArn string, secretContent *[]byte) (data *secretsmanager.PutSecretValueOutput, err error) + SsmPutParameter(parameterName string, parameterContent *[]byte, keyId string) (response *ssm.PutParameterOutput, err error) +} + +type Client struct { + ctx context.Context + s3 S3Client + secretsManager SecretsManagerClient + ssm SsmClient +} + +func CreateAwsClients(context context.Context) AwsClient { + cfg, err := config.LoadDefaultConfig(context) + if err != nil { + log.Fatalf("unable to load SDK config, %v", err) + } + return &Client{ + ctx: context, + s3: s3.NewFromConfig(cfg), + secretsManager: secretsmanager.NewFromConfig(cfg), + ssm: ssm.NewFromConfig(cfg), + } +} + +type SopsS3File struct { + Bucket string `json:"Bucket,omitempty"` + Key string `json:"Key,omitempty"` +} + +func (c *Client) S3GetObject(file SopsS3File) (data []byte, err error) { + logger := slog.With("Package", "client", "Function", "S3GetObject") + logger.Info("Downloading file", "Bucket", file.Bucket, "Key", file.Key) + + resp, err := c.s3.GetObject(c.ctx, &s3.GetObjectInput{ + Bucket: &file.Bucket, + Key: &file.Key, + }) + if err != nil { + return nil, fmt.Errorf("S3 get object error:\n%v", err) + } + defer resp.Body.Close() + + buf := new(bytes.Buffer) + _, err = buf.ReadFrom(resp.Body) + if err != nil { + return nil, fmt.Errorf("read buffer error:\n%v", err) + } + logger.Info("Downloaded file", "Size", buf.Len()) + return buf.Bytes(), nil +} + +func (c *Client) S3GetObjectETAG(file SopsS3File) (*string, error) { + attr, err := c.s3.GetObjectAttributes(c.ctx, &s3.GetObjectAttributesInput{ + Bucket: &file.Bucket, + Key: &file.Key, + ObjectAttributes: []s3Types.ObjectAttributes{ + "ETag", + }, + }) + + if err != nil { + return nil, fmt.Errorf("error while getting S3 object attributes:\n%v", err) + } + + if attr.ETag == nil { + return nil, fmt.Errorf("no ETag checksum found in S3 object:\n%v", err) + } + + return attr.ETag, nil +} + +func (c *Client) SecretsManagerPutSecretValue(sopsHash string, secretArn string, secretContent *[]byte) (data *secretsmanager.PutSecretValueOutput, err error) { + secretContentString := string(*secretContent) + input := &secretsmanager.PutSecretValueInput{ + SecretId: &secretArn, + SecretString: &secretContentString, + ClientRequestToken: &sopsHash, + } + return c.secretsManager.PutSecretValue(c.ctx, input) +} + +func (c *Client) SsmPutParameter(parameterName string, parameterContent *[]byte, keyId string) (response *ssm.PutParameterOutput, err error) { + parameterContentString := string(*parameterContent) + input := &ssm.PutParameterInput{ + Name: ¶meterName, + Value: ¶meterContentString, + Type: ssmTypes.ParameterTypeSecureString, + Overwrite: aws.Bool(true), + KeyId: &keyId, + } + return c.ssm.PutParameter(c.ctx, input) +} diff --git a/lambda/internal/client/client_test.go b/lambda/internal/client/client_test.go new file mode 100644 index 00000000..b7341dbb --- /dev/null +++ b/lambda/internal/client/client_test.go @@ -0,0 +1,228 @@ +package client + +import ( + "bytes" + "context" + "fmt" + "io" + "testing" + + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager" + "github.com/aws/aws-sdk-go-v2/service/ssm" + "github.com/stretchr/testify/assert" +) + +func TestS3GetObject(t *testing.T) { + tests := []struct { + name string + mockClient *MockAwsClient + expectedData []byte + expectedErrMsg string + }{ + { + name: "successful get object", + mockClient: &MockAwsClient{ + t: t, + snapsFileName: "s3_get_object", + GetObjectRet: &s3.GetObjectOutput{ + Body: io.NopCloser(bytes.NewReader([]byte("mock content"))), + }, + ReturnError: nil, + }, + expectedData: []byte("mock content"), + }, + { + name: "get object error", + mockClient: &MockAwsClient{ + t: t, + snapsFileName: "s3_get_object_error", + GetObjectRet: nil, + ReturnError: fmt.Errorf("mock error"), + }, + expectedErrMsg: "S3 get object error:\nmock error", + }, + { + name: "reader body error", + mockClient: &MockAwsClient{ + t: t, + snapsFileName: "s3_get_object_reader_error", + GetObjectRet: &s3.GetObjectOutput{ + Body: io.NopCloser(&mockErrorReader{}), + }, + ReturnError: nil, + }, + expectedErrMsg: "read buffer error:\nmock read error", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + client := &Client{ + ctx: context.Background(), + s3: tt.mockClient, + } + + data, err := client.S3GetObject(SopsS3File{Bucket: "test-bucket", Key: "test-key"}) + if tt.expectedErrMsg != "" { + assert.Error(t, err) + assert.Contains(t, err.Error(), tt.expectedErrMsg) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.expectedData, data) + } + }) + } +} + +func TestS3GetObjectETAG(t *testing.T) { + tests := []struct { + name string + mockClient *MockAwsClient + expectedETAG *string + expectedErrMsg string + }{ + { + name: "successful get object etag", + mockClient: &MockAwsClient{ + t: t, + snapsFileName: "s3_get_object_etag", + GetObjectAttributesRet: &s3.GetObjectAttributesOutput{ + ETag: aws.String("mock-etag"), + }, + ReturnError: nil, + }, + expectedETAG: aws.String("mock-etag"), + }, + { + name: "get object attributes error", + mockClient: &MockAwsClient{ + t: t, + snapsFileName: "s3_get_object_attributes_error", + GetObjectAttributesRet: nil, + ReturnError: fmt.Errorf("mock error"), + }, + expectedErrMsg: "error while getting S3 object attributes:\nmock error", + }, + { + name: "etag not found", + mockClient: &MockAwsClient{ + t: t, + snapsFileName: "s3_get_object_etag_not_found", + GetObjectAttributesRet: &s3.GetObjectAttributesOutput{ + ETag: nil, + }, + ReturnError: nil, + }, + expectedErrMsg: "no ETag checksum found in S3 object:\n", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + client := &Client{ + ctx: context.Background(), + s3: tt.mockClient, + } + + etag, err := client.S3GetObjectETAG(SopsS3File{Bucket: "test-bucket", Key: "test-key"}) + if tt.expectedErrMsg != "" { + assert.Error(t, err) + assert.Contains(t, err.Error(), tt.expectedErrMsg) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.expectedETAG, etag) + } + }) + } +} + +func TestSecretsManagerPutSecretValue(t *testing.T) { + tests := []struct { + name string + mockClient *MockAwsClient + expectedARN *string + expectedErrMsg string + }{ + { + name: "successful put secret value", + mockClient: &MockAwsClient{ + t: t, + snapsFileName: "secrets_manager_put_secret_value", + PutSecretValueRet: &secretsmanager.PutSecretValueOutput{ + ARN: aws.String("mock-arn"), + }, + ReturnError: nil, + }, + expectedARN: aws.String("mock-arn"), + }, + { + name: "put secret value error", + mockClient: &MockAwsClient{ + t: t, + snapsFileName: "secrets_manager_put_secret_value_error", + PutSecretValueRet: nil, + ReturnError: fmt.Errorf("mock error"), + }, + expectedErrMsg: "failed to store secret value:\nsecretArn: test-arn\nClientRequestToken: test-hash\nmock error", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + client := &Client{ + ctx: context.Background(), + secretsManager: tt.mockClient, + } + + content := []byte("content") + resp, err := client.SecretsManagerPutSecretValue("hash", "arn", &content) + assert.Equal(t, tt.mockClient.ReturnError, err) + assert.Equal(t, tt.mockClient.PutSecretValueRet, resp) + }) + } +} + +func TestSsmPutParameter(t *testing.T) { + tests := []struct { + name string + mockClient *MockAwsClient + expectedVersion *int64 + expectedErrMsg string + }{ + { + name: "successful update parameter", + mockClient: &MockAwsClient{ + t: t, + snapsFileName: "ssm_update_update_parameter", + PutParameterRet: &ssm.PutParameterOutput{ + Version: *aws.Int64(1), + }, + ReturnError: nil, + }, + }, + { + name: "update parameter error", + mockClient: &MockAwsClient{ + t: t, + snapsFileName: "ssm_update_update_parameter_error", + PutParameterRet: nil, + ReturnError: fmt.Errorf("mock error"), + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + client := &Client{ + ctx: context.Background(), + ssm: tt.mockClient, + } + content := []byte("content") + resp, err := client.SsmPutParameter("parameter", &content, "key") + assert.Equal(t, tt.mockClient.ReturnError, err) + assert.Equal(t, tt.mockClient.PutParameterRet, resp) + }) + } +} diff --git a/lambda/internal/client/mock.go b/lambda/internal/client/mock.go new file mode 100644 index 00000000..89ec3d92 --- /dev/null +++ b/lambda/internal/client/mock.go @@ -0,0 +1,81 @@ +package client + +import ( + "context" + "fmt" + "testing" + + "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager" + "github.com/aws/aws-sdk-go-v2/service/ssm" + "github.com/gkampitakis/go-snaps/snaps" +) + +type mockErrorReader struct{} + +func (r *mockErrorReader) Read(p []byte) (n int, err error) { + return 0, fmt.Errorf("mock read error") +} + +// MockAwsClient is a mock for the real AWS client +type MockAwsClient struct { + t *testing.T + snapsFileName string + ReturnError error + GetObjectRet *s3.GetObjectOutput + GetObjectAttributesRet *s3.GetObjectAttributesOutput + PutParameterRet *ssm.PutParameterOutput + PutSecretValueRet *secretsmanager.PutSecretValueOutput +} + +func (s *MockAwsClient) GetObject(ctx context.Context, params *s3.GetObjectInput, optFns ...func(*s3.Options)) (*s3.GetObjectOutput, error) { + if s.ReturnError == nil { + snaps.WithConfig(snaps.Filename(s.snapsFileName)).MatchSnapshot(s.t, params) + } + return s.GetObjectRet, s.ReturnError +} + +func (s *MockAwsClient) GetObjectAttributes(ctx context.Context, params *s3.GetObjectAttributesInput, optFns ...func(*s3.Options)) (*s3.GetObjectAttributesOutput, error) { + if s.ReturnError == nil { + snaps.WithConfig(snaps.Filename(s.snapsFileName)).MatchSnapshot(s.t, params) + } + return s.GetObjectAttributesRet, s.ReturnError +} + +func (s *MockAwsClient) PutParameter(ctx context.Context, params *ssm.PutParameterInput, optFns ...func(*ssm.Options)) (*ssm.PutParameterOutput, error) { + if s.ReturnError == nil { + snaps.WithConfig(snaps.Filename(s.snapsFileName)).MatchSnapshot(s.t, params) + } + return s.PutParameterRet, s.ReturnError +} + +func (s *MockAwsClient) PutSecretValue(ctx context.Context, params *secretsmanager.PutSecretValueInput, optFns ...func(*secretsmanager.Options)) (*secretsmanager.PutSecretValueOutput, error) { + if s.ReturnError == nil { + snaps.WithConfig(snaps.Filename(s.snapsFileName)).MatchSnapshot(s.t, params) + } + return s.PutSecretValueRet, s.ReturnError +} + +// MockClient is a mock for "our" AWS client +type MockClient struct { + S3Content []byte + S3Etag string + S3Err error + S3EtagErr error +} + +func (m *MockClient) S3GetObject(file SopsS3File) ([]byte, error) { + return m.S3Content, m.S3Err +} + +func (m *MockClient) S3GetObjectETAG(file SopsS3File) (*string, error) { + return &m.S3Etag, m.S3EtagErr +} + +func (m *MockClient) SecretsManagerPutSecretValue(sopsHash string, secretArn string, secretContent *[]byte) (*secretsmanager.PutSecretValueOutput, error) { + return nil, nil +} + +func (m *MockClient) SsmPutParameter(parameterName string, parameterContent *[]byte, keyId string) (*ssm.PutParameterOutput, error) { + return nil, nil +} diff --git a/lambda/internal/data/__snapshots__/1.simple.flatten.snap b/lambda/internal/data/__snapshots__/1.simple.flatten.snap new file mode 100755 index 00000000..e98a4ff9 --- /dev/null +++ b/lambda/internal/data/__snapshots__/1.simple.flatten.snap @@ -0,0 +1,12 @@ + +[Test_Flatten/1.simple - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "bool": bool(true), + "number": float64(1.1), + "string": "examplestring", + }, + raw: (*[]uint8)(nil), + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/1.simple.fromJson.snap b/lambda/internal/data/__snapshots__/1.simple.fromJson.snap new file mode 100755 index 00000000..3906e71e --- /dev/null +++ b/lambda/internal/data/__snapshots__/1.simple.fromJson.snap @@ -0,0 +1,12 @@ + +[Test_FromJSON/1.simple - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "bool": bool(true), + "number": float64(1.1), + "string": "examplestring", + }, + raw: &[]uint8{0x7b, 0xa, 0x20, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x22, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0xa, 0x20, 0x20, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0x2c, 0xa, 0x20, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x20, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0xa, 0x7d}, + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/1.simple.fromYaml.snap b/lambda/internal/data/__snapshots__/1.simple.fromYaml.snap new file mode 100755 index 00000000..be426370 --- /dev/null +++ b/lambda/internal/data/__snapshots__/1.simple.fromYaml.snap @@ -0,0 +1,12 @@ + +[Test_FromYAML/1.simple - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "bool": bool(true), + "number": float64(1.1), + "string": "examplestring", + }, + raw: &[]uint8{0x62, 0x6f, 0x6f, 0x6c, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0xa, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0xa, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xa}, + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/1.simple.stringify.snap b/lambda/internal/data/__snapshots__/1.simple.stringify.snap new file mode 100755 index 00000000..d20f9162 --- /dev/null +++ b/lambda/internal/data/__snapshots__/1.simple.stringify.snap @@ -0,0 +1,12 @@ + +[Test_Stringify/1.simple - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "bool": "true", + "number": "1.1", + "string": "examplestring", + }, + raw: (*[]uint8)(nil), + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/1.simple.toJson.snap b/lambda/internal/data/__snapshots__/1.simple.toJson.snap new file mode 100755 index 00000000..27892f2d --- /dev/null +++ b/lambda/internal/data/__snapshots__/1.simple.toJson.snap @@ -0,0 +1,8 @@ + +[Test_ToJSON/1.simple - 1] +{ + "bool": true, + "number": 1.1, + "string": "examplestring" +} +--- diff --git a/lambda/internal/data/__snapshots__/1.simple.toStringMap.snap b/lambda/internal/data/__snapshots__/1.simple.toStringMap.snap new file mode 100755 index 00000000..ff867a39 --- /dev/null +++ b/lambda/internal/data/__snapshots__/1.simple.toStringMap.snap @@ -0,0 +1,8 @@ + +[Test_ToStringMap/1.simple - 1] +map[string][]uint8{ + "bool": {0x74, 0x72, 0x75, 0x65}, + "number": {0x31, 0x2e, 0x31}, + "string": {0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67}, +} +--- diff --git a/lambda/internal/data/__snapshots__/1.simple.toYaml.snap b/lambda/internal/data/__snapshots__/1.simple.toYaml.snap new file mode 100755 index 00000000..b530a2a5 --- /dev/null +++ b/lambda/internal/data/__snapshots__/1.simple.toYaml.snap @@ -0,0 +1,7 @@ + +[Test_ToYAML/1.simple - 1] +bool: true +number: 1.1 +string: examplestring + +--- diff --git a/lambda/internal/data/__snapshots__/2.nested.flatten.snap b/lambda/internal/data/__snapshots__/2.nested.flatten.snap new file mode 100755 index 00000000..0c4d7caf --- /dev/null +++ b/lambda/internal/data/__snapshots__/2.nested.flatten.snap @@ -0,0 +1,15 @@ + +[Test_Flatten/2.nested - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "bool": bool(true), + "nested.bool": bool(true), + "nested.number": float64(1.1), + "nested.string": "examplestring", + "number": float64(1.1), + "string": "examplestring", + }, + raw: (*[]uint8)(nil), + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/2.nested.fromJson.snap b/lambda/internal/data/__snapshots__/2.nested.fromJson.snap new file mode 100755 index 00000000..429561de --- /dev/null +++ b/lambda/internal/data/__snapshots__/2.nested.fromJson.snap @@ -0,0 +1,17 @@ + +[Test_FromJSON/2.nested - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "bool": bool(true), + "nested": map[string]interface {}{ + "bool": bool(true), + "number": float64(1.1), + "string": "examplestring", + }, + "number": float64(1.1), + "string": "examplestring", + }, + raw: &[]uint8{0x7b, 0xa, 0x20, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x22, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0xa, 0x20, 0x20, 0x22, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x22, 0x3a, 0x20, 0x7b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x22, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0xa, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0x2c, 0xa, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x20, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0xa, 0x20, 0x20, 0x7d, 0x2c, 0xa, 0x20, 0x20, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0x2c, 0xa, 0x20, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x20, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0xa, 0x7d}, + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/2.nested.fromYaml.snap b/lambda/internal/data/__snapshots__/2.nested.fromYaml.snap new file mode 100755 index 00000000..06907f87 --- /dev/null +++ b/lambda/internal/data/__snapshots__/2.nested.fromYaml.snap @@ -0,0 +1,17 @@ + +[Test_FromYAML/2.nested - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "bool": bool(true), + "nested": map[string]interface {}{ + "bool": bool(true), + "number": float64(1.1), + "string": "examplestring", + }, + "number": float64(1.1), + "string": "examplestring", + }, + raw: &[]uint8{0x62, 0x6f, 0x6f, 0x6c, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0xa, 0x6e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x3a, 0xa, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0xa, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0xa, 0x20, 0x20, 0x20, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xa, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0xa, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xa}, + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/2.nested.stringify.snap b/lambda/internal/data/__snapshots__/2.nested.stringify.snap new file mode 100755 index 00000000..7678d147 --- /dev/null +++ b/lambda/internal/data/__snapshots__/2.nested.stringify.snap @@ -0,0 +1,17 @@ + +[Test_Stringify/2.nested - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "bool": "true", + "nested": map[string]interface {}{ + "bool": "true", + "number": "1.1", + "string": "examplestring", + }, + "number": "1.1", + "string": "examplestring", + }, + raw: (*[]uint8)(nil), + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/2.nested.toJson.snap b/lambda/internal/data/__snapshots__/2.nested.toJson.snap new file mode 100755 index 00000000..8dc44f67 --- /dev/null +++ b/lambda/internal/data/__snapshots__/2.nested.toJson.snap @@ -0,0 +1,13 @@ + +[Test_ToJSON/2.nested - 1] +{ + "bool": true, + "nested": { + "bool": true, + "number": 1.1, + "string": "examplestring" + }, + "number": 1.1, + "string": "examplestring" +} +--- diff --git a/lambda/internal/data/__snapshots__/2.nested.toYaml.snap b/lambda/internal/data/__snapshots__/2.nested.toYaml.snap new file mode 100755 index 00000000..ccf4fb7a --- /dev/null +++ b/lambda/internal/data/__snapshots__/2.nested.toYaml.snap @@ -0,0 +1,11 @@ + +[Test_ToYAML/2.nested - 1] +bool: true +nested: + bool: true + number: 1.1 + string: examplestring +number: 1.1 +string: examplestring + +--- diff --git a/lambda/internal/data/__snapshots__/3.array.flatten.snap b/lambda/internal/data/__snapshots__/3.array.flatten.snap new file mode 100755 index 00000000..8bb596b8 --- /dev/null +++ b/lambda/internal/data/__snapshots__/3.array.flatten.snap @@ -0,0 +1,15 @@ + +[Test_Flatten/3.array - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "[0].bool": bool(true), + "[0].number": float64(1.1), + "[0].string": "examplestring", + "[1].bool": bool(true), + "[1].number": float64(1.1), + "[1].string": "examplestring", + }, + raw: (*[]uint8)(nil), + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/3.array.fromJson.snap b/lambda/internal/data/__snapshots__/3.array.fromJson.snap new file mode 100755 index 00000000..9e92db61 --- /dev/null +++ b/lambda/internal/data/__snapshots__/3.array.fromJson.snap @@ -0,0 +1,19 @@ + +[Test_FromJSON/3.array - 1] +&data.Data{ + parsed: &[]interface {}{ + map[string]interface {}{ + "bool": bool(true), + "number": float64(1.1), + "string": "examplestring", + }, + map[string]interface {}{ + "bool": bool(true), + "number": float64(1.1), + "string": "examplestring", + }, + }, + raw: &[]uint8{0x5b, 0xa, 0x20, 0x20, 0x7b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x22, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0xa, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0x2c, 0xa, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x20, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0xa, 0x20, 0x20, 0x7d, 0x2c, 0xa, 0x20, 0x20, 0x7b, 0xa, 0x20, 0x20, 0x20, 0x20, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x22, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0xa, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0x2c, 0xa, 0x20, 0x20, 0x20, 0x20, 0x22, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x3a, 0x20, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x22, 0xa, 0x20, 0x20, 0x7d, 0xa, 0x5d}, + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/3.array.fromYaml.snap b/lambda/internal/data/__snapshots__/3.array.fromYaml.snap new file mode 100755 index 00000000..1779f97f --- /dev/null +++ b/lambda/internal/data/__snapshots__/3.array.fromYaml.snap @@ -0,0 +1,19 @@ + +[Test_FromYAML/3.array - 1] +&data.Data{ + parsed: &[]interface {}{ + map[string]interface {}{ + "bool": bool(true), + "number": float64(1.1), + "string": "examplestring", + }, + map[string]interface {}{ + "bool": bool(true), + "number": float64(1.1), + "string": "examplestring", + }, + }, + raw: &[]uint8{0x2d, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0xa, 0x20, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0xa, 0x20, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xa, 0x2d, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0xa, 0x20, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x3a, 0x20, 0x31, 0x2e, 0x31, 0xa, 0x20, 0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x3a, 0x20, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0xa}, + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/3.array.stringify.snap b/lambda/internal/data/__snapshots__/3.array.stringify.snap new file mode 100755 index 00000000..a4f9a598 --- /dev/null +++ b/lambda/internal/data/__snapshots__/3.array.stringify.snap @@ -0,0 +1,19 @@ + +[Test_Stringify/3.array - 1] +&data.Data{ + parsed: &[]interface {}{ + map[string]interface {}{ + "bool": "true", + "number": "1.1", + "string": "examplestring", + }, + map[string]interface {}{ + "bool": "true", + "number": "1.1", + "string": "examplestring", + }, + }, + raw: (*[]uint8)(nil), + Hash: (*string)(nil), +} +--- diff --git a/lambda/internal/data/__snapshots__/3.array.toJson.snap b/lambda/internal/data/__snapshots__/3.array.toJson.snap new file mode 100755 index 00000000..97532691 --- /dev/null +++ b/lambda/internal/data/__snapshots__/3.array.toJson.snap @@ -0,0 +1,15 @@ + +[Test_ToJSON/3.array - 1] +[ + { + "bool": true, + "number": 1.1, + "string": "examplestring" + }, + { + "bool": true, + "number": 1.1, + "string": "examplestring" + } +] +--- diff --git a/lambda/internal/data/__snapshots__/3.array.toYaml.snap b/lambda/internal/data/__snapshots__/3.array.toYaml.snap new file mode 100755 index 00000000..bdf39d0f --- /dev/null +++ b/lambda/internal/data/__snapshots__/3.array.toYaml.snap @@ -0,0 +1,10 @@ + +[Test_ToYAML/3.array - 1] +- bool: true + number: 1.1 + string: examplestring +- bool: true + number: 1.1 + string: examplestring + +--- diff --git a/lambda/internal/data/data.go b/lambda/internal/data/data.go new file mode 100644 index 00000000..5acaa91a --- /dev/null +++ b/lambda/internal/data/data.go @@ -0,0 +1,278 @@ +package data + +import ( + "encoding/json" + "fmt" + "reflect" + "slices" + "strings" + + "gopkg.in/yaml.v3" +) + +type Data struct { + parsed *any + raw *[]byte + Hash *string +} + +var ( + ErrorUnparsedData = fmt.Errorf("Data does not contain parsed data") +) + +func FromBinary(in []byte, hash *string) (*Data, error) { + return &Data{ + raw: &in, + Hash: hash, + }, nil +} + +func FromYAML(in []byte, hash *string) (*Data, error) { + var content any + err := yaml.Unmarshal(in, &content) + if err != nil { + return nil, err + } + return &Data{ + parsed: &content, + raw: &in, + Hash: hash, + }, nil +} + +func FromJSON(in []byte, hash *string) (*Data, error) { + var content any + err := json.Unmarshal(in, &content) + if err != nil { + return nil, err + } + return &Data{ + parsed: &content, + raw: &in, + Hash: hash, + }, nil +} + +func FromDotEnv(in []byte, hash *string) (*Data, error) { + var dotEnvMap any = map[string]string{} + dotenvLines := strings.Split(string(in), "\n") + for _, line := range dotenvLines { + if line != "" && !strings.HasPrefix(line, "#") { + parts := strings.SplitN(line, "=", 2) + if len(parts) == 2 { + key := strings.TrimSpace(parts[0]) + value := strings.TrimSpace(parts[1]) + dotEnvMap.(map[string]string)[key] = value + } + } + } + return &Data{ + parsed: &dotEnvMap, + raw: &in, + Hash: hash, + }, nil +} + +func (d *Data) ToJSON() (*[]byte, error) { + if d.parsed == nil { + return nil, ErrorUnparsedData + } + content := *d.parsed + ret, err := json.MarshalIndent(content, "", " ") + if err != nil { + return nil, err + } + return &ret, nil +} + +func (d *Data) ToYAML() (*[]byte, error) { + if d.parsed == nil { + return nil, ErrorUnparsedData + } + ret, err := yaml.Marshal(d.parsed) + if err != nil { + return nil, err + } + return &ret, nil +} + +func (d *Data) ToDotEnv() (*[]byte, error) { + if d.parsed == nil { + return nil, ErrorUnparsedData + } + stringMap, err := d.ToStringMap() + if err != nil { + return nil, err + } + var sb strings.Builder + for k, v := range stringMap { + sb.WriteString(fmt.Sprintf("%s=%s\n", k, v)) + } + ret := []byte(sb.String()) + return &ret, nil +} + +func (d *Data) ToStringMap() (map[string][]byte, error) { + if d.parsed == nil { + return nil, ErrorUnparsedData + } + if result, ok := (*d.parsed).(map[string]interface{}); ok { + stringMap := make(map[string][]byte) + keys := make([]string, 0, len(result)) + for k := range result { + keys = append(keys, k) + } + slices.Sort(keys) + for _, k := range keys { + switch result[k].(type) { + case string, float32, float64, int, int32, int64, uint, uint32, uint64, bool, []byte: + stringMap[k] = []byte(fmt.Sprintf("%v", result[k])) + default: + return nil, fmt.Errorf(`value for key %s is a complex type (map or slice), maybe run "Flatten" first`, k) + } + } + return stringMap, nil + } + return nil, fmt.Errorf("parsed data is not a map[string]interface{}") +} + +func (d *Data) GetRaw() (*[]byte, error) { + if d.raw == nil { + return nil, ErrorUnparsedData + } + return d.raw, nil +} + +func (d *Data) StringifyValues() error { + if d.parsed == nil { + return ErrorUnparsedData + } + stringified, err := stringifyValues(*d.parsed) + if err != nil { + return err + } + d.parsed = &stringified + return nil +} + +func (d *Data) Flatten(separator string) error { + if d.parsed == nil { + return ErrorUnparsedData + } + output := make(map[string]interface{}) + err := flatten("", *d.parsed, output, separator) + if err != nil { + return err + } + var content interface{} = output + d.parsed = &content + return nil +} + +func (d *Data) stripEmptyKey() error { + if d.parsed == nil { + return ErrorUnparsedData + } + if parsedMap, ok := (*d.parsed).(map[string]interface{}); ok { + if val, exists := parsedMap[""]; exists && len(parsedMap) == 1 { + if nestedMap, ok := val.(map[string]interface{}); ok { + var nestedAny any = nestedMap + d.parsed = &nestedAny + } + } + } + return nil +} + +// stringifyValues recursively stringifies primitive values in complex types +func stringifyValues(input any) (any, error) { + // Get the type of the input + v := reflect.ValueOf(input) + + // If the value is a pointer, dereference it to get the actual value + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + + // Handle based on the kind of the value + switch v.Kind() { + case reflect.Map: + // If it's a map, iterate through the map and recursively stringify the values + output := make(map[string]interface{}) + for _, key := range v.MapKeys() { + val := v.MapIndex(key) + strVal, err := stringifyValues(val.Interface()) + if err != nil { + return nil, err + } + output[key.String()] = strVal + } + return output, nil + case reflect.Array, reflect.Slice: + // If it's a slice or array, recursively stringify each element + output := []interface{}{} + for i := 0; i < v.Len(); i++ { + elem := v.Index(i) + strElem, err := stringifyValues(elem.Interface()) + if err != nil { + return nil, err + } + output = append(output, strElem) + } + return output, nil + case reflect.Struct: + // If it's a struct, iterate through its fields and recursively stringify them + output := make(map[string]interface{}) + for i := 0; i < v.NumField(); i++ { + field := v.Field(i) + strField, err := stringifyValues(field.Interface()) + if err != nil { + return nil, err + } + output[v.Type().Field(i).Name] = strField + } + return output, nil + case reflect.String, reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, + reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, + reflect.Float32, reflect.Float64, reflect.Bool, reflect.Complex64, reflect.Complex128: + // If it's a primitive type, convert it to a string + return fmt.Sprintf("%v", input), nil + default: + // If it's an unsupported type, return an error + return nil, fmt.Errorf("unsupported type: %v", v.Kind()) + } +} + +func flatten(parentKey string, input any, output map[string]interface{}, separator string) error { + v := reflect.ValueOf(input) + + // If the value is a pointer, dereference it to get the actual value + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + + switch v.Kind() { + case reflect.Map: + for _, key := range v.MapKeys() { + val := v.MapIndex(key) + newKey := key.String() + if parentKey != "" { + newKey = parentKey + separator + newKey + } + if err := flatten(newKey, val.Interface(), output, separator); err != nil { + return err + } + } + case reflect.Slice, reflect.Array: + for i := 0; i < v.Len(); i++ { + elem := v.Index(i) + newKey := fmt.Sprintf("%s[%d]", parentKey, i) + if err := flatten(newKey, elem.Interface(), output, separator); err != nil { + return err + } + } + default: + output[parentKey] = input + } + return nil +} diff --git a/lambda/internal/data/data_test.go b/lambda/internal/data/data_test.go new file mode 100644 index 00000000..d4b149d0 --- /dev/null +++ b/lambda/internal/data/data_test.go @@ -0,0 +1,274 @@ +package data + +import ( + "bytes" + "fmt" + "os" + "testing" + + "github.com/gkampitakis/go-snaps/snaps" +) + +var testData = map[string]interface{}{ + "1.simple": map[string]interface{}{ + "string": "examplestring", + "number": 1.1, + "bool": true, + }, + "2.nested": map[string]interface{}{ + "string": "examplestring", + "number": 1.1, + "bool": true, + "nested": map[string]interface{}{ + "string": "examplestring", + "number": 1.1, + "bool": true, + }, + }, + "3.array": []interface{}{ + map[string]interface{}{ + "string": "examplestring", + "number": 1.1, + "bool": true, + }, + map[string]interface{}{ + "string": "examplestring", + "number": 1.1, + "bool": true, + }, + }, +} + +func read(filename string) ([]byte, error) { + filePath := "__snapshots__/" + filename + existingContent, err := os.ReadFile(filePath) + if err != nil { + return nil, err + } + lines := bytes.Split(existingContent, []byte("\n")) + if len(lines) > 2 { + existingContent = bytes.Join(lines[2:len(lines)-2], []byte("\n")) + } + return existingContent, nil +} + +func Test_ToJSON(t *testing.T) { + for tName, tData := range testData { + t.Run(tName, func(t *testing.T) { + data := &Data{ + parsed: &tData, + } + jsonData, err := data.ToJSON() + if err != nil { + t.Errorf("ToJson() error = %v", err) + return + } + snaps.WithConfig( + snaps.Filename(tName+".toJson"), + ).MatchSnapshot(t, string(*jsonData)) + }) + } +} + +func Test_ToJSON_fail(t *testing.T) { + data := &Data{} + _, err := data.ToJSON() + if err != ErrorUnparsedData { + t.Errorf("Expected error %v, got %v", ErrorUnparsedData, err) + } +} + +func Test_ToYAML(t *testing.T) { + for tName, tData := range testData { + t.Run(tName, func(t *testing.T) { + data := &Data{ + parsed: &tData, + } + jsonData, err := data.ToYAML() + if err != nil { + t.Errorf("toYAML() error = %v", err) + return + } + snaps.WithConfig( + snaps.Filename(tName+".toYaml"), + ).MatchSnapshot(t, string(*jsonData)) + }) + } +} + +func Test_ToYAML_fail(t *testing.T) { + data := &Data{} + _, err := data.ToYAML() + if err != ErrorUnparsedData { + t.Errorf("Expected error %v, got %v", ErrorUnparsedData, err) + } +} + +func Test_ToStringMap(t *testing.T) { + for tName, tData := range testData { + t.Run(tName, func(t *testing.T) { + data := &Data{ + parsed: &tData, + } + stringMap, err := data.ToStringMap() + + if tName == "3.array" { + errExp := fmt.Errorf("parsed data is not a map[string]interface{}") + if err.Error() != errExp.Error() { + t.Errorf("Expected error %v, got %v", errExp, err) + } + return + } + if tName == "2.nested" { + errExp := fmt.Errorf(`value for key nested is a complex type (map or slice), maybe run "Flatten" first`) + if err.Error() != errExp.Error() { + t.Errorf("Expected error %v, got %v", errExp, err) + } + return + } + if err != nil { + t.Errorf("ToStringMap() error = %v", err) + return + } + snaps.WithConfig( + snaps.Filename(tName+".toStringMap"), + ).MatchSnapshot(t, stringMap) + }) + } +} + +func Test_FromJSON(t *testing.T) { + for tName := range testData { + t.Run(tName, func(t *testing.T) { + jsonData, err := read(tName + ".toJson.snap") + if err != nil { + t.Errorf("Read() error = %v", err) + return + } + data, err := FromJSON(jsonData, nil) + if err != nil { + t.Errorf("FromJSON() error = %v", err) + return + } + snaps.WithConfig( + snaps.Filename(tName+".fromJson"), + ).MatchSnapshot(t, data) + }) + } +} + +func Test_FromYAML(t *testing.T) { + for tName := range testData { + t.Run(tName, func(t *testing.T) { + jsonData, err := read(tName + ".toYaml.snap") + if err != nil { + t.Errorf("Read() error = %v", err) + return + } + data, err := FromYAML(jsonData, nil) + if err != nil { + t.Errorf("FromYAML() error = %v", err) + return + } + snaps.WithConfig( + snaps.Filename(tName+".fromYaml"), + ).MatchSnapshot(t, data) + }) + } +} + +func Test_FromDotEnv(t *testing.T) { + dotEnvData := []byte(` + # This is a comment + STRING=examplestring + NUMBER=1.1 + BOOL=true + NESTED_STRING=examplestring + NESTED_NUMBER=1.1 + NESTED_BOOL=true + `) + + expectedData := map[string]string{ + "STRING": "examplestring", + "NUMBER": "1.1", + "BOOL": "true", + "NESTED_STRING": "examplestring", + "NESTED_NUMBER": "1.1", + "NESTED_BOOL": "true", + } + + data, err := FromDotEnv(dotEnvData, nil) + if err != nil { + t.Errorf("FromDotEnv() error = %v", err) + return + } + + if data.parsed == nil { + t.Errorf("FromDotEnv() parsed data is nil") + return + } + + parsedData, ok := (*data.parsed).(map[string]string) + if !ok { + t.Errorf("FromDotEnv() parsed data is not of type map[string]string") + return + } + + for key, expectedValue := range expectedData { + if parsedValue, exists := parsedData[key]; !exists || parsedValue != expectedValue { + t.Errorf("FromDotEnv() key %s: expected %s, got %s", key, expectedValue, parsedValue) + } + } +} + +func Test_Stringify(t *testing.T) { + for tName, tData := range testData { + t.Run(tName, func(t *testing.T) { + data := &Data{ + parsed: &tData, + } + err := data.StringifyValues() + if err != nil { + t.Errorf("StringifyValues() error = %v", err) + return + } + snaps.WithConfig( + snaps.Filename(tName+".stringify"), + ).MatchSnapshot(t, data) + }) + } +} + +func Test_Stringify_fail(t *testing.T) { + data := &Data{} + _, err := data.ToYAML() + if err != ErrorUnparsedData { + t.Errorf("Expected error %v, got %v", ErrorUnparsedData, err) + } +} + +func Test_Flatten(t *testing.T) { + for tName, tData := range testData { + t.Run(tName, func(t *testing.T) { + data := &Data{ + parsed: &tData, + } + err := data.Flatten(".") + if err != nil { + t.Errorf("Flatten() error = %v", err) + return + } + snaps.WithConfig( + snaps.Filename(tName+".flatten"), + ).MatchSnapshot(t, data) + }) + } +} + +func Test_Flatten_fail(t *testing.T) { + data := &Data{} + _, err := data.ToYAML() + if err != ErrorUnparsedData { + t.Errorf("Expected error %v, got %v", ErrorUnparsedData, err) + } +} diff --git a/lambda/internal/event/__snapshots__/invalid_empty.json.snap b/lambda/internal/event/__snapshots__/invalid_empty.json.snap new file mode 100755 index 00000000..72070749 --- /dev/null +++ b/lambda/internal/event/__snapshots__/invalid_empty.json.snap @@ -0,0 +1,4 @@ + +[TestFromCfnEvent - 1] +(*event.SopsSyncResourcePropertys)(nil) +--- diff --git a/lambda/internal/event/__snapshots__/invalid_empty.json_err.snap b/lambda/internal/event/__snapshots__/invalid_empty.json_err.snap new file mode 100755 index 00000000..ddc10087 --- /dev/null +++ b/lambda/internal/event/__snapshots__/invalid_empty.json_err.snap @@ -0,0 +1,5 @@ + +[TestFromCfnEvent - 1] +invalid resource properties (more details in log): +map[] +--- diff --git a/lambda/internal/event/__snapshots__/valid_full.json.snap b/lambda/internal/event/__snapshots__/valid_full.json.snap new file mode 100755 index 00000000..72070749 --- /dev/null +++ b/lambda/internal/event/__snapshots__/valid_full.json.snap @@ -0,0 +1,4 @@ + +[TestFromCfnEvent - 1] +(*event.SopsSyncResourcePropertys)(nil) +--- diff --git a/lambda/internal/event/__snapshots__/valid_full.json_err.snap b/lambda/internal/event/__snapshots__/valid_full.json_err.snap new file mode 100755 index 00000000..d70e1d43 --- /dev/null +++ b/lambda/internal/event/__snapshots__/valid_full.json_err.snap @@ -0,0 +1,5 @@ + +[TestFromCfnEvent - 1] +invalid resource properties (more details in log): +map[EncryptionKey:string Flatten:false FlattenSeparator:string Format:json OutputFormat:json ParameterKeyPrefix:string ParameterName:string ResourceType:SECRET SecretARN:string SopsInline:map[Content:string Hash:string] SopsS3File:map[Bucket:string Key:string] StringifyValues:false] +--- diff --git a/lambda/internal/event/__snapshots__/valid_minimal.json.snap b/lambda/internal/event/__snapshots__/valid_minimal.json.snap new file mode 100755 index 00000000..72070749 --- /dev/null +++ b/lambda/internal/event/__snapshots__/valid_minimal.json.snap @@ -0,0 +1,4 @@ + +[TestFromCfnEvent - 1] +(*event.SopsSyncResourcePropertys)(nil) +--- diff --git a/lambda/internal/event/__snapshots__/valid_minimal.json_err.snap b/lambda/internal/event/__snapshots__/valid_minimal.json_err.snap new file mode 100755 index 00000000..6f80e85d --- /dev/null +++ b/lambda/internal/event/__snapshots__/valid_minimal.json_err.snap @@ -0,0 +1,5 @@ + +[TestFromCfnEvent - 1] +invalid resource properties (more details in log): +map[Flatten:false FlattenSeparator: Format:yaml OutputFormat:json ResourceType:SECRET StringifyValues:false] +--- diff --git a/lambda/internal/event/config-schema.json b/lambda/internal/event/config-schema.json new file mode 100644 index 00000000..5ec3508e --- /dev/null +++ b/lambda/internal/event/config-schema.json @@ -0,0 +1,83 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "SopsSyncResourcePropertys", + "$defs": { + "SopsInline": { + "properties": { + "Content": { + "type": "string" + }, + "Hash": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "Content", + "Hash" + ] + }, + "SopsS3File": { + "properties": { + "Bucket": { + "type": "string" + }, + "Key": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "Bucket", + "Key" + ] + } + }, + "properties": { + "ResourceType": { + "type": "string", + "enum": [ + "SECRET", + "SECRET_BINARY", + "PARAMETER_MULTI", + "PARAMETER" + ] + }, + "Format": { + "type": "string", + "enum": [ + "json", + "yaml", + "dotenv", + "binary" + ] + }, + "Target": { + "type": "string" + }, + "EncryptionKey": { + "type": "string" + }, + "SopsS3File": { + "$ref": "#/$defs/SopsS3File" + }, + "SopsInline": { + "$ref": "#/$defs/SopsInline" + }, + "FlattenSeparator": { + "type": "string" + }, + "ServiceToken": { + "type": "string" + } + }, + "additionalProperties": false, + "type": "object", + "required": [ + "ResourceType", + "Format", + "Target" + ] +} \ No newline at end of file diff --git a/lambda/internal/event/event.go b/lambda/internal/event/event.go new file mode 100644 index 00000000..809b69e6 --- /dev/null +++ b/lambda/internal/event/event.go @@ -0,0 +1,184 @@ +package event + +import ( + "bytes" + "encoding/base64" + "encoding/json" + "fmt" + "log" + "log/slog" + "os" + "strings" + + _ "embed" + + "github.com/aws/aws-lambda-go/cfn" + jsonSchemaGen "github.com/invopop/jsonschema" + jsonSchemaValidate "github.com/kaptinlin/jsonschema" + "github.com/markussiebert/cdk-sops-secrets/internal/client" + "github.com/markussiebert/cdk-sops-secrets/internal/sops" +) + +//go:embed config-schema.json +var configSchema []byte + +type SopsS3File struct { + Bucket string `json:"Bucket"` + Key string `json:"Key"` +} + +func (s *SopsS3File) IsEmpty() bool { + return s == nil || (s.Bucket == "" && s.Key == "") +} + +type SopsInline struct { + Content string `json:"Content"` + Hash string `json:"Hash"` +} + +func (s *SopsInline) IsEmpty() bool { + return s == nil || (s.Content == "" && s.Hash == "") +} + +type ResourceType string + +const ( + // Secret, flattened and stringified + SECRET ResourceType = "SECRET" + // Secret, just the raw value + SECRET_BINARY ResourceType = "SECRET_BINARY" + // The JSON object is flattened into multiple parameters + PARAMETER_MULTI ResourceType = "PARAMETER_MULTI" + // The raw value is stored as Parameter + PARAMETER ResourceType = "PARAMETER" +) + +type SopsSyncResourcePropertys struct { + ResourceType ResourceType `json:"ResourceType" jsonschema:"enum=SECRET,enum=SECRET_BINARY,enum=PARAMETER_MULTI,enum=PARAMETER"` + Format sops.Format `json:"Format" jsonschema:"enum=json,enum=yaml,enum=dotenv,enum=binary"` + Target string `json:"Target"` + EncryptionKey *string `json:"EncryptionKey,omitempty"` + SopsS3File *SopsS3File `json:"SopsS3File,omitempty"` + SopsInline *SopsInline `json:"SopsInline,omitempty"` + FlattenSeparator *string `json:"FlattenSeparator,omitempty"` + // ServiceToken is the ARN of the service token that was passed to the custom resource + // Populated by the CloudFormation + ServiceToken *string `json:"ServiceToken,omitempty"` +} + +func FromCfnEvent(event cfn.Event) (*SopsSyncResourcePropertys, error) { + logger := slog.With("Package", "event", "Function", "FromCfnEvent") + compiler := jsonSchemaValidate.NewCompiler() + schema, err := compiler.Compile(configSchema) + if err != nil { + logger.Error("Failed to compile schema", "Error", err) + } + + slog.Debug("FromCfnEvent", "Event", event) + + result := schema.Validate(event.ResourceProperties) + if !result.IsValid() { + // Sort the details by evaluationPath + logger.Info("Invalid ResourceProperties", "EvaluationResult", result) + return nil, fmt.Errorf("invalid resource properties (more details in log):\n%v", event.ResourceProperties) + } + + var props SopsSyncResourcePropertys + data, err := json.Marshal(event.ResourceProperties) + if err != nil { + return nil, fmt.Errorf("failed to marshal resource properties: %v", err) + } + + err = json.Unmarshal(data, &props) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal resource properties: %v", err) + } + + return &props, nil +} + +func (p *SopsSyncResourcePropertys) GeneratePhysicalResourceId() string { + return fmt.Sprintf("%s:%s:%s", "arn:custom:sopssync:", p.ResourceType, p.Target) +} + +func (p *SopsSyncResourcePropertys) sopsInlineToSopsEncryptedSecret() (*sops.EncryptedSopsSecret, error) { + content, contentErr := base64.StdEncoding.DecodeString(p.SopsInline.Content) + if contentErr != nil { + return nil, contentErr + } + return sops.CreateEncryptedSopsSecret(content, p.Format, p.SopsInline.Hash) +} + +func (p *SopsSyncResourcePropertys) sopsS3FileToSopsEncryptedSecret(clients client.AwsClient) (*sops.EncryptedSopsSecret, error) { + s3File := client.SopsS3File{ + Bucket: p.SopsS3File.Bucket, + Key: p.SopsS3File.Key, + } + s3Content, s3ContentErr := clients.S3GetObject(s3File) + if s3ContentErr != nil { + return nil, s3ContentErr + } + + s3Etag, s3EtagErr := clients.S3GetObjectETAG(s3File) + if s3EtagErr != nil { + return nil, s3EtagErr + } + + return sops.CreateEncryptedSopsSecret(s3Content, p.Format, *s3Etag) +} + +func (p *SopsSyncResourcePropertys) GetEncryptedSopsSecret(client client.AwsClient) (*sops.EncryptedSopsSecret, error) { + if !p.SopsInline.IsEmpty() && !p.SopsS3File.IsEmpty() { + return nil, fmt.Errorf("both inline and S3 secret content found") + } + if !p.SopsInline.IsEmpty() { + return p.sopsInlineToSopsEncryptedSecret() + } + if !p.SopsS3File.IsEmpty() { + return p.sopsS3FileToSopsEncryptedSecret(client) + } + return nil, fmt.Errorf("no secret content found") +} + +func GenerateSchema() { + schema := jsonSchemaGen.Reflect(&SopsSyncResourcePropertys{}) + + parts := strings.Split(schema.Ref, "/") + resourceName := parts[len(parts)-1] + schema.Properties = schema.Definitions[resourceName].Properties + schema.AdditionalProperties = schema.Definitions[resourceName].AdditionalProperties + schema.Type = schema.Definitions[resourceName].Type + schema.Required = schema.Definitions[resourceName].Required + delete(schema.Definitions, resourceName) + schema.Ref = "" + schema.ID = "SopsSyncResourcePropertys" + schemaJSON, err := schema.MarshalJSON() + if err != nil { + log.Fatalf("Error marshaling JSON schema: %v", err) + } + + var prettyJSON bytes.Buffer + + err = json.Indent(&prettyJSON, schemaJSON, "", " ") + if err != nil { + log.Fatalf("Error indenting JSON schema: %v", err) + } + + schemaJSON = prettyJSON.Bytes() + if err != nil { + log.Fatalf("Error generating JSON schema: %v", err) + } + + file, err := os.Create("config-schema.json") + if err != nil { + log.Fatalf("Error creating schema file: %v", err) + } + defer file.Close() + + _, err = file.Write(schemaJSON) + if err != nil { + log.Fatalf("Error writing JSON schema to file: %v", err) + } + + log.Printf("Generated JSON schema") +} diff --git a/lambda/internal/event/event_test.go b/lambda/internal/event/event_test.go new file mode 100644 index 00000000..9c497d77 --- /dev/null +++ b/lambda/internal/event/event_test.go @@ -0,0 +1,43 @@ +package event + +import ( + "encoding/json" + "fmt" + "os" + "testing" + + "github.com/aws/aws-lambda-go/cfn" + "github.com/gkampitakis/go-snaps/snaps" + "github.com/stretchr/testify/assert" +) + +func TestGenerateSchema(t *testing.T) { + GenerateSchema() +} + +func createTestSchema(t *testing.T, filename string) cfn.Event { + file, err := os.Open("testdata/" + filename) + assert.NoError(t, err) + defer file.Close() + var i map[string]interface{} + err = json.NewDecoder(file).Decode(&i) + assert.NoError(t, err) + return cfn.Event{ + ResourceProperties: i, + } +} + +func TestFromCfnEvent(t *testing.T) { + tests := []string{ + "valid_minimal.json", + "valid_full.json", + "invalid_empty.json", + } + + for _, test := range tests { + mockEvent := createTestSchema(t, test) + props, err := FromCfnEvent(mockEvent) + snaps.WithConfig(snaps.Filename(test)).MatchSnapshot(t, props) + snaps.WithConfig(snaps.Filename(test+"_err")).MatchSnapshot(t, fmt.Sprintf("%v", err)) + } +} diff --git a/lambda/internal/event/testdata/invalid_empty.json b/lambda/internal/event/testdata/invalid_empty.json new file mode 100644 index 00000000..9e26dfee --- /dev/null +++ b/lambda/internal/event/testdata/invalid_empty.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/lambda/internal/event/testdata/valid_full.json b/lambda/internal/event/testdata/valid_full.json new file mode 100644 index 00000000..61eb1bbc --- /dev/null +++ b/lambda/internal/event/testdata/valid_full.json @@ -0,0 +1,20 @@ +{ + "OutputFormat": "json", + "EncryptionKey": "string", + "Flatten": false, + "FlattenSeparator": "string", + "Format": "json", + "ParameterKeyPrefix": "string", + "ParameterName": "string", + "ResourceType": "SECRET", + "SecretARN": "string", + "SopsInline": { + "Content": "string", + "Hash": "string" + }, + "SopsS3File": { + "Bucket": "string", + "Key": "string" + }, + "StringifyValues": false +} \ No newline at end of file diff --git a/lambda/internal/event/testdata/valid_minimal.json b/lambda/internal/event/testdata/valid_minimal.json new file mode 100644 index 00000000..e8034cc6 --- /dev/null +++ b/lambda/internal/event/testdata/valid_minimal.json @@ -0,0 +1,8 @@ +{ + "OutputFormat": "json", + "Flatten": false, + "FlattenSeparator": "", + "Format": "yaml", + "ResourceType": "SECRET", + "StringifyValues": false +} \ No newline at end of file diff --git a/lambda/internal/sops/__snapshots__/binary/sopsfile.enc-age.binary.snap b/lambda/internal/sops/__snapshots__/binary/sopsfile.enc-age.binary.snap new file mode 100755 index 00000000..6488d8dd --- /dev/null +++ b/lambda/internal/sops/__snapshots__/binary/sopsfile.enc-age.binary.snap @@ -0,0 +1,18 @@ + +[TestDecrypt/binary/sopsfile.enc-age.binary - 1] +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDVd/OAdqlMznWINBDoyR+PESgQJlUptwnh/vzbgAaIuHl4gN7Q +W2Jx06bKFgv8yAQ4ouR0EaPv43X1pWFUyE/vK4e2A4M28Ciriy5r2TiBx57EL7bA +AiiCaEvpKx3uAtTgFYcdLdD5xYKUf51gymZ6wU8BBgYMkVlL5rpGmR7ddQIDAQAB +AoGAaeEXG+6/RmNZFHeOs4eeaZ2+21PIBerNshSBYnX7x7CIP2bcHUhWadLq9W0+ +AOFMhrL00UU2pPOTPIYM4rqAOl5PvPeV4GNMvI+9/619p/ZNMbnvj43KqUtaPp1g +JyT22CH4TqDC2io8S9xWxxh9AgvgOI/ekJ3h4PdYpmyVUXkCQQD6b1dkYhlgiy3u +Z84L5WM+7vXG2ivA3N3T5eYJdsQFvlV6gNSqbKcxIR+cFK0RaRiWrd7U2IOM67RF +YRvHNN0rAkEA2jZRXVjHjTZSuAVDMOA4cc6pgxOqByg14clWgRDtbueIMHNCYLJY +bi5YE0kqzjSaH2WbeT7LX1q3S7amoN4f3wJBALw9ZrYYmrSbyRmTQyhj8raCTZF7 +ujmMitzUyJVChVM/3uZm4fN8GivuluDuFaypj4brCDx6xl7taKJhvMx+quMCQF/C +ZoJoa2n05OgMpyfTvfFzl8AF6R+q7bpf+K47F3cL9CAO9JoqqdPwUoZkHXzQaLJO +jKPwgp8d2EJJrWX7FFECQQCRMPE4WsTCLXmVefZne7k000WPclZ4pIjggz1lpGgN +23bwNOla1k4/B10btnEzNi16/b01Kf3K4hYaicd46sLH +-----END RSA PRIVATE KEY----- +--- diff --git a/lambda/internal/sops/__snapshots__/dotenv/encrypted-best-secret.env.snap b/lambda/internal/sops/__snapshots__/dotenv/encrypted-best-secret.env.snap new file mode 100755 index 00000000..0e6f63f9 --- /dev/null +++ b/lambda/internal/sops/__snapshots__/dotenv/encrypted-best-secret.env.snap @@ -0,0 +1,6 @@ + +[TestDecrypt/dotenv/encrypted-best-secret.env - 1] +banane=yellow +crypt="ajkscbuiuXA34%%&&= + +--- diff --git a/lambda/internal/sops/__snapshots__/encrypted-best-secret.env.snap b/lambda/internal/sops/__snapshots__/encrypted-best-secret.env.snap new file mode 100755 index 00000000..30fa84e2 --- /dev/null +++ b/lambda/internal/sops/__snapshots__/encrypted-best-secret.env.snap @@ -0,0 +1,6 @@ + +[TestDecrypt/encrypted-best-secret.env - 1] +banane=yellow +crypt="ajkscbuiuXA34%%&&= + +--- diff --git a/lambda/internal/sops/__snapshots__/json/sopsfile-complex.enc-age.json.snap b/lambda/internal/sops/__snapshots__/json/sopsfile-complex.enc-age.json.snap new file mode 100755 index 00000000..ba501e91 --- /dev/null +++ b/lambda/internal/sops/__snapshots__/json/sopsfile-complex.enc-age.json.snap @@ -0,0 +1,38 @@ + +[TestDecrypt/json/sopsfile-complex.enc-age.json - 1] +{ + "some": { + "deep": { + "nested": { + "object": "structure", + "arrays": [ + "with", + "several", + { + "values": { + "and": "objects" + } + } + ] + } + }, + "notsodeep": "struct" + }, + "and now": { + "some": [ + { + "basic": false + }, + { + "nested": 12345 + }, + { + "type": 1.2345 + }, + { + "tests": "Finish!" + } + ] + } +} +--- diff --git a/lambda/internal/sops/__snapshots__/sops_test.snap b/lambda/internal/sops/__snapshots__/sops_test.snap new file mode 100755 index 00000000..f6a5f3f1 --- /dev/null +++ b/lambda/internal/sops/__snapshots__/sops_test.snap @@ -0,0 +1,44 @@ + +[TestToData/Test_JSON_ToData - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "key": "value", + }, + raw: &[]uint8{0x7b, 0x22, 0x6b, 0x65, 0x79, 0x22, 0x3a, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x7d}, + Hash: &"", +} +--- + +[TestToData/Test_YAML_ToData - 1] +&data.Data{ + parsed: &map[string]interface {}{ + "key": "value", + }, + raw: &[]uint8{0x6b, 0x65, 0x79, 0x3a, 0x20, 0x76, 0x61, 0x6c, 0x75, 0x65}, + Hash: &"", +} +--- + +[TestToData/Test_DotEnv_ToData - 1] +&data.Data{ + parsed: &map[string]string{"KEY":"value"}, + raw: &[]uint8{0x4b, 0x45, 0x59, 0x3d, 0x76, 0x61, 0x6c, 0x75, 0x65}, + Hash: &"", +} +--- + +[TestToData/Test_Binary_ToData - 1] +&data.Data{ + parsed: (*interface {})(nil), + raw: &[]uint8{0x0, 0x1, 0x2, 0x3}, + Hash: &"", +} +--- + +[TestCreateEncryptedSopsSecret/Valid_JSON_Secret - 1] +&sops.EncryptedSopsSecret{ + Content: {0x7b, 0x22, 0x6b, 0x65, 0x79, 0x22, 0x3a, 0x20, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x7d}, + Format: "json", + Hash: "somehash", +} +--- diff --git a/lambda/internal/sops/__snapshots__/sopsfile-complex.enc-age.json.snap b/lambda/internal/sops/__snapshots__/sopsfile-complex.enc-age.json.snap new file mode 100755 index 00000000..652e5d1a --- /dev/null +++ b/lambda/internal/sops/__snapshots__/sopsfile-complex.enc-age.json.snap @@ -0,0 +1,38 @@ + +[TestDecrypt/sopsfile-complex.enc-age.json - 1] +{ + "some": { + "deep": { + "nested": { + "object": "structure", + "arrays": [ + "with", + "several", + { + "values": { + "and": "objects" + } + } + ] + } + }, + "notsodeep": "struct" + }, + "and now": { + "some": [ + { + "basic": false + }, + { + "nested": 12345 + }, + { + "type": 1.2345 + }, + { + "tests": "Finish!" + } + ] + } +} +--- diff --git a/lambda/internal/sops/__snapshots__/sopsfile.enc-age.binary.snap b/lambda/internal/sops/__snapshots__/sopsfile.enc-age.binary.snap new file mode 100755 index 00000000..158ccc96 --- /dev/null +++ b/lambda/internal/sops/__snapshots__/sopsfile.enc-age.binary.snap @@ -0,0 +1,18 @@ + +[TestDecrypt/sopsfile.enc-age.binary - 1] +-----BEGIN RSA PRIVATE KEY----- +MIICXQIBAAKBgQDVd/OAdqlMznWINBDoyR+PESgQJlUptwnh/vzbgAaIuHl4gN7Q +W2Jx06bKFgv8yAQ4ouR0EaPv43X1pWFUyE/vK4e2A4M28Ciriy5r2TiBx57EL7bA +AiiCaEvpKx3uAtTgFYcdLdD5xYKUf51gymZ6wU8BBgYMkVlL5rpGmR7ddQIDAQAB +AoGAaeEXG+6/RmNZFHeOs4eeaZ2+21PIBerNshSBYnX7x7CIP2bcHUhWadLq9W0+ +AOFMhrL00UU2pPOTPIYM4rqAOl5PvPeV4GNMvI+9/619p/ZNMbnvj43KqUtaPp1g +JyT22CH4TqDC2io8S9xWxxh9AgvgOI/ekJ3h4PdYpmyVUXkCQQD6b1dkYhlgiy3u +Z84L5WM+7vXG2ivA3N3T5eYJdsQFvlV6gNSqbKcxIR+cFK0RaRiWrd7U2IOM67RF +YRvHNN0rAkEA2jZRXVjHjTZSuAVDMOA4cc6pgxOqByg14clWgRDtbueIMHNCYLJY +bi5YE0kqzjSaH2WbeT7LX1q3S7amoN4f3wJBALw9ZrYYmrSbyRmTQyhj8raCTZF7 +ujmMitzUyJVChVM/3uZm4fN8GivuluDuFaypj4brCDx6xl7taKJhvMx+quMCQF/C +ZoJoa2n05OgMpyfTvfFzl8AF6R+q7bpf+K47F3cL9CAO9JoqqdPwUoZkHXzQaLJO +jKPwgp8d2EJJrWX7FFECQQCRMPE4WsTCLXmVefZne7k000WPclZ4pIjggz1lpGgN +23bwNOla1k4/B10btnEzNi16/b01Kf3K4hYaicd46sLH +-----END RSA PRIVATE KEY----- +--- diff --git a/lambda/internal/sops/__snapshots__/sopsfile.enc-age.yaml.snap b/lambda/internal/sops/__snapshots__/sopsfile.enc-age.yaml.snap new file mode 100755 index 00000000..ae4a3910 --- /dev/null +++ b/lambda/internal/sops/__snapshots__/sopsfile.enc-age.yaml.snap @@ -0,0 +1,7 @@ + +[TestDecrypt/sopsfile.enc-age.yaml - 1] +key1: value1 +key2: 12345 +key3: false + +--- diff --git a/lambda/internal/sops/__snapshots__/yaml/sopsfile.enc-age.yaml.snap b/lambda/internal/sops/__snapshots__/yaml/sopsfile.enc-age.yaml.snap new file mode 100755 index 00000000..2e97dfb5 --- /dev/null +++ b/lambda/internal/sops/__snapshots__/yaml/sopsfile.enc-age.yaml.snap @@ -0,0 +1,7 @@ + +[TestDecrypt/yaml/sopsfile.enc-age.yaml - 1] +key1: value1 +key2: 12345 +key3: false + +--- diff --git a/lambda/internal/sops/sops.go b/lambda/internal/sops/sops.go new file mode 100644 index 00000000..d46e2c61 --- /dev/null +++ b/lambda/internal/sops/sops.go @@ -0,0 +1,77 @@ +package sops + +import ( + "fmt" + "log/slog" + + "github.com/getsops/sops/v3/decrypt" + "github.com/markussiebert/cdk-sops-secrets/internal/data" +) + +type Format string + +const ( + JSON Format = "json" + YAML Format = "yaml" + DOTENV Format = "dotenv" + BINARY Format = "binary" +) + +type EncryptedSopsSecret struct { + Content []byte + Format Format + Hash string +} + +func CreateEncryptedSopsSecret(content []byte, format Format, hash string) (*EncryptedSopsSecret, error) { + if len(content) == 0 { + return nil, fmt.Errorf("content cannot be empty") + } + if format == "" { + return nil, fmt.Errorf("format cannot be empty") + } + if hash == "" { + return nil, fmt.Errorf("hash cannot be empty") + } + return &EncryptedSopsSecret{ + Content: content, + Format: format, + Hash: hash, + }, nil +} + +type DecryptedSopsSecret struct { + content []byte + format Format + hash string +} + +func (e EncryptedSopsSecret) Decrypt() (*DecryptedSopsSecret, error) { + logger := slog.With("Package", "sops", "Function", "Decrypt") + logger.Info("Decrypting content", "Format", e.Format) + cleartext, err := decrypt.Data(e.Content, string(e.Format)) + if err != nil { + return nil, fmt.Errorf("decryption error:\n%v", err) + } + logger.Info("Decryption successful") + return &DecryptedSopsSecret{ + content: cleartext, + format: e.Format, + hash: e.Hash, + }, nil +} + +func (d DecryptedSopsSecret) ToData() (*data.Data, error) { + switch d.format { + case JSON: + return data.FromJSON(d.content, &d.hash) + case YAML: + return data.FromYAML(d.content, &d.hash) + case DOTENV: + return data.FromDotEnv(d.content, &d.hash) + case BINARY: + return data.FromBinary(d.content, &d.hash) + default: + return nil, fmt.Errorf("unsupported format %s", d.format) + } +} diff --git a/lambda/internal/sops/sops_test.go b/lambda/internal/sops/sops_test.go new file mode 100644 index 00000000..3a884e8e --- /dev/null +++ b/lambda/internal/sops/sops_test.go @@ -0,0 +1,150 @@ +package sops + +import ( + "fmt" + "os" + "testing" + + "github.com/gkampitakis/go-snaps/snaps" +) + +func read(filename string) ([]byte, error) { + filePath := "../../../test-secrets/" + filename + existingContent, err := os.ReadFile(filePath) + if err != nil { + return nil, err + } + return existingContent, nil +} + +func TestDecrypt(t *testing.T) { + tests := map[Format]string{ + BINARY: "sopsfile.enc-age.binary", + DOTENV: "encrypted-best-secret.env", + JSON: "sopsfile-complex.enc-age.json", + YAML: "sopsfile.enc-age.yaml", + } + + t.Setenv("SOPS_AGE_KEY", "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3") + + for format, file := range tests { + t.Run(file, func(t *testing.T) { + + content, err := read(fmt.Sprintf("%s/%s", format, file)) + + if err != nil { + t.Fatalf("Failed to read file: %v", err) + } + + encryptedSecret := EncryptedSopsSecret{ + Content: content, + Format: format, + } + + decryptedSecret, err := encryptedSecret.Decrypt() + if err != nil { + t.Fatalf("Failed to decrypt: %v", err) + } + + snaps.WithConfig( + snaps.Filename(file), + ).MatchSnapshot(t, string(decryptedSecret.content)) + }) + } +} + +func TestToData(t *testing.T) { + tests := []struct { + name string + content []byte + format Format + }{ + { + name: "Test JSON ToData", + content: []byte(`{"key": "value"}`), + format: JSON, + }, + { + name: "Test YAML ToData", + content: []byte(`key: value`), + format: YAML, + }, + { + name: "Test DotEnv ToData", + content: []byte(`KEY=value`), + format: DOTENV, + }, + { + name: "Test Binary ToData", + content: []byte{0x00, 0x01, 0x02, 0x03}, + format: BINARY, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + decryptedSecret := DecryptedSopsSecret{ + content: tt.content, + format: tt.format, + } + + data, err := decryptedSecret.ToData() + if err != nil { + t.Fatalf("Failed to convert to data: %v", err) + } + + snaps.MatchSnapshot(t, data) + }) + } +} + +func TestCreateEncryptedSopsSecret(t *testing.T) { + tests := []struct { + name string + content []byte + format Format + hash string + wantErr bool + }{ + { + name: "Valid JSON Secret", + content: []byte(`{"key": "value"}`), + format: JSON, + hash: "somehash", + wantErr: false, + }, + { + name: "Empty Content", + content: []byte{}, + format: JSON, + hash: "somehash", + wantErr: true, + }, + { + name: "Empty Format", + content: []byte(`{"key": "value"}`), + format: "", + hash: "somehash", + wantErr: true, + }, + { + name: "Empty Hash", + content: []byte(`{"key": "value"}`), + format: JSON, + hash: "", + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + encryptedSecret, err := CreateEncryptedSopsSecret(tt.content, tt.format, tt.hash) + if (err != nil) != tt.wantErr { + t.Fatalf("CreateEncryptedSopsSecret() error = %v, wantErr %v", err, tt.wantErr) + } + if err == nil { + snaps.MatchSnapshot(t, encryptedSecret) + } + }) + } +} diff --git a/lambda/main.go b/lambda/main.go index 5ab7fd30..e1e703ef 100644 --- a/lambda/main.go +++ b/lambda/main.go @@ -2,477 +2,77 @@ package main import ( "context" - "encoding/base64" - "encoding/json" "fmt" - "log" - "reflect" - "regexp" - "sort" - "strconv" - "strings" - - runtime "github.com/aws/aws-lambda-go/lambda" - "github.com/aws/aws-sdk-go/aws" - "github.com/aws/aws-sdk-go/aws/session" - "github.com/aws/aws-sdk-go/service/s3" - "github.com/aws/aws-sdk-go/service/s3/s3iface" - "github.com/aws/aws-sdk-go/service/s3/s3manager" - "github.com/aws/aws-sdk-go/service/s3/s3manager/s3manageriface" - "github.com/aws/aws-sdk-go/service/secretsmanager" - "github.com/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface" - "github.com/aws/aws-sdk-go/service/ssm" - "github.com/aws/aws-sdk-go/service/ssm/ssmiface" - "github.com/getsops/sops/v3/decrypt" - "gopkg.in/yaml.v3" + "log/slog" "github.com/aws/aws-lambda-go/cfn" + runtime "github.com/aws/aws-lambda-go/lambda" + "github.com/markussiebert/cdk-sops-secrets/internal/client" + "github.com/markussiebert/cdk-sops-secrets/internal/event" ) -type SopsS3File struct { - Bucket string `json:"Bucket,omitempty"` - Key string `json:"Key,omitempty"` -} - -type SopsInline struct { - Content string `json:"Content,omitempty"` - Hash string `json:"Hash,omitempty"` -} -type SopsSyncResourcePropertys struct { - SecretARN string `json:"SecretARN,omitempty"` - ParameterName string `json:"ParameterName,omitempty"` - EncryptionKey string `json:"EncryptionKey,omitempty"` - SopsS3File SopsS3File `json:"SopsS3File,omitempty"` - SopsInline SopsInline `json:"SopsInline,omitempty"` - Format string `json:"Format"` - ConvertToJSON string `json:"ConvertToJSON,omitempty"` - Flatten string `json:"Flatten,omitempty"` - FlattenSeparator string `json:"FlattenSeparator,omitempty"` - ParameterKeyPrefix string `json:"ParameterKeyPrefix,omitempty"` - StringifyValues string `json:"StringifyValues,omitempty"` - ResourceType string `json:"ResourceType,omitempty"` -} +func HandleRequestWithClients(clients client.AwsClient, e cfn.Event) (physicalResourceID string, data map[string]interface{}, err error) { + logger := slog.With("Package", "main", "Function", "HandleRequestWithClients") + logger.Debug("Incoming Event", "Event", e) -type AWS struct { - secretsmanager secretsmanageriface.SecretsManagerAPI - ssm ssmiface.SSMAPI - s3Downloader s3manageriface.DownloaderAPI - s3Api s3iface.S3API -} - -func (a AWS) getS3FileContent(file SopsS3File) (data []byte, err error) { - log.Printf("Downloading file '%s' from bucket '%s'\n", file.Key, file.Bucket) - buf := aws.NewWriteAtBuffer([]byte{}) - resp, err := a.s3Downloader.Download(buf, &s3.GetObjectInput{ - Bucket: &file.Bucket, - Key: &file.Key, - }) - if err != nil { - return nil, fmt.Errorf("S3 download error:\n%v", err) + // If it's a delete request, we don't have to do anything + if e.RequestType == cfn.RequestDelete { + return "", nil, nil + } + // We have to run this code only, if it is a CloudFormation Create or Update request + if e.RequestType != cfn.RequestCreate && e.RequestType != cfn.RequestUpdate { + return "", nil, fmt.Errorf("requestType '%s' not supported", e.RequestType) } - log.Printf("Downloaded %d bytes", resp) - return buf.Bytes(), nil -} -func decryptSopsFileContent(content []byte, format string) (data []byte, err error) { - log.Printf("Decrypting content with format %s\n", format) - resp, err := decrypt.Data(content, format) + props, err := event.FromCfnEvent(e) if err != nil { - return nil, fmt.Errorf("decryption error:\n%v", err) + return "", nil, err } - log.Println("Decrypted") - return resp, nil -} -func (a AWS) updateSecret(sopsHash string, secretArn string, secretContent []byte) (data *secretsmanager.PutSecretValueOutput, err error) { - secretContentString := string(secretContent) - input := &secretsmanager.PutSecretValueInput{ - SecretId: &secretArn, - SecretString: &secretContentString, - ClientRequestToken: &sopsHash, - } - secretResp, secretErr := a.secretsmanager.PutSecretValue(input) - if secretErr != nil { - return nil, fmt.Errorf("failed to store secret value:\nsecretArn: %s\nClientRequestToken: %s\n%v", secretArn, sopsHash, secretErr) - } - arn := generatePhysicalResourceId(*secretResp.ARN) - secretResp.ARN = &arn - log.Printf("Succesfully stored secret:\n%v\n", secretResp) - return secretResp, nil -} + secretEncrypted, secretEncryptedErr := props.GetEncryptedSopsSecret(clients) -func (a AWS) updateSSMParameter(parameterName string, parameterContent []byte, keyId string) (response *ssm.PutParameterOutput, err error) { - parameterContentString := string(parameterContent) - input := &ssm.PutParameterInput{ - Name: ¶meterName, - Value: ¶meterContentString, - Type: aws.String("SecureString"), - Overwrite: aws.Bool(true), - KeyId: &keyId, + if secretEncryptedErr != nil { + return "", nil, secretEncryptedErr } - paramResp, paramErr := a.ssm.PutParameter(input) - if paramErr != nil { - return nil, fmt.Errorf("failed to store parameter value:\nparameterName: %s\n%v", parameterName, paramErr) - } - log.Printf("Successfully stored parameter:\n%v\n", paramResp) - return paramResp, nil -} - -func generatePhysicalResourceId(input string) string { - re := regexp.MustCompile(`(^arn:.*:secretsmanager:|ssm:)(.*)`) - return re.ReplaceAllString(input, `arn:custom:sopssync:$2`) -} - -func (a AWS) syncSopsToSecretsmanager(ctx context.Context, event cfn.Event) (physicalResourceID string, data map[string]interface{}, err error) { - // event - // eventJson, _ := json.MarshalIndent(event, "", " ") - // log.Printf("Function invoked with:\n %s", eventJson) - - if event.RequestType == cfn.RequestCreate || event.RequestType == cfn.RequestUpdate { - // some casting - - jsonResourceProps, err := json.Marshal(event.ResourceProperties) - if err != nil { - return "error", nil, err - } - - resourceProperties := SopsSyncResourcePropertys{} - if err := json.Unmarshal(jsonResourceProps, &resourceProperties); err != nil { - return "", nil, err - } - - tempArn := generatePhysicalResourceId(resourceProperties.SecretARN + resourceProperties.ParameterName) - - sopsFile := resourceProperties.SopsS3File - sopsInline := resourceProperties.SopsInline - - var encryptedContent []byte - var sopsHash string - - // If SopsS3File is provided, we have to download this file - if sopsFile != (SopsS3File{}) { - attr, err := a.s3Api.GetObjectAttributes(&s3.GetObjectAttributesInput{ - Bucket: &sopsFile.Bucket, - Key: &sopsFile.Key, - ObjectAttributes: []*string{ - aws.String("ETag"), - }, - }) - if err != nil { - return tempArn, nil, fmt.Errorf("error while getting S3 object attributes:\n%v", err) - } - encryptedContent, err = a.getS3FileContent(sopsFile) - if err != nil { - return tempArn, nil, fmt.Errorf("error while getting S3 file content:\n%v", err) - } - if attr.ETag == nil { - return tempArn, nil, fmt.Errorf("no ETag checksum found in S3 object:\n%v", err) - } - sopsHash = *attr.ETag - } - - // If SopsInline is provided, we have to base64 decode this content - if sopsInline != (SopsInline{}) { - encryptedContent, err = base64.StdEncoding.DecodeString(sopsInline.Content) - sopsHash = sopsInline.Hash - if err != nil { - return tempArn, nil, err - } - } - if encryptedContent == nil { - return tempArn, nil, fmt.Errorf("no encrypted content found! Did you pass SopsS3File or SopsInline:\n%v", err) - } - if sopsHash == "" { - return tempArn, nil, fmt.Errorf("no sopsHash found! Did you pass SopsS3File or SopsInline:\n%v", err) - } + secretDecrypted, secretDecryptedErr := secretEncrypted.Decrypt() - decryptedContent, err := decryptSopsFileContent(encryptedContent, resourceProperties.Format) - if err != nil { - return tempArn, nil, fmt.Errorf("error while decrypting file content\n%v", err) - } - var decryptedInterface interface{} - switch resourceProperties.Format { - case "json": - { - err := json.Unmarshal(decryptedContent, &decryptedInterface) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to parse json content:\n%v", err) - } - } - case "yaml": - { - err := yaml.Unmarshal(decryptedContent, &decryptedInterface) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to parse yaml content:\n%v", err) - } - } - case "dotenv": - { - var dotEnvMap = make(map[string]string) - dotenvLines := strings.Split(string(decryptedContent), "\n") - for _, line := range dotenvLines { - if line != "" && !strings.HasPrefix(line, "#") { - parts := strings.SplitN(line, "=", 2) - if len(parts) == 2 { - key := strings.TrimSpace(parts[0]) - value := strings.TrimSpace(parts[1]) - dotEnvMap[key] = value - } - } - } - decryptedInterface = dotEnvMap - resourceProperties.Flatten = "false" - resourceProperties.StringifyValues = "false" - } - case "binary": - { - resourceProperties.Flatten = "false" - resourceProperties.StringifyValues = "false" - resourceProperties.ConvertToJSON = "false" - } - default: - return "", nil, fmt.Errorf("format %s not supported", resourceProperties.Format) - } - if resourceProperties.Flatten == "" { - resourceProperties.Flatten = "true" - } - resourcePropertiesFlatten, err := strconv.ParseBool(resourceProperties.Flatten) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to parse bool:\n%v", err) - } - - var finalInterface interface{} - - if resourcePropertiesFlatten { - flattenedInterface := make(map[string]interface{}) - err := flatten("", decryptedInterface, flattenedInterface, resourceProperties.FlattenSeparator) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to flatten:\n%v", err) - } - finalInterface = flattenedInterface - } else { - finalInterface = decryptedInterface - } - - if resourceProperties.StringifyValues == "" { - resourceProperties.StringifyValues = "true" - } - resourcePropertiesStringifyValues, err := strconv.ParseBool(resourceProperties.StringifyValues) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to parse bool:\n%v", err) - } - if resourcePropertiesStringifyValues { - finalInterface, _, err = stringifyValues(finalInterface) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to stringify values:\n%v", err) - } - } - - if resourceProperties.ConvertToJSON == "" { - resourceProperties.ConvertToJSON = "true" - } - resourcePropertieConvertToJSON, err := strconv.ParseBool(resourceProperties.ConvertToJSON) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to parse bool:\n%v", err) - } - if resourcePropertieConvertToJSON || resourceProperties.Format == "json" { - decryptedContent, err = toJSON(finalInterface) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to convert to JSON:\n%v", err) - } - } else if resourceProperties.Format == "yaml" { - decryptedContent, err = toYAML(finalInterface) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to convert to YAML:\n%v", err) - } - } - - if resourceProperties.ResourceType == "SECRET" { - updateSecretResp, err := a.updateSecret(sopsHash, resourceProperties.SecretARN, decryptedContent) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to update secret:\n%v", err) - } - returnData := make(map[string]interface{}) - returnData["ARN"] = *updateSecretResp.ARN - returnData["Name"] = *updateSecretResp.Name - returnData["VersionStages"] = updateSecretResp.VersionStages - returnData["VersionId"] = *updateSecretResp.VersionId - return *updateSecretResp.ARN, returnData, nil - } else if resourceProperties.ResourceType == "PARAMETER_MULTI" { - log.Printf("Patching multiple string parameters") - v := reflect.ValueOf(finalInterface) - returnData := make(map[string]interface{}) - keys := v.MapKeys() - keysOrder := func(i, j int) bool { return keys[i].Interface().(string) < keys[j].Interface().(string) } - sort.Slice(keys, keysOrder) - for _, key := range keys { - strKey := resourceProperties.ParameterKeyPrefix + key.String() - log.Printf("Parameter: " + strKey) - value := v.MapIndex(key).Interface() - strValue, ok := value.(string) - if !ok { - return tempArn, nil, nil - } - _, err := a.updateSSMParameter(strKey, []byte(strValue), resourceProperties.EncryptionKey) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to update ssm parameter:\n%v", err) - } - // A returnData map for each parameter is not created, because it would limit the number of possible parameters unnecessarily - } - returnData["Prefix"] = resourceProperties.ParameterKeyPrefix - returnData["Count"] = len(keys) - return tempArn, returnData, nil - } else if resourceProperties.ResourceType == "PARAMETER" { - log.Printf("Patching single string parameter") - response, err := a.updateSSMParameter(resourceProperties.ParameterName, decryptedContent, resourceProperties.EncryptionKey) - if err != nil { - return tempArn, nil, fmt.Errorf("failed to update ssm parameter:\n%v", err) - } - returnData := make(map[string]interface{}) - returnData["ParameterName"] = resourceProperties.ParameterName - returnData["Version"] = response.Version - returnData["Tier"] = response.Tier - return tempArn, returnData, nil - } else { - // Should never happen ... - return tempArn, nil, fmt.Errorf("neither SecretARN nor ParameterName is provided:\n%v", err) - } - } else if event.RequestType == cfn.RequestDelete { - return "", nil, nil - } else { - return "", nil, fmt.Errorf("requestType '%s' not supported", event.RequestType) + if secretDecryptedErr != nil { + return "", nil, secretDecryptedErr } -} -func handleRequest(ctx context.Context, event cfn.Event) (physicalResourceID string, data map[string]interface{}, err error) { - awsSession := session.New() - a := &AWS{ - secretsmanager: secretsmanager.New(awsSession), - ssm: ssm.New(awsSession), - s3Downloader: s3manager.NewDownloader(awsSession), - s3Api: s3.New(awsSession), - } - return a.syncSopsToSecretsmanager(ctx, event) -} - -func main() { - runtime.Start(cfn.LambdaWrap(handleRequest)) -} + secretDecryptedData, secretDecryptedDataErr := secretDecrypted.ToData() -func fromYAML(in []byte) (interface{}, error) { - var ret interface{} - err := yaml.Unmarshal(in, &ret) - if err != nil { - return nil, err + if secretDecryptedDataErr != nil { + return "", nil, secretDecryptedDataErr } - return ret, nil -} -func fromJSON(in []byte) (interface{}, error) { - var ret interface{} - err := json.Unmarshal(in, &ret) - if err != nil { - return nil, err + baseProps := BaseProps{ + properties: props, + clients: clients, + secretDecryptedData: secretDecryptedData, } - return ret, nil -} -func toJSON(in any) ([]byte, error) { - ret, err := json.MarshalIndent(in, "", " ") - if err != nil { - return nil, err + switch props.ResourceType { + case event.SECRET, event.SECRET_BINARY: + return handleSecret(baseProps) + case event.PARAMETER_MULTI: + return handleParameterMulti(baseProps) + case event.PARAMETER: + return handleParameter(baseProps) + default: + return "", nil, fmt.Errorf("unsupported resource type %s", props.ResourceType) } - return ret, nil } -func toYAML(in any) ([]byte, error) { - ret, err := yaml.Marshal(in) - if err != nil { - return nil, err - } - return ret, nil -} +// Just a Wrapper function to allow injecting clients for testing +func HandleRequest(ctx context.Context, event cfn.Event) (physicalResourceID string, data map[string]interface{}, err error) { -func stringifyValues(input any) (interface{}, string, error) { - switch child := input.(type) { - case map[string]interface{}: - { - output := make(map[string]interface{}) - for k, v := range child { - object, val, err := stringifyValues(v) - if err != nil { - return nil, "", err - } - if object != nil { - output[k] = object - } else { - output[k] = val - } - } - return output, "", nil - } - case []interface{}: - { - output := []interface{}{} - for _, v := range child { - object, val, err := stringifyValues(v) - if err != nil { - return nil, "", err - } - if object != nil { - output = append(output, object) - } else { - output = append(output, val) - } - } - return output, "", nil - } - default: - { - return nil, fmt.Sprint(input), nil - } - } -} + clients := client.CreateAwsClients(ctx) -func flatten(parentkey string, input any, output map[string]interface{}, separator string) error { - switch child := input.(type) { - case map[string]interface{}: - { - for k, v := range child { - if parentkey == "" { - flatten(k, v, output, separator) - } else { - flatten(fmt.Sprintf("%s%s%s", parentkey, separator, k), v, output, separator) - } - } - } - case []interface{}: - { - for i, v := range child { - if parentkey == "" { - flatten(fmt.Sprintf("[%d]", i), v, output, separator) - } else { - flatten(fmt.Sprintf("%s[%d]", parentkey, i), v, output, separator) - } - } - } - default: - { - output[parentkey] = input - } - } - return nil + return HandleRequestWithClients(clients, event) } -func toSopsSyncResourcePropertys(input *map[string]interface{}) (*SopsSyncResourcePropertys, error) { - jsonResourceProps, err := json.Marshal(&input) - if err != nil { - return nil, err - } - resourceProperties := SopsSyncResourcePropertys{} - if err := json.Unmarshal(jsonResourceProps, &resourceProperties); err != nil { - return nil, err - } - return &resourceProperties, nil +func main() { + runtime.Start(cfn.LambdaWrap(HandleRequest)) } diff --git a/lambda/main_integration_test.go b/lambda/main_integration_test.go new file mode 100644 index 00000000..28e9bf44 --- /dev/null +++ b/lambda/main_integration_test.go @@ -0,0 +1,242 @@ +package main + +import ( + "context" + "encoding/json" + "os" + "strings" + "testing" + "time" + + "github.com/aws/aws-lambda-go/cfn" + "github.com/aws/aws-sdk-go-v2/config" + "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager" + "github.com/aws/aws-sdk-go-v2/service/ssm" + "github.com/markussiebert/cdk-sops-secrets/internal/client" + "github.com/stretchr/testify/assert" +) + +func prepareUploadS3(t *testing.T, resourceProps map[string]interface{}) { + cfg, err := config.LoadDefaultConfig(context.Background()) + + if err != nil { + t.Errorf("unable to load SDK config, %v", err) + } + + sopsS3File := resourceProps["SopsS3File"].(map[string]interface{}) + + s3Key := sopsS3File["Key"].(string) + s3Bucket := sopsS3File["Bucket"].(string) + localFile := "../" + s3Key + + file, err := os.Open(localFile) + if err != nil { + t.Errorf("failed to open file: %v", err) + } + defer file.Close() + + s3Client := s3.NewFromConfig(cfg) + _, err = s3Client.PutObject(context.Background(), &s3.PutObjectInput{ + Bucket: &s3Bucket, + Key: &s3Key, + Body: file, + }) + + if err != nil { + t.Errorf("failed to upload file to S3: %v", err) + } +} + +func prepareSecret(t *testing.T, resourceProps map[string]interface{}) { + cfg, err := config.LoadDefaultConfig(context.Background()) + if err != nil { + t.Errorf("unable to load SDK config, %v", err) + } + + secretsManagerClient := secretsmanager.NewFromConfig(cfg) + + secretName := resourceProps["Target"].(string) + ResourceType := resourceProps["ResourceType"].(string) + + if ResourceType != "SECRET" && ResourceType != "SECRET_BINARY" { + return + } + + secretValue := "empty" + + _, err = secretsManagerClient.CreateSecret(context.Background(), &secretsmanager.CreateSecretInput{ + Name: &secretName, + SecretString: &secretValue, + }) + + if err != nil { + t.Logf("failed to create secret: %v", err) + } +} + +func cleanupSecret(t *testing.T, resourceProps map[string]interface{}) { + + cfg, err := config.LoadDefaultConfig(context.Background()) + if err != nil { + t.Errorf("unable to load SDK config, %v", err) + } + + secretsManagerClient := secretsmanager.NewFromConfig(cfg) + + secretName := resourceProps["Target"].(string) + ResourceType := resourceProps["ResourceType"].(string) + + if ResourceType != "SECRET" && ResourceType != "SECRET_BINARY" { + return + } + + forceDelete := true + + _, err = secretsManagerClient.DeleteSecret(context.Background(), &secretsmanager.DeleteSecretInput{ + SecretId: &secretName, + ForceDeleteWithoutRecovery: &forceDelete, + }) + + if err != nil { + t.Logf("failed to delete secret: %v", err) + } +} + +func cleanupParameter(t *testing.T, resourceProps map[string]interface{}) { + cfg, err := config.LoadDefaultConfig(context.Background()) + if err != nil { + t.Errorf("unable to load SDK config, %v", err) + } + + ssmClient := ssm.NewFromConfig(cfg) + parameterNames := []string{} + parameterName := resourceProps["Target"].(string) + ResourceType := resourceProps["ResourceType"].(string) + + if ResourceType == "PARAMETER_MULTI" { + input := &ssm.DescribeParametersInput{} + for { + output, err := ssmClient.DescribeParameters(context.Background(), input) + if err != nil { + t.Errorf("failed to describe parameters: %v", err) + return + } + for _, param := range output.Parameters { + if strings.HasPrefix(*param.Name, parameterName) { + parameterNames = append(parameterNames, *param.Name) + } + } + if output.NextToken == nil { + break + } + input.NextToken = output.NextToken + } + } else if ResourceType == "PARAMETER" { + parameterNames = append(parameterNames, parameterName) + } else { + t.Logf("unknown resource type: %s", ResourceType) + return + } + + for _, p := range parameterNames { + t.Logf("deleting parameter %s", p) + _, err = ssmClient.DeleteParameter(context.Background(), &ssm.DeleteParameterInput{ + Name: &p, + }) + if err != nil { + t.Logf("failed to delete parameter: %v", err) + } + } +} + +func TestIntegration_HandleRequestWithClients(t *testing.T) { + t.Logf("Running at: %s", time.Now().String()) // Forces re-run + os.Setenv("AWS_REGION", "eu-central-1") + os.Setenv("SOPS_AGE_KEY", "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3") + files, err := os.ReadDir("events") + if err != nil { + t.Fatalf("failed to read events directory: %v", err) + } + + var tests []struct { + name string + event cfn.Event + } + + for _, file := range files { + if file.IsDir() { + continue + } + + content, err := os.ReadFile("events/" + file.Name()) + if err != nil { + t.Fatalf("failed to read file %s: %v", file.Name(), err) + } + + var resourceProperties map[string]interface{} + if err := json.Unmarshal(content, &resourceProperties); err != nil { + t.Fatalf("failed to unmarshal JSON from file %s: %v", file.Name(), err) + } + + tests = append(tests, struct { + name string + event cfn.Event + }{ + name: file.Name(), + event: cfn.Event{ + RequestType: cfn.RequestCreate, + ResourceProperties: resourceProperties, + }, + }) + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + + prepareUploadS3(t, tt.event.ResourceProperties) + prepareSecret(t, tt.event.ResourceProperties) + + clients := client.CreateAwsClients(context.Background()) + + physicalResourceID, data, err := HandleRequestWithClients(clients, tt.event) + + assert.NoError(t, err) + assert.NotEmpty(t, physicalResourceID) + assert.NotNil(t, data) + }) + } +} + +func TestIntegration_Cleanup(t *testing.T) { + t.Logf("Running at: %s", time.Now().String()) // Forces re-run + os.Setenv("AWS_REGION", "eu-central-1") + + files, err := os.ReadDir("events") + if err != nil { + t.Fatalf("failed to read events directory: %v", err) + } + + for _, file := range files { + if file.IsDir() { + continue + } + + content, err := os.ReadFile("events/" + file.Name()) + if err != nil { + t.Fatalf("failed to read file %s: %v", file.Name(), err) + } + + var resourceProperties map[string]interface{} + if err := json.Unmarshal(content, &resourceProperties); err != nil { + t.Fatalf("failed to unmarshal JSON from file %s: %v", file.Name(), err) + } + + t.Run(file.Name(), func(t *testing.T) { + + cleanupSecret(t, resourceProperties) + cleanupParameter(t, resourceProperties) + + }) + } +} diff --git a/lambda/main_test.go b/lambda/main_test.go index d9ffd4a8..cd136c7b 100644 --- a/lambda/main_test.go +++ b/lambda/main_test.go @@ -1,73 +1,122 @@ package main import ( + "encoding/json" "os" "testing" + "time" + "github.com/aws/aws-lambda-go/cfn" + "github.com/aws/aws-sdk-go-v2/service/secretsmanager" + "github.com/aws/aws-sdk-go-v2/service/ssm" "github.com/gkampitakis/go-snaps/snaps" - "github.com/go-test/deep" + "github.com/markussiebert/cdk-sops-secrets/internal/client" + "github.com/stretchr/testify/assert" ) -func TestMain(t *testing.M) { - - //log.SetOutput(ioutil.Discard) - - v := t.Run() - // After all tests have run `go-snaps` can check for not used snapshots - snaps.Clean(t) - - os.Exit(v) +type putParameterCalls map[string]interface{} +type putSecretValueCalls map[string]interface{} +type getObjectEtagCalls map[string]client.SopsS3File +type getObjectCalls map[string]client.SopsS3File +type MockAwsClient struct { + snapsFileName string + t *testing.T + putParameter putParameterCalls + putSecretValue putSecretValueCalls + getObjectEtag getObjectEtagCalls + getObject getObjectCalls } -func Test_GetS3FileContent(t *testing.T) { - mocks := getMocks(t) - data, err := mocks.getS3FileContent(SopsS3File{ - Bucket: "..", - Key: "../test-secrets/json/sopsfile.enc-age.json", - }) - check(err) - snaps.MatchSnapshot(t, string(data)) +func (m *MockAwsClient) S3GetObject(file client.SopsS3File) ([]byte, error) { + m.getObject[file.Key] = file + localFile := "../" + file.Key + content, err := os.ReadFile(localFile) + if err != nil { + return nil, err + } + return content, nil } -func Test_UpdateSecret(t *testing.T) { - mocks := getMocks(t) - fileName := "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2.yaml" - inputArn := "arn:${Partition}:secretsmanager:${Region}:${Account}:secret:${SecretId}" - secretValue := []byte("some-secret-data") - - response, err := mocks.updateSecret(fileName, inputArn, secretValue) - check(err) - - snaps.MatchSnapshot(t, response) +func (m *MockAwsClient) S3GetObjectETAG(file client.SopsS3File) (*string, error) { + etag := "mock-etag" + m.getObjectEtag[file.Key] = file + return &etag, nil } -func Test_UpdateSSMParameter(t *testing.T) { - mocks := getMocks(t) - - paramterName := "/foo/bar" - parameterValue := []byte("some-secret-data") - - response, err := mocks.updateSSMParameter(paramterName, parameterValue, "key") - check(err) - - snaps.MatchSnapshot(t, response) +func (m *MockAwsClient) SecretsManagerPutSecretValue(sopsHash string, secretArn string, secretContent *[]byte) (*secretsmanager.PutSecretValueOutput, error) { + m.putSecretValue[secretArn] = map[string]interface{}{"sopsHash": sopsHash, "secretContent": string(*secretContent)} + arn := "mock-arn" + return &secretsmanager.PutSecretValueOutput{ + ARN: &arn, + Name: &secretArn, + VersionStages: []string{"mock-version-stage"}, + VersionId: &sopsHash, + }, nil } -func Test_DecryptSopsFileContent(t *testing.T) { +func (m *MockAwsClient) SsmPutParameter(parameterName string, parameterContent *[]byte, keyId string) (*ssm.PutParameterOutput, error) { + m.putParameter[parameterName] = map[string]interface{}{"parameterContent": string(*parameterContent), "keyId": keyId} + return &ssm.PutParameterOutput{Version: 1}, nil +} +func TestHandleRequestWithClients(t *testing.T) { + t.Logf("Running at: %s", time.Now().String()) // Forces re-run + os.Setenv("AWS_REGION", "eu-central-1") os.Setenv("SOPS_AGE_KEY", "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3") + files, err := os.ReadDir("events") + if err != nil { + t.Fatalf("failed to read events directory: %v", err) + } - sopsEncrypted, err := os.ReadFile("../test-secrets/json/sopsfile.enc-age.json") - check(err) - sopsDecrypted, err := decryptSopsFileContent(sopsEncrypted, "json") - check(err) - sopsExpected, err := os.ReadFile("../test-secrets/json/sopsfile.json") - check(err) + var tests []struct { + name string + event cfn.Event + } - sopsDecryptedJ := UnmarshalAny(sopsDecrypted) - sopsExpectedJ := UnmarshalAny(sopsExpected) + for _, file := range files { + if file.IsDir() { + continue + } + + content, err := os.ReadFile("events/" + file.Name()) + if err != nil { + t.Fatalf("failed to read file %s: %v", file.Name(), err) + } + + var resourceProperties map[string]interface{} + if err := json.Unmarshal(content, &resourceProperties); err != nil { + t.Fatalf("failed to unmarshal JSON from file %s: %v", file.Name(), err) + } + + tests = append(tests, struct { + name string + event cfn.Event + }{ + name: file.Name(), + event: cfn.Event{ + RequestType: cfn.RequestCreate, + ResourceProperties: resourceProperties, + }, + }) + } - if diff := deep.Equal(sopsDecryptedJ, sopsExpectedJ); diff != nil { - t.Error(diff) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + clients := &MockAwsClient{ + snapsFileName: tt.name, + t: t, + putParameter: putParameterCalls{}, + putSecretValue: putSecretValueCalls{}, + getObjectEtag: getObjectEtagCalls{}, + getObject: getObjectCalls{}, + } + + physicalResourceID, data, err := HandleRequestWithClients(clients, tt.event) + snaps.WithConfig(snaps.Filename(tt.name)).MatchSnapshot(t, clients.getObject, clients.getObjectEtag, clients.putParameter, clients.putSecretValue) + + assert.NoError(t, err) + assert.NotEmpty(t, physicalResourceID) + assert.NotNil(t, data) + }) } } diff --git a/lambda/mocks.go b/lambda/mocks.go deleted file mode 100644 index 15ed7bd8..00000000 --- a/lambda/mocks.go +++ /dev/null @@ -1,181 +0,0 @@ -package main - -import ( - "crypto/sha256" - "fmt" - "io" - "testing" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go/service/ssm" - "github.com/aws/aws-sdk-go/service/ssm/ssmiface" - - "github.com/aws/aws-sdk-go/service/s3" - "github.com/aws/aws-sdk-go/service/s3/s3iface" - "github.com/aws/aws-sdk-go/service/s3/s3manager" - "github.com/aws/aws-sdk-go/service/s3/s3manager/s3manageriface" - "github.com/aws/aws-sdk-go/service/secretsmanager" - "github.com/aws/aws-sdk-go/service/secretsmanager/secretsmanageriface" - "github.com/gkampitakis/go-snaps/snaps" -) - -type SecretsManagerMockClient struct { - secretsmanageriface.SecretsManagerAPI - t *testing.T -} - -type PutSecretValueInputNotSecure struct { - - // A unique identifier for the new version of the secret. - // - // If you use the Amazon Web Services CLI or one of the Amazon Web Services - // SDKs to call this operation, then you can leave this parameter empty. The - // CLI or SDK generates a random UUID for you and includes it as the value for - // this parameter in the request. - // - // If you generate a raw HTTP request to the Secrets Manager service endpoint, - // then you must generate a ClientRequestToken and include it in the request. - // - // This value helps ensure idempotency. Secrets Manager uses this value to prevent - // the accidental creation of duplicate versions if there are failures and retries - // during a rotation. We recommend that you generate a UUID-type (https://wikipedia.org/wiki/Universally_unique_identifier) - // value to ensure uniqueness of your versions within the specified secret. - // - // * If the ClientRequestToken value isn't already associated with a version - // of the secret then a new version of the secret is created. - // - // * If a version with this value already exists and that version's SecretString - // or SecretBinary values are the same as those in the request then the request - // is ignored. The operation is idempotent. - // - // * If a version with this value already exists and the version of the SecretString - // and SecretBinary values are different from those in the request, then - // the request fails because you can't modify a secret version. You can only - // create new versions to store new secret values. - // - // This value becomes the VersionId of the new version. - ClientRequestToken *string `min:"32" type:"string" idempotencyToken:"true"` - - // The binary data to encrypt and store in the new version of the secret. To - // use this parameter in the command-line tools, we recommend that you store - // your binary data in a file and then pass the contents of the file as a parameter. - // - // You must include SecretBinary or SecretString, but not both. - // - // You can't access this value from the Secrets Manager console. - // - // SecretBinary is a sensitive parameter and its value will be - // replaced with "sensitive" in string returned by PutSecretValueInput's - // String and GoString methods. - // - // SecretBinary is automatically base64 encoded/decoded by the SDK. - SecretBinary []byte `min:"1" type:"blob"` - - // The ARN or name of the secret to add a new version to. - // - // For an ARN, we recommend that you specify a complete ARN rather than a partial - // ARN. See Finding a secret from a partial ARN (https://docs.aws.amazon.com/secretsmanager/latest/userguide/troubleshoot.html#ARN_secretnamehyphen). - // - // If the secret doesn't already exist, use CreateSecret instead. - // - // SecretId is a required field - SecretId *string `min:"1" type:"string" required:"true"` - - // The text to encrypt and store in the new version of the secret. - // - // You must include SecretBinary or SecretString, but not both. - // - // We recommend you create the secret string as JSON key/value pairs, as shown - // in the example. - // - // SecretString is a sensitive parameter and its value will be - // replaced with "sensitive" in string returned by PutSecretValueInput's - // String and GoString methods. - SecretString *string `min:"1" type:"string"` - - // A list of staging labels to attach to this version of the secret. Secrets - // Manager uses staging labels to track versions of a secret through the rotation - // process. - // - // If you specify a staging label that's already associated with a different - // version of the same secret, then Secrets Manager removes the label from the - // other version and attaches it to this version. If you specify AWSCURRENT, - // and it is already attached to another version, then Secrets Manager also - // moves the staging label AWSPREVIOUS to the version that AWSCURRENT was removed - // from. - // - // If you don't include VersionStages, then Secrets Manager automatically moves - // the staging label AWSCURRENT to this version. - VersionStages []*string `min:"1" type:"list"` -} - -type putSecretValueInputNotSecure secretsmanager.PutSecretValueInput - -func (m *SecretsManagerMockClient) PutSecretValue(input *secretsmanager.PutSecretValueInput) (*secretsmanager.PutSecretValueOutput, error) { - versionId := fmt.Sprintf("%x", sha256.Sum256([]byte(*input.SecretString))) - - snaps.MatchSnapshot(m.t, ">>>SecretsManagerMockClient.PutSecretValue.Input", putSecretValueInputNotSecure(*input)) - - name := fmt.Sprintf("%x", sha256.Sum256([]byte(*input.SecretId))) - - return &secretsmanager.PutSecretValueOutput{ - ARN: input.SecretId, - Name: &name, - VersionStages: []*string{&name}, - VersionId: &versionId, - }, nil -} - -type S3ManagerMockClient struct { - s3manageriface.DownloaderAPI - t *testing.T -} - -func (d S3ManagerMockClient) Download(w io.WriterAt, input *s3.GetObjectInput, options ...func(*s3manager.Downloader)) (n int64, err error) { - dat := ReadFile(*input.Key) - snaps.MatchSnapshot(d.t, ">>>S3MAnagerMockClient.Download.Input", input) - _, err = w.WriteAt(dat, int64(0)) - check(err) - return int64(len(dat)), err -} - -type MockSSMClient struct { - ssmiface.SSMAPI - t *testing.T -} - -type putParameterValueInputNotSecure ssm.PutParameterInput - -func (m *MockSSMClient) PutParameter(input *ssm.PutParameterInput) (*ssm.PutParameterOutput, error) { - snaps.MatchSnapshot(m.t, ">>>SecretsManagerMockClient.PutParameterValue.Input", putParameterValueInputNotSecure(*input)) - - var version int64 - version = 1 - - tier := ssm.ParameterTierStandard - return &ssm.PutParameterOutput{ - Tier: &tier, - Version: &version, - }, nil -} - -type MocksS3Api struct { - s3iface.S3API - t *testing.T -} - -func (m *MocksS3Api) GetObjectAttributes(input *s3.GetObjectAttributesInput) (*s3.GetObjectAttributesOutput, error) { - snaps.MatchSnapshot(m.t, ">>>S3ApiMockClient.GetObjectAttributes.Input", *input) - - return &s3.GetObjectAttributesOutput{ - Checksum: nil, - DeleteMarker: nil, - ETag: aws.String("some-32-character-long-string-ab"), - LastModified: nil, - ObjectParts: nil, - ObjectSize: nil, - RequestCharged: nil, - StorageClass: nil, - VersionId: nil, - }, nil -} diff --git a/lambda/testhelper.go b/lambda/testhelper.go deleted file mode 100644 index 99f04f57..00000000 --- a/lambda/testhelper.go +++ /dev/null @@ -1,92 +0,0 @@ -package main - -import ( - "context" - "encoding/base64" - "encoding/json" - "io/ioutil" - "os" - "testing" - "time" - - "github.com/aws/aws-lambda-go/cfn" - "github.com/aws/aws-lambda-go/lambdacontext" -) - -func check(e error) { - if e != nil { - panic(e) - } -} - -func UnmarshalAny(input []byte) map[string]interface{} { - var returnValue map[string]interface{} - err := json.Unmarshal(input, &returnValue) - check(err) - return returnValue -} - -func ReadFile(path string) []byte { - ret, err := os.ReadFile(path) - check(err) - return ret -} - -func ReadJSONFromFile(t *testing.T, inputFile string) []byte { - inputJSON, err := ioutil.ReadFile(inputFile) - if err != nil { - t.Errorf("could not open test file. details: %v", err) - } - - return inputJSON -} - -func base64FromFile(file string) string { - inputData, err := ioutil.ReadFile(file) - check(err) - return base64.StdEncoding.EncodeToString(inputData) -} - -func fileToInline(event cfn.Event) cfn.Event { - sopsProps, err := toSopsSyncResourcePropertys(&event.ResourceProperties) - check(err) - - inlineProps := SopsInline{ - Content: base64FromFile(sopsProps.SopsS3File.Key), - Hash: "MyHash", - } - event.ResourceProperties["SopsInline"] = inlineProps - delete(event.ResourceProperties, "SopsS3File") - return event -} -func getMocks(t *testing.T) *AWS { - return &AWS{ - secretsmanager: &SecretsManagerMockClient{ - t: t, - }, - s3Downloader: &S3ManagerMockClient{ - t: t, - }, - ssm: &MockSSMClient{ - t: t, - }, - s3Api: &MocksS3Api{ - t: t, - }, - } -} -func prepareHandler(t *testing.T, eventFile string) (*AWS, context.Context, cfn.Event) { - os.Setenv("SOPS_AGE_KEY", "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3") - mocks := getMocks(t) - d := time.Now().Add(50 * time.Millisecond) - ctx, _ := context.WithDeadline(context.Background(), d) - ctx = lambdacontext.NewContext(ctx, &lambdacontext.LambdaContext{ - AwsRequestID: "AwsRequestID", - InvokedFunctionArn: "arn:aws:lambda:us-east-2:123456789012:function:cdk-sops-secrets", - }) - inputJson := ReadJSONFromFile(t, eventFile) - var event cfn.Event - err := json.Unmarshal(inputJson, &event) - check(err) - return mocks, ctx, event -} diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 11885db3..00000000 --- a/package-lock.json +++ /dev/null @@ -1,11335 +0,0 @@ -{ - "name": "cdk-sops-secrets", - "version": "0.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "cdk-sops-secrets", - "version": "0.0.0", - "bundleDependencies": [ - "yaml" - ], - "license": "Apache-2.0", - "dependencies": { - "yaml": "^2.5.0" - }, - "devDependencies": { - "@types/jest": "^27", - "@types/node": "^16 <= 16.18.78", - "@typescript-eslint/eslint-plugin": "^7", - "@typescript-eslint/parser": "^7", - "aws-cdk": "^2", - "aws-cdk-lib": "2.144.0", - "commit-and-tag-version": "^12", - "constructs": "10.0.5", - "eslint": "^8", - "eslint-config-prettier": "^8.10.0", - "eslint-import-resolver-typescript": "^2.7.1", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-prettier": "^4.2.1", - "jest": "^27", - "jest-junit": "^15", - "jsii": "1.x", - "jsii-diff": "^1.103.1", - "jsii-docgen": "^10.5.0", - "jsii-pacmak": "^1.103.1", - "jsii-rosetta": "1.x", - "prettier": "^2.8.8", - "projen": "^0.88.1", - "ts-jest": "^27", - "ts-node": "^10.9.2", - "typescript": "^4.9.5" - }, - "peerDependencies": { - "aws-cdk-lib": "^2.144.0", - "constructs": "^10.0.5" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@aws-cdk/asset-awscli-v1": { - "version": "2.2.202", - "resolved": "https://registry.npmjs.org/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.202.tgz", - "integrity": "sha512-JqlF0D4+EVugnG5dAsNZMqhu3HW7ehOXm5SDMxMbXNDMdsF0pxtQKNHRl52z1U9igsHmaFpUgSGjbhAJ+0JONg==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/@aws-cdk/asset-kubectl-v20": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@aws-cdk/asset-kubectl-v20/-/asset-kubectl-v20-2.1.2.tgz", - "integrity": "sha512-3M2tELJOxQv0apCIiuKQ4pAbncz9GuLwnKFqxifWfe77wuMxyTRPmxssYHs42ePqzap1LT6GDcPygGs+hHstLg==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/@aws-cdk/asset-node-proxy-agent-v6": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@aws-cdk/asset-node-proxy-agent-v6/-/asset-node-proxy-agent-v6-2.0.3.tgz", - "integrity": "sha512-twhuEG+JPOYCYPx/xy5uH2+VUsIEhPTzDY0F1KuB+ocjWWB/KEDiOVL19nHvbPCB6fhWnkykXEMJ4HHcKvjtvg==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/@babel/code-frame": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", - "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/highlight": "^7.24.7", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.24.9", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.24.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.9", - "@babel/helper-compilation-targets": "^7.24.8", - "@babel/helper-module-transforms": "^7.24.9", - "@babel/helpers": "^7.24.8", - "@babel/parser": "^7.24.8", - "@babel/template": "^7.24.7", - "@babel/traverse": "^7.24.8", - "@babel/types": "^7.24.9", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.24.10", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.9", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.24.8", - "@babel/helper-validator-option": "^7.24.8", - "browserslist": "^4.23.1", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "license": "ISC" - }, - "node_modules/@babel/helper-environment-visitor": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-function-name": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-hoist-variables": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", - "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.24.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-module-imports": "^7.24.7", - "@babel/helper-simple-access": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/helper-validator-identifier": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz", - "integrity": "sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", - "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-split-export-declaration": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz", - "integrity": "sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", - "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.24.8", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz", - "integrity": "sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.24.7", - "@babel/types": "^7.24.8" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.24.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", - "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.24.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/template": { - "version": "7.24.7", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/parser": "^7.24.7", - "@babel/types": "^7.24.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.24.8", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.24.7", - "@babel/generator": "^7.24.8", - "@babel/helper-environment-visitor": "^7.24.7", - "@babel/helper-function-name": "^7.24.7", - "@babel/helper-hoist-variables": "^7.24.7", - "@babel/helper-split-export-declaration": "^7.24.7", - "@babel/parser": "^7.24.8", - "@babel/types": "^7.24.8", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/types": { - "version": "7.24.9", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.24.8", - "@babel/helper-validator-identifier": "^7.24.7", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.0.tgz", - "integrity": "sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@hutson/parse-repository-url": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", - "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", - "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/console/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@jest/core": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", - "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/reporters": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^27.5.1", - "jest-config": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-resolve-dependencies": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "jest-watcher": "^27.5.1", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/core/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/environment/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/fake-timers/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@jest/globals": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", - "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/types": "^27.5.1", - "expect": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", - "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-haste-map": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/reporters/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@jest/source-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", - "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9", - "source-map": "^0.6.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/test-result": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", - "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", - "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", - "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.5.1", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-util": "^27.5.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/types/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@jsii/check-node": { - "version": "1.103.1", - "resolved": "https://registry.npmjs.org/@jsii/check-node/-/check-node-1.103.1.tgz", - "integrity": "sha512-Vi6ONm5WXEim98a2DJ6WMlrP/w5AGzXrrQBpGcfVV7cu86DPx1L0OAZnqzGAJE8ly0VfcSXkmxJ9LFcn3jylBQ==", - "dev": true, - "dependencies": { - "chalk": "^4.1.2", - "semver": "^7.6.3" - }, - "engines": { - "node": ">= 14.17.0" - } - }, - "node_modules/@jsii/spec": { - "version": "1.103.1", - "resolved": "https://registry.npmjs.org/@jsii/spec/-/spec-1.103.1.tgz", - "integrity": "sha512-14OGYM3DjEBjUOUaih+bwPgkhFnR8L9TSNSM0oE0L0hjWscTapvClqOgMDJ1ID52qkROCAgKl1d71Vmm4v0Buw==", - "dev": true, - "dependencies": { - "ajv": "^8.17.1" - }, - "engines": { - "node": ">= 14.17.0" - } - }, - "node_modules/@jsii/spec/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@jsii/spec/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@sinonjs/commons": { - "version": "1.8.6", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", - "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", - "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.3.0" - } - }, - "node_modules/@types/graceful-fs": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", - "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/graceful-fs/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", - "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", - "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "27.5.2", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.5.2.tgz", - "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-matcher-utils": "^27.0.0", - "pretty-format": "^27.0.0" - } - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "16.18.78", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.78.tgz", - "integrity": "sha512-2poPMDdsGfvhcLmgJZ85QrIfN6z3PijYRMiV0FWIEUiQW/t/lzH7BEm4vN+HMhjZXbtIKssMcAxTcgu4Rm83YA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/prettier": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.0.tgz", - "integrity": "sha512-G/AdOadiZhnJp0jXCaBQU449W2h716OW/EoXeYkCytxKL06X1WCXB4DZpp8TpZ8eyIJVS1cw4lrlkkSYU21cDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/stack-utils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", - "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/yargs": { - "version": "16.0.9", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.9.tgz", - "integrity": "sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.3", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", - "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.17.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/type-utils": "7.17.0", - "@typescript-eslint/utils": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "7.17.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/typescript-estree": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "7.17.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "7.17.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "7.17.0", - "@typescript-eslint/utils": "7.17.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "7.17.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.17.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/visitor-keys": "7.17.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "7.17.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.17.0", - "@typescript-eslint/types": "7.17.0", - "@typescript-eslint/typescript-estree": "7.17.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.17.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.17.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/@xmldom/xmldom": { - "version": "0.8.10", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.10.tgz", - "integrity": "sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-globals/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals/node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.3", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.3.tgz", - "integrity": "sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/add-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", - "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, - "license": "MIT" - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-ify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", - "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", - "dev": true, - "license": "MIT" - }, - "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/aws-cdk": { - "version": "2.150.0", - "dev": true, - "license": "Apache-2.0", - "bin": { - "cdk": "bin/cdk" - }, - "engines": { - "node": ">= 14.15.0" - }, - "optionalDependencies": { - "fsevents": "2.3.2" - } - }, - "node_modules/aws-cdk-lib": { - "version": "2.144.0", - "resolved": "https://registry.npmjs.org/aws-cdk-lib/-/aws-cdk-lib-2.144.0.tgz", - "integrity": "sha512-DpyIyTs8NHX6WgAyYM2mGorirIk+eTjWzXGQRfzAe40qkwcqsb5Ax4JEl5gz1OEo9QIJIgWDtmImgWN0tUbILA==", - "bundleDependencies": [ - "@balena/dockerignore", - "case", - "fs-extra", - "ignore", - "jsonschema", - "minimatch", - "punycode", - "semver", - "table", - "yaml", - "mime-types" - ], - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@aws-cdk/asset-awscli-v1": "^2.2.202", - "@aws-cdk/asset-kubectl-v20": "^2.1.2", - "@aws-cdk/asset-node-proxy-agent-v6": "^2.0.3", - "@balena/dockerignore": "^1.0.2", - "case": "1.6.3", - "fs-extra": "^11.2.0", - "ignore": "^5.3.1", - "jsonschema": "^1.4.1", - "mime-types": "^2.1.35", - "minimatch": "^3.1.2", - "punycode": "^2.3.1", - "semver": "^7.6.0", - "table": "^6.8.2", - "yaml": "1.10.2" - }, - "engines": { - "node": ">= 14.15.0" - }, - "peerDependencies": { - "constructs": "^10.0.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/@balena/dockerignore": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@balena/dockerignore/-/dockerignore-1.0.2.tgz", - "integrity": "sha512-wMue2Sy4GAVTk6Ic4tJVcnfdau+gx2EnG7S+uAEe+TWJFqE4YoWN4/H8MSLj4eYJKxGg26lZwboEniNiNwZQ6Q==", - "dev": true, - "inBundle": true, - "license": "Apache-2.0" - }, - "node_modules/aws-cdk-lib/node_modules/ajv": { - "version": "8.13.0", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.4.1" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/aws-cdk-lib/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/aws-cdk-lib/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/aws-cdk-lib/node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/aws-cdk-lib/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/aws-cdk-lib/node_modules/case": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/case/-/case-1.6.3.tgz", - "integrity": "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==", - "dev": true, - "inBundle": true, - "license": "(MIT OR GPL-3.0-or-later)", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/aws-cdk-lib/node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/aws-cdk-lib/node_modules/ignore": { - "version": "5.3.1", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/aws-cdk-lib/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/aws-cdk-lib/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/aws-cdk-lib/node_modules/jsonschema": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.4.1.tgz", - "integrity": "sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/aws-cdk-lib/node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/aws-cdk-lib/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/aws-cdk-lib/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/aws-cdk-lib/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/aws-cdk-lib/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/aws-cdk-lib/node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/aws-cdk-lib/node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/semver": { - "version": "7.6.0", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/aws-cdk-lib/node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/aws-cdk-lib/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/aws-cdk-lib/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/aws-cdk-lib/node_modules/table": { - "version": "6.8.2", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", - "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", - "dev": true, - "inBundle": true, - "license": "BSD-3-Clause", - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/uri-js": { - "version": "4.4.1", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/aws-cdk-lib/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/aws-cdk-lib/node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, - "node_modules/babel-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", - "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", - "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/babel-preset-current-node-syntax": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", - "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", - "dev": true, - "license": "MIT", - "dependencies": { - "babel-plugin-jest-hoist": "^27.5.1", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/browserslist": { - "version": "4.23.2", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001640", - "electron-to-chromium": "^1.4.820", - "node-releases": "^2.0.14", - "update-browserslist-db": "^1.1.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/camelcase-keys/node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001643", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/case": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/case/-/case-1.6.3.tgz", - "integrity": "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==", - "dev": true, - "license": "(MIT OR GPL-3.0-or-later)", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/cjs-module-lexer": { - "version": "1.3.1", - "dev": true, - "license": "MIT" - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/codemaker": { - "version": "1.103.1", - "resolved": "https://registry.npmjs.org/codemaker/-/codemaker-1.103.1.tgz", - "integrity": "sha512-y3Ru0bZV6qiuPAt8c/Hik1dCI0dVb6lj/6gAIWckvNYVu5FS51avr3FU/mRtuPrY3b1bW/EA0pszGB/P54Bl5A==", - "dev": true, - "dependencies": { - "camelcase": "^6.3.0", - "decamelize": "^5.0.1", - "fs-extra": "^10.1.0" - }, - "engines": { - "node": ">= 14.17.0" - } - }, - "node_modules/codemaker/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/collect-v8-coverage": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", - "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commit-and-tag-version": { - "version": "12.4.4", - "resolved": "https://registry.npmjs.org/commit-and-tag-version/-/commit-and-tag-version-12.4.4.tgz", - "integrity": "sha512-sK+69usdfluwRO6DtXs8wpRvyM9OAuV6y8kTgMj+ncRG3KrXeKjNcxFsWnnwH/KZU9k8ErKu5uQ1ptX6/pPk7A==", - "dev": true, - "dependencies": { - "chalk": "^2.4.2", - "conventional-changelog": "4.0.0", - "conventional-changelog-config-spec": "2.1.0", - "conventional-changelog-conventionalcommits": "6.1.0", - "conventional-recommended-bump": "7.0.1", - "detect-indent": "^6.0.0", - "detect-newline": "^3.1.0", - "dotgitignore": "^2.1.0", - "figures": "^3.1.0", - "find-up": "^5.0.0", - "git-semver-tags": "^5.0.0", - "jsdom": "^25.0.0", - "semver": "^7.6.3", - "w3c-xmlserializer": "^5.0.0", - "yaml": "^2.4.1", - "yargs": "^17.7.2" - }, - "bin": { - "commit-and-tag-version": "bin/cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/commit-and-tag-version/node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dev": true, - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/commit-and-tag-version/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/commit-and-tag-version/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/commit-and-tag-version/node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/commit-and-tag-version/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/commit-and-tag-version/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-4.0.0.tgz", - "integrity": "sha512-JbZjwE1PzxQCvm+HUTIr+pbSekS8qdOZzMakdFyPtdkEWwFvwEJYONzjgMm0txCb2yBcIcfKDmg8xtCKTdecNQ==", - "dev": true, - "dependencies": { - "conventional-changelog-angular": "^6.0.0", - "conventional-changelog-atom": "^3.0.0", - "conventional-changelog-codemirror": "^3.0.0", - "conventional-changelog-conventionalcommits": "^6.0.0", - "conventional-changelog-core": "^5.0.0", - "conventional-changelog-ember": "^3.0.0", - "conventional-changelog-eslint": "^4.0.0", - "conventional-changelog-express": "^3.0.0", - "conventional-changelog-jquery": "^4.0.0", - "conventional-changelog-jshint": "^3.0.0", - "conventional-changelog-preset-loader": "^3.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-angular": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz", - "integrity": "sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==", - "dev": true, - "dependencies": { - "compare-func": "^2.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-atom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-3.0.0.tgz", - "integrity": "sha512-pnN5bWpH+iTUWU3FaYdw5lJmfWeqSyrUkG+wyHBI9tC1dLNnHkbAOg1SzTQ7zBqiFrfo55h40VsGXWMdopwc5g==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-codemirror": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-3.0.0.tgz", - "integrity": "sha512-wzchZt9HEaAZrenZAUUHMCFcuYzGoZ1wG/kTRMICxsnW5AXohYMRxnyecP9ob42Gvn5TilhC0q66AtTPRSNMfw==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-conventionalcommits": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-6.1.0.tgz", - "integrity": "sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==", - "dev": true, - "dependencies": { - "compare-func": "^2.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-core": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-5.0.2.tgz", - "integrity": "sha512-RhQOcDweXNWvlRwUDCpaqXzbZemKPKncCWZG50Alth72WITVd6nhVk9MJ6w1k9PFNBcZ3YwkdkChE+8+ZwtUug==", - "dev": true, - "dependencies": { - "add-stream": "^1.0.0", - "conventional-changelog-writer": "^6.0.0", - "conventional-commits-parser": "^4.0.0", - "dateformat": "^3.0.3", - "get-pkg-repo": "^4.2.1", - "git-raw-commits": "^3.0.0", - "git-remote-origin-url": "^2.0.0", - "git-semver-tags": "^5.0.0", - "normalize-package-data": "^3.0.3", - "read-pkg": "^3.0.0", - "read-pkg-up": "^3.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-ember": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-3.0.0.tgz", - "integrity": "sha512-7PYthCoSxIS98vWhVcSphMYM322OxptpKAuHYdVspryI0ooLDehRXWeRWgN+zWSBXKl/pwdgAg8IpLNSM1/61A==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-eslint": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-4.0.0.tgz", - "integrity": "sha512-nEZ9byP89hIU0dMx37JXQkE1IpMmqKtsaR24X7aM3L6Yy/uAtbb+ogqthuNYJkeO1HyvK7JsX84z8649hvp43Q==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-express": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-3.0.0.tgz", - "integrity": "sha512-HqxihpUMfIuxvlPvC6HltA4ZktQEUan/v3XQ77+/zbu8No/fqK3rxSZaYeHYant7zRxQNIIli7S+qLS9tX9zQA==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-jquery": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-4.0.0.tgz", - "integrity": "sha512-TTIN5CyzRMf8PUwyy4IOLmLV2DFmPtasKN+x7EQKzwSX8086XYwo+NeaeA3VUT8bvKaIy5z/JoWUvi7huUOgaw==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-jshint": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-3.0.0.tgz", - "integrity": "sha512-bQof4byF4q+n+dwFRkJ/jGf9dCNUv4/kCDcjeCizBvfF81TeimPZBB6fT4HYbXgxxfxWXNl/i+J6T0nI4by6DA==", - "dev": true, - "dependencies": { - "compare-func": "^2.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-preset-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-3.0.0.tgz", - "integrity": "sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA==", - "dev": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-changelog-writer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-6.0.1.tgz", - "integrity": "sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==", - "dev": true, - "dependencies": { - "conventional-commits-filter": "^3.0.0", - "dateformat": "^3.0.3", - "handlebars": "^4.7.7", - "json-stringify-safe": "^5.0.1", - "meow": "^8.1.2", - "semver": "^7.0.0", - "split": "^1.0.1" - }, - "bin": { - "conventional-changelog-writer": "cli.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-commits-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz", - "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==", - "dev": true, - "dependencies": { - "lodash.ismatch": "^4.4.0", - "modify-values": "^1.0.1" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-commits-parser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", - "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", - "dev": true, - "dependencies": { - "is-text-path": "^1.0.1", - "JSONStream": "^1.3.5", - "meow": "^8.1.2", - "split2": "^3.2.2" - }, - "bin": { - "conventional-commits-parser": "cli.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/conventional-recommended-bump": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-7.0.1.tgz", - "integrity": "sha512-Ft79FF4SlOFvX4PkwFDRnaNiIVX7YbmqGU0RwccUaiGvgp3S0a8ipR2/Qxk31vclDNM+GSdJOVs2KrsUCjblVA==", - "dev": true, - "dependencies": { - "concat-stream": "^2.0.0", - "conventional-changelog-preset-loader": "^3.0.0", - "conventional-commits-filter": "^3.0.0", - "conventional-commits-parser": "^4.0.0", - "git-raw-commits": "^3.0.0", - "git-semver-tags": "^5.0.0", - "meow": "^8.1.2" - }, - "bin": { - "conventional-recommended-bump": "cli.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/cssstyle": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.1.0.tgz", - "integrity": "sha512-h66W1URKpBS5YMI/V8PyXvTMFT8SupJ1IzoIV8IeBC/ji8WVmrO8dGlTi+2dh6whmdk6BiKJLD/ZBkhWbcg6nA==", - "dev": true, - "dependencies": { - "rrweb-cssom": "^0.7.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/commit-and-tag-version/node_modules/data-urls": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", - "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", - "dev": true, - "dependencies": { - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/commit-and-tag-version/node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/commit-and-tag-version/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/commit-and-tag-version/node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/commit-and-tag-version/node_modules/git-raw-commits": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-3.0.0.tgz", - "integrity": "sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==", - "dev": true, - "dependencies": { - "dargs": "^7.0.0", - "meow": "^8.1.2", - "split2": "^3.2.2" - }, - "bin": { - "git-raw-commits": "cli.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/git-semver-tags": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-5.0.1.tgz", - "integrity": "sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA==", - "dev": true, - "dependencies": { - "meow": "^8.1.2", - "semver": "^7.0.0" - }, - "bin": { - "git-semver-tags": "cli.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/commit-and-tag-version/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/commit-and-tag-version/node_modules/html-encoding-sniffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", - "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", - "dev": true, - "dependencies": { - "whatwg-encoding": "^3.1.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/commit-and-tag-version/node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/commit-and-tag-version/node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "dev": true, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/commit-and-tag-version/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/commit-and-tag-version/node_modules/jsdom": { - "version": "25.0.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-25.0.1.tgz", - "integrity": "sha512-8i7LzZj7BF8uplX+ZyOlIz86V6TAsSs+np6m1kpW9u0JWi4z/1t+FzcK1aek+ybTnAC4KhBL4uXCNT0wcUIeCw==", - "dev": true, - "dependencies": { - "cssstyle": "^4.1.0", - "data-urls": "^5.0.0", - "decimal.js": "^10.4.3", - "form-data": "^4.0.0", - "html-encoding-sniffer": "^4.0.0", - "http-proxy-agent": "^7.0.2", - "https-proxy-agent": "^7.0.5", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.12", - "parse5": "^7.1.2", - "rrweb-cssom": "^0.7.1", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^5.0.0", - "w3c-xmlserializer": "^5.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^3.1.1", - "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.0.0", - "ws": "^8.18.0", - "xml-name-validator": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "peerDependencies": { - "canvas": "^2.11.2" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/commit-and-tag-version/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/commit-and-tag-version/node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "dev": true, - "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/commit-and-tag-version/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/commit-and-tag-version/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/commit-and-tag-version/node_modules/parse5": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", - "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", - "dev": true, - "dependencies": { - "entities": "^4.4.0" - }, - "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" - } - }, - "node_modules/commit-and-tag-version/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/commit-and-tag-version/node_modules/saxes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", - "dev": true, - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=v12.22.7" - } - }, - "node_modules/commit-and-tag-version/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/commit-and-tag-version/node_modules/tough-cookie": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.0.0.tgz", - "integrity": "sha512-FRKsF7cz96xIIeMZ82ehjC3xW2E+O2+v11udrDYewUbszngYhsGa8z6YUMMzO9QJZzzyd0nGGXnML/TReX6W8Q==", - "dev": true, - "dependencies": { - "tldts": "^6.1.32" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/commit-and-tag-version/node_modules/tr46": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", - "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", - "dev": true, - "dependencies": { - "punycode": "^2.3.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/commit-and-tag-version/node_modules/w3c-xmlserializer": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", - "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", - "dev": true, - "dependencies": { - "xml-name-validator": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/commit-and-tag-version/node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/commit-and-tag-version/node_modules/whatwg-encoding": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", - "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", - "dev": true, - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/commit-and-tag-version/node_modules/whatwg-mimetype": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", - "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", - "dev": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/commit-and-tag-version/node_modules/whatwg-url": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", - "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", - "dev": true, - "dependencies": { - "tr46": "^5.0.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/commit-and-tag-version/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/commit-and-tag-version/node_modules/xml-name-validator": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", - "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", - "dev": true, - "engines": { - "node": ">=18" - } - }, - "node_modules/commit-and-tag-version/node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/commit-and-tag-version/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/commonmark": { - "version": "0.31.2", - "resolved": "https://registry.npmjs.org/commonmark/-/commonmark-0.31.2.tgz", - "integrity": "sha512-2fRLTyb9r/2835k5cwcAwOj0DEc44FARnMp5veGsJ+mEAZdi52sNopLu07ZyElQUz058H43whzlERDIaaSw4rg==", - "dev": true, - "dependencies": { - "entities": "~3.0.1", - "mdurl": "~1.0.1", - "minimist": "~1.2.8" - }, - "bin": { - "commonmark": "bin/commonmark" - }, - "engines": { - "node": "*" - } - }, - "node_modules/compare-func": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-ify": "^1.0.0", - "dot-prop": "^5.1.0" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "dev": true, - "engines": [ - "node >= 6.0" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/constructs": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.0.5.tgz", - "integrity": "sha512-IwOwekzrASFC3qt4ozCtV09rteAIAesuCGsW0p+uBfqHd2XcvA5CXqJjgf4eUqm6g8e/noXlVCMDWwC8GaLtrg==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">= 10.17.0" - } - }, - "node_modules/conventional-changelog-config-spec": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz", - "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", - "dev": true, - "license": "MIT" - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true, - "license": "MIT" - }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true, - "license": "MIT" - }, - "node_modules/dargs": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", - "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/date-format": { - "version": "4.0.14", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", - "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/debug": { - "version": "4.3.5", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-5.0.1.tgz", - "integrity": "sha512-VfxadyCECXgQlkoEAjeghAr5gY3Hf+IKjKb+X8tGVDtveCjN+USwprd2q3QXBR9T1+x2DG0XZF5/w+7HAtSaXA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decamelize-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", - "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", - "dev": true, - "license": "MIT", - "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decamelize-keys/node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decimal.js": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", - "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", - "dev": true, - "license": "MIT" - }, - "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true, - "license": "MIT" - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/deepmerge": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/detect-indent": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", - "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dir-glob/node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "license": "MIT", - "dependencies": { - "webidl-conversions": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dotgitignore": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/dotgitignore/-/dotgitignore-2.1.0.tgz", - "integrity": "sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==", - "dev": true, - "license": "ISC", - "dependencies": { - "find-up": "^3.0.0", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/dotgitignore/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/dotgitignore/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/dotgitignore/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.1", - "dev": true, - "license": "ISC" - }, - "node_modules/emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/entities": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz", - "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==", - "dev": true, - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/escalade": { - "version": "3.1.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-prettier": { - "version": "8.10.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz", - "integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==", - "dev": true, - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/eslint-import-resolver-typescript": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.7.1.tgz", - "integrity": "sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "debug": "^4.3.4", - "glob": "^7.2.0", - "is-glob": "^4.0.3", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "*", - "eslint-plugin-import": "*" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.8.1", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", - "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "eslint": ">=7.28.0", - "prettier": ">=2.0.0" - }, - "peerDependenciesMeta": { - "eslint-config-prettier": { - "optional": true - } - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/eslint/node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/eslint/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/eslint/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-uri": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.1.tgz", - "integrity": "sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "bser": "2.1.1" - } - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up/node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true, - "license": "ISC" - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-pkg-repo": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", - "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@hutson/parse-repository-url": "^3.0.0", - "hosted-git-info": "^4.0.0", - "through2": "^2.0.0", - "yargs": "^16.2.0" - }, - "bin": { - "get-pkg-repo": "src/cli.js" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-pkg-repo/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/get-pkg-repo/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/get-pkg-repo/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/get-pkg-repo/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/git-remote-origin-url": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", - "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "gitconfiglocal": "^1.0.0", - "pify": "^2.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/git-remote-origin-url/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/gitconfiglocal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", - "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==", - "dev": true, - "license": "BSD", - "dependencies": { - "ini": "^1.3.2" - } - }, - "node_modules/gitconfiglocal/node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "license": "ISC" - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, - "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, - "node_modules/hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "whatwg-encoding": "^1.0.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true, - "license": "MIT" - }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ignore": { - "version": "5.3.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-fresh/node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/import-local": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", - "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.15.0", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-text-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", - "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "text-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true, - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/istanbul-lib-coverage": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", - "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", - "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^4.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", - "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "^27.5.1", - "import-local": "^3.0.2", - "jest-cli": "^27.5.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", - "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "execa": "^5.0.0", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", - "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-cli": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", - "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/core": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-config": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", - "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.5.1", - "@jest/types": "^27.5.1", - "babel-jest": "^27.5.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.9", - "jest-circus": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-jasmine2": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-docblock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", - "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-each": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", - "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-jsdom": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", - "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1", - "jsdom": "^16.6.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-jsdom/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-environment-node": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", - "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-node/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", - "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^27.5.1", - "jest-serializer": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-haste-map/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-haste-map/node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/jest-jasmine2": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", - "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-jasmine2/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-junit": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/jest-junit/-/jest-junit-15.0.0.tgz", - "integrity": "sha512-Z5sVX0Ag3HZdMUnD5DFlG+1gciIFSy7yIVPhOdGUi8YJaI9iLvvBb530gtQL2CHmv0JJeiwRZenr0VrSR7frvg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "mkdirp": "^1.0.4", - "strip-ansi": "^6.0.1", - "uuid": "^8.3.2", - "xml": "^1.0.1" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/jest-leak-detector": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", - "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-mock/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", - "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", - "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-snapshot": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runner": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", - "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-leak-detector": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runner/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-runtime": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", - "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/globals": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runtime/node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-serializer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", - "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-serializer/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-snapshot": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", - "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^27.5.1", - "semver": "^7.3.2" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-util/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-validate": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", - "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/types": "^27.5.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "leven": "^3.1.0", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watcher": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", - "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.5.1", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-watcher/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/node_modules/@types/node": { - "version": "20.14.12", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "license": "MIT", - "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/jsii": { - "version": "1.103.1", - "resolved": "https://registry.npmjs.org/jsii/-/jsii-1.103.1.tgz", - "integrity": "sha512-SjS/g9iq8UJIEPBcaGUIYUJ3/oCboBKpDlJOOzMj2w4MpXQbXP3eyRO6NWBWkWsrIczyJ7HZiRWUJ7J4rUJ0sg==", - "dev": true, - "dependencies": { - "@jsii/check-node": "1.103.1", - "@jsii/spec": "^1.103.1", - "case": "^1.6.3", - "chalk": "^4", - "fast-deep-equal": "^3.1.3", - "fs-extra": "^10.1.0", - "log4js": "^6.9.1", - "semver": "^7.6.3", - "semver-intersect": "^1.5.0", - "sort-json": "^2.0.1", - "spdx-license-list": "^6.9.0", - "typescript": "~3.9.10", - "yargs": "^16.2.0" - }, - "bin": { - "jsii": "bin/jsii" - }, - "engines": { - "node": ">= 14.17.0" - } - }, - "node_modules/jsii-diff": { - "version": "1.103.1", - "resolved": "https://registry.npmjs.org/jsii-diff/-/jsii-diff-1.103.1.tgz", - "integrity": "sha512-JceGFJkOsTEFjtubTsDTDIw+3PrAVx0lpUtHSvFUZ+aeFYpnbWLcOGcX7vuxwnvZO2oDbm7qE+ymmov53exKqQ==", - "dev": true, - "dependencies": { - "@jsii/check-node": "1.103.1", - "@jsii/spec": "^1.103.1", - "fs-extra": "^10.1.0", - "jsii-reflect": "^1.103.1", - "log4js": "^6.9.1", - "yargs": "^16.2.0" - }, - "bin": { - "jsii-diff": "bin/jsii-diff" - }, - "engines": { - "node": ">= 14.17.0" - } - }, - "node_modules/jsii-docgen": { - "version": "10.5.5", - "resolved": "https://registry.npmjs.org/jsii-docgen/-/jsii-docgen-10.5.5.tgz", - "integrity": "sha512-xPlCmtR0HEVLTIv2dkXL7NZ0l6G7AWbmYZDRQvIie1AjHDwTEszlyivG1zXqP4jx180bQl5ezOf9BWGJLxHyTA==", - "dev": true, - "dependencies": { - "@jsii/spec": "^1.103.1", - "case": "^1.6.3", - "fs-extra": "^10.1.0", - "glob": "^8.1.0", - "glob-promise": "^6.0.7", - "jsii-reflect": "^1.103.1", - "semver": "^7.6.3", - "yargs": "^16.2.0" - }, - "bin": { - "jsii-docgen": "bin/jsii-docgen" - }, - "peerDependencies": { - "jsii-rosetta": "^1.85.0 || ~5.0.14 || ~5.1.2 || ~5.2.0 || ~5.3.0 || ~5.4.0 || ~5.5.0" - } - }, - "node_modules/jsii-docgen/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/jsii-docgen/node_modules/glob-promise": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/glob-promise/-/glob-promise-6.0.7.tgz", - "integrity": "sha512-DEAe6br1w8ZF+y6KM2pzgdfhpreladtNvyNNVgSkxxkFWzXTJFXxQrJQQbAnc7kL0EUd7w5cR8u4K0P4+/q+Gw==", - "dev": true, - "engines": { - "node": ">=16" - }, - "funding": { - "type": "individual", - "url": "https://github.com/sponsors/ahmadnassri" - }, - "peerDependencies": { - "glob": "^8.0.3" - } - }, - "node_modules/jsii-docgen/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jsii-pacmak": { - "version": "1.103.1", - "resolved": "https://registry.npmjs.org/jsii-pacmak/-/jsii-pacmak-1.103.1.tgz", - "integrity": "sha512-2zzm/OYsdbxcaYuq4n0o2lQAPQ5Fo+T+sQJPGFeMXD0kgDZTNqXv21FdsKBKuQ/DutxTATOaZ7gTXEDK1n7/RQ==", - "dev": true, - "dependencies": { - "@jsii/check-node": "1.103.1", - "@jsii/spec": "^1.103.1", - "clone": "^2.1.2", - "codemaker": "^1.103.1", - "commonmark": "^0.31.1", - "escape-string-regexp": "^4.0.0", - "fs-extra": "^10.1.0", - "jsii-reflect": "^1.103.1", - "semver": "^7.6.3", - "spdx-license-list": "^6.9.0", - "xmlbuilder": "^15.1.1", - "yargs": "^16.2.0" - }, - "bin": { - "jsii-pacmak": "bin/jsii-pacmak" - }, - "engines": { - "node": ">= 14.17.0" - }, - "peerDependencies": { - "jsii-rosetta": "^1.103.1 || ~5.2.0 || ~5.3.0 || ~5.4.0 || ~5.5.0" - } - }, - "node_modules/jsii-pacmak/node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jsii-reflect": { - "version": "1.103.1", - "resolved": "https://registry.npmjs.org/jsii-reflect/-/jsii-reflect-1.103.1.tgz", - "integrity": "sha512-kFm09KL9dlxyxesf7mtm12+4vVaRin5YI4Eca2OOa0X28HNVpr62/n21T3BuAAhFaI0nkiUoJuBWtdOz475BSQ==", - "dev": true, - "dependencies": { - "@jsii/check-node": "1.103.1", - "@jsii/spec": "^1.103.1", - "chalk": "^4", - "fs-extra": "^10.1.0", - "oo-ascii-tree": "^1.103.1", - "yargs": "^16.2.0" - }, - "bin": { - "jsii-tree": "bin/jsii-tree" - }, - "engines": { - "node": ">= 14.17.0" - } - }, - "node_modules/jsii-rosetta": { - "version": "1.103.1", - "resolved": "https://registry.npmjs.org/jsii-rosetta/-/jsii-rosetta-1.103.1.tgz", - "integrity": "sha512-LzLtFqQXOXdvYxDeq2OzaiR+Xhq7q9+NfUEWTpNVsvVh3N7E7w3G/75shsl8BfacJVvrH0hYVMkOH4Lyd0np2g==", - "dev": true, - "dependencies": { - "@jsii/check-node": "1.103.1", - "@jsii/spec": "1.103.1", - "@xmldom/xmldom": "^0.8.10", - "commonmark": "^0.31.1", - "fast-glob": "^3.3.2", - "jsii": "1.103.1", - "semver": "^7.6.3", - "semver-intersect": "^1.5.0", - "stream-json": "^1.8.0", - "typescript": "~3.9.10", - "workerpool": "^6.5.1", - "yargs": "^16.2.0" - }, - "bin": { - "jsii-rosetta": "bin/jsii-rosetta" - }, - "engines": { - "node": ">= 14.17.0" - } - }, - "node_modules/jsii-rosetta/node_modules/typescript": { - "version": "3.9.10", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", - "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/jsii/node_modules/typescript": { - "version": "3.9.10", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", - "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "license": "ISC" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "dev": true, - "engines": [ - "node >= 0.2.0" - ], - "license": "MIT" - }, - "node_modules/JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, - "license": "(MIT OR Apache-2.0)", - "dependencies": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, - "bin": { - "JSONStream": "bin.js" - }, - "engines": { - "node": "*" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "license": "MIT" - }, - "node_modules/load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/load-json-file/node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "license": "MIT", - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.ismatch": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", - "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/log4js": { - "version": "6.9.1", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", - "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "flatted": "^3.2.7", - "rfdc": "^1.3.0", - "streamroller": "^3.1.5" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, - "license": "ISC" - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "tmpl": "1.0.5" - } - }, - "node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", - "dev": true - }, - "node_modules/meow": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", - "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/meow/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/read-pkg/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true, - "license": "ISC" - }, - "node_modules/meow/node_modules/read-pkg/node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/meow/node_modules/read-pkg/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/meow/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/type-fest": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true, - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.7", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimatch/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/modify-values": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", - "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-releases": { - "version": "2.0.18", - "dev": true, - "license": "MIT" - }, - "node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/normalize-package-data/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true, - "license": "ISC" - }, - "node_modules/normalize-package-data/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nwsapi": { - "version": "2.2.12", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.12.tgz", - "integrity": "sha512-qXDmcVlZV4XRtKFzddidpfVP4oMSGhga+xdMc25mv8kaLUHtgzCDhUxkrN8exkGdTlLNaXj7CV3GtON7zuGZ+w==", - "dev": true, - "license": "MIT" - }, - "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/oo-ascii-tree": { - "version": "1.103.1", - "resolved": "https://registry.npmjs.org/oo-ascii-tree/-/oo-ascii-tree-1.103.1.tgz", - "integrity": "sha512-X0nmbb8xUUi637JXzCxY/K4AtO/I0fB5b7iiGaHJHu8IXBWV8TnQ4xqa0Igb/NoAg3OP2uXNhSeiTsErETOA/g==", - "dev": true, - "engines": { - "node": ">= 14.17.0" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true, - "license": "MIT" - }, - "node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT" - }, - "node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/picocolors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", - "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "license": "MIT" - }, - "node_modules/projen": { - "version": "0.88.1", - "resolved": "https://registry.npmjs.org/projen/-/projen-0.88.1.tgz", - "integrity": "sha512-LAv/kUAcCSTXH7/E+eeAJln3NvVFvhHgx9ezGPudcEPUOhr98M+Uojt6lniGvKESmk6rDO8AcVvzIhFH3kcz1g==", - "bundleDependencies": [ - "@iarna/toml", - "case", - "chalk", - "comment-json", - "conventional-changelog-config-spec", - "fast-json-patch", - "glob", - "ini", - "semver", - "shx", - "xmlbuilder2", - "yaml", - "yargs" - ], - "dev": true, - "dependencies": { - "@iarna/toml": "^2.2.5", - "case": "^1.6.3", - "chalk": "^4.1.2", - "comment-json": "4.2.2", - "constructs": "^10.0.0", - "conventional-changelog-config-spec": "^2.1.0", - "fast-json-patch": "^3.1.1", - "glob": "^8", - "ini": "^2.0.0", - "semver": "^7.6.3", - "shx": "^0.3.4", - "xmlbuilder2": "^3.1.1", - "yaml": "^2.2.2", - "yargs": "^17.7.2" - }, - "bin": { - "projen": "bin/projen" - }, - "engines": { - "node": ">= 16.0.0" - }, - "peerDependencies": { - "constructs": "^10.0.0" - } - }, - "node_modules/projen/node_modules/@iarna/toml": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/@iarna/toml/-/toml-2.2.5.tgz", - "integrity": "sha512-trnsAYxU3xnS1gPHPyU961coFyLkh4gAD/0zQ5mymY4yOZ+CYvsPqUbOFSw0aDM4y0tV7tiFxL/1XfXPNC6IPg==", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/projen/node_modules/@oozcitak/dom": { - "version": "1.15.10", - "resolved": "https://registry.npmjs.org/@oozcitak/dom/-/dom-1.15.10.tgz", - "integrity": "sha512-0JT29/LaxVgRcGKvHmSrUTEvZ8BXvZhGl2LASRUgHqDTC1M5g1pLmVv56IYNyt3bG2CUjDkc67wnyZC14pbQrQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@oozcitak/infra": "1.0.8", - "@oozcitak/url": "1.0.4", - "@oozcitak/util": "8.3.8" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/projen/node_modules/@oozcitak/infra": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@oozcitak/infra/-/infra-1.0.8.tgz", - "integrity": "sha512-JRAUc9VR6IGHOL7OGF+yrvs0LO8SlqGnPAMqyzOuFZPSZSXI7Xf2O9+awQPSMXgIWGtgUf/dA6Hs6X6ySEaWTg==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@oozcitak/util": "8.3.8" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/projen/node_modules/@oozcitak/url": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@oozcitak/url/-/url-1.0.4.tgz", - "integrity": "sha512-kDcD8y+y3FCSOvnBI6HJgl00viO/nGbQoCINmQ0h98OhnGITrWR3bOGfwYCthgcrV8AnTJz8MzslTQbC3SOAmw==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@oozcitak/infra": "1.0.8", - "@oozcitak/util": "8.3.8" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/projen/node_modules/@oozcitak/util": { - "version": "8.3.8", - "resolved": "https://registry.npmjs.org/@oozcitak/util/-/util-8.3.8.tgz", - "integrity": "sha512-T8TbSnGsxo6TDBJx/Sgv/BlVJL3tshxZP7Aq5R1mSnM5OcHY2dQaxLMu2+E8u3gN0MLOzdjurqN4ZRVuzQycOQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8.0" - } - }, - "node_modules/projen/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/projen/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/projen/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/projen/node_modules/array-timsort": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-timsort/-/array-timsort-1.0.3.tgz", - "integrity": "sha512-/+3GRL7dDAGEfM6TseQk/U+mi18TU2Ms9I3UlLdUMhz2hbvGNTKdj9xniwXfUqgYhHxRx0+8UnKkvlNwVU+cWQ==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/projen/node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/projen/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/projen/node_modules/case": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/case/-/case-1.6.3.tgz", - "integrity": "sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==", - "dev": true, - "inBundle": true, - "license": "(MIT OR GPL-3.0-or-later)", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/projen/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/projen/node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/projen/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/projen/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/projen/node_modules/comment-json": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/comment-json/-/comment-json-4.2.2.tgz", - "integrity": "sha512-H8T+kl3nZesZu41zO2oNXIJWojNeK3mHxCLrsBNu6feksBXsgb+PtYz5daP5P86A0F3sz3840KVYehr04enISQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "array-timsort": "^1.0.3", - "core-util-is": "^1.0.3", - "esprima": "^4.0.1", - "has-own-prop": "^2.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/projen/node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/projen/node_modules/constructs": { - "version": "10.3.0", - "resolved": "https://registry.npmjs.org/constructs/-/constructs-10.3.0.tgz", - "integrity": "sha512-vbK8i3rIb/xwZxSpTjz3SagHn1qq9BChLEfy5Hf6fB3/2eFbrwt2n9kHwQcS0CPTRBesreeAcsJfMq2229FnbQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">= 16.14.0" - } - }, - "node_modules/projen/node_modules/conventional-changelog-config-spec": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz", - "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/projen/node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/projen/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/projen/node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/projen/node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "inBundle": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/projen/node_modules/fast-json-patch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", - "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/projen/node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/projen/node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "inBundle": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/projen/node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/projen/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/projen/node_modules/glob/node_modules/minimatch": { - "version": "5.1.6", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/projen/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/projen/node_modules/has-own-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-own-prop/-/has-own-prop-2.0.0.tgz", - "integrity": "sha512-Pq0h+hvsVm6dDEa8x82GnLSYHOzNDt7f0ddFa3FqcQlgzEiptPqL+XrOJNavjOzSYiYWIrgeVYYgGlLmnxwilQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/projen/node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/projen/node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/projen/node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/projen/node_modules/ini": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/projen/node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/projen/node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/projen/node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/projen/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/projen/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/projen/node_modules/minimatch/node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/projen/node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "inBundle": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/projen/node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/projen/node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/projen/node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "inBundle": true, - "license": "MIT" - }, - "node_modules/projen/node_modules/rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==", - "dev": true, - "inBundle": true, - "dependencies": { - "resolve": "^1.1.6" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/projen/node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/projen/node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/projen/node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/projen/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "inBundle": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/projen/node_modules/shelljs": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz", - "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==", - "dev": true, - "inBundle": true, - "license": "BSD-3-Clause", - "dependencies": { - "glob": "^7.0.0", - "interpret": "^1.0.0", - "rechoir": "^0.6.2" - }, - "bin": { - "shjs": "bin/shjs" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/projen/node_modules/shelljs/node_modules/glob": { - "version": "7.2.3", - "dev": true, - "inBundle": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/projen/node_modules/shx": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/shx/-/shx-0.3.4.tgz", - "integrity": "sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.3", - "shelljs": "^0.8.5" - }, - "bin": { - "shx": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/projen/node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, - "inBundle": true, - "license": "BSD-3-Clause" - }, - "node_modules/projen/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/projen/node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/projen/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/projen/node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "inBundle": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/projen/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/projen/node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "inBundle": true, - "license": "ISC" - }, - "node_modules/projen/node_modules/xmlbuilder2": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder2/-/xmlbuilder2-3.1.1.tgz", - "integrity": "sha512-WCSfbfZnQDdLQLiMdGUQpMxxckeQ4oZNMNhLVkcekTu7xhD4tuUDyAPoY8CwXvBYE6LwBHd6QW2WZXlOWr1vCw==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "@oozcitak/dom": "1.15.10", - "@oozcitak/infra": "1.0.8", - "@oozcitak/util": "8.3.8", - "js-yaml": "3.14.1" - }, - "engines": { - "node": ">=12.0" - } - }, - "node_modules/projen/node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/projen/node_modules/yaml": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.1.tgz", - "integrity": "sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==", - "dev": true, - "inBundle": true, - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/projen/node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "inBundle": true, - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/projen/node_modules/yargs/node_modules/yargs-parser": { - "version": "21.1.1", - "dev": true, - "inBundle": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true, - "license": "MIT" - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==", - "dev": true, - "license": "MIT" - }, - "node_modules/read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, - "license": "MIT", - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve.exports": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.1.tgz", - "integrity": "sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "dev": true, - "license": "MIT" - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rrweb-cssom": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", - "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", - "dev": true - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "license": "ISC", - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver-intersect": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/semver-intersect/-/semver-intersect-1.5.0.tgz", - "integrity": "sha512-BDjWX7yCC0haX4W/zrnV2JaMpVirwaEkGOBmgRQtH++F1N3xl9v7k9H44xfTqwl+yLNNSbMKosoVSTIiJVQ2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^6.3.0" - } - }, - "node_modules/semver-intersect/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true, - "license": "MIT" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/sort-json": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/sort-json/-/sort-json-2.0.1.tgz", - "integrity": "sha512-s8cs2bcsQCzo/P2T/uoU6Js4dS/jnX8+4xunziNoq9qmSpZNCrRIAIvp4avsz0ST18HycV4z/7myJ7jsHWB2XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-indent": "^5.0.0", - "detect-newline": "^2.1.0", - "minimist": "^1.2.0" - }, - "bin": { - "sort-json": "app/cmd.js" - } - }, - "node_modules/sort-json/node_modules/detect-indent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", - "integrity": "sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/sort-json/node_modules/detect-newline": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", - "integrity": "sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true, - "license": "CC-BY-3.0" - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.18", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/spdx-license-list": { - "version": "6.9.0", - "resolved": "https://registry.npmjs.org/spdx-license-list/-/spdx-license-list-6.9.0.tgz", - "integrity": "sha512-L2jl5vc2j6jxWcNCvcVj/BW9A8yGIG02Dw+IUw0ZxDM70f7Ylf5Hq39appV1BI9yxyWQRpq2TQ1qaXvf+yjkqA==", - "dev": true, - "license": "CC0-1.0", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "through": "2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", - "dev": true, - "license": "ISC", - "dependencies": { - "readable-stream": "^3.0.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/stack-utils": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", - "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/stream-chain": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/stream-chain/-/stream-chain-2.2.5.tgz", - "integrity": "sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/stream-json": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/stream-json/-/stream-json-1.8.0.tgz", - "integrity": "sha512-HZfXngYHUAr1exT4fxlbc1IOce1RYxp2ldeaf97LYCOPSoOqY/1Psp7iGvpb+6JIOgkra9zDYnPX01hGAHzEPw==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "stream-chain": "^2.2.5" - } - }, - "node_modules/streamroller": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", - "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", - "dev": true, - "license": "MIT", - "dependencies": { - "date-format": "^4.0.14", - "debug": "^4.3.4", - "fs-extra": "^8.1.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/streamroller/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/streamroller/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/streamroller/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true, - "license": "MIT" - }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-extensions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", - "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT" - }, - "node_modules/throat": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", - "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true, - "license": "MIT" - }, - "node_modules/tldts": { - "version": "6.1.50", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.50.tgz", - "integrity": "sha512-q9GOap6q3KCsLMdOjXhWU5jVZ8/1dIib898JBRLsN+tBhENpBDcAVQbE0epADOjw11FhQQy9AcbqKGBQPUfTQA==", - "dev": true, - "dependencies": { - "tldts-core": "^6.1.50" - }, - "bin": { - "tldts": "bin/cli.js" - } - }, - "node_modules/tldts-core": { - "version": "6.1.50", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.50.tgz", - "integrity": "sha512-na2EcZqmdA2iV9zHV7OHQDxxdciEpxrjbkp+aHmZgnZKHzoElLajP59np5/4+sare9fQBfixgvXKx8ev1d7ytw==", - "dev": true - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tough-cookie": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", - "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/trim-newlines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/ts-jest": { - "version": "27.1.5", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.5.tgz", - "integrity": "sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA==", - "dev": true, - "license": "MIT", - "dependencies": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^27.0.0", - "json5": "2.x", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@types/jest": "^27.0.0", - "babel-jest": ">=27.0.0 <28", - "jest": "^27.0.0", - "typescript": ">=3.8 <5.0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@types/jest": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "4.9.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", - "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/uglify-js": { - "version": "3.19.0", - "dev": true, - "license": "BSD-2-Clause", - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "dev": true, - "license": "MIT" - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", - "integrity": "sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.1.2", - "picocolors": "^1.0.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "license": "MIT" - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, - "license": "MIT" - }, - "node_modules/v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", - "dev": true, - "license": "ISC", - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/v8-to-istanbul/node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 8" - } - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=10.4" - } - }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "license": "MIT", - "dependencies": { - "iconv-lite": "0.4.24" - } - }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/workerpool": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", - "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.5.10", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", - "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.3.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xml": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz", - "integrity": "sha512-huCv9IH9Tcf95zuYCsQraZtWnJvBtLVE0QHMOs8bWyZAFZNDcYjsPq1nEx8jKA9y+Beo9v+7OBPRisQTjinQMw==", - "dev": true, - "license": "MIT" - }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/xmlbuilder": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", - "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.0" - } - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true, - "license": "MIT" - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, - "node_modules/yaml": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.5.0.tgz", - "integrity": "sha512-2wWLbGbYDiSqqIKoPjar3MPgB94ErzCtrNE1FdqGuaO0pi2JGjmE8aW8TDZwzU7vuxcGRdL/4gPQwQ7hD5AMSw==", - "inBundle": true, - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/package.json b/package.json index d49447b5..8fb06252 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "@typescript-eslint/eslint-plugin": "^8", "@typescript-eslint/parser": "^8", "aws-cdk": "^2", - "aws-cdk-lib": "2.144.0", + "aws-cdk-lib": "2.177.0", "commit-and-tag-version": "^12", "constructs": "10.0.5", "eslint": "^9", @@ -79,6 +79,7 @@ "jsii-docgen": "^10.5.0", "jsii-pacmak": "^1.106.0", "jsii-rosetta": "~5.6.0", + "json-schema-to-typescript": "^15.0.4", "prettier": "^2.8.8", "projen": "^0.91.7", "ts-jest": "^27", @@ -86,7 +87,7 @@ "typescript": "^4.9.5" }, "peerDependencies": { - "aws-cdk-lib": "^2.144.0", + "aws-cdk-lib": "^2.177.0", "constructs": "^10.0.5" }, "dependencies": { diff --git a/src/LambdaInterface.ts b/src/LambdaInterface.ts new file mode 100644 index 00000000..655a3289 --- /dev/null +++ b/src/LambdaInterface.ts @@ -0,0 +1,24 @@ +/* eslint-disable */ +/** + * This file was automatically generated by json-schema-to-typescript. + * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, + * and run json-schema-to-typescript to regenerate this file. + */ + +export interface SopsSyncResourcePropertys { + ResourceType: "SECRET" | "SECRET_BINARY" | "PARAMETER_MULTI" | "PARAMETER"; + Format: "json" | "yaml" | "dotenv" | "binary"; + Target: string; + EncryptionKey?: string; + SopsS3File?: SopsS3File; + SopsInline?: SopsInline; + FlattenSeparator?: string; +} +export interface SopsS3File { + Bucket: string; + Key: string; +} +export interface SopsInline { + Content: string; + Hash: string; +} diff --git a/src/MultiStringParameter.ts b/src/MultiStringParameter.ts index a2c98478..f944c970 100644 --- a/src/MultiStringParameter.ts +++ b/src/MultiStringParameter.ts @@ -4,15 +4,25 @@ import { ParameterTier, StringParameter } from 'aws-cdk-lib/aws-ssm'; import { ResourceEnvironment, Stack } from 'aws-cdk-lib/core'; import { Construct } from 'constructs'; import * as YAML from 'yaml'; -import { SopsStringParameterProps } from './SopsStringParameter'; +import { SopsCommonParameterProps } from './SopsStringParameter'; import { ResourceType, SopsSync, SopsSyncOptions } from './SopsSync'; interface JSONObject { [key: string]: any; } -export interface MultiStringParameterProps extends SopsStringParameterProps { +export interface MultiStringParameterProps extends SopsCommonParameterProps { + /** + * The seperator used to seperate keys + * + * @default - '/' + */ readonly keySeparator?: string; + /** + * The prefix used for all parameters + * + * @default - '/' + */ readonly keyPrefix?: string; } @@ -79,10 +89,9 @@ export class MultiStringParameter extends Construct { this.sync = new SopsSync(this, 'SopsSync', { encryptionKey: this.encryptionKey, resourceType: ResourceType.PARAMETER_MULTI, - flatten: true, flattenSeparator: this.keySeparator, - parameterKeyPrefix: this.keyPrefix, parameterNames: keys, + target: this.keyPrefix, ...(props as SopsSyncOptions), }); } diff --git a/src/SopsSecret.ts b/src/SopsSecret.ts index ba574851..e09723a0 100644 --- a/src/SopsSecret.ts +++ b/src/SopsSecret.ts @@ -25,7 +25,13 @@ import { ResourceType, SopsSync, SopsSyncOptions } from './SopsSync'; /** * The configuration options of the SopsSecret */ -export interface SopsSecretProps extends SecretProps, SopsSyncOptions {} +export interface SopsSecretProps extends SecretProps, SopsSyncOptions { + /** + * Should the secret parsed and transformed to json? + * @default - true + */ + readonly rawOutput?: boolean; +} /** * A drop in replacement for the normal Secret, that is populated with the encrypted @@ -56,9 +62,10 @@ export class SopsSecret extends Construct implements ISecret { }; this.sync = new SopsSync(this, 'SopsSync', { - secret: this.secret, - resourceType: ResourceType.SECRET, + target: this.secret.secretArn, + resourceType: props.rawOutput === true? ResourceType.SECRET_BINARY : ResourceType.SECRET, flattenSeparator: '.', + secret: this.secret, ...(props as SopsSyncOptions), }); } diff --git a/src/SopsStringParameter.ts b/src/SopsStringParameter.ts index 42321106..db5648cf 100644 --- a/src/SopsStringParameter.ts +++ b/src/SopsStringParameter.ts @@ -2,8 +2,8 @@ import { Grant, IGrantable } from 'aws-cdk-lib/aws-iam'; import { IKey } from 'aws-cdk-lib/aws-kms'; import { IStringParameter, + ParameterTier, StringParameter, - StringParameterProps, } from 'aws-cdk-lib/aws-ssm'; import { RemovalPolicy, ResourceEnvironment, Stack } from 'aws-cdk-lib/core'; import { Construct } from 'constructs'; @@ -12,12 +12,31 @@ import { ResourceType, SopsSync, SopsSyncOptions } from './SopsSync'; /** * The configuration options of the StringParameter */ -export interface SopsStringParameterProps - extends SopsSyncOptions, - StringParameterProps { +export interface SopsCommonParameterProps extends SopsSyncOptions { + /** + * The tier of the string parameter + * + * @default - undefined + */ + readonly tier?: ParameterTier; + /** + * Information about the parameter that you want to add to the system. + * + * @default none + */ + readonly description?: string; readonly encryptionKey: IKey; } +export interface SopsStringParameterProps extends SopsCommonParameterProps{ + /** + * The name of the parameter. + * + * @default - a name will be generated by CloudFormation + */ + readonly parameterName?: string; +} + /** * A drop in replacement for the normal String Parameter, that is populated with the encrypted * content of the given sops file. @@ -48,9 +67,12 @@ export class SopsStringParameter extends Construct implements IStringParameter { }; this.parameter = new StringParameter(this, 'Resource', { - ...(props as StringParameterProps), + parameterName: props.parameterName, + description: props.description, + tier: props.tier, stringValue: ' ', }); + this.parameterArn = this.parameter.parameterArn; this.parameterName = this.parameter.parameterName; this.parameterType = this.parameter.parameterType; @@ -58,8 +80,9 @@ export class SopsStringParameter extends Construct implements IStringParameter { this.sync = new SopsSync(this, 'SopsSync', { encryptionKey: this.parameter.encryptionKey, - parameterNames: [this.parameter.parameterName], + target: this.parameter.parameterName, resourceType: ResourceType.PARAMETER, + parameterNames: [this.parameter.parameterName], ...(props as SopsSyncOptions), }); } diff --git a/src/SopsSync.ts b/src/SopsSync.ts index fcffb5aa..b9dd1f4b 100644 --- a/src/SopsSync.ts +++ b/src/SopsSync.ts @@ -21,6 +21,7 @@ import { SingletonFunction, Code, Runtime } from 'aws-cdk-lib/aws-lambda'; import { Asset } from 'aws-cdk-lib/aws-s3-assets'; import { ISecret } from 'aws-cdk-lib/aws-secretsmanager'; import { Construct } from 'constructs'; +import { SopsSyncResourcePropertys } from './LambdaInterface'; export enum UploadType { /** @@ -35,6 +36,7 @@ export enum UploadType { export enum ResourceType { SECRET = 'SECRET', + SECRET_BINARY = 'SECRET_BINARY', PARAMETER = 'PARAMETER', PARAMETER_MULTI = 'PARAMETER_MULTI', } @@ -96,41 +98,13 @@ export interface SopsSyncOptions { */ readonly sopsAgeKey?: SecretValue; - /** - * Should the encrypted sops value should be converted to JSON? - * Only JSON can be handled by cloud formations dynamic references. - * - * @default true - */ - readonly convertToJSON?: boolean; - - /** - * Should the structure be flattened? The result will be a flat structure and all - * object keys will be replaced with the full jsonpath as key. - * This is usefull for dynamic references, as those don't support nested objects. - * - * @default true - */ - readonly flatten?: boolean; - /** * If the structure should be flattened use the provided separator between keys. * - * @default '.' + * @default - undefined */ readonly flattenSeparator?: string; - /** - * Add this prefix to parameter names. - */ - readonly parameterKeyPrefix?: string; - - /** - * Shall all values be flattened? This is usefull for dynamic references, as there - * are lookup errors for certain float types - */ - readonly stringifyValues?: boolean; - /** * Should this construct automatically create IAM permissions? * @@ -143,15 +117,13 @@ export interface SopsSyncOptions { * The configuration options extended by the target Secret / Parameter */ export interface SopsSyncProps extends SopsSyncOptions { - /** - * The secret that will be populated with the encrypted sops file content. - */ - readonly secret?: ISecret; - - /** - * The parameter names. If set this creates encrypted SSM Parameters instead of a secret. + /** + * The target to populate with the sops file content. + * - for secret, it's the name or arn of the secret + * - for parameter, it's the name of the parameter + * - for parameter multi, it's the prefix of the parameters */ - readonly parameterNames?: string[]; + readonly target: string /** * The encryption key used for encrypting the ssm parameter if `parameterName` is set. @@ -161,7 +133,10 @@ export interface SopsSyncProps extends SopsSyncOptions { /** * Will this Sync deploy a Secret or Parameter(s) */ - readonly resourceType?: ResourceType; + readonly resourceType: ResourceType; + + readonly secret?: ISecret, + readonly parameterNames?: string[]; } /** @@ -239,28 +214,9 @@ export class SopsSync extends Construct { */ readonly versionId: string; - /** - * Was the format converted to json? - */ - readonly converToJSON: boolean; - - /** - * Was the structure flattened? - */ - readonly flatten: boolean; - - /** - * Were the values stringified? - */ - readonly stringifiedValues: boolean; - constructor(scope: Construct, id: string, props: SopsSyncProps) { super(scope, id); - this.converToJSON = props.convertToJSON ?? true; - this.flatten = props.flatten ?? true; - this.stringifiedValues = props.stringifyValues ?? true; - const provider = props.sopsProvider ?? new SopsSyncProvider(scope); let uploadType = props.uploadType ?? UploadType.INLINE; @@ -283,35 +239,36 @@ export class SopsSync extends Construct { } if (props.sopsFilePath !== undefined) { - const _sopsFileFormat = - props.sopsFileFormat ?? props.sopsFilePath.split('.').pop(); - switch (_sopsFileFormat) { - case 'json': { - sopsFileFormat = 'json'; - break; - } - case 'yaml': { - sopsFileFormat = 'yaml'; - break; - } - case 'yml': { - sopsFileFormat = 'yaml'; - break; - } - case 'dotenv': { - sopsFileFormat = 'dotenv'; - break; - } - case 'env': { - sopsFileFormat = 'dotenv'; - break; - } - case 'binary': { - sopsFileFormat = 'binary'; - break; - } - default: { - throw new Error(`Unsupported sopsFileFormat ${_sopsFileFormat}`); + if (sopsFileFormat === undefined) { + const _sopsFileFormat = props.sopsFilePath.split('.').pop(); + switch (_sopsFileFormat) { + case 'json': { + sopsFileFormat = 'json'; + break; + } + case 'yaml': { + sopsFileFormat = 'yaml'; + break; + } + case 'yml': { + sopsFileFormat = 'yaml'; + break; + } + case 'dotenv': { + sopsFileFormat = 'dotenv'; + break; + } + case 'env': { + sopsFileFormat = 'dotenv'; + break; + } + case 'binary': { + sopsFileFormat = 'binary'; + break; + } + default: { + Annotations.of(this).addError("Failed to determine sops file format. Please specify 'sopsFileFormat'!"); + } } } @@ -391,26 +348,14 @@ export class SopsSync extends Construct { serviceToken: provider.functionArn, resourceType: 'Custom::SopsSync', properties: { - SecretARN: props.secret?.secretArn, SopsS3File: sopsS3File, SopsInline: sopsInline, - ConvertToJSON: this.converToJSON, - Flatten: this.flatten, - FlattenSeparator: props.flattenSeparator ?? '.', - ParameterKeyPrefix: props.parameterKeyPrefix, + FlattenSeparator: props.flattenSeparator, Format: sopsFileFormat, - StringifiedValues: this.stringifiedValues, - ParameterName: - // Dirty Workaround, refactor ... - props.parameterNames && props.parameterNames.length == 1 - ? props.parameterNames[0] - : undefined, - EncryptionKey: - props.secret !== undefined ? undefined : props.encryptionKey?.keyId, - ResourceType: props.resourceType - ? props.resourceType.toString() - : ResourceType.SECRET.toString(), - }, + EncryptionKey: props.encryptionKey?.keyId, + ResourceType: props.resourceType, + Target: props.target, + } satisfies SopsSyncResourcePropertys, }); this.versionId = cr.getAttString('VersionId'); } diff --git a/test/__snapshots__/permissions.test.ts.snap b/test/__snapshots__/permissions.test.ts.snap index 3c64327c..64184f60 100644 --- a/test/__snapshots__/permissions.test.ts.snap +++ b/test/__snapshots__/permissions.test.ts.snap @@ -31,6 +31,9 @@ Object { ], "Version": "2012-10-17", }, + "Roles": Array [ + "test-role", + ], }, "Type": "AWS::IAM::ManagedPolicy", }, diff --git a/test/secret-asset.integ.snapshot/SecretIntegrationAsset.assets.json b/test/secret-asset.integ.snapshot/SecretIntegrationAsset.assets.json index d65692cd..3166351a 100644 --- a/test/secret-asset.integ.snapshot/SecretIntegrationAsset.assets.json +++ b/test/secret-asset.integ.snapshot/SecretIntegrationAsset.assets.json @@ -1,15 +1,15 @@ { - "version": "36.0.0", + "version": "39.0.0", "files": { - "71584c9f9a2d019cb5df6044c81ca32662370c709381898a7d72f8c7d40a21a4": { + "2f5ea59cc41c6a2ba0e5f9363d4f3836e8883e03cd54cc5e9789115b0979c218": { "source": { - "path": "asset.71584c9f9a2d019cb5df6044c81ca32662370c709381898a7d72f8c7d40a21a4.zip", + "path": "asset.2f5ea59cc41c6a2ba0e5f9363d4f3836e8883e03cd54cc5e9789115b0979c218.zip", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "71584c9f9a2d019cb5df6044c81ca32662370c709381898a7d72f8c7d40a21a4.zip", + "objectKey": "2f5ea59cc41c6a2ba0e5f9363d4f3836e8883e03cd54cc5e9789115b0979c218.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } @@ -79,7 +79,7 @@ } } }, - "be9b36c08762ff449b54230ebeb5b0d09e6a0e7737d3eda30a64be5f835d49ad": { + "5ca3964bb939bad69e0ce4cca4833760895d0e5d11890d89fa18e56079d585ed": { "source": { "path": "SecretIntegrationAsset.template.json", "packaging": "file" @@ -87,7 +87,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "be9b36c08762ff449b54230ebeb5b0d09e6a0e7737d3eda30a64be5f835d49ad.json", + "objectKey": "5ca3964bb939bad69e0ce4cca4833760895d0e5d11890d89fa18e56079d585ed.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/test/secret-asset.integ.snapshot/SecretIntegrationAsset.template.json b/test/secret-asset.integ.snapshot/SecretIntegrationAsset.template.json index f459ca54..daa9dd66 100644 --- a/test/secret-asset.integ.snapshot/SecretIntegrationAsset.template.json +++ b/test/secret-asset.integ.snapshot/SecretIntegrationAsset.template.json @@ -17,21 +17,18 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsSecretJSON72040543" - }, "SopsS3File": { "Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, "Key": "2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649.json" }, - "ConvertToJSON": true, - "Flatten": true, "FlattenSeparator": ".", "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET", + "Target": { + "Ref": "SopsSecretJSON72040543" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -231,7 +228,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "71584c9f9a2d019cb5df6044c81ca32662370c709381898a7d72f8c7d40a21a4.zip" + "S3Key": "2f5ea59cc41c6a2ba0e5f9363d4f3836e8883e03cd54cc5e9789115b0979c218.zip" }, "Environment": { "Variables": { @@ -270,21 +267,18 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsSecretYAMLC392F558" - }, "SopsS3File": { "Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, "Key": "c0d63dcd2d506c5d270284d70d1805688ff5d3a2e0d7515bfa56b1b3ed416c4f.yaml" }, - "ConvertToJSON": false, - "Flatten": true, "FlattenSeparator": ".", "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET_BINARY", + "Target": { + "Ref": "SopsSecretYAMLC392F558" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -306,21 +300,18 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsSecretYAMLasJSON64419C04" - }, "SopsS3File": { "Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, "Key": "c0d63dcd2d506c5d270284d70d1805688ff5d3a2e0d7515bfa56b1b3ed416c4f.yaml" }, - "ConvertToJSON": true, - "Flatten": true, "FlattenSeparator": ".", "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET", + "Target": { + "Ref": "SopsSecretYAMLasJSON64419C04" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -342,21 +333,18 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsComplexSecretJSONAD4C2662" - }, "SopsS3File": { "Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, "Key": "313aad921c737076a990ead756b250f1677aecc927177440df0c809cd56bf282.json" }, - "ConvertToJSON": true, - "Flatten": false, "FlattenSeparator": ".", "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET", + "Target": { + "Ref": "SopsComplexSecretJSONAD4C2662" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -378,21 +366,18 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, "SopsS3File": { "Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, "Key": "313aad921c737076a990ead756b250f1677aecc927177440df0c809cd56bf282.json" }, - "ConvertToJSON": true, - "Flatten": true, "FlattenSeparator": ".", "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET", + "Target": { + "Ref": "SopsComplexSecretJSONFlatF5FC1D69" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -414,21 +399,18 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopComplexSecretYAMLF52D88F2" - }, "SopsS3File": { "Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, "Key": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2.yaml" }, - "ConvertToJSON": false, - "Flatten": false, "FlattenSeparator": ".", "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET_BINARY", + "Target": { + "Ref": "SopComplexSecretYAMLF52D88F2" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -450,21 +432,18 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopComplexSecretYAMLFlatD9CE8782" - }, "SopsS3File": { "Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, "Key": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2.yaml" }, - "ConvertToJSON": false, - "Flatten": true, "FlattenSeparator": ".", "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET_BINARY", + "Target": { + "Ref": "SopComplexSecretYAMLFlatD9CE8782" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -486,21 +465,18 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsComplexSecretYAMLasJSONEAE81DB0" - }, "SopsS3File": { "Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, "Key": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2.yaml" }, - "ConvertToJSON": true, - "Flatten": false, "FlattenSeparator": ".", "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET_BINARY", + "Target": { + "Ref": "SopsComplexSecretYAMLasJSONEAE81DB0" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -522,21 +498,18 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, "SopsS3File": { "Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, "Key": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2.yaml" }, - "ConvertToJSON": true, - "Flatten": true, "FlattenSeparator": ".", "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET", + "Target": { + "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -558,21 +531,18 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsBinaryAsBinary6FB08519" - }, "SopsS3File": { "Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, "Key": "a8aece61894327fcfc2c7fab967a72583c0f795025e4d5f2e87c248b6e916d4b.binary" }, - "ConvertToJSON": true, - "Flatten": true, "FlattenSeparator": ".", "Format": "binary", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET_BINARY", + "Target": { + "Ref": "SopsBinaryAsBinary6FB08519" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" diff --git a/test/secret-asset.integ.ts b/test/secret-asset.integ.ts index bdfa441b..c8585330 100644 --- a/test/secret-asset.integ.ts +++ b/test/secret-asset.integ.ts @@ -17,7 +17,7 @@ new SopsSecret(stack, 'SopsSecretJSON', { new SopsSecret(stack, 'SopsSecretYAML', { sopsFilePath: 'test-secrets/yaml/sopsfile.enc-age.yaml', - convertToJSON: false, + rawOutput: true, uploadType: UploadType.ASSET, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( @@ -27,7 +27,6 @@ new SopsSecret(stack, 'SopsSecretYAML', { new SopsSecret(stack, 'SopsSecretYAMLasJSON', { sopsFilePath: 'test-secrets/yaml/sopsfile.enc-age.yaml', - convertToJSON: true, uploadType: UploadType.ASSET, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( @@ -37,7 +36,6 @@ new SopsSecret(stack, 'SopsSecretYAMLasJSON', { new SopsSecret(stack, 'SopsComplexSecretJSON', { sopsFilePath: 'test-secrets/json/sopsfile-complex.enc-age.json', - flatten: false, uploadType: UploadType.ASSET, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( @@ -51,7 +49,6 @@ const sopsComplexSecretJSONFlat = new SopsSecret( { sopsFilePath: 'test-secrets/json/sopsfile-complex.enc-age.json', uploadType: UploadType.ASSET, - flatten: true, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', @@ -61,9 +58,8 @@ const sopsComplexSecretJSONFlat = new SopsSecret( new SopsSecret(stack, 'SopComplexSecretYAML', { sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - convertToJSON: false, + rawOutput: true, uploadType: UploadType.ASSET, - flatten: false, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', @@ -72,9 +68,8 @@ new SopsSecret(stack, 'SopComplexSecretYAML', { new SopsSecret(stack, 'SopComplexSecretYAMLFlat', { sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - convertToJSON: false, + rawOutput: true, uploadType: UploadType.ASSET, - flatten: true, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', @@ -83,9 +78,8 @@ new SopsSecret(stack, 'SopComplexSecretYAMLFlat', { new SopsSecret(stack, 'SopsComplexSecretYAMLasJSON', { sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - convertToJSON: true, + rawOutput: true, uploadType: UploadType.ASSET, - flatten: false, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', @@ -98,17 +92,17 @@ const sopsComplexSecretYAMLasJSONFlat = new SopsSecret( { sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', uploadType: UploadType.ASSET, - convertToJSON: true, - flatten: true, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', ), + }, ); new SopsSecret(stack, 'SopsBinaryAsBinary', { sopsFilePath: 'test-secrets/binary/sopsfile.enc-age.binary', + rawOutput: true, uploadType: UploadType.ASSET, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( diff --git a/test/secret-inline.integ.snapshot/SecretIntegrationInline.assets.json b/test/secret-inline.integ.snapshot/SecretIntegrationInline.assets.json index cbef6f0f..1af921c5 100644 --- a/test/secret-inline.integ.snapshot/SecretIntegrationInline.assets.json +++ b/test/secret-inline.integ.snapshot/SecretIntegrationInline.assets.json @@ -1,20 +1,20 @@ { - "version": "36.0.0", + "version": "39.0.0", "files": { - "71584c9f9a2d019cb5df6044c81ca32662370c709381898a7d72f8c7d40a21a4": { + "87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186": { "source": { - "path": "asset.71584c9f9a2d019cb5df6044c81ca32662370c709381898a7d72f8c7d40a21a4.zip", + "path": "asset.87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186.zip", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "71584c9f9a2d019cb5df6044c81ca32662370c709381898a7d72f8c7d40a21a4.zip", + "objectKey": "87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "923c03ac17667e1ede779db4e03cde855c2a7e868de1c36506f34013c2c0f0e6": { + "4c92c042db4db86f1084ca0562e63918e871e3ee0a0066735d556df1737079f1": { "source": { "path": "SecretIntegrationInline.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "923c03ac17667e1ede779db4e03cde855c2a7e868de1c36506f34013c2c0f0e6.json", + "objectKey": "4c92c042db4db86f1084ca0562e63918e871e3ee0a0066735d556df1737079f1.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/test/secret-inline.integ.snapshot/SecretIntegrationInline.template.json b/test/secret-inline.integ.snapshot/SecretIntegrationInline.template.json index a48e5033..ff1d0475 100644 --- a/test/secret-inline.integ.snapshot/SecretIntegrationInline.template.json +++ b/test/secret-inline.integ.snapshot/SecretIntegrationInline.template.json @@ -17,19 +17,16 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsSecretJSON72040543" - }, "SopsInline": { "Content": "ewoJImtleTEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpBclNqQzBWZCxpdjpORnJJajFla00yZFU4SkNVNk5wbW5IRm13Y0ZhRVFhZ0N3L2Z4S1YyYjZBPSx0YWc6R3JHZ2VObXRxRnV5aVRqS0ovNzhrdz09LHR5cGU6c3RyXSIsCgkia2V5MiI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOk5lb2FuZFk9LGl2OjJvQ2NCazBSL1h4dkgvTythYUNJYTdWOXBGc3k3ZGhDS1o3MGViamM1RHM9LHRhZzpHVlpYVUZGd2JwTVZZL0tDTE5FTkFRPT0sdHlwZTpmbG9hdF0iLAoJImtleTMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp5NHRCYU5nPSxpdjptSHVZcnRmMEtlL29IQmN1bnBnZFBwemFZa0J4N1VqTWNPUWdwbVZjOC9RPSx0YWc6Y3VFZzJVRTE3UG82b3BmcEg4aWtvZz09LHR5cGU6Ym9vbF0iLAoJInNvcHMiOiB7CgkJImttcyI6IG51bGwsCgkJImdjcF9rbXMiOiBudWxsLAoJCSJhenVyZV9rdiI6IG51bGwsCgkJImhjX3ZhdWx0IjogbnVsbCwKCQkiYWdlIjogWwoJCQl7CgkJCQkicmVjaXBpZW50IjogImFnZTFkamxsdzJwenVwcnJxYzBlbjVtOHZjOGs1Z2UzdG0wZjZnN2NqMGMwZ2xmenA0NHZkYzRxbDhuZ3Z1IiwKCQkJCSJlbmMiOiAiLS0tLS1CRUdJTiBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQk9XbEF4ZWtWTk5YZGplblY1Y21kUlxuWkRsUVUzTjVXQzlvZUVOVWJVcFljV3hrZVU5a1ZTOVRlVVIzQ201emJHaElMMEo2V0c5VFdpOUtSM1pVVFZwaFxuYmxwaVVEWnRRa2xuV2xSclNHWnpUWGxaTjJaNldqZ0tMUzB0SURJM1pITkhSME5tV1RNemRUZzBkRXRYY1U5M1xuYkVkTlduZEtkV1JPV0dkTGRIQXdUR0Z0Ukdsc2FEUUtWN0hKRzYyOXJQV0RCWTA0Nkh4ajR1dHhVa2V4M1N3VVxuVlVRUlgwMHA2cjlmZmMraUM1REdVbS9LT2tldEFIdW5PNEtuMHVPUzRXSGcrSmcyQ3d1NzJRPT1cbi0tLS0tRU5EIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG4iCgkJCX0KCQldLAoJCSJsYXN0bW9kaWZpZWQiOiAiMjAyMi0wMy0yOVQyMTowMjozMloiLAoJCSJtYWMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YToydm16d1c3NE9TSnExOEdFY1NjcE1INzZBV3JoSmRFTmxLdzJ2UnpHclFmUGl4VE5jcndKMG5lVEgrQnZHS2ZSOU9sTFIyRVpUaGVScGhRMElrYjRTZGhmSW5vRGpIbyswalhON1JRNG5lVGxrbzRqL1lSVmVrNjFvZVBnQUtBcWNtdkwySWh6UkdPMlZSOG5EUHVKdXZSQ21QNXdPTU9Ca2VyeWRSS0hlRGM9LGl2Ok5IV1BOV0RtdWhla0pVSUpwQzFjREo1MWxMS1RzWExFNmRDNHRwdy9xU0k9LHRhZzp5VjVuZ1JkSVlaZlVnajZudHNZNUNRPT0sdHlwZTpzdHJdIiwKCQkicGdwIjogbnVsbCwKCQkidW5lbmNyeXB0ZWRfc3VmZml4IjogIl91bmVuY3J5cHRlZCIsCgkJInZlcnNpb24iOiAiMy43LjIiCgl9Cn0=", "Hash": "2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649" }, - "ConvertToJSON": true, - "Flatten": true, "FlattenSeparator": ".", "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET", + "Target": { + "Ref": "SopsSecretJSON72040543" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -198,7 +195,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "71584c9f9a2d019cb5df6044c81ca32662370c709381898a7d72f8c7d40a21a4.zip" + "S3Key": "87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186.zip" }, "Environment": { "Variables": { @@ -237,19 +234,16 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsSecretYAMLC392F558" - }, "SopsInline": { "Content": "a2V5MTogRU5DW0FFUzI1Nl9HQ00sZGF0YTpod2ZNM2JEMCxpdjo1T0JEMjg4c1B5TGhXdE82b2FWTkduT2NtazFOcmFCQ2QyVnhvcFd2S0R3PSx0YWc6a1JrYnNwK09Jd0l3aGUvaVhKbFB4UT09LHR5cGU6c3RyXQprZXkyOiBFTkNbQUVTMjU2X0dDTSxkYXRhOkgrdlpWTVU9LGl2Omxub08xckc4LzY0MDU0R3B2enA3SGRvd2g2TmhJQWNhYW5YZUZ3KzZWM3M9LHRhZzpNZkQrZmVKeDZDcGtnMTNyMkw1bENnPT0sdHlwZTppbnRdCmtleTM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6UnE4Y2FhMD0saXY6OW56c1ArSElYN3o1RjNzdHlSa1U0NDd0WE44NkdaL3l5bnN4QlFLM1lvTT0sdGFnOjhOUW1Hd2M0SEY5a3d5ZDF4dGk5aHc9PSx0eXBlOmJvb2xdCnNvcHM6CiAgICBrbXM6IFtdCiAgICBnY3Bfa21zOiBbXQogICAgYXp1cmVfa3Y6IFtdCiAgICBoY192YXVsdDogW10KICAgIGFnZToKICAgICAgICAtIHJlY2lwaWVudDogYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUKICAgICAgICAgIGVuYzogfAogICAgICAgICAgICAtLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tCiAgICAgICAgICAgIFlXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JOZVdkM2RHVjZNVTFzZERCWU5EVnQKICAgICAgICAgICAgYzJGNlMxSlNTazVqU25FMk0wVlZTMDgxZEZKT1dXTlllbXhWQ201TVVVWlVVRFZOT1Vod2RXRmFZalpRZDFWdwogICAgICAgICAgICBOWGtySzJJdmJtZ3hRVk5pVWxKa1pWaFRhbFJLU2trS0xTMHRJRkpIYVhneVRrMUhkMk5yZUV4V1dIRnVOVUp6CiAgICAgICAgICAgIFJVcFpUVVJ5VjFkRVRFMDVjbFZ1UTNScmVHc3JTbThLWjkxMFZXekZaajd1QU9oRTRvblBwemVmb2t1SCt4bnoKICAgICAgICAgICAgQlBKUFRodkQ4MFF3UFdVZGpKN1Fua1p6VzhGaGROM01JU2QwRzZ2TElqcTNTcUthY2RjcjZnPT0KICAgICAgICAgICAgLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgIGxhc3Rtb2RpZmllZDogIjIwMjItMDQtMDFUMjA6NDA6MTlaIgogICAgbWFjOiBFTkNbQUVTMjU2X0dDTSxkYXRhOjM5ZS9FbVdYeGVZZHpIZ01WRGQ4WUtRNW8zNk9DZGdGSk9HamU1cm5uRVU2bi8raWhmUDhUQlhBYTYySml0WFJEUW15Vm4wbWx2K3MrYjFJbzB6THNjd3d5ZHBLOUI2a25laFpBMjlwd1dJUy9hRkF1WStGMDhja2c5TjhIUUhRcXFaL0FLd0Q4UnRUMWdET0hXeG54MEpnQ2grdkw2Z0NOMlZIVzJpQzlIND0saXY6dEhnbjNqcEJJUTcyTHhRVjJHMTBrVzIxekMwbVNtQTZlNTVBUTNGcjJhMD0sdGFnOktraFhhVFpFS2kvSG5xVXpnWVJVTnc9PSx0eXBlOnN0cl0KICAgIHBncDogW10KICAgIHVuZW5jcnlwdGVkX3N1ZmZpeDogX3VuZW5jcnlwdGVkCiAgICB2ZXJzaW9uOiAzLjcuMgo=", "Hash": "c0d63dcd2d506c5d270284d70d1805688ff5d3a2e0d7515bfa56b1b3ed416c4f" }, - "ConvertToJSON": false, - "Flatten": true, "FlattenSeparator": ".", "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET_BINARY", + "Target": { + "Ref": "SopsSecretYAMLC392F558" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -271,19 +265,16 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsSecretYAMLasJSON64419C04" - }, "SopsInline": { "Content": "a2V5MTogRU5DW0FFUzI1Nl9HQ00sZGF0YTpod2ZNM2JEMCxpdjo1T0JEMjg4c1B5TGhXdE82b2FWTkduT2NtazFOcmFCQ2QyVnhvcFd2S0R3PSx0YWc6a1JrYnNwK09Jd0l3aGUvaVhKbFB4UT09LHR5cGU6c3RyXQprZXkyOiBFTkNbQUVTMjU2X0dDTSxkYXRhOkgrdlpWTVU9LGl2Omxub08xckc4LzY0MDU0R3B2enA3SGRvd2g2TmhJQWNhYW5YZUZ3KzZWM3M9LHRhZzpNZkQrZmVKeDZDcGtnMTNyMkw1bENnPT0sdHlwZTppbnRdCmtleTM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6UnE4Y2FhMD0saXY6OW56c1ArSElYN3o1RjNzdHlSa1U0NDd0WE44NkdaL3l5bnN4QlFLM1lvTT0sdGFnOjhOUW1Hd2M0SEY5a3d5ZDF4dGk5aHc9PSx0eXBlOmJvb2xdCnNvcHM6CiAgICBrbXM6IFtdCiAgICBnY3Bfa21zOiBbXQogICAgYXp1cmVfa3Y6IFtdCiAgICBoY192YXVsdDogW10KICAgIGFnZToKICAgICAgICAtIHJlY2lwaWVudDogYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUKICAgICAgICAgIGVuYzogfAogICAgICAgICAgICAtLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tCiAgICAgICAgICAgIFlXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JOZVdkM2RHVjZNVTFzZERCWU5EVnQKICAgICAgICAgICAgYzJGNlMxSlNTazVqU25FMk0wVlZTMDgxZEZKT1dXTlllbXhWQ201TVVVWlVVRFZOT1Vod2RXRmFZalpRZDFWdwogICAgICAgICAgICBOWGtySzJJdmJtZ3hRVk5pVWxKa1pWaFRhbFJLU2trS0xTMHRJRkpIYVhneVRrMUhkMk5yZUV4V1dIRnVOVUp6CiAgICAgICAgICAgIFJVcFpUVVJ5VjFkRVRFMDVjbFZ1UTNScmVHc3JTbThLWjkxMFZXekZaajd1QU9oRTRvblBwemVmb2t1SCt4bnoKICAgICAgICAgICAgQlBKUFRodkQ4MFF3UFdVZGpKN1Fua1p6VzhGaGROM01JU2QwRzZ2TElqcTNTcUthY2RjcjZnPT0KICAgICAgICAgICAgLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgIGxhc3Rtb2RpZmllZDogIjIwMjItMDQtMDFUMjA6NDA6MTlaIgogICAgbWFjOiBFTkNbQUVTMjU2X0dDTSxkYXRhOjM5ZS9FbVdYeGVZZHpIZ01WRGQ4WUtRNW8zNk9DZGdGSk9HamU1cm5uRVU2bi8raWhmUDhUQlhBYTYySml0WFJEUW15Vm4wbWx2K3MrYjFJbzB6THNjd3d5ZHBLOUI2a25laFpBMjlwd1dJUy9hRkF1WStGMDhja2c5TjhIUUhRcXFaL0FLd0Q4UnRUMWdET0hXeG54MEpnQ2grdkw2Z0NOMlZIVzJpQzlIND0saXY6dEhnbjNqcEJJUTcyTHhRVjJHMTBrVzIxekMwbVNtQTZlNTVBUTNGcjJhMD0sdGFnOktraFhhVFpFS2kvSG5xVXpnWVJVTnc9PSx0eXBlOnN0cl0KICAgIHBncDogW10KICAgIHVuZW5jcnlwdGVkX3N1ZmZpeDogX3VuZW5jcnlwdGVkCiAgICB2ZXJzaW9uOiAzLjcuMgo=", "Hash": "c0d63dcd2d506c5d270284d70d1805688ff5d3a2e0d7515bfa56b1b3ed416c4f" }, - "ConvertToJSON": true, - "Flatten": true, "FlattenSeparator": ".", "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET_BINARY", + "Target": { + "Ref": "SopsSecretYAMLasJSON64419C04" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -305,19 +296,16 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsSecretDOTENV13EC93B6" - }, "SopsInline": { "Content": "YmFuYW5lPUVOQ1tBRVMyNTZfR0NNLGRhdGE6S2ZDYm83WjgsaXY6ZXdES1ZaSDcvZkw0d1Jrc0N5U2I0TTlISWhaNCt3NDNtWGdtWVV0S3pVOD0sdGFnOkt1b0ZGVUE0N0xKTFdwREpKd2I3Y0E9PSx0eXBlOnN0cl0KY3J5cHQ9RU5DW0FFUzI1Nl9HQ00sZGF0YToyQnBXVjR3RzdHbzU5Znl4VG1RYXFLbkl1Zz09LGl2OklmRUh3UytSZTJHOElIY091eW9tdldmZ2IwRzZYNnNsUlNOb05jbEROajQ9LHRhZzo1NDFRVFBMVUpjdW52cDhMWkl2K3hRPT0sdHlwZTpzdHJdCnNvcHNfYWdlX19saXN0XzBfX21hcF9lbmM9LS0tLS1CRUdJTiBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQXdWRUpCY1hCcU1FdDZMM2xRVEZaTVxuWVVwbFNHUlBSRFZzTDJZME5GQk5ZV0Y1Y21aTGNYcGhjakZGQ21GeVVUVXZSalJSUlZoc09WZG1kMDluYmtaclxuZEc1d1RqZENZbFp4VG5sTVFXTkZkM0ZhVDNGdEswMEtMUzB0SUVJeVMycGpZVGxTU0RONVIwRnJlalpNZFVaa1xuTWxwbVJEVmpaazFTWlVWR1IwTkRkblZoV2podlZUZ0tzQjJNdlZyVWlKVTJxdk44eDhrVWhaZHZLUDFScXFmZFxudUh2YVhuVlowcHVMQ3lXNmJKUFBINDA4Tituc216Y1pJUzlYUHc5YVJwdFF2VVY1M081TlZ3PT1cbi0tLS0tRU5EIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG4Kc29wc19hZ2VfX2xpc3RfMF9fbWFwX3JlY2lwaWVudD1hZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dQpzb3BzX2xhc3Rtb2RpZmllZD0yMDI0LTA0LTI5VDExOjU4OjI3Wgpzb3BzX21hYz1FTkNbQUVTMjU2X0dDTSxkYXRhOldFWWdMdlNBaVpwYmdUcTY3b2F3UFlpZTN2dWpIVmlZRlI1MXExS05ZQ3ZwdFo5WFZtNndVQ2Z1VmVuRDc5TWdTU3lTVEVGeFY3QlhjYnFNSUtUUCthRzdLNVBLZUh1dUE5MXVFUHdLdXYvWDJFcmNRMHR0SFZkK1JERGxvdjk3dzhOT0tXcmdxTmhXbFE4UE00dUNveXNwdDBEUlRMREZtRWRMeTkvTEpuWT0saXY6VURJUUpEV24wbWdnWVpTdHo5eDB6SjlPSlFRN0dMcTBldXI4TTRLMXUwbz0sdGFnOmtwWW9LTjlBdVgrSTZYcFJRZldPRFE9PSx0eXBlOnN0cl0Kc29wc191bmVuY3J5cHRlZF9zdWZmaXg9X3VuZW5jcnlwdGVkCnNvcHNfdmVyc2lvbj0zLjguMQo=", "Hash": "50e5eafdf09ae2e57258067e3833ee033c15faeff45ae85f22a3b74c7302d7fd" }, - "ConvertToJSON": false, - "Flatten": true, "FlattenSeparator": ".", "Format": "dotenv", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET_BINARY", + "Target": { + "Ref": "SopsSecretDOTENV13EC93B6" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -339,19 +327,16 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsSecretDOTENVasJSONC46F5173" - }, "SopsInline": { "Content": "YmFuYW5lPUVOQ1tBRVMyNTZfR0NNLGRhdGE6S2ZDYm83WjgsaXY6ZXdES1ZaSDcvZkw0d1Jrc0N5U2I0TTlISWhaNCt3NDNtWGdtWVV0S3pVOD0sdGFnOkt1b0ZGVUE0N0xKTFdwREpKd2I3Y0E9PSx0eXBlOnN0cl0KY3J5cHQ9RU5DW0FFUzI1Nl9HQ00sZGF0YToyQnBXVjR3RzdHbzU5Znl4VG1RYXFLbkl1Zz09LGl2OklmRUh3UytSZTJHOElIY091eW9tdldmZ2IwRzZYNnNsUlNOb05jbEROajQ9LHRhZzo1NDFRVFBMVUpjdW52cDhMWkl2K3hRPT0sdHlwZTpzdHJdCnNvcHNfYWdlX19saXN0XzBfX21hcF9lbmM9LS0tLS1CRUdJTiBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQXdWRUpCY1hCcU1FdDZMM2xRVEZaTVxuWVVwbFNHUlBSRFZzTDJZME5GQk5ZV0Y1Y21aTGNYcGhjakZGQ21GeVVUVXZSalJSUlZoc09WZG1kMDluYmtaclxuZEc1d1RqZENZbFp4VG5sTVFXTkZkM0ZhVDNGdEswMEtMUzB0SUVJeVMycGpZVGxTU0RONVIwRnJlalpNZFVaa1xuTWxwbVJEVmpaazFTWlVWR1IwTkRkblZoV2podlZUZ0tzQjJNdlZyVWlKVTJxdk44eDhrVWhaZHZLUDFScXFmZFxudUh2YVhuVlowcHVMQ3lXNmJKUFBINDA4Tituc216Y1pJUzlYUHc5YVJwdFF2VVY1M081TlZ3PT1cbi0tLS0tRU5EIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG4Kc29wc19hZ2VfX2xpc3RfMF9fbWFwX3JlY2lwaWVudD1hZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dQpzb3BzX2xhc3Rtb2RpZmllZD0yMDI0LTA0LTI5VDExOjU4OjI3Wgpzb3BzX21hYz1FTkNbQUVTMjU2X0dDTSxkYXRhOldFWWdMdlNBaVpwYmdUcTY3b2F3UFlpZTN2dWpIVmlZRlI1MXExS05ZQ3ZwdFo5WFZtNndVQ2Z1VmVuRDc5TWdTU3lTVEVGeFY3QlhjYnFNSUtUUCthRzdLNVBLZUh1dUE5MXVFUHdLdXYvWDJFcmNRMHR0SFZkK1JERGxvdjk3dzhOT0tXcmdxTmhXbFE4UE00dUNveXNwdDBEUlRMREZtRWRMeTkvTEpuWT0saXY6VURJUUpEV24wbWdnWVpTdHo5eDB6SjlPSlFRN0dMcTBldXI4TTRLMXUwbz0sdGFnOmtwWW9LTjlBdVgrSTZYcFJRZldPRFE9PSx0eXBlOnN0cl0Kc29wc191bmVuY3J5cHRlZF9zdWZmaXg9X3VuZW5jcnlwdGVkCnNvcHNfdmVyc2lvbj0zLjguMQo=", "Hash": "50e5eafdf09ae2e57258067e3833ee033c15faeff45ae85f22a3b74c7302d7fd" }, - "ConvertToJSON": true, - "Flatten": true, "FlattenSeparator": ".", "Format": "dotenv", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET", + "Target": { + "Ref": "SopsSecretDOTENVasJSONC46F5173" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -373,19 +358,16 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsComplexSecretJSONAD4C2662" - }, "SopsInline": { "Content": "ewoJInNvbWUiOiB7CgkJImRlZXAiOiB7CgkJCSJuZXN0ZWQiOiB7CgkJCQkib2JqZWN0IjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6eXVrSHVHc0Qwd2dZLGl2OlVnaG44T2dOY2RJUFN6MWhYQ3BjbkpPRFNEcmsxOXkwVU1jd1F6VFJKRmM9LHRhZzp3T3BhMDNQZHA2M2VlVkwxdDlHUHdBPT0sdHlwZTpzdHJdIiwKCQkJCSJhcnJheXMiOiBbCgkJCQkJIkVOQ1tBRVMyNTZfR0NNLGRhdGE6TTMrOHZnPT0saXY6R0RyUWxSbkgwUDMybWxEOWVaTW92aEo0Tms2ck1iL0U3OUdRNXVQYmEwND0sdGFnOmFiT3YzeXNVMVlrOTZtdXhMR3lPSFE9PSx0eXBlOnN0cl0iLAoJCQkJCSJFTkNbQUVTMjU2X0dDTSxkYXRhOjBOQzBHTDVwUkE9PSxpdjorSkg2MlJTa253NkFYTjZ2TVBEQjJnbTlSUnRuQ2h4UHo4dHc5OVgvNnkwPSx0YWc6WlBLekhDWTY2SEswQmF1a2p2Wmx2UT09LHR5cGU6c3RyXSIsCgkJCQkJewoJCQkJCQkidmFsdWVzIjogewoJCQkJCQkJImFuZCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOlBWam5aMlptOWc9PSxpdjpXQWVORFQ0eGw5WEtYbmtHQXJzREthTjZUeFJUSTh1V090bjh4K0cwaG5NPSx0YWc6U3lMaWI4UlBONjVweXFrRmdQaGxWQT09LHR5cGU6c3RyXSIKCQkJCQkJfQoJCQkJCX0KCQkJCV0KCQkJfQoJCX0sCgkJIm5vdHNvZGVlcCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOktTZjZwbDFlLGl2Ok9LUjUraHc2R0N6Ym03NTBzQWxBWFc4L0c0U2U4QnUxRldISHRFZW5ZZVU9LHRhZzo1aGxGMDNPbTdxVmNKVUczVTk1dXZRPT0sdHlwZTpzdHJdIgoJfSwKCSJhbmQgbm93IjogewoJCSJzb21lIjogWwoJCQl7CgkJCQkiYmFzaWMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpLQm80L2swPSxpdjprcDRneGhDcFduUC9WdkluRkJObHdYVEU2c2s0OE4zMjJzQWFHc05lZWJrPSx0YWc6RTQ1encxMmxrUmdLZEVJSC9BUm55QT09LHR5cGU6Ym9vbF0iCgkJCX0sCgkJCXsKCQkJCSJuZXN0ZWQiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpyekpzMW04PSxpdjorb1JuWFlQYTZKYnYvaU50MVFrbnloZFI3WjY3ZlZIVnEybnZxM0daT1RVPSx0YWc6QVdMaHRENEUvK0VISURKZ2lwcU0xQT09LHR5cGU6ZmxvYXRdIgoJCQl9LAoJCQl7CgkJCQkidHlwZSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOm5haFYzQk5FLGl2OmlkZGppenRqUmFVcVRhUzZ1VlRQUERpWEhOWVJEQytvSVBEODE5L0dDUnM9LHRhZzpxRDRienRDR3c5QzR3aTBLbDd2TFV3PT0sdHlwZTpmbG9hdF0iCgkJCX0sCgkJCXsKCQkJCSJ0ZXN0cyI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOjhvZlhUSE5ENnc9PSxpdjpEcktvNHJ2M3ZWL044YjFTNWRUaUpHeUxITmx2bnJYOGdJWkRxTnpxMWVnPSx0YWc6Z0ZQbmRWOTZyT2sxUjBkQXplZm11QT09LHR5cGU6c3RyXSIKCQkJfQoJCV0KCX0sCgkic29wcyI6IHsKCQkia21zIjogbnVsbCwKCQkiZ2NwX2ttcyI6IG51bGwsCgkJImF6dXJlX2t2IjogbnVsbCwKCQkiaGNfdmF1bHQiOiBudWxsLAoJCSJhZ2UiOiBbCgkJCXsKCQkJCSJyZWNpcGllbnQiOiAiYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUiLAoJCQkJImVuYyI6ICItLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG5ZV2RsTFdWdVkzSjVjSFJwYjI0dWIzSm5MM1l4Q2kwK0lGZ3lOVFV4T1NBeFQzTkdVMEpFVDBOaVkxTlFjbTluXG5aRlpRU0NzMU56ZFphRWt2U0dobVREVjZiRkJIWTJWWmEyZGpDa2xDWmtKNFZ5OVNUbEJ1ZDJwclNtNUtSMWhyXG5OMGhwYURkb1dHdHhha1I2TVdnNVVqSTBTWEJpYlVVS0xTMHRJSGR0UjI5U1dUSXhXbWhNZW5sYWVVNXhlbTl1XG5LemhLYTNOS2JHcDJkRlZ4TVRWdVdpOVZkWEozTVc4S2FuejNEcElnUFhPOXU0NFRVc1RQdGd3VExiUDZZcFVmXG5Kb3Y0VDJvTHk0VW82NjhSTkNCMWZiS250NW55Y21SSnhlK3JZbU92bjJWZUw5dldjdzBrWnc9PVxuLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS1cbiIKCQkJfQoJCV0sCgkJImxhc3Rtb2RpZmllZCI6ICIyMDIyLTA0LTAzVDE3OjI0OjI0WiIsCgkJIm1hYyI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOm1VU0tGeVlxYnhRV2lyZnpOdnlOTXZySjkraiszUTlzL0FSak9XSlpPSnJBeXBKWVB0YlphL2R1U0w0Q3pCVzZLZExmOVlSZkk3SGppS1g1RzhTVUw5ZjVCekFYSUdCcS9EQUVmYVhaOEFyekhmSzR0dHg5UGUydEwrRGpPLy9tSEdFSjg4SllFVmpyRU1MRytORGE5YXJwREtLOCtPNEx1RUNTb0NhYWFxST0saXY6MlcyVnRDVkdmc2tvb1dNQWlMb0xMY0RndTlQdXcyQ2YzZGkyaVRZdlBjVT0sdGFnOjVlcG44U2FFOERFMkVLUm1iSW8xZ2c9PSx0eXBlOnN0cl0iLAoJCSJwZ3AiOiBudWxsLAoJCSJ1bmVuY3J5cHRlZF9zdWZmaXgiOiAiX3VuZW5jcnlwdGVkIiwKCQkidmVyc2lvbiI6ICIzLjcuMiIKCX0KfQ==", "Hash": "313aad921c737076a990ead756b250f1677aecc927177440df0c809cd56bf282" }, - "ConvertToJSON": true, - "Flatten": false, "FlattenSeparator": ".", "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET", + "Target": { + "Ref": "SopsComplexSecretJSONAD4C2662" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -407,19 +389,16 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, "SopsInline": { "Content": "ewoJInNvbWUiOiB7CgkJImRlZXAiOiB7CgkJCSJuZXN0ZWQiOiB7CgkJCQkib2JqZWN0IjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6eXVrSHVHc0Qwd2dZLGl2OlVnaG44T2dOY2RJUFN6MWhYQ3BjbkpPRFNEcmsxOXkwVU1jd1F6VFJKRmM9LHRhZzp3T3BhMDNQZHA2M2VlVkwxdDlHUHdBPT0sdHlwZTpzdHJdIiwKCQkJCSJhcnJheXMiOiBbCgkJCQkJIkVOQ1tBRVMyNTZfR0NNLGRhdGE6TTMrOHZnPT0saXY6R0RyUWxSbkgwUDMybWxEOWVaTW92aEo0Tms2ck1iL0U3OUdRNXVQYmEwND0sdGFnOmFiT3YzeXNVMVlrOTZtdXhMR3lPSFE9PSx0eXBlOnN0cl0iLAoJCQkJCSJFTkNbQUVTMjU2X0dDTSxkYXRhOjBOQzBHTDVwUkE9PSxpdjorSkg2MlJTa253NkFYTjZ2TVBEQjJnbTlSUnRuQ2h4UHo4dHc5OVgvNnkwPSx0YWc6WlBLekhDWTY2SEswQmF1a2p2Wmx2UT09LHR5cGU6c3RyXSIsCgkJCQkJewoJCQkJCQkidmFsdWVzIjogewoJCQkJCQkJImFuZCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOlBWam5aMlptOWc9PSxpdjpXQWVORFQ0eGw5WEtYbmtHQXJzREthTjZUeFJUSTh1V090bjh4K0cwaG5NPSx0YWc6U3lMaWI4UlBONjVweXFrRmdQaGxWQT09LHR5cGU6c3RyXSIKCQkJCQkJfQoJCQkJCX0KCQkJCV0KCQkJfQoJCX0sCgkJIm5vdHNvZGVlcCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOktTZjZwbDFlLGl2Ok9LUjUraHc2R0N6Ym03NTBzQWxBWFc4L0c0U2U4QnUxRldISHRFZW5ZZVU9LHRhZzo1aGxGMDNPbTdxVmNKVUczVTk1dXZRPT0sdHlwZTpzdHJdIgoJfSwKCSJhbmQgbm93IjogewoJCSJzb21lIjogWwoJCQl7CgkJCQkiYmFzaWMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpLQm80L2swPSxpdjprcDRneGhDcFduUC9WdkluRkJObHdYVEU2c2s0OE4zMjJzQWFHc05lZWJrPSx0YWc6RTQ1encxMmxrUmdLZEVJSC9BUm55QT09LHR5cGU6Ym9vbF0iCgkJCX0sCgkJCXsKCQkJCSJuZXN0ZWQiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpyekpzMW04PSxpdjorb1JuWFlQYTZKYnYvaU50MVFrbnloZFI3WjY3ZlZIVnEybnZxM0daT1RVPSx0YWc6QVdMaHRENEUvK0VISURKZ2lwcU0xQT09LHR5cGU6ZmxvYXRdIgoJCQl9LAoJCQl7CgkJCQkidHlwZSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOm5haFYzQk5FLGl2OmlkZGppenRqUmFVcVRhUzZ1VlRQUERpWEhOWVJEQytvSVBEODE5L0dDUnM9LHRhZzpxRDRienRDR3c5QzR3aTBLbDd2TFV3PT0sdHlwZTpmbG9hdF0iCgkJCX0sCgkJCXsKCQkJCSJ0ZXN0cyI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOjhvZlhUSE5ENnc9PSxpdjpEcktvNHJ2M3ZWL044YjFTNWRUaUpHeUxITmx2bnJYOGdJWkRxTnpxMWVnPSx0YWc6Z0ZQbmRWOTZyT2sxUjBkQXplZm11QT09LHR5cGU6c3RyXSIKCQkJfQoJCV0KCX0sCgkic29wcyI6IHsKCQkia21zIjogbnVsbCwKCQkiZ2NwX2ttcyI6IG51bGwsCgkJImF6dXJlX2t2IjogbnVsbCwKCQkiaGNfdmF1bHQiOiBudWxsLAoJCSJhZ2UiOiBbCgkJCXsKCQkJCSJyZWNpcGllbnQiOiAiYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUiLAoJCQkJImVuYyI6ICItLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG5ZV2RsTFdWdVkzSjVjSFJwYjI0dWIzSm5MM1l4Q2kwK0lGZ3lOVFV4T1NBeFQzTkdVMEpFVDBOaVkxTlFjbTluXG5aRlpRU0NzMU56ZFphRWt2U0dobVREVjZiRkJIWTJWWmEyZGpDa2xDWmtKNFZ5OVNUbEJ1ZDJwclNtNUtSMWhyXG5OMGhwYURkb1dHdHhha1I2TVdnNVVqSTBTWEJpYlVVS0xTMHRJSGR0UjI5U1dUSXhXbWhNZW5sYWVVNXhlbTl1XG5LemhLYTNOS2JHcDJkRlZ4TVRWdVdpOVZkWEozTVc4S2FuejNEcElnUFhPOXU0NFRVc1RQdGd3VExiUDZZcFVmXG5Kb3Y0VDJvTHk0VW82NjhSTkNCMWZiS250NW55Y21SSnhlK3JZbU92bjJWZUw5dldjdzBrWnc9PVxuLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS1cbiIKCQkJfQoJCV0sCgkJImxhc3Rtb2RpZmllZCI6ICIyMDIyLTA0LTAzVDE3OjI0OjI0WiIsCgkJIm1hYyI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOm1VU0tGeVlxYnhRV2lyZnpOdnlOTXZySjkraiszUTlzL0FSak9XSlpPSnJBeXBKWVB0YlphL2R1U0w0Q3pCVzZLZExmOVlSZkk3SGppS1g1RzhTVUw5ZjVCekFYSUdCcS9EQUVmYVhaOEFyekhmSzR0dHg5UGUydEwrRGpPLy9tSEdFSjg4SllFVmpyRU1MRytORGE5YXJwREtLOCtPNEx1RUNTb0NhYWFxST0saXY6MlcyVnRDVkdmc2tvb1dNQWlMb0xMY0RndTlQdXcyQ2YzZGkyaVRZdlBjVT0sdGFnOjVlcG44U2FFOERFMkVLUm1iSW8xZ2c9PSx0eXBlOnN0cl0iLAoJCSJwZ3AiOiBudWxsLAoJCSJ1bmVuY3J5cHRlZF9zdWZmaXgiOiAiX3VuZW5jcnlwdGVkIiwKCQkidmVyc2lvbiI6ICIzLjcuMiIKCX0KfQ==", "Hash": "313aad921c737076a990ead756b250f1677aecc927177440df0c809cd56bf282" }, - "ConvertToJSON": true, - "Flatten": true, "FlattenSeparator": ".", "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET", + "Target": { + "Ref": "SopsComplexSecretJSONFlatF5FC1D69" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -441,19 +420,16 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopComplexSecretYAMLF52D88F2" - }, "SopsInline": { "Content": "c29tZToKICAgIGRlZXA6CiAgICAgICAgbmVzdGVkOgogICAgICAgICAgICBvYmplY3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6WW1kZVJGRUdLS1VULGl2OjhPOVFVdlU3ZzFFK2F3WUtYU3hra3pVS3pCYzhhZFVEdG1QaXdqdFBQYjA9LHRhZzozT3Q4eU5DbzJwM1JIMERUNStBa2JRPT0sdHlwZTpzdHJdCiAgICAgICAgICAgIGFycmF5czoKICAgICAgICAgICAgICAgIC0gRU5DW0FFUzI1Nl9HQ00sZGF0YTpoYWFEWnc9PSxpdjo0L2FVZ3NFbXNVcEUvMUs1aUdiQjJJQmNiWm0wUDdrM2lMNElSOWtPbkFJPSx0YWc6bkFhc1MvLzEvWEFBU3Myc2I2dklUQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSBFTkNbQUVTMjU2X0dDTSxkYXRhOlZvalRZbUVpbHc9PSxpdjppMi9zRm05TXBMYjRML1dZeWtCNGJ4THVvN3FadjVOcmRTSGNNK2dZaGh3PSx0YWc6NS8rTTZlRUlkc2IvYjN3clhQanNtQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSB2YWx1ZXM6CiAgICAgICAgICAgICAgICAgICAgYW5kOiBFTkNbQUVTMjU2X0dDTSxkYXRhOkJnOTI0dExUWmc9PSxpdjprOEFFYkw4Vkd0NXViS0tOV1JYVVBlTVF4ODRjeFBDb1EweVd4NkR2d29jPSx0YWc6bzhjUnRHSnh0Q3RKYTdCajNaMG0yQT09LHR5cGU6c3RyXQogICAgbm90c29kZWVwOiBFTkNbQUVTMjU2X0dDTSxkYXRhOndwaU15cExoLGl2OmhpTG9BZGd6RTlQYlNrMjEydTNJamlnRXp4aU5nYUtWZysyU2pqRUZ1bkU9LHRhZzpkTGwxdTVSOUYxMDVKN3FJNWMzb0V3PT0sdHlwZTpzdHJdCmFuZCBub3c6CiAgICBzb21lOgogICAgICAgIC0gYmFzaWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6bU9od0duYz0saXY6ZGdNaklaTkl6QlZUZE0wTHllVHdKYk92cmh0TDNDZUVWSlFRYVplRkdvWT0sdGFnOm9CU3dEanlEQXlGZ2xJVFlCdnNIZVE9PSx0eXBlOmJvb2xdCiAgICAgICAgLSBuZXN0ZWQ6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6c2dzcTJLYz0saXY6MmoxQ0R6cXdDU3dvK1E4eHpOV2FpUVB3ZUMvOFZSMGlwMjVmeFFuNitubz0sdGFnOjl4RHFyZERjSDA3VkVock9hSzdMemc9PSx0eXBlOmludF0KICAgICAgICAtIHR5cGU6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6dDlpSUpVazAsaXY6NVl1K2tDV1BJNzZ1QzR0OUZqMTdnRVdWYytScHB2eXNZSFluMVJQV1ZRMD0sdGFnOlRCaHowb0d2aGJPRWZoU0FsMEFsd3c9PSx0eXBlOmZsb2F0XQogICAgICAgIC0gdGVzdHM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6S2xoa21RREQxQT09LGl2Om1zT1dBb0duc0I4bGNreTBIZUJ1WFlYN0JYY2xxVmZNMm95cldKcm5FNzA9LHRhZzphcENTNlFtYVZiVXpkc3VsOWw5V0NnPT0sdHlwZTpzdHJdCnNvcHM6CiAgICBrbXM6IFtdCiAgICBnY3Bfa21zOiBbXQogICAgYXp1cmVfa3Y6IFtdCiAgICBoY192YXVsdDogW10KICAgIGFnZToKICAgICAgICAtIHJlY2lwaWVudDogYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUKICAgICAgICAgIGVuYzogfAogICAgICAgICAgICAtLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tCiAgICAgICAgICAgIFlXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JhVVZCQ1JWaDFTbVZxYkc1RGVuRmEKICAgICAgICAgICAgYnk5SVUyNHJPSGRWTWtjMFkxTkNhQ3RxUVRFd2R6WnFXVzF2Q2t4NU5YQk1aa1pDZVRrdlFXMXRVRWR2UjJseQogICAgICAgICAgICBNV2xTVEUxalZXdEhkMFJvYTNSUFMzVktRalJUWWxVS0xTMHRJRGhDWjNNMlFWZFZiMmwwUzBOUE1ETlNhbFZTCiAgICAgICAgICAgIE5WbzRaVlZTTkhGUFJHRnllbkJxTjJ0UE5XUndOemdLeHBUZmlKRkJtTjlPd1F5SDJrSVMxUHBoTmllQ0tNcFoKICAgICAgICAgICAgeWtXQXRoS1oyYTM1dnpHcGRiMFVWVFVjM2hReG93Nm5KQ0dlUExndkxHQ05FSytCWDluUTV3PT0KICAgICAgICAgICAgLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgIGxhc3Rtb2RpZmllZDogIjIwMjItMDQtMDNUMTc6MjU6MjRaIgogICAgbWFjOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNZRGo5eGsrUktYZ3pCR0JOVHpzcUNjSGdMVjBqak9JMXE1U3lTTGhsYnNHNjNjaDdmWGVkWkxzT0p0V2hGNXgxdjIyZmZVU1lVK0hITVFnQnBQUklsa0h1R1FDU1hrOEt5dGg0eUlmUnBZcmVKYlUzaC9ZNmNEMjcycWNYWHJqK0V5QlFEM3k1dzZiU2RGYXRLeFgvVmk0VG1uZ3JNL2F6ajRqTHp1L3UrST0saXY6ajBiMFd2d0paa3RuNWwxcG91V2RFOE1xNllsMXlqdWxDNTlKbENUMGhFdz0sdGFnOmY2RzBEQjc3bURwcWxvV25hZGMzVWc9PSx0eXBlOnN0cl0KICAgIHBncDogW10KICAgIHVuZW5jcnlwdGVkX3N1ZmZpeDogX3VuZW5jcnlwdGVkCiAgICB2ZXJzaW9uOiAzLjcuMgo=", "Hash": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2" }, - "ConvertToJSON": false, - "Flatten": false, "FlattenSeparator": ".", "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET", + "Target": { + "Ref": "SopComplexSecretYAMLF52D88F2" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -475,19 +451,16 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopComplexSecretYAMLFlatD9CE8782" - }, "SopsInline": { "Content": "c29tZToKICAgIGRlZXA6CiAgICAgICAgbmVzdGVkOgogICAgICAgICAgICBvYmplY3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6WW1kZVJGRUdLS1VULGl2OjhPOVFVdlU3ZzFFK2F3WUtYU3hra3pVS3pCYzhhZFVEdG1QaXdqdFBQYjA9LHRhZzozT3Q4eU5DbzJwM1JIMERUNStBa2JRPT0sdHlwZTpzdHJdCiAgICAgICAgICAgIGFycmF5czoKICAgICAgICAgICAgICAgIC0gRU5DW0FFUzI1Nl9HQ00sZGF0YTpoYWFEWnc9PSxpdjo0L2FVZ3NFbXNVcEUvMUs1aUdiQjJJQmNiWm0wUDdrM2lMNElSOWtPbkFJPSx0YWc6bkFhc1MvLzEvWEFBU3Myc2I2dklUQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSBFTkNbQUVTMjU2X0dDTSxkYXRhOlZvalRZbUVpbHc9PSxpdjppMi9zRm05TXBMYjRML1dZeWtCNGJ4THVvN3FadjVOcmRTSGNNK2dZaGh3PSx0YWc6NS8rTTZlRUlkc2IvYjN3clhQanNtQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSB2YWx1ZXM6CiAgICAgICAgICAgICAgICAgICAgYW5kOiBFTkNbQUVTMjU2X0dDTSxkYXRhOkJnOTI0dExUWmc9PSxpdjprOEFFYkw4Vkd0NXViS0tOV1JYVVBlTVF4ODRjeFBDb1EweVd4NkR2d29jPSx0YWc6bzhjUnRHSnh0Q3RKYTdCajNaMG0yQT09LHR5cGU6c3RyXQogICAgbm90c29kZWVwOiBFTkNbQUVTMjU2X0dDTSxkYXRhOndwaU15cExoLGl2OmhpTG9BZGd6RTlQYlNrMjEydTNJamlnRXp4aU5nYUtWZysyU2pqRUZ1bkU9LHRhZzpkTGwxdTVSOUYxMDVKN3FJNWMzb0V3PT0sdHlwZTpzdHJdCmFuZCBub3c6CiAgICBzb21lOgogICAgICAgIC0gYmFzaWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6bU9od0duYz0saXY6ZGdNaklaTkl6QlZUZE0wTHllVHdKYk92cmh0TDNDZUVWSlFRYVplRkdvWT0sdGFnOm9CU3dEanlEQXlGZ2xJVFlCdnNIZVE9PSx0eXBlOmJvb2xdCiAgICAgICAgLSBuZXN0ZWQ6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6c2dzcTJLYz0saXY6MmoxQ0R6cXdDU3dvK1E4eHpOV2FpUVB3ZUMvOFZSMGlwMjVmeFFuNitubz0sdGFnOjl4RHFyZERjSDA3VkVock9hSzdMemc9PSx0eXBlOmludF0KICAgICAgICAtIHR5cGU6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6dDlpSUpVazAsaXY6NVl1K2tDV1BJNzZ1QzR0OUZqMTdnRVdWYytScHB2eXNZSFluMVJQV1ZRMD0sdGFnOlRCaHowb0d2aGJPRWZoU0FsMEFsd3c9PSx0eXBlOmZsb2F0XQogICAgICAgIC0gdGVzdHM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6S2xoa21RREQxQT09LGl2Om1zT1dBb0duc0I4bGNreTBIZUJ1WFlYN0JYY2xxVmZNMm95cldKcm5FNzA9LHRhZzphcENTNlFtYVZiVXpkc3VsOWw5V0NnPT0sdHlwZTpzdHJdCnNvcHM6CiAgICBrbXM6IFtdCiAgICBnY3Bfa21zOiBbXQogICAgYXp1cmVfa3Y6IFtdCiAgICBoY192YXVsdDogW10KICAgIGFnZToKICAgICAgICAtIHJlY2lwaWVudDogYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUKICAgICAgICAgIGVuYzogfAogICAgICAgICAgICAtLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tCiAgICAgICAgICAgIFlXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JhVVZCQ1JWaDFTbVZxYkc1RGVuRmEKICAgICAgICAgICAgYnk5SVUyNHJPSGRWTWtjMFkxTkNhQ3RxUVRFd2R6WnFXVzF2Q2t4NU5YQk1aa1pDZVRrdlFXMXRVRWR2UjJseQogICAgICAgICAgICBNV2xTVEUxalZXdEhkMFJvYTNSUFMzVktRalJUWWxVS0xTMHRJRGhDWjNNMlFWZFZiMmwwUzBOUE1ETlNhbFZTCiAgICAgICAgICAgIE5WbzRaVlZTTkhGUFJHRnllbkJxTjJ0UE5XUndOemdLeHBUZmlKRkJtTjlPd1F5SDJrSVMxUHBoTmllQ0tNcFoKICAgICAgICAgICAgeWtXQXRoS1oyYTM1dnpHcGRiMFVWVFVjM2hReG93Nm5KQ0dlUExndkxHQ05FSytCWDluUTV3PT0KICAgICAgICAgICAgLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgIGxhc3Rtb2RpZmllZDogIjIwMjItMDQtMDNUMTc6MjU6MjRaIgogICAgbWFjOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNZRGo5eGsrUktYZ3pCR0JOVHpzcUNjSGdMVjBqak9JMXE1U3lTTGhsYnNHNjNjaDdmWGVkWkxzT0p0V2hGNXgxdjIyZmZVU1lVK0hITVFnQnBQUklsa0h1R1FDU1hrOEt5dGg0eUlmUnBZcmVKYlUzaC9ZNmNEMjcycWNYWHJqK0V5QlFEM3k1dzZiU2RGYXRLeFgvVmk0VG1uZ3JNL2F6ajRqTHp1L3UrST0saXY6ajBiMFd2d0paa3RuNWwxcG91V2RFOE1xNllsMXlqdWxDNTlKbENUMGhFdz0sdGFnOmY2RzBEQjc3bURwcWxvV25hZGMzVWc9PSx0eXBlOnN0cl0KICAgIHBncDogW10KICAgIHVuZW5jcnlwdGVkX3N1ZmZpeDogX3VuZW5jcnlwdGVkCiAgICB2ZXJzaW9uOiAzLjcuMgo=", "Hash": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2" }, - "ConvertToJSON": false, - "Flatten": true, "FlattenSeparator": ".", "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET", + "Target": { + "Ref": "SopComplexSecretYAMLFlatD9CE8782" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -509,19 +482,16 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsComplexSecretYAMLasJSONEAE81DB0" - }, "SopsInline": { "Content": "c29tZToKICAgIGRlZXA6CiAgICAgICAgbmVzdGVkOgogICAgICAgICAgICBvYmplY3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6WW1kZVJGRUdLS1VULGl2OjhPOVFVdlU3ZzFFK2F3WUtYU3hra3pVS3pCYzhhZFVEdG1QaXdqdFBQYjA9LHRhZzozT3Q4eU5DbzJwM1JIMERUNStBa2JRPT0sdHlwZTpzdHJdCiAgICAgICAgICAgIGFycmF5czoKICAgICAgICAgICAgICAgIC0gRU5DW0FFUzI1Nl9HQ00sZGF0YTpoYWFEWnc9PSxpdjo0L2FVZ3NFbXNVcEUvMUs1aUdiQjJJQmNiWm0wUDdrM2lMNElSOWtPbkFJPSx0YWc6bkFhc1MvLzEvWEFBU3Myc2I2dklUQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSBFTkNbQUVTMjU2X0dDTSxkYXRhOlZvalRZbUVpbHc9PSxpdjppMi9zRm05TXBMYjRML1dZeWtCNGJ4THVvN3FadjVOcmRTSGNNK2dZaGh3PSx0YWc6NS8rTTZlRUlkc2IvYjN3clhQanNtQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSB2YWx1ZXM6CiAgICAgICAgICAgICAgICAgICAgYW5kOiBFTkNbQUVTMjU2X0dDTSxkYXRhOkJnOTI0dExUWmc9PSxpdjprOEFFYkw4Vkd0NXViS0tOV1JYVVBlTVF4ODRjeFBDb1EweVd4NkR2d29jPSx0YWc6bzhjUnRHSnh0Q3RKYTdCajNaMG0yQT09LHR5cGU6c3RyXQogICAgbm90c29kZWVwOiBFTkNbQUVTMjU2X0dDTSxkYXRhOndwaU15cExoLGl2OmhpTG9BZGd6RTlQYlNrMjEydTNJamlnRXp4aU5nYUtWZysyU2pqRUZ1bkU9LHRhZzpkTGwxdTVSOUYxMDVKN3FJNWMzb0V3PT0sdHlwZTpzdHJdCmFuZCBub3c6CiAgICBzb21lOgogICAgICAgIC0gYmFzaWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6bU9od0duYz0saXY6ZGdNaklaTkl6QlZUZE0wTHllVHdKYk92cmh0TDNDZUVWSlFRYVplRkdvWT0sdGFnOm9CU3dEanlEQXlGZ2xJVFlCdnNIZVE9PSx0eXBlOmJvb2xdCiAgICAgICAgLSBuZXN0ZWQ6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6c2dzcTJLYz0saXY6MmoxQ0R6cXdDU3dvK1E4eHpOV2FpUVB3ZUMvOFZSMGlwMjVmeFFuNitubz0sdGFnOjl4RHFyZERjSDA3VkVock9hSzdMemc9PSx0eXBlOmludF0KICAgICAgICAtIHR5cGU6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6dDlpSUpVazAsaXY6NVl1K2tDV1BJNzZ1QzR0OUZqMTdnRVdWYytScHB2eXNZSFluMVJQV1ZRMD0sdGFnOlRCaHowb0d2aGJPRWZoU0FsMEFsd3c9PSx0eXBlOmZsb2F0XQogICAgICAgIC0gdGVzdHM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6S2xoa21RREQxQT09LGl2Om1zT1dBb0duc0I4bGNreTBIZUJ1WFlYN0JYY2xxVmZNMm95cldKcm5FNzA9LHRhZzphcENTNlFtYVZiVXpkc3VsOWw5V0NnPT0sdHlwZTpzdHJdCnNvcHM6CiAgICBrbXM6IFtdCiAgICBnY3Bfa21zOiBbXQogICAgYXp1cmVfa3Y6IFtdCiAgICBoY192YXVsdDogW10KICAgIGFnZToKICAgICAgICAtIHJlY2lwaWVudDogYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUKICAgICAgICAgIGVuYzogfAogICAgICAgICAgICAtLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tCiAgICAgICAgICAgIFlXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JhVVZCQ1JWaDFTbVZxYkc1RGVuRmEKICAgICAgICAgICAgYnk5SVUyNHJPSGRWTWtjMFkxTkNhQ3RxUVRFd2R6WnFXVzF2Q2t4NU5YQk1aa1pDZVRrdlFXMXRVRWR2UjJseQogICAgICAgICAgICBNV2xTVEUxalZXdEhkMFJvYTNSUFMzVktRalJUWWxVS0xTMHRJRGhDWjNNMlFWZFZiMmwwUzBOUE1ETlNhbFZTCiAgICAgICAgICAgIE5WbzRaVlZTTkhGUFJHRnllbkJxTjJ0UE5XUndOemdLeHBUZmlKRkJtTjlPd1F5SDJrSVMxUHBoTmllQ0tNcFoKICAgICAgICAgICAgeWtXQXRoS1oyYTM1dnpHcGRiMFVWVFVjM2hReG93Nm5KQ0dlUExndkxHQ05FSytCWDluUTV3PT0KICAgICAgICAgICAgLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgIGxhc3Rtb2RpZmllZDogIjIwMjItMDQtMDNUMTc6MjU6MjRaIgogICAgbWFjOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNZRGo5eGsrUktYZ3pCR0JOVHpzcUNjSGdMVjBqak9JMXE1U3lTTGhsYnNHNjNjaDdmWGVkWkxzT0p0V2hGNXgxdjIyZmZVU1lVK0hITVFnQnBQUklsa0h1R1FDU1hrOEt5dGg0eUlmUnBZcmVKYlUzaC9ZNmNEMjcycWNYWHJqK0V5QlFEM3k1dzZiU2RGYXRLeFgvVmk0VG1uZ3JNL2F6ajRqTHp1L3UrST0saXY6ajBiMFd2d0paa3RuNWwxcG91V2RFOE1xNllsMXlqdWxDNTlKbENUMGhFdz0sdGFnOmY2RzBEQjc3bURwcWxvV25hZGMzVWc9PSx0eXBlOnN0cl0KICAgIHBncDogW10KICAgIHVuZW5jcnlwdGVkX3N1ZmZpeDogX3VuZW5jcnlwdGVkCiAgICB2ZXJzaW9uOiAzLjcuMgo=", "Hash": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2" }, - "ConvertToJSON": true, - "Flatten": false, "FlattenSeparator": ".", "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET", + "Target": { + "Ref": "SopsComplexSecretYAMLasJSONEAE81DB0" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -543,19 +513,16 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, "SopsInline": { "Content": "c29tZToKICAgIGRlZXA6CiAgICAgICAgbmVzdGVkOgogICAgICAgICAgICBvYmplY3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6WW1kZVJGRUdLS1VULGl2OjhPOVFVdlU3ZzFFK2F3WUtYU3hra3pVS3pCYzhhZFVEdG1QaXdqdFBQYjA9LHRhZzozT3Q4eU5DbzJwM1JIMERUNStBa2JRPT0sdHlwZTpzdHJdCiAgICAgICAgICAgIGFycmF5czoKICAgICAgICAgICAgICAgIC0gRU5DW0FFUzI1Nl9HQ00sZGF0YTpoYWFEWnc9PSxpdjo0L2FVZ3NFbXNVcEUvMUs1aUdiQjJJQmNiWm0wUDdrM2lMNElSOWtPbkFJPSx0YWc6bkFhc1MvLzEvWEFBU3Myc2I2dklUQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSBFTkNbQUVTMjU2X0dDTSxkYXRhOlZvalRZbUVpbHc9PSxpdjppMi9zRm05TXBMYjRML1dZeWtCNGJ4THVvN3FadjVOcmRTSGNNK2dZaGh3PSx0YWc6NS8rTTZlRUlkc2IvYjN3clhQanNtQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSB2YWx1ZXM6CiAgICAgICAgICAgICAgICAgICAgYW5kOiBFTkNbQUVTMjU2X0dDTSxkYXRhOkJnOTI0dExUWmc9PSxpdjprOEFFYkw4Vkd0NXViS0tOV1JYVVBlTVF4ODRjeFBDb1EweVd4NkR2d29jPSx0YWc6bzhjUnRHSnh0Q3RKYTdCajNaMG0yQT09LHR5cGU6c3RyXQogICAgbm90c29kZWVwOiBFTkNbQUVTMjU2X0dDTSxkYXRhOndwaU15cExoLGl2OmhpTG9BZGd6RTlQYlNrMjEydTNJamlnRXp4aU5nYUtWZysyU2pqRUZ1bkU9LHRhZzpkTGwxdTVSOUYxMDVKN3FJNWMzb0V3PT0sdHlwZTpzdHJdCmFuZCBub3c6CiAgICBzb21lOgogICAgICAgIC0gYmFzaWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6bU9od0duYz0saXY6ZGdNaklaTkl6QlZUZE0wTHllVHdKYk92cmh0TDNDZUVWSlFRYVplRkdvWT0sdGFnOm9CU3dEanlEQXlGZ2xJVFlCdnNIZVE9PSx0eXBlOmJvb2xdCiAgICAgICAgLSBuZXN0ZWQ6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6c2dzcTJLYz0saXY6MmoxQ0R6cXdDU3dvK1E4eHpOV2FpUVB3ZUMvOFZSMGlwMjVmeFFuNitubz0sdGFnOjl4RHFyZERjSDA3VkVock9hSzdMemc9PSx0eXBlOmludF0KICAgICAgICAtIHR5cGU6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6dDlpSUpVazAsaXY6NVl1K2tDV1BJNzZ1QzR0OUZqMTdnRVdWYytScHB2eXNZSFluMVJQV1ZRMD0sdGFnOlRCaHowb0d2aGJPRWZoU0FsMEFsd3c9PSx0eXBlOmZsb2F0XQogICAgICAgIC0gdGVzdHM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6S2xoa21RREQxQT09LGl2Om1zT1dBb0duc0I4bGNreTBIZUJ1WFlYN0JYY2xxVmZNMm95cldKcm5FNzA9LHRhZzphcENTNlFtYVZiVXpkc3VsOWw5V0NnPT0sdHlwZTpzdHJdCnNvcHM6CiAgICBrbXM6IFtdCiAgICBnY3Bfa21zOiBbXQogICAgYXp1cmVfa3Y6IFtdCiAgICBoY192YXVsdDogW10KICAgIGFnZToKICAgICAgICAtIHJlY2lwaWVudDogYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUKICAgICAgICAgIGVuYzogfAogICAgICAgICAgICAtLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tCiAgICAgICAgICAgIFlXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JhVVZCQ1JWaDFTbVZxYkc1RGVuRmEKICAgICAgICAgICAgYnk5SVUyNHJPSGRWTWtjMFkxTkNhQ3RxUVRFd2R6WnFXVzF2Q2t4NU5YQk1aa1pDZVRrdlFXMXRVRWR2UjJseQogICAgICAgICAgICBNV2xTVEUxalZXdEhkMFJvYTNSUFMzVktRalJUWWxVS0xTMHRJRGhDWjNNMlFWZFZiMmwwUzBOUE1ETlNhbFZTCiAgICAgICAgICAgIE5WbzRaVlZTTkhGUFJHRnllbkJxTjJ0UE5XUndOemdLeHBUZmlKRkJtTjlPd1F5SDJrSVMxUHBoTmllQ0tNcFoKICAgICAgICAgICAgeWtXQXRoS1oyYTM1dnpHcGRiMFVWVFVjM2hReG93Nm5KQ0dlUExndkxHQ05FSytCWDluUTV3PT0KICAgICAgICAgICAgLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgIGxhc3Rtb2RpZmllZDogIjIwMjItMDQtMDNUMTc6MjU6MjRaIgogICAgbWFjOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNZRGo5eGsrUktYZ3pCR0JOVHpzcUNjSGdMVjBqak9JMXE1U3lTTGhsYnNHNjNjaDdmWGVkWkxzT0p0V2hGNXgxdjIyZmZVU1lVK0hITVFnQnBQUklsa0h1R1FDU1hrOEt5dGg0eUlmUnBZcmVKYlUzaC9ZNmNEMjcycWNYWHJqK0V5QlFEM3k1dzZiU2RGYXRLeFgvVmk0VG1uZ3JNL2F6ajRqTHp1L3UrST0saXY6ajBiMFd2d0paa3RuNWwxcG91V2RFOE1xNllsMXlqdWxDNTlKbENUMGhFdz0sdGFnOmY2RzBEQjc3bURwcWxvV25hZGMzVWc9PSx0eXBlOnN0cl0KICAgIHBncDogW10KICAgIHVuZW5jcnlwdGVkX3N1ZmZpeDogX3VuZW5jcnlwdGVkCiAgICB2ZXJzaW9uOiAzLjcuMgo=", "Hash": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2" }, - "ConvertToJSON": true, - "Flatten": true, "FlattenSeparator": ".", "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET", + "Target": { + "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" diff --git a/test/secret-inline.integ.ts b/test/secret-inline.integ.ts index b6fcdd29..d6f7b057 100644 --- a/test/secret-inline.integ.ts +++ b/test/secret-inline.integ.ts @@ -16,7 +16,7 @@ new SopsSecret(stack, 'SopsSecretJSON', { new SopsSecret(stack, 'SopsSecretYAML', { sopsFilePath: 'test-secrets/yaml/sopsfile.enc-age.yaml', - convertToJSON: false, + rawOutput: true, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', @@ -25,7 +25,7 @@ new SopsSecret(stack, 'SopsSecretYAML', { new SopsSecret(stack, 'SopsSecretYAMLasJSON', { sopsFilePath: 'test-secrets/yaml/sopsfile.enc-age.yaml', - convertToJSON: true, + rawOutput: true, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', @@ -34,7 +34,7 @@ new SopsSecret(stack, 'SopsSecretYAMLasJSON', { new SopsSecret(stack, 'SopsSecretDOTENV', { sopsFilePath: 'test-secrets/dotenv/encrypted-best-secret.env', - convertToJSON: false, + rawOutput: true, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', @@ -43,7 +43,6 @@ new SopsSecret(stack, 'SopsSecretDOTENV', { new SopsSecret(stack, 'SopsSecretDOTENVasJSON', { sopsFilePath: 'test-secrets/dotenv/encrypted-best-secret.env', - convertToJSON: true, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', @@ -52,7 +51,6 @@ new SopsSecret(stack, 'SopsSecretDOTENVasJSON', { new SopsSecret(stack, 'SopsComplexSecretJSON', { sopsFilePath: 'test-secrets/json/sopsfile-complex.enc-age.json', - flatten: false, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', @@ -64,7 +62,6 @@ const sopsComplexSecretJSONFlat = new SopsSecret( 'SopsComplexSecretJSONFlat', { sopsFilePath: 'test-secrets/json/sopsfile-complex.enc-age.json', - flatten: true, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', @@ -74,8 +71,6 @@ const sopsComplexSecretJSONFlat = new SopsSecret( new SopsSecret(stack, 'SopComplexSecretYAML', { sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - convertToJSON: false, - flatten: false, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', @@ -84,8 +79,6 @@ new SopsSecret(stack, 'SopComplexSecretYAML', { new SopsSecret(stack, 'SopComplexSecretYAMLFlat', { sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - convertToJSON: false, - flatten: true, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', @@ -94,8 +87,6 @@ new SopsSecret(stack, 'SopComplexSecretYAMLFlat', { new SopsSecret(stack, 'SopsComplexSecretYAMLasJSON', { sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - convertToJSON: true, - flatten: false, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', @@ -107,8 +98,6 @@ const sopsComplexSecretYAMLasJSONFlat = new SopsSecret( 'SopsComplexSecretYAMLasJSONFlat', { sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - convertToJSON: true, - flatten: true, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', diff --git a/test/secret-manual.integ.snapshot/SecretIntegrationAsset.assets.json b/test/secret-manual.integ.snapshot/SecretIntegrationAsset.assets.json index 8e7b7417..5d4f2d77 100644 --- a/test/secret-manual.integ.snapshot/SecretIntegrationAsset.assets.json +++ b/test/secret-manual.integ.snapshot/SecretIntegrationAsset.assets.json @@ -1,20 +1,20 @@ { - "version": "36.0.0", + "version": "39.0.0", "files": { - "71584c9f9a2d019cb5df6044c81ca32662370c709381898a7d72f8c7d40a21a4": { + "87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186": { "source": { - "path": "asset.71584c9f9a2d019cb5df6044c81ca32662370c709381898a7d72f8c7d40a21a4.zip", + "path": "asset.87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186.zip", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "71584c9f9a2d019cb5df6044c81ca32662370c709381898a7d72f8c7d40a21a4.zip", + "objectKey": "87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "cbd798901289cce0c6e4c46d57c3c5dc432ce41487704d15c6582549466775a6": { + "19a59647220be293c0e14415e45809167fb8f8a037a3d0497e45cef7a555515e": { "source": { "path": "SecretIntegrationAsset.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "cbd798901289cce0c6e4c46d57c3c5dc432ce41487704d15c6582549466775a6.json", + "objectKey": "19a59647220be293c0e14415e45809167fb8f8a037a3d0497e45cef7a555515e.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/test/secret-manual.integ.snapshot/SecretIntegrationAsset.template.json b/test/secret-manual.integ.snapshot/SecretIntegrationAsset.template.json index 21dbd590..8c0e21de 100644 --- a/test/secret-manual.integ.snapshot/SecretIntegrationAsset.template.json +++ b/test/secret-manual.integ.snapshot/SecretIntegrationAsset.template.json @@ -17,19 +17,16 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsSecretJSON72040543" - }, "SopsS3File": { "Bucket": "testbucket", "Key": "secret.json" }, - "ConvertToJSON": true, - "Flatten": true, "FlattenSeparator": ".", "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET", + "Target": { + "Ref": "SopsSecretJSON72040543" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -72,7 +69,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "71584c9f9a2d019cb5df6044c81ca32662370c709381898a7d72f8c7d40a21a4.zip" + "S3Key": "87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186.zip" }, "Environment": { "Variables": { @@ -110,19 +107,16 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsSecretYAMLC392F558" - }, "SopsS3File": { "Bucket": "testbucket", "Key": "secret.json" }, - "ConvertToJSON": false, - "Flatten": true, "FlattenSeparator": ".", "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET_BINARY", + "Target": { + "Ref": "SopsSecretYAMLC392F558" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -144,19 +138,16 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsSecretYAMLasJSON64419C04" - }, "SopsS3File": { "Bucket": "testbucket", "Key": "secret.json" }, - "ConvertToJSON": true, - "Flatten": true, "FlattenSeparator": ".", "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET_BINARY", + "Target": { + "Ref": "SopsSecretYAMLasJSON64419C04" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -178,19 +169,16 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsComplexSecretJSONAD4C2662" - }, "SopsS3File": { "Bucket": "testbucket", "Key": "secret.json" }, - "ConvertToJSON": true, - "Flatten": false, "FlattenSeparator": ".", "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET_BINARY", + "Target": { + "Ref": "SopsComplexSecretJSONAD4C2662" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -212,19 +200,16 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, "SopsS3File": { "Bucket": "testbucket", "Key": "secret.json" }, - "ConvertToJSON": true, - "Flatten": true, "FlattenSeparator": ".", "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET_BINARY", + "Target": { + "Ref": "SopsComplexSecretJSONFlatF5FC1D69" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -246,19 +231,16 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopComplexSecretYAMLF52D88F2" - }, "SopsS3File": { "Bucket": "testbucket", "Key": "secret.yaml" }, - "ConvertToJSON": false, - "Flatten": false, "FlattenSeparator": ".", "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET_BINARY", + "Target": { + "Ref": "SopComplexSecretYAMLF52D88F2" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -280,19 +262,16 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopComplexSecretYAMLFlatD9CE8782" - }, "SopsS3File": { "Bucket": "testbucket", "Key": "secret.yaml" }, - "ConvertToJSON": false, - "Flatten": true, "FlattenSeparator": ".", "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET_BINARY", + "Target": { + "Ref": "SopComplexSecretYAMLFlatD9CE8782" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -314,19 +293,16 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsComplexSecretYAMLasJSONEAE81DB0" - }, "SopsS3File": { "Bucket": "testbucket", "Key": "secret.yaml" }, - "ConvertToJSON": true, - "Flatten": false, "FlattenSeparator": ".", "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET_BINARY", + "Target": { + "Ref": "SopsComplexSecretYAMLasJSONEAE81DB0" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -348,19 +324,16 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, "SopsS3File": { "Bucket": "testbucket", "Key": "secret.yaml" }, - "ConvertToJSON": true, - "Flatten": true, "FlattenSeparator": ".", "Format": "yaml", - "StringifiedValues": true, - "ResourceType": "SECRET" + "ResourceType": "SECRET", + "Target": { + "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" diff --git a/test/secret-manual.integ.ts b/test/secret-manual.integ.ts index efde44c0..77b98cf3 100644 --- a/test/secret-manual.integ.ts +++ b/test/secret-manual.integ.ts @@ -20,7 +20,7 @@ new SopsSecret(stack, 'SopsSecretYAML', { sopsS3Bucket: 'testbucket', sopsS3Key: 'secret.json', sopsFileFormat: 'json', - convertToJSON: false, + rawOutput: true, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', @@ -31,7 +31,7 @@ new SopsSecret(stack, 'SopsSecretYAMLasJSON', { sopsS3Bucket: 'testbucket', sopsS3Key: 'secret.json', sopsFileFormat: 'yaml', - convertToJSON: true, + rawOutput: true, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', @@ -42,7 +42,7 @@ new SopsSecret(stack, 'SopsComplexSecretJSON', { sopsS3Bucket: 'testbucket', sopsS3Key: 'secret.json', sopsFileFormat: 'json', - flatten: false, + rawOutput: true, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', @@ -56,7 +56,7 @@ const sopsComplexSecretJSONFlat = new SopsSecret( sopsS3Bucket: 'testbucket', sopsS3Key: 'secret.json', sopsFileFormat: 'json', - flatten: true, + rawOutput: true, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', @@ -68,8 +68,7 @@ new SopsSecret(stack, 'SopComplexSecretYAML', { sopsS3Bucket: 'testbucket', sopsS3Key: 'secret.yaml', sopsFileFormat: 'yaml', - convertToJSON: false, - flatten: false, + rawOutput: true, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', @@ -80,8 +79,7 @@ new SopsSecret(stack, 'SopComplexSecretYAMLFlat', { sopsS3Bucket: 'testbucket', sopsS3Key: 'secret.yaml', sopsFileFormat: 'yaml', - convertToJSON: false, - flatten: true, + rawOutput: true, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', @@ -92,8 +90,7 @@ new SopsSecret(stack, 'SopsComplexSecretYAMLasJSON', { sopsS3Bucket: 'testbucket', sopsS3Key: 'secret.yaml', sopsFileFormat: 'yaml', - convertToJSON: true, - flatten: false, + rawOutput: true, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', @@ -107,8 +104,6 @@ const sopsComplexSecretYAMLasJSONFlat = new SopsSecret( sopsS3Bucket: 'testbucket', sopsS3Key: 'secret.yaml', sopsFileFormat: 'yaml', - convertToJSON: true, - flatten: true, // see test-secrets/README.md for further information regarding the test file sopsAgeKey: SecretValue.unsafePlainText( 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', diff --git a/test/secret-multikms.integ.snapshot/SecretMultiKms.assets.json b/test/secret-multikms.integ.snapshot/SecretMultiKms.assets.json index d6254030..ad4c24e5 100644 --- a/test/secret-multikms.integ.snapshot/SecretMultiKms.assets.json +++ b/test/secret-multikms.integ.snapshot/SecretMultiKms.assets.json @@ -1,15 +1,15 @@ { - "version": "36.0.0", + "version": "39.0.0", "files": { - "71584c9f9a2d019cb5df6044c81ca32662370c709381898a7d72f8c7d40a21a4": { + "87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186": { "source": { - "path": "asset.71584c9f9a2d019cb5df6044c81ca32662370c709381898a7d72f8c7d40a21a4.zip", + "path": "asset.87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186.zip", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "71584c9f9a2d019cb5df6044c81ca32662370c709381898a7d72f8c7d40a21a4.zip", + "objectKey": "87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } @@ -27,7 +27,7 @@ } } }, - "c7ca4322ec89a67d983576a0211a865f3c27ff3ebbafa5d7c0f83da41603ac4e": { + "145eaec53312b66209121447805f22cf621c21f83a764ac0782eda0516ae54bd": { "source": { "path": "SecretMultiKms.template.json", "packaging": "file" @@ -35,7 +35,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "c7ca4322ec89a67d983576a0211a865f3c27ff3ebbafa5d7c0f83da41603ac4e.json", + "objectKey": "145eaec53312b66209121447805f22cf621c21f83a764ac0782eda0516ae54bd.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/test/secret-multikms.integ.snapshot/SecretMultiKms.template.json b/test/secret-multikms.integ.snapshot/SecretMultiKms.template.json index 7c45193e..d6807534 100644 --- a/test/secret-multikms.integ.snapshot/SecretMultiKms.template.json +++ b/test/secret-multikms.integ.snapshot/SecretMultiKms.template.json @@ -177,21 +177,21 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsSecretOwnKmsMey0B320436" - }, "SopsS3File": { "Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, "Key": "2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649.json" }, - "ConvertToJSON": true, - "Flatten": true, "FlattenSeparator": ".", "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" + "EncryptionKey": { + "Ref": "CustomKey1E6D0D07" + }, + "ResourceType": "SECRET", + "Target": { + "Ref": "SopsSecretOwnKmsMey0B320436" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -336,7 +336,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "71584c9f9a2d019cb5df6044c81ca32662370c709381898a7d72f8c7d40a21a4.zip" + "S3Key": "87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186.zip" }, "Environment": { "Variables": { @@ -376,21 +376,19 @@ "Arn" ] }, - "SecretARN": { - "Ref": "SopsSecretForeignKmsMey8C3BA0B7" - }, "SopsS3File": { "Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, "Key": "2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649.json" }, - "ConvertToJSON": true, - "Flatten": true, "FlattenSeparator": ".", "Format": "json", - "StringifiedValues": true, - "ResourceType": "SECRET" + "EncryptionKey": "12345678-1234-1234-1234-123456789012", + "ResourceType": "SECRET", + "Target": { + "Ref": "SopsSecretForeignKmsMey8C3BA0B7" + } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" diff --git a/yarn.lock b/yarn.lock index 4438ea25..5e07fc79 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10,6 +10,15 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.24" +"@apidevtools/json-schema-ref-parser@^11.5.5": + version "11.9.0" + resolved "https://registry.yarnpkg.com/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.9.0.tgz#863c1c15f0b87ec442f1c932b31823ea1d17ab51" + integrity sha512-8Q/r5mXLa8Rfyh6r4SgEEFJgISVN5cDNFlcfSWLgFn3odzQhTfHAqzI3hMGdcROViL+8NrDNVVFQtEUrYOksDg== + dependencies: + "@jsdevtools/ono" "^7.1.3" + "@types/json-schema" "^7.0.15" + js-yaml "^4.1.0" + "@asamuzakjp/css-color@^2.8.2": version "2.8.3" resolved "https://registry.yarnpkg.com/@asamuzakjp/css-color/-/css-color-2.8.3.tgz#665f0f5e8edb95d8f543847529e30fe5cc437ef7" @@ -21,21 +30,29 @@ "@csstools/css-tokenizer" "^3.0.3" lru-cache "^10.4.3" -"@aws-cdk/asset-awscli-v1@^2.2.202": - version "2.2.221" - resolved "https://registry.yarnpkg.com/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.221.tgz#747506051071610dbe054d7266208fd9afb2fff2" - integrity sha512-+Vu2cMvgtkaHwNezrTVng4+FAMAWKJTkC/2ZQlgkbY05k0lHHK/2eWKqBhTeA7EpxVrx9uFN7GdBFz3mcThpxg== +"@aws-cdk/asset-awscli-v1@^2.2.208": + version "2.2.222" + resolved "https://registry.yarnpkg.com/@aws-cdk/asset-awscli-v1/-/asset-awscli-v1-2.2.222.tgz#a1f912b93a038b4779ed04d63afcf8df20cb50ed" + integrity sha512-9qjd91FwBYmxjfF3ckieTKrmmvIBZdSe1Daf/hRGxAPnhtH9Fm5Y3Oi0dJD2tRw0ufyM6AbvX9zgejcTqXc+LQ== -"@aws-cdk/asset-kubectl-v20@^2.1.2": +"@aws-cdk/asset-kubectl-v20@^2.1.3": version "2.1.3" resolved "https://registry.yarnpkg.com/@aws-cdk/asset-kubectl-v20/-/asset-kubectl-v20-2.1.3.tgz#80e09004be173995e91614e34d947da11dd9ff4d" integrity sha512-cDG1w3ieM6eOT9mTefRuTypk95+oyD7P5X/wRltwmYxU7nZc3+076YEVS6vrjDKr3ADYbfn0lDKpfB1FBtO9CQ== -"@aws-cdk/asset-node-proxy-agent-v6@^2.0.3": +"@aws-cdk/asset-node-proxy-agent-v6@^2.1.0": version "2.1.0" resolved "https://registry.yarnpkg.com/@aws-cdk/asset-node-proxy-agent-v6/-/asset-node-proxy-agent-v6-2.1.0.tgz#6d3c7860354d4856a7e75375f2f0ecab313b4989" integrity sha512-7bY3J8GCVxLupn/kNmpPc5VJz8grx+4RKfnnJiO1LG+uxkZfANZG3RMHhE+qQxxwkyQ9/MfPtTpf748UhR425A== +"@aws-cdk/cloud-assembly-schema@^39.2.0": + version "39.2.15" + resolved "https://registry.yarnpkg.com/@aws-cdk/cloud-assembly-schema/-/cloud-assembly-schema-39.2.15.tgz#e869dd3c76c9d093ecf27fe3378fbae64b7d958e" + integrity sha512-roeUKO5QR9JLnNEULg0RiS1ac6PZ9qsPaOcAJXCP0D1NLLECdxwwqJvLbhV91pCWrGTeWY5OhLtlL5OPS6Ycvg== + dependencies: + jsonschema "~1.4.1" + semver "^7.7.1" + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.2": version "7.26.2" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85" @@ -656,6 +673,11 @@ "@jridgewell/resolve-uri" "^3.1.0" "@jridgewell/sourcemap-codec" "^1.4.14" +"@jsdevtools/ono@^7.1.3": + version "7.1.3" + resolved "https://registry.yarnpkg.com/@jsdevtools/ono/-/ono-7.1.3.tgz#9df03bbd7c696a5c58885c34aa06da41c8543796" + integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg== + "@jsii/check-node@1.106.0": version "1.106.0" resolved "https://registry.yarnpkg.com/@jsii/check-node/-/check-node-1.106.0.tgz#5deb20b0bbe0a506c4bd9edf60b17b0a93f83834" @@ -847,6 +869,11 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== +"@types/lodash@^4.17.7": + version "4.17.15" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.15.tgz#12d4af0ed17cc7600ce1f9980cec48fc17ad1e89" + integrity sha512-w/P33JFeySuhN6JLkysYUK2gEmy9kHHFN7E8ro0tkfmlDOgxBDzWEZ/J8cWA+fHqFevpswDTFZnDx+R9lbL6xw== + "@types/minimist@^1.2.0": version "1.2.5" resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.5.tgz#ec10755e871497bcd83efe927e43ec46e8c0747e" @@ -1220,23 +1247,24 @@ available-typed-arrays@^1.0.7: dependencies: possible-typed-array-names "^1.0.0" -aws-cdk-lib@2.144.0: - version "2.144.0" - resolved "https://registry.yarnpkg.com/aws-cdk-lib/-/aws-cdk-lib-2.144.0.tgz#0e224634d361cea0a8019b4677a517752600609b" - integrity sha512-DpyIyTs8NHX6WgAyYM2mGorirIk+eTjWzXGQRfzAe40qkwcqsb5Ax4JEl5gz1OEo9QIJIgWDtmImgWN0tUbILA== +aws-cdk-lib@2.177.0: + version "2.177.0" + resolved "https://registry.yarnpkg.com/aws-cdk-lib/-/aws-cdk-lib-2.177.0.tgz#dd161eb9b3fca56d0677c903ff758780a3eeb974" + integrity sha512-nTnHAwjZaPJ5gfJjtzE/MyK6q0a66nWthoJl7l8srucRb+I30dczhbbXor6QCdVpJaTRAEliMOMq23aglsAQbg== dependencies: - "@aws-cdk/asset-awscli-v1" "^2.2.202" - "@aws-cdk/asset-kubectl-v20" "^2.1.2" - "@aws-cdk/asset-node-proxy-agent-v6" "^2.0.3" + "@aws-cdk/asset-awscli-v1" "^2.2.208" + "@aws-cdk/asset-kubectl-v20" "^2.1.3" + "@aws-cdk/asset-node-proxy-agent-v6" "^2.1.0" + "@aws-cdk/cloud-assembly-schema" "^39.2.0" "@balena/dockerignore" "^1.0.2" case "1.6.3" fs-extra "^11.2.0" - ignore "^5.3.1" + ignore "^5.3.2" jsonschema "^1.4.1" mime-types "^2.1.35" minimatch "^3.1.2" punycode "^2.3.1" - semver "^7.6.0" + semver "^7.6.3" table "^6.8.2" yaml "1.10.2" @@ -2415,6 +2443,11 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" +fdir@^6.4.2: + version "6.4.3" + resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.3.tgz#011cdacf837eca9b811c89dbb902df714273db72" + integrity sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw== + figures@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" @@ -2891,7 +2924,7 @@ iconv-lite@0.6.3: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" -ignore@^5.2.0, ignore@^5.3.1: +ignore@^5.2.0, ignore@^5.3.1, ignore@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== @@ -3848,6 +3881,21 @@ json-parse-even-better-errors@^2.3.0: resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== +json-schema-to-typescript@^15.0.4: + version "15.0.4" + resolved "https://registry.yarnpkg.com/json-schema-to-typescript/-/json-schema-to-typescript-15.0.4.tgz#a530c7f17312503b262ae12233749732171840f3" + integrity sha512-Su9oK8DR4xCmDsLlyvadkXzX6+GGXJpbhwoLtOGArAG61dvbW4YQmSEno2y66ahpIdmLMg6YUf/QHLgiwvkrHQ== + dependencies: + "@apidevtools/json-schema-ref-parser" "^11.5.5" + "@types/json-schema" "^7.0.15" + "@types/lodash" "^4.17.7" + is-glob "^4.0.3" + js-yaml "^4.1.0" + lodash "^4.17.21" + minimist "^1.2.8" + prettier "^3.2.5" + tinyglobby "^0.2.9" + json-schema-traverse@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" @@ -3906,6 +3954,11 @@ jsonschema@^1.4.1: resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.5.0.tgz#f6aceb1ab9123563dd901d05f81f9d4883d3b7d8" integrity sha512-K+A9hhqbn0f3pJX17Q/7H6yQfD/5OXgdrR5UE12gMXCiN9D5Xq2o5mddV2QEcX/bjla99ASsAAQUyMCCRWAEhw== +jsonschema@~1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.1.tgz#cc4c3f0077fb4542982973d8a083b6b34f482dab" + integrity sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ== + keyv@^4.5.4: version "4.5.4" resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" @@ -4001,7 +4054,7 @@ lodash.truncate@^4.4.2: resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== -lodash@^4.7.0: +lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -4162,7 +4215,7 @@ minimist-options@4.1.0: is-plain-obj "^1.1.0" kind-of "^6.0.3" -minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6, minimist@~1.2.8: +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6, minimist@^1.2.8, minimist@~1.2.8: version "1.2.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== @@ -4468,6 +4521,11 @@ picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +picomatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab" + integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg== + pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" @@ -4512,6 +4570,11 @@ prettier@^2.8.8: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== +prettier@^3.2.5: + version "3.4.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.4.2.tgz#a5ce1fb522a588bf2b78ca44c6e6fe5aa5a2b13f" + integrity sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ== + pretty-format@^27.0.0, pretty-format@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" @@ -4849,6 +4912,11 @@ semver@^6.3.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== +semver@^7.7.1: + version "7.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f" + integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA== + set-function-length@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" @@ -5265,6 +5333,14 @@ through@2, "through@>=2.2.7 <3": resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== +tinyglobby@^0.2.9: + version "0.2.10" + resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.10.tgz#e712cf2dc9b95a1f5c5bbd159720e15833977a0f" + integrity sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew== + dependencies: + fdir "^6.4.2" + picomatch "^4.0.2" + tldts-core@^6.1.76: version "6.1.76" resolved "https://registry.yarnpkg.com/tldts-core/-/tldts-core-6.1.76.tgz#1ea632bbf11b288645dd7e2f3fb9cb6fa41e6bd7" From e2bb67877f448314b7f71daed2a74164f559a340 Mon Sep 17 00:00:00 2001 From: Florian Bauer <45170246+derbauer97@users.noreply.github.com> Date: Mon, 10 Feb 2025 08:35:55 +0100 Subject: [PATCH 02/12] fix: html encoding (#1113) Signed-off-by: Florian Fl Bauer --- .../sopsfile-complex.enc-age.json.snap | 39 +++++++++++-------- lambda/internal/sops/sops.go | 20 ++++++++++ .../json/sopsfile-complex.enc-age.json | 31 ++++++++------- test-secrets/json/sopsfile-complex.json | 5 +++ 4 files changed, 65 insertions(+), 30 deletions(-) diff --git a/lambda/internal/sops/__snapshots__/sopsfile-complex.enc-age.json.snap b/lambda/internal/sops/__snapshots__/sopsfile-complex.enc-age.json.snap index 652e5d1a..e46d5cba 100755 --- a/lambda/internal/sops/__snapshots__/sopsfile-complex.enc-age.json.snap +++ b/lambda/internal/sops/__snapshots__/sopsfile-complex.enc-age.json.snap @@ -1,23 +1,6 @@ [TestDecrypt/sopsfile-complex.enc-age.json - 1] { - "some": { - "deep": { - "nested": { - "object": "structure", - "arrays": [ - "with", - "several", - { - "values": { - "and": "objects" - } - } - ] - } - }, - "notsodeep": "struct" - }, "and now": { "some": [ { @@ -33,6 +16,28 @@ "tests": "Finish!" } ] + }, + "some": { + "deep": { + "nested": { + "arrays": [ + "with", + "several", + { + "values": { + "and": "objects" + } + } + ], + "object": "structure" + } + }, + "notsodeep": "struct" + }, + "with": { + "TestValue": "test ", + "TestValue2": "&", + "TestValue3": "@" } } --- diff --git a/lambda/internal/sops/sops.go b/lambda/internal/sops/sops.go index d46e2c61..4246862c 100644 --- a/lambda/internal/sops/sops.go +++ b/lambda/internal/sops/sops.go @@ -1,6 +1,8 @@ package sops import ( + "bytes" + "encoding/json" "fmt" "log/slog" @@ -54,6 +56,24 @@ func (e EncryptedSopsSecret) Decrypt() (*DecryptedSopsSecret, error) { return nil, fmt.Errorf("decryption error:\n%v", err) } logger.Info("Decryption successful") + + if e.Format == JSON { + var jsonObj interface{} + var buf bytes.Buffer + err := json.Unmarshal(cleartext, &jsonObj) + if err != nil { + return nil, fmt.Errorf("decoding error:\n%v", err) + } + encoder := json.NewEncoder(&buf) + encoder.SetEscapeHTML(false) + encoder.SetIndent("", " ") // tab inside + err = encoder.Encode(jsonObj) + if err != nil { + return nil, fmt.Errorf("encoding error:\n%v", err) + } + cleartext = bytes.TrimSpace(buf.Bytes()) + } + return &DecryptedSopsSecret{ content: cleartext, format: e.Format, diff --git a/test-secrets/json/sopsfile-complex.enc-age.json b/test-secrets/json/sopsfile-complex.enc-age.json index c865fd96..22a401fb 100644 --- a/test-secrets/json/sopsfile-complex.enc-age.json +++ b/test-secrets/json/sopsfile-complex.enc-age.json @@ -2,33 +2,38 @@ "some": { "deep": { "nested": { - "object": "ENC[AES256_GCM,data:yukHuGsD0wgY,iv:Ughn8OgNcdIPSz1hXCpcnJODSDrk19y0UMcwQzTRJFc=,tag:wOpa03Pdp63eeVL1t9GPwA==,type:str]", + "object": "ENC[AES256_GCM,data:KqcODVlKoN+h,iv:0cIx2pZoTzfGq6JaSD72yVYLbzThijiEyDCnle7m8Bo=,tag:m4HgUT9//lEjgxxWKcwTlQ==,type:str]", "arrays": [ - "ENC[AES256_GCM,data:M3+8vg==,iv:GDrQlRnH0P32mlD9eZMovhJ4Nk6rMb/E79GQ5uPba04=,tag:abOv3ysU1Yk96muxLGyOHQ==,type:str]", - "ENC[AES256_GCM,data:0NC0GL5pRA==,iv:+JH62RSknw6AXN6vMPDB2gm9RRtnChxPz8tw99X/6y0=,tag:ZPKzHCY66HK0BaukjvZlvQ==,type:str]", + "ENC[AES256_GCM,data:cwdZGg==,iv:nHtR+SK2qPPwvkWIuLSQR0NOy7vm53KXHg8A7WOjVyM=,tag:EW/JaUnr3n43H3ZNC4AAbA==,type:str]", + "ENC[AES256_GCM,data:zqWmSAyFuw==,iv:M/0wJ2xjwWdlNJ4XSMOHpUT6bPlh21jl3inR19qj8qc=,tag:60Hb9dVqXphkHl48cU+skA==,type:str]", { "values": { - "and": "ENC[AES256_GCM,data:PVjnZ2Zm9g==,iv:WAeNDT4xl9XKXnkGArsDKaN6TxRTI8uWOtn8x+G0hnM=,tag:SyLib8RPN65pyqkFgPhlVA==,type:str]" + "and": "ENC[AES256_GCM,data:9q+bY2/Fxg==,iv:oGUlni+NO9BE1FSvVhp3mGs64DhNErVES3tMVY1geFU=,tag:9a//E2BWpBnzJNBkshNVPQ==,type:str]" } } ] } }, - "notsodeep": "ENC[AES256_GCM,data:KSf6pl1e,iv:OKR5+hw6GCzbm750sAlAXW8/G4Se8Bu1FWHHtEenYeU=,tag:5hlF03Om7qVcJUG3U95uvQ==,type:str]" + "notsodeep": "ENC[AES256_GCM,data:sSIRj3Fd,iv:hvi5Yygsf+czctpvuvAItgioIIfGBhFuvse9CsF7BVM=,tag:drZ9yZCsQZ+N9f78gYe/sg==,type:str]" + }, + "with": { + "TestValue": "ENC[AES256_GCM,data:bto965a3UQy4xhGhrnLHp6UOlLVY,iv:jfyb6zm1S4DxsEDnwNx17PjpNoLoM1GjWycNAYLIiTo=,tag:p5NKNN/4gfPK4wbxalrMgg==,type:str]", + "TestValue2": "ENC[AES256_GCM,data:2A==,iv:5pptPCrBWBdZ2dyEE7fb53kdF9AXSBO3U2zQJ36SEFo=,tag:R4p7PdwCQVJzkFtpHcWzyA==,type:str]", + "TestValue3": "ENC[AES256_GCM,data:pg==,iv:qAzebSlwqDH75A4ptv0b5u2nX01Q+K+I22lyHXfOGg8=,tag:TS/dSzzkIXsoNyyqfu9dbw==,type:str]" }, "and now": { "some": [ { - "basic": "ENC[AES256_GCM,data:KBo4/k0=,iv:kp4gxhCpWnP/VvInFBNlwXTE6sk48N322sAaGsNeebk=,tag:E45zw12lkRgKdEIH/ARnyA==,type:bool]" + "basic": "ENC[AES256_GCM,data:LLfe+cU=,iv:KK/akV0TnHIKxi+ZVRRuqGW9/BZeaVq+bVoWjbw8V94=,tag:fZKNID18dnK+TTcUC02iBQ==,type:bool]" }, { - "nested": "ENC[AES256_GCM,data:rzJs1m8=,iv:+oRnXYPa6Jbv/iNt1QknyhdR7Z67fVHVq2nvq3GZOTU=,tag:AWLhtD4E/+EHIDJgipqM1A==,type:float]" + "nested": "ENC[AES256_GCM,data:94TT9qM=,iv:suWnfGAoEJ8oRbh6guaX5ZmaBJii9k9s+1Rktn3PeUQ=,tag:eAgf5Id1PiU2nVo3Q+h67w==,type:float]" }, { - "type": "ENC[AES256_GCM,data:nahV3BNE,iv:iddjiztjRaUqTaS6uVTPPDiXHNYRDC+oIPD819/GCRs=,tag:qD4bztCGw9C4wi0Kl7vLUw==,type:float]" + "type": "ENC[AES256_GCM,data:9MGS4J8e,iv:LIza4w0iCTY13SBtIkL/zXXvcot1NRkhQoXQCO6YI1E=,tag:U3tdtG7sCOgJuX0HNwd6Bw==,type:float]" }, { - "tests": "ENC[AES256_GCM,data:8ofXTHND6w==,iv:DrKo4rv3vV/N8b1S5dTiJGyLHNlvnrX8gIZDqNzq1eg=,tag:gFPndV96rOk1R0dAzefmuA==,type:str]" + "tests": "ENC[AES256_GCM,data:ZywWxDM6mQ==,iv:cbJtn9JN7UvB7qcvu6/x+BAE6IKZR28ec1295tvbo3g=,tag:9T8Q3PiisNnwKbJyGXsI/w==,type:str]" } ] }, @@ -40,13 +45,13 @@ "age": [ { "recipient": "age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAxT3NGU0JET0NiY1NQcm9n\nZFZQSCs1NzdZaEkvSGhmTDV6bFBHY2VZa2djCklCZkJ4Vy9STlBud2prSm5KR1hr\nN0hpaDdoWGtxakR6MWg5UjI0SXBibUUKLS0tIHdtR29SWTIxWmhMenlaeU5xem9u\nKzhKa3NKbGp2dFVxMTVuWi9VdXJ3MW8Kanz3DpIgPXO9u44TUsTPtgwTLbP6YpUf\nJov4T2oLy4Uo668RNCB1fbKnt5nycmRJxe+rYmOvn2VeL9vWcw0kZw==\n-----END AGE ENCRYPTED FILE-----\n" + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB3RzBneS9sWnFmWnl3NDBO\nV0FFQ3lhYzZTZmQ1U3dmbUgrR2dUaTEybzJZCmxyaEhQT2hLalM5WWlXMjVCdWpS\nWHI5dUE5MjhyM2VlWjRWY1FMd3Zub0EKLS0tIGFiZlhrMTlJY1MrMXJGMS9xbUVQ\nY2d1czhGOGdsdzIzVjNsSDNRWE93bWMKTBl/gzy3HxvBfdwBkTQ8x0zaAHflC+DU\nDZu42K3OgMSJ16s7Abbk7Bp5uzUx+UEIJB+Fb5IzVIFAvovFq2fhNA==\n-----END AGE ENCRYPTED FILE-----\n" } ], - "lastmodified": "2022-04-03T17:24:24Z", - "mac": "ENC[AES256_GCM,data:mUSKFyYqbxQWirfzNvyNMvrJ9+j+3Q9s/ARjOWJZOJrAypJYPtbZa/duSL4CzBW6KdLf9YRfI7HjiKX5G8SUL9f5BzAXIGBq/DAEfaXZ8ArzHfK4ttx9Pe2tL+DjO//mHGEJ88JYEVjrEMLG+NDa9arpDKK8+O4LuECSoCaaaqI=,iv:2W2VtCVGfskooWMAiLoLLcDgu9Puw2Cf3di2iTYvPcU=,tag:5epn8SaE8DE2EKRmbIo1gg==,type:str]", + "lastmodified": "2025-02-07T10:08:49Z", + "mac": "ENC[AES256_GCM,data:HYmEvL9BQFp8AQNzRP6QoY8/7lsYpceP5qCPmgL/SCokgVqazV7BJp58b/6eHI5yUSxBOsvtqse0fo7R4POoOEqzVh6oSLGfT7hB0sXjn9G34MQCz6aQZiOyz41uV6/tzsOoivH+/xSLV0I5sosY8jHxa6HdD/d3V7ke+wJOSXs=,iv:VEYU+FMfdAZMha1ny9rD7GeimMyiB/E6uM3mXpaYvVU=,tag:mGwHGZFLem7Xz0dDzj0rvQ==,type:str]", "pgp": null, "unencrypted_suffix": "_unencrypted", - "version": "3.7.2" + "version": "3.9.4" } } \ No newline at end of file diff --git a/test-secrets/json/sopsfile-complex.json b/test-secrets/json/sopsfile-complex.json index c0fb8aa2..8b8f8be8 100644 --- a/test-secrets/json/sopsfile-complex.json +++ b/test-secrets/json/sopsfile-complex.json @@ -16,6 +16,11 @@ }, "notsodeep": "struct" }, + "with": { + "TestValue": "test ", + "TestValue2": "&", + "TestValue3": "@" + }, "and now": { "some": [ { From 9fc6c1d257a434e87b8d49b4f3cf69de7aec574f Mon Sep 17 00:00:00 2001 From: Markus Date: Mon, 10 Feb 2025 10:01:36 +0100 Subject: [PATCH 03/12] chore: save work --- .gitignore | 56 +- .npmignore | 7 +- .projen/tasks.json | 237 ++-- .projenrc.js | 2 +- API.md | 368 ++---- README.md | 451 ++++--- lambda/README.md | 33 +- ...arameter-binary-binary-true-true.json.snap | 17 - ...2-secret-binary-binary-true-true.json.snap | 17 - ...1-parametermulti-json-na-true-na.json.snap | 49 - ...2-parametermulti-yaml-na-true-na.json.snap | 49 - ...parametermulti-dotenv-na-true-na.json.snap | 21 - .../21-secret-json-json-true-true.json.snap | 17 - .../22-secret-json-binary-na-na.json.snap | 17 - .../23-secret-yaml-json-true-true.json.snap | 17 - .../24-secret-yaml-binary-na-na.json.snap | 17 - .../25-secret-dotenv-json-true-true.json.snap | 17 - .../26-secret-dotenv-binary-na-na.json.snap | 17 - .../01-SECRET-json.json.snap | 18 + .../02-SECRET-yaml.json.snap | 18 + .../03-SECRET-dotenv.json.snap | 18 + .../11-SECRET_RAW-json.json.snap | 18 + .../12-SECRET_RAW-yaml.json.snap | 18 + .../13-SECRET_RAW-dotenv.json.snap | 18 + .../21-SECRET_BINARY-json.json.snap | 18 + .../22-SECRET_BINARY-yaml.json.snap | 18 + .../23-SECRET_BINARY-dotenv.json.snap | 18 + .../31-PARAMETER-json.json.snap | 17 + .../32-PARAMETER-yaml.json.snap | 17 + .../33-PARAMETER-dotenv.json.snap | 17 + .../34-PARAMETER-binary.json.snap | 17 + .../41-PARAMETER_MULTI-json.json.snap | 81 ++ .../42-PARAMETER_MULTI-yaml.json.snap | 81 ++ .../43-PARAMETER_MULTI-dotenv.json.snap | 81 ++ .../01-SECRET-json.json.snap | 6 + .../02-SECRET-yaml.json.snap | 6 + .../03-SECRET-dotenv.json.snap | 6 + .../11-SECRET_RAW-json.json.snap | 6 + .../12-SECRET_RAW-yaml.json.snap | 6 + .../13-SECRET_RAW-dotenv.json.snap | 6 + .../21-SECRET_BINARY-json.json.snap | 6 + .../22-SECRET_BINARY-yaml.json.snap | 6 + .../23-SECRET_BINARY-dotenv.json.snap | 6 + .../31-PARAMETER-json.json.snap | 5 + .../32-PARAMETER-yaml.json.snap | 5 + .../33-PARAMETER-dotenv.json.snap | 5 + .../34-PARAMETER-binary.json.snap | 5 + .../41-PARAMETER_MULTI-json.json.snap | 85 ++ .../42-PARAMETER_MULTI-yaml.json.snap | 85 ++ .../43-PARAMETER_MULTI-dotenv.json.snap | 85 ++ ...son-true-true.json => 01-SECRET-json.json} | 8 +- .../01-parameter-binary-binary-true-true.json | 11 - ...son-true-true.json => 02-SECRET-yaml.json} | 8 +- .../02-secret-binary-binary-true-true.json | 10 - ...n-true-true.json => 03-SECRET-dotenv.json} | 9 +- lambda/events/11-SECRET_RAW-json.json | 10 + lambda/events/12-SECRET_RAW-yaml.json | 10 + lambda/events/13-SECRET_RAW-dotenv.json | 10 + ...-na-na.json => 21-SECRET_BINARY-json.json} | 8 +- ...-na-na.json => 22-SECRET_BINARY-yaml.json} | 8 +- ...a-na.json => 23-SECRET_BINARY-dotenv.json} | 8 +- lambda/events/31-PARAMETER-json.json | 10 + lambda/events/32-PARAMETER-yaml.json | 10 + lambda/events/33-PARAMETER-dotenv.json | 10 + lambda/events/34-PARAMETER-binary.json | 10 + ...e-na.json => 41-PARAMETER_MULTI-json.json} | 8 +- ...e-na.json => 42-PARAMETER_MULTI-yaml.json} | 8 +- ...na.json => 43-PARAMETER_MULTI-dotenv.json} | 8 +- lambda/handle.go | 47 +- lambda/internal/client/client.go | 20 +- lambda/internal/client/client_test.go | 6 +- lambda/internal/data/data.go | 2 + lambda/internal/event/config-schema.json | 1 + lambda/internal/event/event.go | 6 +- .../__snapshots__/README.sops.binary.snap | 14 + .../binary/sopsfile.enc-age.binary.snap | 18 - .../dotenv/encrypted-best-secret.env.snap | 6 - .../encrypted-best-secret.env.snap | 6 - .../json/sopsfile-complex.enc-age.json.snap | 38 - .../sopsfile-complex.enc-age.json.snap | 43 - .../sopsfile.enc-age.binary.snap | 18 - .../__snapshots__/sopsfile.enc-age.yaml.snap | 7 - .../__snapshots__/testsecret.sops.env.snap | 21 + .../__snapshots__/testsecret.sops.json.snap | 32 + .../__snapshots__/testsecret.sops.yaml.snap | 24 + .../yaml/sopsfile.enc-age.yaml.snap | 7 - lambda/internal/sops/sops_test.go | 11 +- lambda/main.go | 2 +- lambda/main_integration_test.go | 163 ++- lambda/main_test.go | 8 +- package.json | 43 +- src/MultiStringParameter.ts | 35 +- src/SopsSecret.ts | 41 +- src/SopsStringParameter.ts | 11 +- src/SopsSync.ts | 24 +- test-secrets/README.md | 2 +- test-secrets/README.sops.binary | 20 + test-secrets/_testsecret.env | 17 + test-secrets/_testsecret.json | 29 + test-secrets/_testsecret.yaml | 21 + test-secrets/binary/sopsfile.binary | 15 - test-secrets/binary/sopsfile.enc-age.binary | 20 - test-secrets/dotenv/best-secret.env | 2 - test-secrets/dotenv/encrypted-best-secret.env | 8 - test-secrets/json/complex.sops.binary | 20 + test-secrets/json/complex.sops.json | 20 + test-secrets/testsecret.notsupported | 0 test-secrets/testsecret.sops.env | 23 + test-secrets/testsecret.sops.json | 46 + test-secrets/testsecret.sops.yaml | 40 + .../PARAMETER.assets.json} | 12 +- .../PARAMETER.template.json | 388 ++++++ test/PARAMETER.integ.ts | 49 + .../PARAMETERMULTI.assets.json} | 12 +- .../PARAMETERMULTI.template.json | 1060 +++++++++++++++++ test/PARAMETER_MULTI.integ.ts | 46 + test/SECRET.integ.snapshot/SECRET.assets.json | 32 + .../SECRET.template.json | 408 +++++++ test/SECRET.integ.ts | 70 ++ .../SecretIntegrationAsset.assets.json | 97 -- .../SecretIntegrationAsset.template.json | 981 --------------- test/secret-asset.integ.ts | 156 --- .../SecretIntegrationInline.template.json | 961 --------------- test/secret-inline.integ.ts | 151 --- .../SecretIntegrationAsset.template.json | 772 ------------ test/secret-manual.integ.ts | 157 --- .../SecretMultiKms.assets.json | 45 - .../SecretMultiKms.template.json | 431 ------- test/secret-multikms.integ.ts | 34 - test/secret.test.ts | 11 +- yarn.lock | 14 +- 131 files changed, 4162 insertions(+), 5037 deletions(-) delete mode 100755 lambda/__snapshots__/01-parameter-binary-binary-true-true.json.snap delete mode 100755 lambda/__snapshots__/02-secret-binary-binary-true-true.json.snap delete mode 100755 lambda/__snapshots__/11-parametermulti-json-na-true-na.json.snap delete mode 100755 lambda/__snapshots__/12-parametermulti-yaml-na-true-na.json.snap delete mode 100755 lambda/__snapshots__/13-parametermulti-dotenv-na-true-na.json.snap delete mode 100755 lambda/__snapshots__/21-secret-json-json-true-true.json.snap delete mode 100755 lambda/__snapshots__/22-secret-json-binary-na-na.json.snap delete mode 100755 lambda/__snapshots__/23-secret-yaml-json-true-true.json.snap delete mode 100755 lambda/__snapshots__/24-secret-yaml-binary-na-na.json.snap delete mode 100755 lambda/__snapshots__/25-secret-dotenv-json-true-true.json.snap delete mode 100755 lambda/__snapshots__/26-secret-dotenv-binary-na-na.json.snap create mode 100755 lambda/__snapshots__/TestHandleRequestWithClients/01-SECRET-json.json/01-SECRET-json.json.snap create mode 100755 lambda/__snapshots__/TestHandleRequestWithClients/02-SECRET-yaml.json/02-SECRET-yaml.json.snap create mode 100755 lambda/__snapshots__/TestHandleRequestWithClients/03-SECRET-dotenv.json/03-SECRET-dotenv.json.snap create mode 100755 lambda/__snapshots__/TestHandleRequestWithClients/11-SECRET_RAW-json.json/11-SECRET_RAW-json.json.snap create mode 100755 lambda/__snapshots__/TestHandleRequestWithClients/12-SECRET_RAW-yaml.json/12-SECRET_RAW-yaml.json.snap create mode 100755 lambda/__snapshots__/TestHandleRequestWithClients/13-SECRET_RAW-dotenv.json/13-SECRET_RAW-dotenv.json.snap create mode 100755 lambda/__snapshots__/TestHandleRequestWithClients/21-SECRET_BINARY-json.json/21-SECRET_BINARY-json.json.snap create mode 100755 lambda/__snapshots__/TestHandleRequestWithClients/22-SECRET_BINARY-yaml.json/22-SECRET_BINARY-yaml.json.snap create mode 100755 lambda/__snapshots__/TestHandleRequestWithClients/23-SECRET_BINARY-dotenv.json/23-SECRET_BINARY-dotenv.json.snap create mode 100755 lambda/__snapshots__/TestHandleRequestWithClients/31-PARAMETER-json.json/31-PARAMETER-json.json.snap create mode 100755 lambda/__snapshots__/TestHandleRequestWithClients/32-PARAMETER-yaml.json/32-PARAMETER-yaml.json.snap create mode 100755 lambda/__snapshots__/TestHandleRequestWithClients/33-PARAMETER-dotenv.json/33-PARAMETER-dotenv.json.snap create mode 100755 lambda/__snapshots__/TestHandleRequestWithClients/34-PARAMETER-binary.json/34-PARAMETER-binary.json.snap create mode 100755 lambda/__snapshots__/TestHandleRequestWithClients/41-PARAMETER_MULTI-json.json/41-PARAMETER_MULTI-json.json.snap create mode 100755 lambda/__snapshots__/TestHandleRequestWithClients/42-PARAMETER_MULTI-yaml.json/42-PARAMETER_MULTI-yaml.json.snap create mode 100755 lambda/__snapshots__/TestHandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json/43-PARAMETER_MULTI-dotenv.json.snap create mode 100755 lambda/__snapshots__/TestIntegration_HandleRequestWithClients/01-SECRET-json.json.snap create mode 100755 lambda/__snapshots__/TestIntegration_HandleRequestWithClients/02-SECRET-yaml.json.snap create mode 100755 lambda/__snapshots__/TestIntegration_HandleRequestWithClients/03-SECRET-dotenv.json.snap create mode 100755 lambda/__snapshots__/TestIntegration_HandleRequestWithClients/11-SECRET_RAW-json.json.snap create mode 100755 lambda/__snapshots__/TestIntegration_HandleRequestWithClients/12-SECRET_RAW-yaml.json.snap create mode 100755 lambda/__snapshots__/TestIntegration_HandleRequestWithClients/13-SECRET_RAW-dotenv.json.snap create mode 100755 lambda/__snapshots__/TestIntegration_HandleRequestWithClients/21-SECRET_BINARY-json.json.snap create mode 100755 lambda/__snapshots__/TestIntegration_HandleRequestWithClients/22-SECRET_BINARY-yaml.json.snap create mode 100755 lambda/__snapshots__/TestIntegration_HandleRequestWithClients/23-SECRET_BINARY-dotenv.json.snap create mode 100755 lambda/__snapshots__/TestIntegration_HandleRequestWithClients/31-PARAMETER-json.json.snap create mode 100755 lambda/__snapshots__/TestIntegration_HandleRequestWithClients/32-PARAMETER-yaml.json.snap create mode 100755 lambda/__snapshots__/TestIntegration_HandleRequestWithClients/33-PARAMETER-dotenv.json.snap create mode 100755 lambda/__snapshots__/TestIntegration_HandleRequestWithClients/34-PARAMETER-binary.json.snap create mode 100755 lambda/__snapshots__/TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json.snap create mode 100755 lambda/__snapshots__/TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json.snap create mode 100755 lambda/__snapshots__/TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json.snap rename lambda/events/{21-secret-json-json-true-true.json => 01-SECRET-json.json} (67%) delete mode 100644 lambda/events/01-parameter-binary-binary-true-true.json rename lambda/events/{23-secret-yaml-json-true-true.json => 02-SECRET-yaml.json} (67%) delete mode 100644 lambda/events/02-secret-binary-binary-true-true.json rename lambda/events/{25-secret-dotenv-json-true-true.json => 03-SECRET-dotenv.json} (63%) create mode 100644 lambda/events/11-SECRET_RAW-json.json create mode 100644 lambda/events/12-SECRET_RAW-yaml.json create mode 100644 lambda/events/13-SECRET_RAW-dotenv.json rename lambda/events/{22-secret-json-binary-na-na.json => 21-SECRET_BINARY-json.json} (67%) rename lambda/events/{24-secret-yaml-binary-na-na.json => 22-SECRET_BINARY-yaml.json} (68%) rename lambda/events/{26-secret-dotenv-binary-na-na.json => 23-SECRET_BINARY-dotenv.json} (68%) create mode 100644 lambda/events/31-PARAMETER-json.json create mode 100644 lambda/events/32-PARAMETER-yaml.json create mode 100644 lambda/events/33-PARAMETER-dotenv.json create mode 100644 lambda/events/34-PARAMETER-binary.json rename lambda/events/{11-parametermulti-json-na-true-na.json => 41-PARAMETER_MULTI-json.json} (67%) rename lambda/events/{12-parametermulti-yaml-na-true-na.json => 42-PARAMETER_MULTI-yaml.json} (67%) rename lambda/events/{13-parametermulti-dotenv-na-true-na.json => 43-PARAMETER_MULTI-dotenv.json} (67%) create mode 100755 lambda/internal/sops/__snapshots__/README.sops.binary.snap delete mode 100755 lambda/internal/sops/__snapshots__/binary/sopsfile.enc-age.binary.snap delete mode 100755 lambda/internal/sops/__snapshots__/dotenv/encrypted-best-secret.env.snap delete mode 100755 lambda/internal/sops/__snapshots__/encrypted-best-secret.env.snap delete mode 100755 lambda/internal/sops/__snapshots__/json/sopsfile-complex.enc-age.json.snap delete mode 100755 lambda/internal/sops/__snapshots__/sopsfile-complex.enc-age.json.snap delete mode 100755 lambda/internal/sops/__snapshots__/sopsfile.enc-age.binary.snap delete mode 100755 lambda/internal/sops/__snapshots__/sopsfile.enc-age.yaml.snap create mode 100755 lambda/internal/sops/__snapshots__/testsecret.sops.env.snap create mode 100755 lambda/internal/sops/__snapshots__/testsecret.sops.json.snap create mode 100755 lambda/internal/sops/__snapshots__/testsecret.sops.yaml.snap delete mode 100755 lambda/internal/sops/__snapshots__/yaml/sopsfile.enc-age.yaml.snap create mode 100644 test-secrets/README.sops.binary create mode 100644 test-secrets/_testsecret.env create mode 100644 test-secrets/_testsecret.json create mode 100644 test-secrets/_testsecret.yaml delete mode 100644 test-secrets/binary/sopsfile.binary delete mode 100644 test-secrets/binary/sopsfile.enc-age.binary delete mode 100644 test-secrets/dotenv/best-secret.env delete mode 100644 test-secrets/dotenv/encrypted-best-secret.env create mode 100644 test-secrets/json/complex.sops.binary create mode 100644 test-secrets/json/complex.sops.json create mode 100644 test-secrets/testsecret.notsupported create mode 100644 test-secrets/testsecret.sops.env create mode 100644 test-secrets/testsecret.sops.json create mode 100644 test-secrets/testsecret.sops.yaml rename test/{secret-manual.integ.snapshot/SecretIntegrationAsset.assets.json => PARAMETER.integ.snapshot/PARAMETER.assets.json} (62%) create mode 100644 test/PARAMETER.integ.snapshot/PARAMETER.template.json create mode 100644 test/PARAMETER.integ.ts rename test/{secret-inline.integ.snapshot/SecretIntegrationInline.assets.json => PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.assets.json} (62%) create mode 100644 test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.template.json create mode 100644 test/PARAMETER_MULTI.integ.ts create mode 100644 test/SECRET.integ.snapshot/SECRET.assets.json create mode 100644 test/SECRET.integ.snapshot/SECRET.template.json create mode 100644 test/SECRET.integ.ts delete mode 100644 test/secret-asset.integ.snapshot/SecretIntegrationAsset.assets.json delete mode 100644 test/secret-asset.integ.snapshot/SecretIntegrationAsset.template.json delete mode 100644 test/secret-asset.integ.ts delete mode 100644 test/secret-inline.integ.snapshot/SecretIntegrationInline.template.json delete mode 100644 test/secret-inline.integ.ts delete mode 100644 test/secret-manual.integ.snapshot/SecretIntegrationAsset.template.json delete mode 100644 test/secret-manual.integ.ts delete mode 100644 test/secret-multikms.integ.snapshot/SecretMultiKms.assets.json delete mode 100644 test/secret-multikms.integ.snapshot/SecretMultiKms.template.json delete mode 100644 test/secret-multikms.integ.ts diff --git a/.gitignore b/.gitignore index a3a8d04f..dd804af9 100644 --- a/.gitignore +++ b/.gitignore @@ -52,39 +52,31 @@ junit.xml .jsii tsconfig.json !/API.md -test/secret-asset.integ.snapshot/asset.* -test/secret-asset.integ.snapshot/**/asset.* -test/secret-asset.integ.snapshot/cdk.out -test/secret-asset.integ.snapshot/**/cdk.out -test/secret-asset.integ.snapshot/manifest.json -test/secret-asset.integ.snapshot/**/manifest.json -test/secret-asset.integ.snapshot/tree.json -test/secret-asset.integ.snapshot/**/tree.json -test/secret-inline.integ.snapshot/asset.* -test/secret-inline.integ.snapshot/**/asset.* -test/secret-inline.integ.snapshot/cdk.out -test/secret-inline.integ.snapshot/**/cdk.out -test/secret-inline.integ.snapshot/manifest.json -test/secret-inline.integ.snapshot/**/manifest.json -test/secret-inline.integ.snapshot/tree.json -test/secret-inline.integ.snapshot/**/tree.json -test/secret-manual.integ.snapshot/asset.* -test/secret-manual.integ.snapshot/**/asset.* -test/secret-manual.integ.snapshot/cdk.out -test/secret-manual.integ.snapshot/**/cdk.out -test/secret-manual.integ.snapshot/manifest.json -test/secret-manual.integ.snapshot/**/manifest.json -test/secret-manual.integ.snapshot/tree.json -test/secret-manual.integ.snapshot/**/tree.json +test/PARAMETER_MULTI.integ.snapshot/asset.* +test/PARAMETER_MULTI.integ.snapshot/**/asset.* +test/PARAMETER_MULTI.integ.snapshot/cdk.out +test/PARAMETER_MULTI.integ.snapshot/**/cdk.out +test/PARAMETER_MULTI.integ.snapshot/manifest.json +test/PARAMETER_MULTI.integ.snapshot/**/manifest.json +test/PARAMETER_MULTI.integ.snapshot/tree.json +test/PARAMETER_MULTI.integ.snapshot/**/tree.json +test/PARAMETER.integ.snapshot/asset.* +test/PARAMETER.integ.snapshot/**/asset.* +test/PARAMETER.integ.snapshot/cdk.out +test/PARAMETER.integ.snapshot/**/cdk.out +test/PARAMETER.integ.snapshot/manifest.json +test/PARAMETER.integ.snapshot/**/manifest.json +test/PARAMETER.integ.snapshot/tree.json +test/PARAMETER.integ.snapshot/**/tree.json test/.tmp -test/secret-multikms.integ.snapshot/asset.* -test/secret-multikms.integ.snapshot/**/asset.* -test/secret-multikms.integ.snapshot/cdk.out -test/secret-multikms.integ.snapshot/**/cdk.out -test/secret-multikms.integ.snapshot/manifest.json -test/secret-multikms.integ.snapshot/**/manifest.json -test/secret-multikms.integ.snapshot/tree.json -test/secret-multikms.integ.snapshot/**/tree.json +test/SECRET.integ.snapshot/asset.* +test/SECRET.integ.snapshot/**/asset.* +test/SECRET.integ.snapshot/cdk.out +test/SECRET.integ.snapshot/**/cdk.out +test/SECRET.integ.snapshot/manifest.json +test/SECRET.integ.snapshot/**/manifest.json +test/SECRET.integ.snapshot/tree.json +test/SECRET.integ.snapshot/**/tree.json *.iml .idea /assets diff --git a/.npmignore b/.npmignore index 867547c3..e465bc97 100644 --- a/.npmignore +++ b/.npmignore @@ -24,11 +24,10 @@ dist tsconfig.tsbuildinfo /.eslintrc.json !.jsii -test/secret-asset.integ.snapshot -test/secret-inline.integ.snapshot -test/secret-manual.integ.snapshot +test/PARAMETER_MULTI.integ.snapshot +test/PARAMETER.integ.snapshot test/.tmp -test/secret-multikms.integ.snapshot +test/SECRET.integ.snapshot /lambda /dist-lambda /scripts diff --git a/.projen/tasks.json b/.projen/tasks.json index db4d0bb9..cc050eaf 100644 --- a/.projen/tasks.json +++ b/.projen/tasks.json @@ -153,255 +153,192 @@ } ] }, - "integ:secret-asset:assert": { - "name": "integ:secret-asset:assert", - "description": "assert the snapshot of integration test 'secret-asset'", + "integ:PARAMETER_MULTI:assert": { + "name": "integ:PARAMETER_MULTI:assert", + "description": "assert the snapshot of integration test 'PARAMETER_MULTI'", "steps": [ { - "exec": "[ -d \"test/secret-asset.integ.snapshot\" ] || (echo \"No snapshot available for integration test 'secret-asset'. Run 'projen integ:secret-asset:deploy' to capture.\" && exit 1)" + "exec": "[ -d \"test/PARAMETER_MULTI.integ.snapshot\" ] || (echo \"No snapshot available for integration test 'PARAMETER_MULTI'. Run 'projen integ:PARAMETER_MULTI:deploy' to capture.\" && exit 1)" }, { - "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/secret-asset.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/.tmp/secret-asset.integ/assert.cdk.out > /dev/null" + "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/PARAMETER_MULTI.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/.tmp/PARAMETER_MULTI.integ/assert.cdk.out > /dev/null" }, { - "exec": "diff -r -x asset.* -x cdk.out -x manifest.json -x tree.json test/secret-asset.integ.snapshot/ test/.tmp/secret-asset.integ/assert.cdk.out/" + "exec": "diff -r -x asset.* -x cdk.out -x manifest.json -x tree.json test/PARAMETER_MULTI.integ.snapshot/ test/.tmp/PARAMETER_MULTI.integ/assert.cdk.out/" } ] }, - "integ:secret-asset:deploy": { - "name": "integ:secret-asset:deploy", - "description": "deploy integration test 'secret-asset' and capture snapshot", + "integ:PARAMETER_MULTI:deploy": { + "name": "integ:PARAMETER_MULTI:deploy", + "description": "deploy integration test 'PARAMETER_MULTI' and capture snapshot", "steps": [ { - "exec": "rm -fr test/.tmp/secret-asset.integ/deploy.cdk.out" + "exec": "rm -fr test/.tmp/PARAMETER_MULTI.integ/deploy.cdk.out" }, { - "exec": "cdk deploy --app \"ts-node -P tsconfig.dev.json test/secret-asset.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' --require-approval=never -o test/.tmp/secret-asset.integ/deploy.cdk.out" + "exec": "cdk deploy --app \"ts-node -P tsconfig.dev.json test/PARAMETER_MULTI.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' --require-approval=never -o test/.tmp/PARAMETER_MULTI.integ/deploy.cdk.out" }, { - "exec": "rm -fr test/secret-asset.integ.snapshot" + "exec": "rm -fr test/PARAMETER_MULTI.integ.snapshot" }, { - "exec": "mv test/.tmp/secret-asset.integ/deploy.cdk.out test/secret-asset.integ.snapshot" + "exec": "mv test/.tmp/PARAMETER_MULTI.integ/deploy.cdk.out test/PARAMETER_MULTI.integ.snapshot" }, { - "spawn": "integ:secret-asset:destroy" + "spawn": "integ:PARAMETER_MULTI:destroy" } ] }, - "integ:secret-asset:destroy": { - "name": "integ:secret-asset:destroy", - "description": "destroy integration test 'secret-asset'", + "integ:PARAMETER_MULTI:destroy": { + "name": "integ:PARAMETER_MULTI:destroy", + "description": "destroy integration test 'PARAMETER_MULTI'", "steps": [ { - "exec": "cdk destroy --app test/secret-asset.integ.snapshot '**' --no-version-reporting" + "exec": "cdk destroy --app test/PARAMETER_MULTI.integ.snapshot '**' --no-version-reporting" } ] }, - "integ:secret-asset:snapshot": { - "name": "integ:secret-asset:snapshot", - "description": "update snapshot for integration test \"secret-asset\"", + "integ:PARAMETER_MULTI:snapshot": { + "name": "integ:PARAMETER_MULTI:snapshot", + "description": "update snapshot for integration test \"PARAMETER_MULTI\"", "steps": [ { - "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/secret-asset.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/secret-asset.integ.snapshot > /dev/null" + "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/PARAMETER_MULTI.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/PARAMETER_MULTI.integ.snapshot > /dev/null" } ] }, - "integ:secret-asset:watch": { - "name": "integ:secret-asset:watch", - "description": "watch integration test 'secret-asset' (without updating snapshots)", + "integ:PARAMETER_MULTI:watch": { + "name": "integ:PARAMETER_MULTI:watch", + "description": "watch integration test 'PARAMETER_MULTI' (without updating snapshots)", "steps": [ { - "exec": "cdk watch --app \"ts-node -P tsconfig.dev.json test/secret-asset.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' -o test/.tmp/secret-asset.integ/deploy.cdk.out" + "exec": "cdk watch --app \"ts-node -P tsconfig.dev.json test/PARAMETER_MULTI.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' -o test/.tmp/PARAMETER_MULTI.integ/deploy.cdk.out" } ] }, - "integ:secret-inline:assert": { - "name": "integ:secret-inline:assert", - "description": "assert the snapshot of integration test 'secret-inline'", + "integ:PARAMETER:assert": { + "name": "integ:PARAMETER:assert", + "description": "assert the snapshot of integration test 'PARAMETER'", "steps": [ { - "exec": "[ -d \"test/secret-inline.integ.snapshot\" ] || (echo \"No snapshot available for integration test 'secret-inline'. Run 'projen integ:secret-inline:deploy' to capture.\" && exit 1)" + "exec": "[ -d \"test/PARAMETER.integ.snapshot\" ] || (echo \"No snapshot available for integration test 'PARAMETER'. Run 'projen integ:PARAMETER:deploy' to capture.\" && exit 1)" }, { - "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/secret-inline.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/.tmp/secret-inline.integ/assert.cdk.out > /dev/null" + "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/PARAMETER.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/.tmp/PARAMETER.integ/assert.cdk.out > /dev/null" }, { - "exec": "diff -r -x asset.* -x cdk.out -x manifest.json -x tree.json test/secret-inline.integ.snapshot/ test/.tmp/secret-inline.integ/assert.cdk.out/" + "exec": "diff -r -x asset.* -x cdk.out -x manifest.json -x tree.json test/PARAMETER.integ.snapshot/ test/.tmp/PARAMETER.integ/assert.cdk.out/" } ] }, - "integ:secret-inline:deploy": { - "name": "integ:secret-inline:deploy", - "description": "deploy integration test 'secret-inline' and capture snapshot", + "integ:PARAMETER:deploy": { + "name": "integ:PARAMETER:deploy", + "description": "deploy integration test 'PARAMETER' and capture snapshot", "steps": [ { - "exec": "rm -fr test/.tmp/secret-inline.integ/deploy.cdk.out" + "exec": "rm -fr test/.tmp/PARAMETER.integ/deploy.cdk.out" }, { - "exec": "cdk deploy --app \"ts-node -P tsconfig.dev.json test/secret-inline.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' --require-approval=never -o test/.tmp/secret-inline.integ/deploy.cdk.out" + "exec": "cdk deploy --app \"ts-node -P tsconfig.dev.json test/PARAMETER.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' --require-approval=never -o test/.tmp/PARAMETER.integ/deploy.cdk.out" }, { - "exec": "rm -fr test/secret-inline.integ.snapshot" + "exec": "rm -fr test/PARAMETER.integ.snapshot" }, { - "exec": "mv test/.tmp/secret-inline.integ/deploy.cdk.out test/secret-inline.integ.snapshot" + "exec": "mv test/.tmp/PARAMETER.integ/deploy.cdk.out test/PARAMETER.integ.snapshot" }, { - "spawn": "integ:secret-inline:destroy" + "spawn": "integ:PARAMETER:destroy" } ] }, - "integ:secret-inline:destroy": { - "name": "integ:secret-inline:destroy", - "description": "destroy integration test 'secret-inline'", + "integ:PARAMETER:destroy": { + "name": "integ:PARAMETER:destroy", + "description": "destroy integration test 'PARAMETER'", "steps": [ { - "exec": "cdk destroy --app test/secret-inline.integ.snapshot '**' --no-version-reporting" + "exec": "cdk destroy --app test/PARAMETER.integ.snapshot '**' --no-version-reporting" } ] }, - "integ:secret-inline:snapshot": { - "name": "integ:secret-inline:snapshot", - "description": "update snapshot for integration test \"secret-inline\"", + "integ:PARAMETER:snapshot": { + "name": "integ:PARAMETER:snapshot", + "description": "update snapshot for integration test \"PARAMETER\"", "steps": [ { - "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/secret-inline.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/secret-inline.integ.snapshot > /dev/null" + "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/PARAMETER.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/PARAMETER.integ.snapshot > /dev/null" } ] }, - "integ:secret-inline:watch": { - "name": "integ:secret-inline:watch", - "description": "watch integration test 'secret-inline' (without updating snapshots)", + "integ:PARAMETER:watch": { + "name": "integ:PARAMETER:watch", + "description": "watch integration test 'PARAMETER' (without updating snapshots)", "steps": [ { - "exec": "cdk watch --app \"ts-node -P tsconfig.dev.json test/secret-inline.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' -o test/.tmp/secret-inline.integ/deploy.cdk.out" + "exec": "cdk watch --app \"ts-node -P tsconfig.dev.json test/PARAMETER.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' -o test/.tmp/PARAMETER.integ/deploy.cdk.out" } ] }, - "integ:secret-manual:assert": { - "name": "integ:secret-manual:assert", - "description": "assert the snapshot of integration test 'secret-manual'", + "integ:SECRET:assert": { + "name": "integ:SECRET:assert", + "description": "assert the snapshot of integration test 'SECRET'", "steps": [ { - "exec": "[ -d \"test/secret-manual.integ.snapshot\" ] || (echo \"No snapshot available for integration test 'secret-manual'. Run 'projen integ:secret-manual:deploy' to capture.\" && exit 1)" + "exec": "[ -d \"test/SECRET.integ.snapshot\" ] || (echo \"No snapshot available for integration test 'SECRET'. Run 'projen integ:SECRET:deploy' to capture.\" && exit 1)" }, { - "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/secret-manual.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/.tmp/secret-manual.integ/assert.cdk.out > /dev/null" + "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/SECRET.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/.tmp/SECRET.integ/assert.cdk.out > /dev/null" }, { - "exec": "diff -r -x asset.* -x cdk.out -x manifest.json -x tree.json test/secret-manual.integ.snapshot/ test/.tmp/secret-manual.integ/assert.cdk.out/" + "exec": "diff -r -x asset.* -x cdk.out -x manifest.json -x tree.json test/SECRET.integ.snapshot/ test/.tmp/SECRET.integ/assert.cdk.out/" } ] }, - "integ:secret-manual:deploy": { - "name": "integ:secret-manual:deploy", - "description": "deploy integration test 'secret-manual' and capture snapshot", + "integ:SECRET:deploy": { + "name": "integ:SECRET:deploy", + "description": "deploy integration test 'SECRET' and capture snapshot", "steps": [ { - "exec": "rm -fr test/.tmp/secret-manual.integ/deploy.cdk.out" + "exec": "rm -fr test/.tmp/SECRET.integ/deploy.cdk.out" }, { - "exec": "cdk deploy --app \"ts-node -P tsconfig.dev.json test/secret-manual.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' --require-approval=never -o test/.tmp/secret-manual.integ/deploy.cdk.out" + "exec": "cdk deploy --app \"ts-node -P tsconfig.dev.json test/SECRET.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' --require-approval=never -o test/.tmp/SECRET.integ/deploy.cdk.out" }, { - "exec": "rm -fr test/secret-manual.integ.snapshot" + "exec": "rm -fr test/SECRET.integ.snapshot" }, { - "exec": "mv test/.tmp/secret-manual.integ/deploy.cdk.out test/secret-manual.integ.snapshot" + "exec": "mv test/.tmp/SECRET.integ/deploy.cdk.out test/SECRET.integ.snapshot" }, { - "spawn": "integ:secret-manual:destroy" + "spawn": "integ:SECRET:destroy" } ] }, - "integ:secret-manual:destroy": { - "name": "integ:secret-manual:destroy", - "description": "destroy integration test 'secret-manual'", + "integ:SECRET:destroy": { + "name": "integ:SECRET:destroy", + "description": "destroy integration test 'SECRET'", "steps": [ { - "exec": "cdk destroy --app test/secret-manual.integ.snapshot '**' --no-version-reporting" + "exec": "cdk destroy --app test/SECRET.integ.snapshot '**' --no-version-reporting" } ] }, - "integ:secret-manual:snapshot": { - "name": "integ:secret-manual:snapshot", - "description": "update snapshot for integration test \"secret-manual\"", + "integ:SECRET:snapshot": { + "name": "integ:SECRET:snapshot", + "description": "update snapshot for integration test \"SECRET\"", "steps": [ { - "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/secret-manual.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/secret-manual.integ.snapshot > /dev/null" + "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/SECRET.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/SECRET.integ.snapshot > /dev/null" } ] }, - "integ:secret-manual:watch": { - "name": "integ:secret-manual:watch", - "description": "watch integration test 'secret-manual' (without updating snapshots)", + "integ:SECRET:watch": { + "name": "integ:SECRET:watch", + "description": "watch integration test 'SECRET' (without updating snapshots)", "steps": [ { - "exec": "cdk watch --app \"ts-node -P tsconfig.dev.json test/secret-manual.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' -o test/.tmp/secret-manual.integ/deploy.cdk.out" - } - ] - }, - "integ:secret-multikms:assert": { - "name": "integ:secret-multikms:assert", - "description": "assert the snapshot of integration test 'secret-multikms'", - "steps": [ - { - "exec": "[ -d \"test/secret-multikms.integ.snapshot\" ] || (echo \"No snapshot available for integration test 'secret-multikms'. Run 'projen integ:secret-multikms:deploy' to capture.\" && exit 1)" - }, - { - "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/secret-multikms.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/.tmp/secret-multikms.integ/assert.cdk.out > /dev/null" - }, - { - "exec": "diff -r -x asset.* -x cdk.out -x manifest.json -x tree.json test/secret-multikms.integ.snapshot/ test/.tmp/secret-multikms.integ/assert.cdk.out/" - } - ] - }, - "integ:secret-multikms:deploy": { - "name": "integ:secret-multikms:deploy", - "description": "deploy integration test 'secret-multikms' and capture snapshot", - "steps": [ - { - "exec": "rm -fr test/.tmp/secret-multikms.integ/deploy.cdk.out" - }, - { - "exec": "cdk deploy --app \"ts-node -P tsconfig.dev.json test/secret-multikms.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' --require-approval=never -o test/.tmp/secret-multikms.integ/deploy.cdk.out" - }, - { - "exec": "rm -fr test/secret-multikms.integ.snapshot" - }, - { - "exec": "mv test/.tmp/secret-multikms.integ/deploy.cdk.out test/secret-multikms.integ.snapshot" - }, - { - "spawn": "integ:secret-multikms:destroy" - } - ] - }, - "integ:secret-multikms:destroy": { - "name": "integ:secret-multikms:destroy", - "description": "destroy integration test 'secret-multikms'", - "steps": [ - { - "exec": "cdk destroy --app test/secret-multikms.integ.snapshot '**' --no-version-reporting" - } - ] - }, - "integ:secret-multikms:snapshot": { - "name": "integ:secret-multikms:snapshot", - "description": "update snapshot for integration test \"secret-multikms\"", - "steps": [ - { - "exec": "cdk synth --app \"ts-node -P tsconfig.dev.json test/secret-multikms.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata -o test/secret-multikms.integ.snapshot > /dev/null" - } - ] - }, - "integ:secret-multikms:watch": { - "name": "integ:secret-multikms:watch", - "description": "watch integration test 'secret-multikms' (without updating snapshots)", - "steps": [ - { - "exec": "cdk watch --app \"ts-node -P tsconfig.dev.json test/secret-multikms.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' -o test/.tmp/secret-multikms.integ/deploy.cdk.out" + "exec": "cdk watch --app \"ts-node -P tsconfig.dev.json test/SECRET.integ.ts\" --no-notices --no-version-reporting --no-asset-metadata --no-path-metadata '**' -o test/.tmp/SECRET.integ/deploy.cdk.out" } ] }, @@ -410,16 +347,13 @@ "description": "update snapshot for all integration tests", "steps": [ { - "spawn": "integ:secret-asset:snapshot" - }, - { - "spawn": "integ:secret-inline:snapshot" + "spawn": "integ:PARAMETER_MULTI:snapshot" }, { - "spawn": "integ:secret-manual:snapshot" + "spawn": "integ:PARAMETER:snapshot" }, { - "spawn": "integ:secret-multikms:snapshot" + "spawn": "integ:SECRET:snapshot" } ] }, @@ -544,16 +478,13 @@ "spawn": "eslint" }, { - "spawn": "integ:secret-asset:assert" - }, - { - "spawn": "integ:secret-inline:assert" + "spawn": "integ:PARAMETER_MULTI:assert" }, { - "spawn": "integ:secret-manual:assert" + "spawn": "integ:PARAMETER:assert" }, { - "spawn": "integ:secret-multikms:assert" + "spawn": "integ:SECRET:assert" } ] }, diff --git a/.projenrc.js b/.projenrc.js index 1e088b42..b7dfd20e 100644 --- a/.projenrc.js +++ b/.projenrc.js @@ -34,7 +34,7 @@ const project = new awscdk.AwsCdkConstructLibrary({ // description: undefined, /* The description is just a string that helps people understand the purpose of the package. */ devDeps: [ 'json-schema-to-typescript', - ], /* Build dependencies for this module. */ + ] /* Build dependencies for this module. */, integrationTestAutoDiscover: true, prettier: true, prettierOptions: { diff --git a/API.md b/API.md index 943f6712..d21a6e3a 100644 --- a/API.md +++ b/API.md @@ -1759,7 +1759,6 @@ const multiStringParameterProps: MultiStringParameterProps = { ... } | **Name** | **Type** | **Description** | | --- | --- | --- | | autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | -| flattenSeparator | string | If the structure should be flattened use the provided separator between keys. | | sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | | sopsFileFormat | string | The format of the sops file. | | sopsFilePath | string | The filepath to the sops file. | @@ -1768,7 +1767,7 @@ const multiStringParameterProps: MultiStringParameterProps = { ... } | sopsS3Bucket | string | If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | | sopsS3Key | string | If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | | uploadType | UploadType | How should the secret be passed to the CustomResource? | -| encryptionKey | aws-cdk-lib.aws_kms.IKey | *No description.* | +| encryptionKey | aws-cdk-lib.aws_kms.IKey | The customer-managed encryption key to use for encrypting the secret value. | | description | string | Information about the parameter that you want to add to the system. | | tier | aws-cdk-lib.aws_ssm.ParameterTier | The tier of the string parameter. | | keyPrefix | string | The prefix used for all parameters. | @@ -1789,19 +1788,6 @@ Should this construct automatically create IAM permissions? --- -##### `flattenSeparator`Optional - -```typescript -public readonly flattenSeparator: string; -``` - -- *Type:* string -- *Default:* undefined - -If the structure should be flattened use the provided separator between keys. - ---- - ##### `sopsAgeKey`Optional ```typescript @@ -1915,6 +1901,9 @@ public readonly encryptionKey: IKey; ``` - *Type:* aws-cdk-lib.aws_kms.IKey +- *Default:* A default KMS key for the account and region is used. + +The customer-managed encryption key to use for encrypting the secret value. --- @@ -1987,7 +1976,6 @@ const sopsCommonParameterProps: SopsCommonParameterProps = { ... } | **Name** | **Type** | **Description** | | --- | --- | --- | | autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | -| flattenSeparator | string | If the structure should be flattened use the provided separator between keys. | | sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | | sopsFileFormat | string | The format of the sops file. | | sopsFilePath | string | The filepath to the sops file. | @@ -1996,7 +1984,7 @@ const sopsCommonParameterProps: SopsCommonParameterProps = { ... } | sopsS3Bucket | string | If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | | sopsS3Key | string | If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | | uploadType | UploadType | How should the secret be passed to the CustomResource? | -| encryptionKey | aws-cdk-lib.aws_kms.IKey | *No description.* | +| encryptionKey | aws-cdk-lib.aws_kms.IKey | The customer-managed encryption key to use for encrypting the secret value. | | description | string | Information about the parameter that you want to add to the system. | | tier | aws-cdk-lib.aws_ssm.ParameterTier | The tier of the string parameter. | @@ -2015,19 +2003,6 @@ Should this construct automatically create IAM permissions? --- -##### `flattenSeparator`Optional - -```typescript -public readonly flattenSeparator: string; -``` - -- *Type:* string -- *Default:* undefined - -If the structure should be flattened use the provided separator between keys. - ---- - ##### `sopsAgeKey`Optional ```typescript @@ -2141,6 +2116,9 @@ public readonly encryptionKey: IKey; ``` - *Type:* aws-cdk-lib.aws_kms.IKey +- *Default:* A default KMS key for the account and region is used. + +The customer-managed encryption key to use for encrypting the secret value. --- @@ -2186,17 +2164,7 @@ const sopsSecretProps: SopsSecretProps = { ... } | **Name** | **Type** | **Description** | | --- | --- | --- | -| description | string | An optional, human-friendly description of the secret. | -| encryptionKey | aws-cdk-lib.aws_kms.IKey | The customer-managed encryption key to use for encrypting the secret value. | -| generateSecretString | aws-cdk-lib.aws_secretsmanager.SecretStringGenerator | Configuration for how to generate a secret value. | -| removalPolicy | aws-cdk-lib.RemovalPolicy | Policy to apply when the secret is removed from this stack. | -| replicaRegions | aws-cdk-lib.aws_secretsmanager.ReplicaRegion[] | A list of regions where to replicate this secret. | -| secretName | string | A name for the secret. | -| secretObjectValue | {[ key: string ]: aws-cdk-lib.SecretValue} | Initial value for a JSON secret. | -| secretStringBeta1 | aws-cdk-lib.aws_secretsmanager.SecretStringValueBeta1 | Initial value for the secret. | -| secretStringValue | aws-cdk-lib.SecretValue | Initial value for the secret. | | autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | -| flattenSeparator | string | If the structure should be flattened use the provided separator between keys. | | sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | | sopsFileFormat | string | The format of the sops file. | | sopsFilePath | string | The filepath to the sops file. | @@ -2205,180 +2173,12 @@ const sopsSecretProps: SopsSecretProps = { ... } | sopsS3Bucket | string | If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | | sopsS3Key | string | If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | | uploadType | UploadType | How should the secret be passed to the CustomResource? | +| description | string | An optional, human-friendly description of the secret. | +| encryptionKey | aws-cdk-lib.aws_kms.IKey | The customer-managed encryption key to use for encrypting the secret value. | | rawOutput | boolean | Should the secret parsed and transformed to json? | - ---- - -##### `description`Optional - -```typescript -public readonly description: string; -``` - -- *Type:* string -- *Default:* No description. - -An optional, human-friendly description of the secret. - ---- - -##### `encryptionKey`Optional - -```typescript -public readonly encryptionKey: IKey; -``` - -- *Type:* aws-cdk-lib.aws_kms.IKey -- *Default:* A default KMS key for the account and region is used. - -The customer-managed encryption key to use for encrypting the secret value. - ---- - -##### `generateSecretString`Optional - -```typescript -public readonly generateSecretString: SecretStringGenerator; -``` - -- *Type:* aws-cdk-lib.aws_secretsmanager.SecretStringGenerator -- *Default:* 32 characters with upper-case letters, lower-case letters, punctuation and numbers (at least one from each category), per the default values of ``SecretStringGenerator``. - -Configuration for how to generate a secret value. - -Only one of `secretString` and `generateSecretString` can be provided. - ---- - -##### `removalPolicy`Optional - -```typescript -public readonly removalPolicy: RemovalPolicy; -``` - -- *Type:* aws-cdk-lib.RemovalPolicy -- *Default:* Not set. - -Policy to apply when the secret is removed from this stack. - ---- - -##### `replicaRegions`Optional - -```typescript -public readonly replicaRegions: ReplicaRegion[]; -``` - -- *Type:* aws-cdk-lib.aws_secretsmanager.ReplicaRegion[] -- *Default:* Secret is not replicated - -A list of regions where to replicate this secret. - ---- - -##### `secretName`Optional - -```typescript -public readonly secretName: string; -``` - -- *Type:* string -- *Default:* A name is generated by CloudFormation. - -A name for the secret. - -Note that deleting secrets from SecretsManager does not happen immediately, but after a 7 to -30 days blackout period. During that period, it is not possible to create another secret that shares the same name. - ---- - -##### `secretObjectValue`Optional - -```typescript -public readonly secretObjectValue: {[ key: string ]: SecretValue}; -``` - -- *Type:* {[ key: string ]: aws-cdk-lib.SecretValue} -- *Default:* SecretsManager generates a new secret value. - -Initial value for a JSON secret. - -**NOTE:** *It is **highly** encouraged to leave this field undefined and allow SecretsManager to create the secret value. -The secret object -- if provided -- will be included in the output of the cdk as part of synthesis, -and will appear in the CloudFormation template in the console. This can be secure(-ish) if that value is merely reference to -another resource (or one of its attributes), but if the value is a plaintext string, it will be visible to anyone with access -to the CloudFormation template (via the AWS Console, SDKs, or CLI). - -Specifies a JSON object that you want to encrypt and store in this new version of the secret. -To specify a simple string value instead, use `SecretProps.secretStringValue` - -Only one of `secretStringBeta1`, `secretStringValue`, 'secretObjectValue', and `generateSecretString` can be provided. - ---- - -*Example* - -```typescript -declare const user: iam.User; -declare const accessKey: iam.AccessKey; -declare const stack: Stack; -new secretsmanager.Secret(stack, 'JSONSecret', { - secretObjectValue: { - username: SecretValue.unsafePlainText(user.userName), // intrinsic reference, not exposed as plaintext - database: SecretValue.unsafePlainText('foo'), // rendered as plain text, but not a secret - password: accessKey.secretAccessKey, // SecretValue - }, -}); -``` - - -##### ~~`secretStringBeta1`~~Optional - -- *Deprecated:* Use `secretStringValue` instead. - -```typescript -public readonly secretStringBeta1: SecretStringValueBeta1; -``` - -- *Type:* aws-cdk-lib.aws_secretsmanager.SecretStringValueBeta1 -- *Default:* SecretsManager generates a new secret value. - -Initial value for the secret. - -**NOTE:** *It is **highly** encouraged to leave this field undefined and allow SecretsManager to create the secret value. -The secret string -- if provided -- will be included in the output of the cdk as part of synthesis, -and will appear in the CloudFormation template in the console. This can be secure(-ish) if that value is merely reference to -another resource (or one of its attributes), but if the value is a plaintext string, it will be visible to anyone with access -to the CloudFormation template (via the AWS Console, SDKs, or CLI). - -Specifies text data that you want to encrypt and store in this new version of the secret. -May be a simple string value, or a string representation of a JSON structure. - -Only one of `secretStringBeta1`, `secretStringValue`, and `generateSecretString` can be provided. - ---- - -##### `secretStringValue`Optional - -```typescript -public readonly secretStringValue: SecretValue; -``` - -- *Type:* aws-cdk-lib.SecretValue -- *Default:* SecretsManager generates a new secret value. - -Initial value for the secret. - -**NOTE:** *It is **highly** encouraged to leave this field undefined and allow SecretsManager to create the secret value. -The secret string -- if provided -- will be included in the output of the cdk as part of synthesis, -and will appear in the CloudFormation template in the console. This can be secure(-ish) if that value is merely reference to -another resource (or one of its attributes), but if the value is a plaintext string, it will be visible to anyone with access -to the CloudFormation template (via the AWS Console, SDKs, or CLI). - -Specifies text data that you want to encrypt and store in this new version of the secret. -May be a simple string value. To provide a string representation of JSON structure, use `SecretProps.secretObjectValue` instead. - -Only one of `secretStringBeta1`, `secretStringValue`, 'secretObjectValue', and `generateSecretString` can be provided. +| removalPolicy | aws-cdk-lib.RemovalPolicy | Policy to apply when the secret is removed from this stack. | +| replicaRegions | aws-cdk-lib.aws_secretsmanager.ReplicaRegion[] | A list of regions where to replicate this secret. | +| secretName | string | A name for the secret. | --- @@ -2395,19 +2195,6 @@ Should this construct automatically create IAM permissions? --- -##### `flattenSeparator`Optional - -```typescript -public readonly flattenSeparator: string; -``` - -- *Type:* string -- *Default:* undefined - -If the structure should be flattened use the provided separator between keys. - ---- - ##### `sopsAgeKey`Optional ```typescript @@ -2514,6 +2301,32 @@ How should the secret be passed to the CustomResource? --- +##### `description`Optional + +```typescript +public readonly description: string; +``` + +- *Type:* string +- *Default:* No description. + +An optional, human-friendly description of the secret. + +--- + +##### `encryptionKey`Optional + +```typescript +public readonly encryptionKey: IKey; +``` + +- *Type:* aws-cdk-lib.aws_kms.IKey +- *Default:* A default KMS key for the account and region is used. + +The customer-managed encryption key to use for encrypting the secret value. + +--- + ##### `rawOutput`Optional ```typescript @@ -2527,6 +2340,48 @@ Should the secret parsed and transformed to json? --- +##### `removalPolicy`Optional + +```typescript +public readonly removalPolicy: RemovalPolicy; +``` + +- *Type:* aws-cdk-lib.RemovalPolicy +- *Default:* Not set. + +Policy to apply when the secret is removed from this stack. + +--- + +##### `replicaRegions`Optional + +```typescript +public readonly replicaRegions: ReplicaRegion[]; +``` + +- *Type:* aws-cdk-lib.aws_secretsmanager.ReplicaRegion[] +- *Default:* Secret is not replicated + +A list of regions where to replicate this secret. + +--- + +##### `secretName`Optional + +```typescript +public readonly secretName: string; +``` + +- *Type:* string +- *Default:* A name is generated by CloudFormation. + +A name for the secret. + +Note that deleting secrets from SecretsManager does not happen immediately, but after a 7 to +30 days blackout period. During that period, it is not possible to create another secret that shares the same name. + +--- + ### SopsStringParameterProps #### Initializer @@ -2542,7 +2397,6 @@ const sopsStringParameterProps: SopsStringParameterProps = { ... } | **Name** | **Type** | **Description** | | --- | --- | --- | | autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | -| flattenSeparator | string | If the structure should be flattened use the provided separator between keys. | | sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | | sopsFileFormat | string | The format of the sops file. | | sopsFilePath | string | The filepath to the sops file. | @@ -2551,7 +2405,7 @@ const sopsStringParameterProps: SopsStringParameterProps = { ... } | sopsS3Bucket | string | If you want to pass the sops file via s3, you can specify the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | | sopsS3Key | string | If you want to pass the sops file via s3, you can specify the key inside the bucket you can use cfn parameter here Both, sopsS3Bucket and sopsS3Key have to be specified. | | uploadType | UploadType | How should the secret be passed to the CustomResource? | -| encryptionKey | aws-cdk-lib.aws_kms.IKey | *No description.* | +| encryptionKey | aws-cdk-lib.aws_kms.IKey | The customer-managed encryption key to use for encrypting the secret value. | | description | string | Information about the parameter that you want to add to the system. | | tier | aws-cdk-lib.aws_ssm.ParameterTier | The tier of the string parameter. | | parameterName | string | The name of the parameter. | @@ -2571,19 +2425,6 @@ Should this construct automatically create IAM permissions? --- -##### `flattenSeparator`Optional - -```typescript -public readonly flattenSeparator: string; -``` - -- *Type:* string -- *Default:* undefined - -If the structure should be flattened use the provided separator between keys. - ---- - ##### `sopsAgeKey`Optional ```typescript @@ -2697,6 +2538,9 @@ public readonly encryptionKey: IKey; ``` - *Type:* aws-cdk-lib.aws_kms.IKey +- *Default:* A default KMS key for the account and region is used. + +The customer-managed encryption key to use for encrypting the secret value. --- @@ -2756,7 +2600,6 @@ const sopsSyncOptions: SopsSyncOptions = { ... } | **Name** | **Type** | **Description** | | --- | --- | --- | | autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | -| flattenSeparator | string | If the structure should be flattened use the provided separator between keys. | | sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | | sopsFileFormat | string | The format of the sops file. | | sopsFilePath | string | The filepath to the sops file. | @@ -2781,19 +2624,6 @@ Should this construct automatically create IAM permissions? --- -##### `flattenSeparator`Optional - -```typescript -public readonly flattenSeparator: string; -``` - -- *Type:* string -- *Default:* undefined - -If the structure should be flattened use the provided separator between keys. - ---- - ##### `sopsAgeKey`Optional ```typescript @@ -2917,7 +2747,6 @@ const sopsSyncProps: SopsSyncProps = { ... } | **Name** | **Type** | **Description** | | --- | --- | --- | | autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | -| flattenSeparator | string | If the structure should be flattened use the provided separator between keys. | | sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | | sopsFileFormat | string | The format of the sops file. | | sopsFilePath | string | The filepath to the sops file. | @@ -2929,6 +2758,7 @@ const sopsSyncProps: SopsSyncProps = { ... } | resourceType | ResourceType | Will this Sync deploy a Secret or Parameter(s). | | target | string | The target to populate with the sops file content. | | encryptionKey | aws-cdk-lib.aws_kms.IKey | The encryption key used for encrypting the ssm parameter if `parameterName` is set. | +| flattenSeparator | string | If the structure should be flattened use the provided separator between keys. | | parameterNames | string[] | *No description.* | | secret | aws-cdk-lib.aws_secretsmanager.ISecret | *No description.* | @@ -2947,19 +2777,6 @@ Should this construct automatically create IAM permissions? --- -##### `flattenSeparator`Optional - -```typescript -public readonly flattenSeparator: string; -``` - -- *Type:* string -- *Default:* undefined - -If the structure should be flattened use the provided separator between keys. - ---- - ##### `sopsAgeKey`Optional ```typescript @@ -3106,6 +2923,19 @@ The encryption key used for encrypting the ssm parameter if `parameterName` is s --- +##### `flattenSeparator`Optional + +```typescript +public readonly flattenSeparator: string; +``` + +- *Type:* string +- *Default:* undefined + +If the structure should be flattened use the provided separator between keys. + +--- + ##### `parameterNames`Optional ```typescript diff --git a/README.md b/README.md index 3467c007..1e84623f 100644 --- a/README.md +++ b/README.md @@ -1,213 +1,300 @@ -

-![stability](https://img.shields.io/badge/Stability-stable-green)  -[![release](https://github.com/dbsystel/cdk-sops-secrets/actions/workflows/release.yml/badge.svg)](https://github.com/dbsystel/cdk-sops-secrets/actions/workflows/release.yml)
+![stability](https://img.shields.io/badge/Stability-stable-green) +[![release](https://github.com/dbsystel/cdk-sops-secrets/actions/workflows/release.yml/badge.svg)](https://github.com/dbsystel/cdk-sops-secrets/actions/workflows/release.yml) +[![cdk-construct-hub](https://img.shields.io/badge/CDK-ConstructHub-blue)](https://constructs.dev/packages/cdk-sops-secrets) +[![npm](https://img.shields.io/npm/v/cdk-sops-secrets.svg)](https://www.npmjs.com/package/cdk-sops-secrets) +[![npm downloads](https://img.shields.io/npm/dw/cdk-sops-secrets)](https://www.npmjs.com/package/cdk-sops-secrets) +[![pypi](https://img.shields.io/pypi/v/cdk-sops-secrets.svg)](https://pypi.org/project/cdk-sops-secrets) +[![pypi downloads](https://img.shields.io/pypi/dw/cdk-sops-secrets)](https://pypi.org/project/cdk-sops-secrets) +![GitHub Downloads (all assets, latest release)](https://img.shields.io/github/:variant/:user/:repo/latest/total) +[![codecov](https://codecov.io/gh/dbsystel/cdk-sops-secrets/branch/main/graph/badge.svg?token=OT7P7HQHXB)](https://codecov.io/gh/dbsystel/cdk-sops-secrets) +[![security-vulnerabilities](https://img.shields.io/github/issues-search/dbsystel/cdk-sops-secrets?color=%23ff0000&label=security-vulnerabilities&query=is%3Aissue%20is%3Aopen%20label%3A%22Mend%3A%20dependency%20security%20vulnerability%22)](https://github.com/dbsystel/cdk-sops-secrets/issues?q=is%3Aissue+is%3Aopen+label%3A%22security+vulnerability%22) -[![cdk-construct-hub](https://img.shields.io/badge/CDK-ConstructHub-blue)](https://constructs.dev/packages/cdk-sops-secrets)
-[![npm](https://img.shields.io/npm/v/cdk-sops-secrets.svg)](https://www.npmjs.com/package/cdk-sops-secrets)  -[![npm downloads](https://img.shields.io/npm/dw/cdk-sops-secrets)](https://www.npmjs.com/package/cdk-sops-secrets)
-[![pypi](https://img.shields.io/pypi/v/cdk-sops-secrets.svg)](https://pypi.org/project/cdk-sops-secrets)  -[![pypi downloads](https://img.shields.io/pypi/dw/cdk-sops-secrets)](https://pypi.org/project/cdk-sops-secrets)
+# Introduction -[![codecov](https://codecov.io/gh/dbsystel/cdk-sops-secrets/branch/main/graph/badge.svg?token=OT7P7HQHXB)](https://codecov.io/gh/dbsystel/cdk-sops-secrets)   -[![security-vulnerabilities](https://img.shields.io/github/issues-search/dbsystel/cdk-sops-secrets?color=%23ff0000&label=security-vulnerabilities&query=is%3Aissue%20is%3Aopen%20label%3A%22Mend%3A%20dependency%20security%20vulnerability%22)](https://github.com/dbsystel/cdk-sops-secrets/issues?q=is%3Aissue+is%3Aopen+label%3A%22security+vulnerability%22)  +This construct library offers CDK Constructs that facilitate syncing SOPS-encrypted secrets to AWS Secrets Manager and SSM Parameter Store. +It enables secure storage of secrets in Git repositories while allowing seamless synchronization and usage within AWS. -## Introduction +# Table Of Contents -This construct library provides a replacement for CDK SecretsManager secrets, with extended functionality for Mozilla/sops. +- [Available Constructs](#available-constructs) + - [SopsSecret — Sops to SecretsManager](#sopssecret--sops-to-secretsmanager) + - [SopsStringParameter — Sops to single SSM ParameterStore Parameter](#sopsstringparameter--sops-to-single-ssm-parameterstore-parameter) + - [MultiStringParameter — Sops to multiple SSM ParameterStore Parameters](#multistringparameter--sops-to-multiple-ssm-parameterstore-parameters) + - [SopsSyncProvider](#sopssyncprovider) + - [Common configuration options for SopsSecret, SopsStringParameter and MultiStringParameter](#common-configuration-options-for-sopssecret-sopsstringparameter-and-multistringparameter) +- [Considerations](#considerations) +- [FAQ](#faq) -

-Using this library it is possible to populate Secrets with values from a Mozilla/sops file without additional scripts and steps in the CI stage. Thereby transformations like JSON conversion of YAML files and transformation into a flat, JSONPath like structure will be performed, but can be disabled. +# Available Constructs -Secrets filled in this way can be used immediately within the CloudFormation stack and dynamic references. This construct should handle all dependencies, if you use the `secretValueFromJson()` or `secretValue()` call to access secret values. +The construct library cdk-sops-secrets supports three different Constructs that help you to sync your encrypted sops secrets to secure places in AWS. -This way, secrets can be securely stored in git repositories and easily synchronized into AWS SecretsManager secrets. +Let's assume we want to store the following secret information in AWS: -## Stability - -You can consider this package as stable. Updates will follow [Semantic Versioning](https://semver.org/).
-Nevertheless, I would recommend pinning the exact version of this library in your `package.json`. +```json +{ + "apiKey": "sk-1234567890abcdef", + "database": { + "user": "admin", + "password": "P@ssw0rd!", + "host": "db.example.com" + }, + "tokens": [ + {"service": "github", "token": "ghp_abcd1234"}, + {"service": "aws", "token": "AKIAIOSFODNN7EXAMPLE"} + ], + "someOtherKey": "base64:VGhpcyBpcyBhIHNlY3JldCBrZXk=" +} +``` -## Prerequisites +It doesn't matter if this data is in `json`, `yaml` or `dotenv` format, `cdk-sops-secret` can handle them all. +Even binary data is supported with some limitations. -- [AWS](https://aws.amazon.com/): I think you already knew it, but this construct will only work with an AWS account. +## SopsSecret — Sops to SecretsManager -* [KMS Key](https://aws.amazon.com/kms/?nc1=h_ls): It makes most sense to encrypt your secrets with AWS KMS if you want to sync and use the secret content afterwards in your AWS account. -* [mozilla/sops](https://github.com/mozilla/sops): This construct assumes that you store your secrets encrypted via sops in your git repository. -* [CDK](https://aws.amazon.com/cdk/?nc1=h_ls): As this is a CDK construct, it's only useful if you use the CloudDevelopmentToolkit. +If you want to store your secret data in the AWS SecretsManager, use the `SopsSecret` construct. This is a "drop-in-replacement" for the [Secret Construct](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_secretsmanager.Secret.html) of the AWS CDK. -## Getting started +Minimal Example: -1. Create a Mozilla/sops secrets file (encrypted with an already existing KMS key) and place it somewhere in your git repository -2. Create a secret with the SopsSecret construct inside your app - ```ts - const secret = new SopsSecret(stack, 'SopsComplexSecretJSON', { - sopsFilePath: 'secrets/sopsfile-encrypted.json', - }); - ``` -3. Optional: Access the secret via dynamic references - ```ts - secret.secretValueFromJson('json.path.dotted.notation.accessor[0]').toString(), - ``` +```ts +const secret = new SopsSecret(stack, 'MySopsSecret', { + secertName: 'mySecret', // name of the secret in AWS SecretsManager + sopsFilePath: 'secrets/sopsfile-encrypted-secret.json', // filepath to the sops encrypted file +}); +``` -## Advanced configuration examples +The content referenced sops secret file will be synced to the AWS SecretsManager Secret with the name `mySecret`. +For convenience, several transformations apply: -Even if using the main functionality should be done in 3 lines of code, there are more options to configure the constructs of this library. If you want to get an Overview of all available configuration options take a look at the [documentation at the CDK ConstructHub](https://constructs.dev/packages/cdk-sops-secrets). +- Nested structures and arrays will be resolved and flattened to a JSONPath notation +- All values will be stored as strings + +This is done also because of limitations of CDK in conjunction with +[dynamic references](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references-secretsmanager.html) and limitiations +of the `Key/Value` view of the AWS SecretsManager WebConsole. So the result, saved in the AWS SecretsManager will actually be: -The most useful settings will be explained in the further chapters: +```json +{ + "apiKey": "sk-1234567890abcdef", + "database.user": "admin", + "database.password": "P@ssw0rd!", + "database.host": "db.example.com", + "tokens[0].service": "github", + "tokens[0].token": "ghp_abcd1234", + "tokens[1].service": "aws", + "tokens[1].token": "AKIAIOSFODNN7EXAMPLE", + "someOtherKey": "base64:VGhpcyBpcyBhIHNlY3JldCBrZXk=" +} +``` -### Binary - Just the raw file +This allows you to access the values from your secret via CDK: -If you have the need to just upload a sops encrypted binary file, just name your sops encrypted file *.binary, or specify the option "binary" as format. +```ts +secret.secretValueFromJson('"database.password"').toString(), +secret.secretValueFromJson('"tokens[0].token"').toString() +``` +If you don't want these conversions, you can completely disable them by using the `rawOutput` property. -```typescript -const secret = new SopsSecret(this, 'SopsComplexSecretJSON', { +```ts +const secret = new SopsSecret(stack, 'MySopsSecret', { + rawOutput: true, ... - sopsFilePath: 'secrets/sopsfile-encrypted.binary', }); ``` -or +This will turn off the conversions and just place the decrypted content in the target secret. -```typescript -const secret = new SopsSecret(this, 'SopsComplexSecretJSON', { - ... - sopsFilePath: 'secrets/sopsfile-encrypted.something', - sopsFileFormat: 'binary', +## SopsStringParameter — Sops to single SSM ParameterStore Parameter + +If you want to sync the whole content of a sops encrypted file to an encrypted AWS SSM ParameterStore Parameter, you can use the SopsStringParameter Construct. + +```ts +const parameter = new SopsStringParameter(stack, 'MySopsParameter', { + encryptionKey: Key.fromLookup(stack, 'DefaultKey', { + aliasName: 'alias/aws/ssm', + }), + sopsFilePath: 'secrets/sopsfile-encrypted-secret.json', }); ``` +This will create a Parameter with the value of the decrypted sops file content. No transformations are applied. -### Getting a specific (older version) - -While creating the secret or updating the entries of a secret, the native CDK function ```cdk.FileSystem.fingerprint(...)``` is used to generate the version information of the AWS SecretsManager secret. -Therefore, it is possible to reference the entries from a specific AWS SecretsManager version. +## MultiStringParameter — Sops to multiple SSM ParameterStore Parameters -```typescript -const versionId = cdk.FileSystem.fingerprint(`./sops/SomeSecrets.json`) -const passphrase = ecs.Secret.fromSecretsManagerVersion(secretMgmt, { versionId: versionId }, 'MY_PRIVATE_PASSPHRASE') +If you have a structured sops file (yaml, json, dotenv) and want to populate the AWS SSM ParameterStore with it, you want to use the MultiStringParameter Construct. -const container = TaskDef.addContainer('Container', { - secrets: { - MY_PRIVATE_PASSPHRASE: passphrase, - }, -}); +```ts +const multi = new MultiStringParameter(stack, 'MyMultiParameter', { + encryptionKey: Key.fromLookup(stack, 'DefaultKey', { + aliasName: 'alias/aws/ssm', + }), + sopsFilePath: 'secrets/sopsfile-encrypted-secret.json' +}) ``` -### Default conversions and how to disable them? +This will create several AWS SSM ParameterStore Parameters: + +```bash +ParameterName => Value + +/apiKey => "sk-1234567890abcdef" +/database/user => "admin" +/database/password => "P@ssw0rd!" +/database/host => "db.example.com" +/tokens/0/service => "github" +/tokens/0/token => "ghp_abcd1234" +/tokens/1/service => "aws" +/tokens/1/token => "AKIAIOSFODNN7EXAMPLE" +/someOtherKey => "base64:VGhpcyBpcyBhIHNlY3JldCBrZXk=" +``` -As default behavior, the SopsSecret (via the SopsSync) will convert all content to JSON and flatten its structure. This is useful, because the AWS SecretsManager has some limitations if it comes to YAML and/or complex objects and decimal values. Even if you can store YAML, complex objects and even binaries in AWS SecretsManager secrets, you can't access their values via the SecretsManager API — you can only return them as is. So accessing (nested) values or values from YAML files won't be possible via [dynamic references](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references.html) in CloudFormation (and CDK). That's why I decided that conversion to JSON, flatten the structure and stringify all values should be the default behavior. But you can turn off all of these conversion steps: +You can configure the naming schema via the properties `keySeperator` and `keyPrefix`: -```typescript -const secret = new SopsSecret(this, 'SopsComplexSecretJSON', { - convertToJSON: false, // disable converting the encrypted content to JSON - stringify: false, // disable stringifying all values - flatten: false, // disable flattening of the object structure - sopsFilePath: 'secrets/sopsfile-encrypted.json', -}); +```ts +const multi = new MultiStringParameter(stack, 'MyMultiParameter', { + keyPrefix: 'mykeyprefix.' // All keys will start with this string, default '/' + keySeperator: '-' // This seperator is used when converting to a flat structure, default '/' +}) ``` -### Resource provider is missing permissions +This would lead to Parameters -Sometimes it can be necessary to access the IAM role of the SopsSync provider. If this is the case, you should create the provider before creating the SopsSecret, and pass the provider to it like this: +```bash +ParameterName => Value -```typescript -// Create the provider -const provider = new SopsSyncProvider(this, 'CustomSopsSyncProvider'); -// Grant whatever you need to the provider -const myExtraKmsKey = Key.fromKeyArn(this, 'MyExtraKmsKey', 'YourKeyArn'); -myExtraKmsKey.grantDecrypt(provider); -// create the secret and pass the the provider to it -const secret = new SopsSecret(this, 'SopsComplexSecretJSON', { - sopsProvider: provider, - secretName: 'myCoolSecret', - sopsFilePath: 'secrets/sopsfile-encrypted.json', -}); +mykeyprefix.apiKey => "sk-1234567890abcdef" +mykeyprefix.database-user => "admin" +mykeyprefix.tokens-0-service => "github" +... ``` -### User Provided IAM Permissions +## SopsSyncProvider -If you don't want to use the IAM autogenration, you can provide your own IAM Role with all required permissions: +The SOPS-Provider is the custom resource AWS Lambda Function, that is doing all the work. It downloads, decrypts +and stores the secret content in your desired location. This Lambda Function needs several IAM permissions to do it's work. -```typescript -const sopsProviderRole = new Role(stack, 'SopsProviderRole', { - assumedBy: new ServicePrincipal('lambda.amazonaws.com'), -}); +For most use cases, you don't need to create it on your own, as the other Constructs try to create this and derive the required IAM permissions from your input. -sopsProviderRole.addManagedPolicy({ - managedPolicyArn: - 'arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole', -}); +But there are use cases, that require you to change the defaults of this Provider. If this is the case, +you have to create the provider on your own and add it to the other constructs. -sopsProviderRole.addToPolicy( - new PolicyStatement({ - actions: ['todo:WriteYourRequiredPermissions'], - resources: ['*'], - }), -); +```ts +const provider = new SopsSyncProvider(this, 'MySopsSyncProvider', { + role: customRole, // you can pass a custom role -new SopsSyncProvider(stack, 'SopsSyncProvider', { - role: sopsProviderRole, + vpc: customVpc, // The default SopsSync Provider + vpcSubnets: { // won't run in any VPC, + subnets: [ // as it does not require + customSubnet1, // access to any VPC resources. + customSubnet2, // But if you want, + ] // you can change this behaviour + }, // and set vpc, subnet and + securityGroups: [ // securitygroups to your + customSecurityGroup // needs. + ], }); -new SopsSecret(stack, 'SopsSecretJSON', { - sopsFilePath: 'test-secrets/json/sopsfile.enc-age.json', - uploadType: UploadType.ASSET, - // disable auto IAM generation - autoGenerateIamPermissions: false, +provider.addToRolePolicy( // You cann pass PolicyStatements + new PolicyStatement({ // via the addToRolePolicy Method + actions: ['...'], // + resources: ['...'], // + }) // +); // + +kmsKey.grantDecrypt( // The provider implements + provider // the IGrantable interface, +); // so you can use it as grant target + +const secret = new SopsSecret(this, 'MySecret', { + sopsProvider: provider, // this property is available in all Constructs + ... }); ``` -### Use a VPC for the Lambda Function - -Internally, SopsSync uses a lambda function. In some environments it may be necessary to place this lambda function into a VPC and configure subnets and/or security groups for it. -This can be done by creating a custom `SopsSyncProvider`, setting the required networking configuration and passing it to the secret like this: +## Common configuration options for SopsSecret, SopsStringParameter and MultiStringParameter + +```ts + +const construct = new Sops...(this, 'My' { + /** + * use your own SopsSyncProvider + * @see SopsSyncProvider + */ + sopsProvider: myCustomProvider // default - a new provider will be created + + /** + * the constructs try to derive the required iam permissions from the sops file + * and the target. If you don't want this, you can disable this behaviour. + * You have to take care of all required permissions on your own. + */ + autoGenerateIamPermissions: false, // default: true + + /** + * the default behaviour of passing the sops file content to the provider is + * by embedding the base64 encoded content in the cloudformation template. + * Using CKD Assets is also supported. It might be required to switch to + * Assets, if your sops files are very large. + */ + uploadType: UploadType.ASSET, // default: UploadType.INLINE + + /** + * if you don't want this constructs to take care of passing the encrypted + * sops file to the sops provider, you can upload them yourself to a + * S3 bucket. + * You can pass bucket and key, and the constructs won't pass the content + * as ASSET or in the CloudFormation Template. + * As the construct isn't aware of the sopsfile, we can't derive the required + * permissions to decrypt the sops file. The same applies to the sopsFileFormat. + * You have to pass them all manually. + */ + sopsS3Bucket: 'my-custom-bucket', + sopsS3Key: 'encoded-sops.json', + sopsKmsKey: [ + kmsKeyUsedForEncryption, + ] + sopsFileFormat: 'json', // Allowed values are json, yaml, dotenv and binary +}) -```typescript -// Create the provider -const provider = new SopsSyncProvider(this, 'CustomSopsSyncProvider', { - vpc: myVpc, - vpcSubnets: subnetSelection, - securityGroups: [mySecurityGroup], -}); -// create the secret and pass the the provider to it -const secret = new SopsSecret(this, 'SopsSecret', { - sopsProvider: provider, - secretName: 'myCoolSecret', - sopsFilePath: 'secrets/sopsfile-encrypted.json', -}); ``` +# Considerations -### UploadType: INLINE / ASSET +## UploadType: INLINE / ASSET I decided, that the default behavior should be "INLINE" because of the following consideration: -- Fewer permissions: If we use inline content instead of a S3 asset, the SopsSyncProvider does not need permissions to access the asset bucket and its KMS key. -- Faster: If we don't have to upload and download things from and to S3, it should be a little faster. -- Interchangeable: As we use the same information to generate the version of the secret, no new version of the secret should be created, if you change from INLINE to ASSET or vice versa, even if the CloudFormation resource updates. -- I personally think sops files are not that big, that we should run into limits, but if so — we can change to asset `uploadType`. +- Fewer permissions + + _If we use inline content instead of a S3 asset, the SopsSyncProvider does not need permissions to access the asset bucket and its KMS key._ -You can change the uplaodType via the properties: +- Faster -```typescript -const secret = new SopsSecret(this, 'SopsWithAssetUpload', { - sopsFilePath: 'secrets/sopsfile-encrypted.json', - uploadType: UploadType.ASSET, // instead of the default UploadType.INLINE -}); -``` + _If we don't have to upload and download things from and to S3, it should be a little faster._ + +- Interchangeable + + _As we use the same information to generate the version of the secret, + no new version of the secret should be created, if you change from INLINE to ASSET or vice versa, + even if the CloudFormation resource updates._ -## FAQ +## Stability + +You can consider this package as stable. Updates will follow [Semantic Versioning](https://semver.org/). + +Nevertheless, I would recommend pinning the exact version of this library in your `package.json`. + +# FAQ -### It does not work, what can I do? +## It does not work, what can I do? -Even if this construct has some unit and integration tests performed, there can be bugs and issues. As everything is performed by a cloudformation custom resource provider, a good starting point is the log of the corresponding lambda function. It should be located in your AWS Account under Cloudwatch -> Log groups: +Even if this construct has some unit and integration tests performed, there can be bugs and issues. As everything is performed by a cloudformation custom resource provider, a good starting point is the log of the corresponding lambda function. It should be located in your AWS Account under Cloudwatch -> Log groups: ```/aws/lambda/-SingletonLambdaSopsSyncProvider``` -### I get errors with dotenv formatted files +## I get errors with `dotenv` formatted files Only very basic dotenv syntax is working right now. Only single line values are accepted. The format must match: @@ -217,11 +304,11 @@ key=value comments must be a single line, not after value assignments. -### Error getting data key: 0 successful groups required, got 0 +## Error: Error getting data key: 0 successful groups required, got 0 -This error message (and failed sync) is related to the mozilla/sops issues [#948](https://github.com/mozilla/sops/issues/948) and [#634](https://github.com/mozilla/sops/issues/634). You must not create your secret with the ```--aws-profile``` flag. This profile will be written to your sops filed and is required in every runtime environment. You have to define the profile to use via the environment variable ```AWS_PROFILE``` instead, to avoid this. +This error message (and failed sync) is related to the getsops/sops issues [#948](https://github.com/getsops/sops/issues/948) and [#634](https://github.com/getsops/sops/issues/634). You must not create your secret with the ```--aws-profile``` flag. This profile will be written to your sops filed and is required in every runtime environment. You have to define the profile to use via the environment variable ```AWS_PROFILE``` instead, to avoid this. -### Asset of sync lambda not found +## Error: Asset of sync lambda not found The lambda asset code is generated relative to the path of the index.ts in this package. With tools like nx this can lead to wrong results, so that the asset could not be found. @@ -229,7 +316,7 @@ You can override the asset path via the [cdk.json](https://docs.aws.amazon.com/c The context used for this override is ```sops_sync_provider_asset_path```. -So for example you can use +So for example you can use ```bash cdk deploy -c "sops_sync_provider_asset_path=some/path/asset.zip" @@ -245,23 +332,12 @@ or in your cdk.json } ``` -### I want to upload the sops file myself and only want to reference it +## Can I upload the sops file myself and provide the required information as CloudFormation Parameter? -That's possible since version 1.8.0. You can reference the file in S3 like: +This should be possible the following way. Ensure, that you have created a custom sops provider, +with proper IAM permissions. ```typescript -new SopsSecret(stack, 'SopsSecret', { - sopsS3Bucket: 'testbucket', - sopsS3Key: 'secret.json', - sopsFileFormat: 'json', - // ... -}); -``` - -Passing those values as CloudFormation parameters should also be possible: - -```typescript - const sopsS3BucketParam = new CfnParameter(this, "s3BucketName", { type: "String", description: "The name of the Amazon S3 bucket where your sopsFile was uploaded."}); @@ -270,35 +346,58 @@ const sopsS3KeyParam = new CfnParameter(this, "s3KeyName", { type: "String", description: "The name of the key of the sopsFile inside the Amazon S3 bucket."}); +const sopsKmsKeyArn = new CfnParameter(this, "sopsKeyArn", { + type: "String", + description: "The ARN of the KMS Key used for sops encryption"}); + +const sopsKmsKey = Key.fromKeyArn(this, 'Key', sopsKmsKeyArn.valueAsString) + new SopsSecret(stack, 'SopsSecret', { sopsS3Bucket: sopsS3BucketParam.valueAsString, sopsS3Key: sopsS3KeyParam.valueAsString, + sopsKmsKey: [ + sopsKmsKey + ], sopsFileFormat: 'json', - // ... + ... }); ``` -## Motivation +## Can I access older versions of the secret stored in the SecretsManager? -I have created this project to solve a recurring problem of syncing Mozilla/sops secrets into AWS SecretsManager in a convenient, secure way. +While creating the secret or updating the entries of a secret, the native CDK function `cdk.FileSystem.fingerprint(...)` is used +to generate the version information of the AWS SecretsManager secret. +Therefore, it is possible to reference the entries from a specific AWS SecretsManager version. -Other than that, or perhaps more importantly, my goal was to learn new things: +```typescript +const versionId = cdk.FileSystem.fingerprint(`./sops/SomeSecrets.json`) +const passphrase = ecs.Secret.fromSecretsManagerVersion(secretMgmt, { versionId: versionId }, 'MY_PRIVATE_PASSPHRASE') + +const container = TaskDef.addContainer('Container', { + secrets: { + MY_PRIVATE_PASSPHRASE: passphrase, + }, +}); +``` + +## I want the `raw` content of the sops file, but I always get the content nested in json + +To get the best raw experience, you should encrypt your sops files in binary format: + +```bash +sops encrypt ... my-whatever-file --output my-secret-information.sops.binary --input-type binary +``` -- Write a Golang lambda -- Writing unit tests incl. mocks in Golang -- Reproducible builds of Golang binaries (byte-by-byte identical) -- Build reproducible zips (byte-by-byte identical) -- Release a NPM package -- Setting up projects with projen -- CI/CD with GitHub actions -- CDK unit and integration tests +You will lose features like only encrypting the values, not the keys. +The whole file content will be stored in the sops file. +You can store everything you like as binary, even binary data[^1]. -## Other Tools like this +When using binary encrypted secrets with this constructs, ensure the ending is also binary, or override via +`sopsFormat` property. -The problem this Construct addresses is so good, already two other implementations exist: +This does not work for `MultiStringParameter` -- [isotoma/sops-secretsmanager-cdk](https://github.com/isotoma/sops-secretsmanager-cdk): Does nearly the same. Uses CustomResource, wraps the sops CLI, does not support flatten. Found it after I published my solution to NPM :-/ -- [taimos/secretsmanager-versioning](https://github.com/taimos/secretsmanager-versioning): Different approach on the same problem. This is a CLI tool with very nice integration into CDK and also handles git versioning information. +[^1] Even if sops can handle binary data, only the AWS SecretsManager allows to store it. ## License diff --git a/lambda/README.md b/lambda/README.md index 8892d94f..1f51deee 100644 --- a/lambda/README.md +++ b/lambda/README.md @@ -1,15 +1,22 @@ # Tested combinations -| Test Case | Input Format | Output Format | Flatten | Stringify | Handling Type | Expected Behavior | -| --------- | ------------ | ------------- | ---------- | --------- | --------------- | -------------------------------------- | -| 01 | binary | binary | N/A | N/A | SECRET | No transformation, raw binary output | -| 02 | binary | binary | N/A | N/A | PARAMETER | No transformation, raw binary output | -| 11 | json | N/A | true (N/A) | true | PARAMETER_MULTI | Outputformat allways map[string]string | -| 12 | yaml | N/A | true (N/A) | true | PARAMETER_MULTI | Outputformat allways map[string]string | -| 13 | dotenv | N/A | true (N/A) | true | PARAMETER_MULTI | Outputformat allways map[string]string | -| 21 | json | json | true | true | SECRET | Stringified, Flattened JSON | -| 22 | json | binary | N/A | N/A | SECRET | RAW Input is output | -| 23 | yaml | json | true | true | SECRET | Stringified, Flattened JSON | -| 24 | yaml | binary | N/A | N/A | SECRET | RAW Input is output | -| 25 | dotenv | json | true | true | SECRET | Stringified, Flattened JSON | -| 26 | dotenv | binary | N/A | N/A | SECRET | RAW Input is output | +| Test Case | Resource Type | Input Format | Expected Behavior | +| --------- | --------------- | ------------ | ----------------------------------------------- | +| 01 | SECRET | json | Save json as stringified, flattened JSON | +| 02 | SECRET | yaml | Save yaml as stringified, flattened JSON | +| 03 | SECRET | dotenv | Save dotenv as stringified, flattened JSON | +| 11 | SECRET_RAW | json | Save json as raw String SecretValue | +| 12 | SECRET_RAW | yaml | Save yaml as raw String SecretValue | +| 13 | SECRET_RAW | dotenv | Save dotenv as raw String SecretValue | +| 14 | SECRET_RAW | binary | Save binary as raw String SecretValue | +| 21 | SECRET_BINARY | json | Save json as Binary SecretValue | +| 22 | SECRET_BINARY | yaml | Save yaml as Binary SecretValue | +| 23 | SECRET_BINARY | dotenv | Save dotenv as Binary SecretValue | +| 24 | SECRET_BINARY | binary | Save binary as Binary SecretValue | +| 31 | PARAMETER | json | Save raw json into StringParameter | +| 32 | PARAMETER | yaml | Save raw yaml into StringParameter | +| 33 | PARAMETER | dotenv | Save raw dotenv into StringParameter | +| 34 | PARAMETER | binary | Save raw binary into StringParameter | +| 41 | PARAMETER_MULTI | json | Create multpiple Parameters (from json input) | +| 42 | PARAMETER_MULTI | yaml | Create multpiple Parameters (from yaml input) | +| 43 | PARAMETER_MULTI | dotenv | Create multpiple Parameters (from dotenv input) | diff --git a/lambda/__snapshots__/01-parameter-binary-binary-true-true.json.snap b/lambda/__snapshots__/01-parameter-binary-binary-true-true.json.snap deleted file mode 100755 index 403d7167..00000000 --- a/lambda/__snapshots__/01-parameter-binary-binary-true-true.json.snap +++ /dev/null @@ -1,17 +0,0 @@ - -[TestHandleRequestWithClients/01-parameter-binary-binary-true-true.json - 1] -main.getObjectCalls{ - "test-secrets/binary/sopsfile.enc-age.binary": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/binary/sopsfile.enc-age.binary"}, -} -main.getObjectEtagCalls{ - "test-secrets/binary/sopsfile.enc-age.binary": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/binary/sopsfile.enc-age.binary"}, -} -main.putParameterCalls{ - "01-parameter-binary-binary-true-true": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQDVd/OAdqlMznWINBDoyR+PESgQJlUptwnh/vzbgAaIuHl4gN7Q\nW2Jx06bKFgv8yAQ4ouR0EaPv43X1pWFUyE/vK4e2A4M28Ciriy5r2TiBx57EL7bA\nAiiCaEvpKx3uAtTgFYcdLdD5xYKUf51gymZ6wU8BBgYMkVlL5rpGmR7ddQIDAQAB\nAoGAaeEXG+6/RmNZFHeOs4eeaZ2+21PIBerNshSBYnX7x7CIP2bcHUhWadLq9W0+\nAOFMhrL00UU2pPOTPIYM4rqAOl5PvPeV4GNMvI+9/619p/ZNMbnvj43KqUtaPp1g\nJyT22CH4TqDC2io8S9xWxxh9AgvgOI/ekJ3h4PdYpmyVUXkCQQD6b1dkYhlgiy3u\nZ84L5WM+7vXG2ivA3N3T5eYJdsQFvlV6gNSqbKcxIR+cFK0RaRiWrd7U2IOM67RF\nYRvHNN0rAkEA2jZRXVjHjTZSuAVDMOA4cc6pgxOqByg14clWgRDtbueIMHNCYLJY\nbi5YE0kqzjSaH2WbeT7LX1q3S7amoN4f3wJBALw9ZrYYmrSbyRmTQyhj8raCTZF7\nujmMitzUyJVChVM/3uZm4fN8GivuluDuFaypj4brCDx6xl7taKJhvMx+quMCQF/C\nZoJoa2n05OgMpyfTvfFzl8AF6R+q7bpf+K47F3cL9CAO9JoqqdPwUoZkHXzQaLJO\njKPwgp8d2EJJrWX7FFECQQCRMPE4WsTCLXmVefZne7k000WPclZ4pIjggz1lpGgN\n23bwNOla1k4/B10btnEzNi16/b01Kf3K4hYaicd46sLH\n-----END RSA PRIVATE KEY-----", - }, -} -main.putSecretValueCalls{ -} ---- diff --git a/lambda/__snapshots__/02-secret-binary-binary-true-true.json.snap b/lambda/__snapshots__/02-secret-binary-binary-true-true.json.snap deleted file mode 100755 index e9ae9bc0..00000000 --- a/lambda/__snapshots__/02-secret-binary-binary-true-true.json.snap +++ /dev/null @@ -1,17 +0,0 @@ - -[TestHandleRequestWithClients/02-secret-binary-binary-true-true.json - 1] -main.getObjectCalls{ - "test-secrets/binary/sopsfile.enc-age.binary": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/binary/sopsfile.enc-age.binary"}, -} -main.getObjectEtagCalls{ - "test-secrets/binary/sopsfile.enc-age.binary": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/binary/sopsfile.enc-age.binary"}, -} -main.putParameterCalls{ -} -main.putSecretValueCalls{ - "02-secret-binary-binary-true-true": map[string]interface {}{ - "secretContent": "-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQDVd/OAdqlMznWINBDoyR+PESgQJlUptwnh/vzbgAaIuHl4gN7Q\nW2Jx06bKFgv8yAQ4ouR0EaPv43X1pWFUyE/vK4e2A4M28Ciriy5r2TiBx57EL7bA\nAiiCaEvpKx3uAtTgFYcdLdD5xYKUf51gymZ6wU8BBgYMkVlL5rpGmR7ddQIDAQAB\nAoGAaeEXG+6/RmNZFHeOs4eeaZ2+21PIBerNshSBYnX7x7CIP2bcHUhWadLq9W0+\nAOFMhrL00UU2pPOTPIYM4rqAOl5PvPeV4GNMvI+9/619p/ZNMbnvj43KqUtaPp1g\nJyT22CH4TqDC2io8S9xWxxh9AgvgOI/ekJ3h4PdYpmyVUXkCQQD6b1dkYhlgiy3u\nZ84L5WM+7vXG2ivA3N3T5eYJdsQFvlV6gNSqbKcxIR+cFK0RaRiWrd7U2IOM67RF\nYRvHNN0rAkEA2jZRXVjHjTZSuAVDMOA4cc6pgxOqByg14clWgRDtbueIMHNCYLJY\nbi5YE0kqzjSaH2WbeT7LX1q3S7amoN4f3wJBALw9ZrYYmrSbyRmTQyhj8raCTZF7\nujmMitzUyJVChVM/3uZm4fN8GivuluDuFaypj4brCDx6xl7taKJhvMx+quMCQF/C\nZoJoa2n05OgMpyfTvfFzl8AF6R+q7bpf+K47F3cL9CAO9JoqqdPwUoZkHXzQaLJO\njKPwgp8d2EJJrWX7FFECQQCRMPE4WsTCLXmVefZne7k000WPclZ4pIjggz1lpGgN\n23bwNOla1k4/B10btnEzNi16/b01Kf3K4hYaicd46sLH\n-----END RSA PRIVATE KEY-----", - "sopsHash": "mock-etag", - }, -} ---- diff --git a/lambda/__snapshots__/11-parametermulti-json-na-true-na.json.snap b/lambda/__snapshots__/11-parametermulti-json-na-true-na.json.snap deleted file mode 100755 index 35ced433..00000000 --- a/lambda/__snapshots__/11-parametermulti-json-na-true-na.json.snap +++ /dev/null @@ -1,49 +0,0 @@ - -[TestHandleRequestWithClients/11-parametermulti-json-na-true-na.json - 1] -main.getObjectCalls{ - "test-secrets/json/sopsfile-complex.enc-age.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/json/sopsfile-complex.enc-age.json"}, -} -main.getObjectEtagCalls{ - "test-secrets/json/sopsfile-complex.enc-age.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/json/sopsfile-complex.enc-age.json"}, -} -main.putParameterCalls{ - "/11-parametermulti-json-na-true-na/and_now/some/0/basic": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "false", - }, - "/11-parametermulti-json-na-true-na/and_now/some/1/nested": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "12345", - }, - "/11-parametermulti-json-na-true-na/and_now/some/2/type": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "1.2345", - }, - "/11-parametermulti-json-na-true-na/and_now/some/3/tests": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "Finish!", - }, - "/11-parametermulti-json-na-true-na/some/deep/nested/arrays/0": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "with", - }, - "/11-parametermulti-json-na-true-na/some/deep/nested/arrays/1": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "several", - }, - "/11-parametermulti-json-na-true-na/some/deep/nested/arrays/2/values/and": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "objects", - }, - "/11-parametermulti-json-na-true-na/some/deep/nested/object": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "structure", - }, - "/11-parametermulti-json-na-true-na/some/notsodeep": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "struct", - }, -} -main.putSecretValueCalls{ -} ---- diff --git a/lambda/__snapshots__/12-parametermulti-yaml-na-true-na.json.snap b/lambda/__snapshots__/12-parametermulti-yaml-na-true-na.json.snap deleted file mode 100755 index 0e72ed0c..00000000 --- a/lambda/__snapshots__/12-parametermulti-yaml-na-true-na.json.snap +++ /dev/null @@ -1,49 +0,0 @@ - -[TestHandleRequestWithClients/12-parametermulti-yaml-na-true-na.json - 1] -main.getObjectCalls{ - "test-secrets/yaml/sopsfile-complex.enc-age.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/yaml/sopsfile-complex.enc-age.yaml"}, -} -main.getObjectEtagCalls{ - "test-secrets/yaml/sopsfile-complex.enc-age.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/yaml/sopsfile-complex.enc-age.yaml"}, -} -main.putParameterCalls{ - "/12-parametermulti-yaml-na-true-true/and_now/some/0/basic": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "false", - }, - "/12-parametermulti-yaml-na-true-true/and_now/some/1/nested": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "12345", - }, - "/12-parametermulti-yaml-na-true-true/and_now/some/2/type": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "1.2345", - }, - "/12-parametermulti-yaml-na-true-true/and_now/some/3/tests": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "Finish!", - }, - "/12-parametermulti-yaml-na-true-true/some/deep/nested/arrays/0": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "with", - }, - "/12-parametermulti-yaml-na-true-true/some/deep/nested/arrays/1": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "several", - }, - "/12-parametermulti-yaml-na-true-true/some/deep/nested/arrays/2/values/and": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "objects", - }, - "/12-parametermulti-yaml-na-true-true/some/deep/nested/object": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "structure", - }, - "/12-parametermulti-yaml-na-true-true/some/notsodeep": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "struct", - }, -} -main.putSecretValueCalls{ -} ---- diff --git a/lambda/__snapshots__/13-parametermulti-dotenv-na-true-na.json.snap b/lambda/__snapshots__/13-parametermulti-dotenv-na-true-na.json.snap deleted file mode 100755 index 1d4df3ff..00000000 --- a/lambda/__snapshots__/13-parametermulti-dotenv-na-true-na.json.snap +++ /dev/null @@ -1,21 +0,0 @@ - -[TestHandleRequestWithClients/13-parametermulti-dotenv-na-true-na.json - 1] -main.getObjectCalls{ - "test-secrets/dotenv/encrypted-best-secret.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/dotenv/encrypted-best-secret.env"}, -} -main.getObjectEtagCalls{ - "test-secrets/dotenv/encrypted-best-secret.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/dotenv/encrypted-best-secret.env"}, -} -main.putParameterCalls{ - "/13-parametermulti-dotenv-na-true-na/banane": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "yellow", - }, - "/13-parametermulti-dotenv-na-true-na/crypt": map[string]interface {}{ - "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "parameterContent": "\"ajkscbuiuXA34%%&&=", - }, -} -main.putSecretValueCalls{ -} ---- diff --git a/lambda/__snapshots__/21-secret-json-json-true-true.json.snap b/lambda/__snapshots__/21-secret-json-json-true-true.json.snap deleted file mode 100755 index 545bab6b..00000000 --- a/lambda/__snapshots__/21-secret-json-json-true-true.json.snap +++ /dev/null @@ -1,17 +0,0 @@ - -[TestHandleRequestWithClients/21-secret-json-json-true-true.json - 1] -main.getObjectCalls{ - "test-secrets/json/sopsfile-complex.enc-age.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/json/sopsfile-complex.enc-age.json"}, -} -main.getObjectEtagCalls{ - "test-secrets/json/sopsfile-complex.enc-age.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/json/sopsfile-complex.enc-age.json"}, -} -main.putParameterCalls{ -} -main.putSecretValueCalls{ - "21-secret-json-json-true-true": map[string]interface {}{ - "secretContent": "{\n \"and now.some[0].basic\": \"false\",\n \"and now.some[1].nested\": \"12345\",\n \"and now.some[2].type\": \"1.2345\",\n \"and now.some[3].tests\": \"Finish!\",\n \"some.deep.nested.arrays[0]\": \"with\",\n \"some.deep.nested.arrays[1]\": \"several\",\n \"some.deep.nested.arrays[2].values.and\": \"objects\",\n \"some.deep.nested.object\": \"structure\",\n \"some.notsodeep\": \"struct\"\n}", - "sopsHash": "mock-etag", - }, -} ---- diff --git a/lambda/__snapshots__/22-secret-json-binary-na-na.json.snap b/lambda/__snapshots__/22-secret-json-binary-na-na.json.snap deleted file mode 100755 index 4d63c6af..00000000 --- a/lambda/__snapshots__/22-secret-json-binary-na-na.json.snap +++ /dev/null @@ -1,17 +0,0 @@ - -[TestHandleRequestWithClients/22-secret-json-binary-na-na.json - 1] -main.getObjectCalls{ - "test-secrets/json/sopsfile-complex.enc-age.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/json/sopsfile-complex.enc-age.json"}, -} -main.getObjectEtagCalls{ - "test-secrets/json/sopsfile-complex.enc-age.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/json/sopsfile-complex.enc-age.json"}, -} -main.putParameterCalls{ -} -main.putSecretValueCalls{ - "22-secret-json-binary-true-true": map[string]interface {}{ - "secretContent": "{\n\t\"some\": {\n\t\t\"deep\": {\n\t\t\t\"nested\": {\n\t\t\t\t\"object\": \"structure\",\n\t\t\t\t\"arrays\": [\n\t\t\t\t\t\"with\",\n\t\t\t\t\t\"several\",\n\t\t\t\t\t{\n\t\t\t\t\t\t\"values\": {\n\t\t\t\t\t\t\t\"and\": \"objects\"\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}\n\t\t},\n\t\t\"notsodeep\": \"struct\"\n\t},\n\t\"and now\": {\n\t\t\"some\": [\n\t\t\t{\n\t\t\t\t\"basic\": false\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"nested\": 12345\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"type\": 1.2345\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"tests\": \"Finish!\"\n\t\t\t}\n\t\t]\n\t}\n}", - "sopsHash": "mock-etag", - }, -} ---- diff --git a/lambda/__snapshots__/23-secret-yaml-json-true-true.json.snap b/lambda/__snapshots__/23-secret-yaml-json-true-true.json.snap deleted file mode 100755 index bcc42659..00000000 --- a/lambda/__snapshots__/23-secret-yaml-json-true-true.json.snap +++ /dev/null @@ -1,17 +0,0 @@ - -[TestHandleRequestWithClients/23-secret-yaml-json-true-true.json - 1] -main.getObjectCalls{ - "test-secrets/yaml/sopsfile-complex.enc-age.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/yaml/sopsfile-complex.enc-age.yaml"}, -} -main.getObjectEtagCalls{ - "test-secrets/yaml/sopsfile-complex.enc-age.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/yaml/sopsfile-complex.enc-age.yaml"}, -} -main.putParameterCalls{ -} -main.putSecretValueCalls{ - "23-secret-yaml-json-true-true": map[string]interface {}{ - "secretContent": "{\n \"and now.some[0].basic\": \"false\",\n \"and now.some[1].nested\": \"12345\",\n \"and now.some[2].type\": \"1.2345\",\n \"and now.some[3].tests\": \"Finish!\",\n \"some.deep.nested.arrays[0]\": \"with\",\n \"some.deep.nested.arrays[1]\": \"several\",\n \"some.deep.nested.arrays[2].values.and\": \"objects\",\n \"some.deep.nested.object\": \"structure\",\n \"some.notsodeep\": \"struct\"\n}", - "sopsHash": "mock-etag", - }, -} ---- diff --git a/lambda/__snapshots__/24-secret-yaml-binary-na-na.json.snap b/lambda/__snapshots__/24-secret-yaml-binary-na-na.json.snap deleted file mode 100755 index 479e17c1..00000000 --- a/lambda/__snapshots__/24-secret-yaml-binary-na-na.json.snap +++ /dev/null @@ -1,17 +0,0 @@ - -[TestHandleRequestWithClients/24-secret-yaml-binary-na-na.json - 1] -main.getObjectCalls{ - "test-secrets/yaml/sopsfile-complex.enc-age.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/yaml/sopsfile-complex.enc-age.yaml"}, -} -main.getObjectEtagCalls{ - "test-secrets/yaml/sopsfile-complex.enc-age.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/yaml/sopsfile-complex.enc-age.yaml"}, -} -main.putParameterCalls{ -} -main.putSecretValueCalls{ - "24-secret-yaml-binary-na-na": map[string]interface {}{ - "secretContent": "some:\n deep:\n nested:\n object: structure\n arrays:\n - with\n - several\n - values:\n and: objects\n notsodeep: struct\nand now:\n some:\n - basic: false\n - nested: 12345\n - type: 1.2345\n - tests: Finish!\n", - "sopsHash": "mock-etag", - }, -} ---- diff --git a/lambda/__snapshots__/25-secret-dotenv-json-true-true.json.snap b/lambda/__snapshots__/25-secret-dotenv-json-true-true.json.snap deleted file mode 100755 index 20d2085d..00000000 --- a/lambda/__snapshots__/25-secret-dotenv-json-true-true.json.snap +++ /dev/null @@ -1,17 +0,0 @@ - -[TestHandleRequestWithClients/25-secret-dotenv-json-true-true.json - 1] -main.getObjectCalls{ - "test-secrets/dotenv/encrypted-best-secret.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/dotenv/encrypted-best-secret.env"}, -} -main.getObjectEtagCalls{ - "test-secrets/dotenv/encrypted-best-secret.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/dotenv/encrypted-best-secret.env"}, -} -main.putParameterCalls{ -} -main.putSecretValueCalls{ - "25-secret-dotenv-json-true-true": map[string]interface {}{ - "secretContent": "{\n \"banane\": \"yellow\",\n \"crypt\": \"\\\"ajkscbuiuXA34%%\\u0026\\u0026=\"\n}", - "sopsHash": "mock-etag", - }, -} ---- diff --git a/lambda/__snapshots__/26-secret-dotenv-binary-na-na.json.snap b/lambda/__snapshots__/26-secret-dotenv-binary-na-na.json.snap deleted file mode 100755 index 83e4b854..00000000 --- a/lambda/__snapshots__/26-secret-dotenv-binary-na-na.json.snap +++ /dev/null @@ -1,17 +0,0 @@ - -[TestHandleRequestWithClients/26-secret-dotenv-binary-na-na.json - 1] -main.getObjectCalls{ - "test-secrets/dotenv/encrypted-best-secret.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/dotenv/encrypted-best-secret.env"}, -} -main.getObjectEtagCalls{ - "test-secrets/dotenv/encrypted-best-secret.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/dotenv/encrypted-best-secret.env"}, -} -main.putParameterCalls{ -} -main.putSecretValueCalls{ - "26-secret-dotenv-binary-true-true": map[string]interface {}{ - "secretContent": "banane=yellow\ncrypt=\"ajkscbuiuXA34%%&&=\n", - "sopsHash": "mock-etag", - }, -} ---- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/01-SECRET-json.json/01-SECRET-json.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/01-SECRET-json.json/01-SECRET-json.json.snap new file mode 100755 index 00000000..d08d088a --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/01-SECRET-json.json/01-SECRET-json.json.snap @@ -0,0 +1,18 @@ + +[TestHandleRequestWithClients/01-SECRET-json.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.json"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.json"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "01-SECRET-json": map[string]interface {}{ + "binary": bool(false), + "secretContent": "{\n \"apiKey\": \"sk-1234567890abcdef\",\n \"database.host\": \"db.example.com\",\n \"database.password\": \"P@ssw0rd!\",\n \"database.user\": \"admin\",\n \"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n \"specific.HTLMEncodingTest3\": \"@\",\n \"specific.HTMLEncodingTest1\": \"test \\u003ctest@test.test\\u003e\",\n \"specific.HTMLEncodingTest2\": \"\\u0026\",\n \"specific.SpecialCharacters\": \"\\\"ajkscbuiuXA34%%\\u0026\\u0026=\",\n \"specific.boolean\": \"true\",\n \"specific.null\": \"\",\n \"specific.number1\": \"123\",\n \"specific.number2\": \"123.456\",\n \"tokens[0].service\": \"service1\",\n \"tokens[0].token\": \"token1\",\n \"tokens[1].service\": \"service2\",\n \"tokens[1].token\": \"token2\"\n}", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/02-SECRET-yaml.json/02-SECRET-yaml.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/02-SECRET-yaml.json/02-SECRET-yaml.json.snap new file mode 100755 index 00000000..7e0d9670 --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/02-SECRET-yaml.json/02-SECRET-yaml.json.snap @@ -0,0 +1,18 @@ + +[TestHandleRequestWithClients/02-SECRET-yaml.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.yaml"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.yaml"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "02-SECRET-yaml": map[string]interface {}{ + "binary": bool(false), + "secretContent": "{\n \"apiKey\": \"sk-1234567890abcdef\",\n \"database.host\": \"db.example.com\",\n \"database.password\": \"P@ssw0rd!\",\n \"database.user\": \"admin\",\n \"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n \"specific.HTLMEncodingTest3\": \"@\",\n \"specific.HTMLEncodingTest1\": \"test \\u003ctest@test.test\\u003e\",\n \"specific.HTMLEncodingTest2\": \"\\u0026\",\n \"specific.SpecialCharacters\": \"\\\"ajkscbuiuXA34%%\\u0026\\u0026=\",\n \"specific.boolean\": \"true\",\n \"specific.null\": \"\",\n \"specific.number1\": \"123\",\n \"specific.number2\": \"123.456\",\n \"tokens[0].service\": \"service1\",\n \"tokens[0].token\": \"token1\",\n \"tokens[1].service\": \"service2\",\n \"tokens[1].token\": \"token2\"\n}", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/03-SECRET-dotenv.json/03-SECRET-dotenv.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/03-SECRET-dotenv.json/03-SECRET-dotenv.json.snap new file mode 100755 index 00000000..74bc8685 --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/03-SECRET-dotenv.json/03-SECRET-dotenv.json.snap @@ -0,0 +1,18 @@ + +[TestHandleRequestWithClients/03-SECRET-dotenv.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.env"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.env"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "03-SECRET-dotenv": map[string]interface {}{ + "binary": bool(false), + "secretContent": "{\n \"apiKey\": \"sk-1234567890abcdef\",\n \"database:host\": \"db.example.com\",\n \"database:password\": \"P@ssw0rd!\",\n \"database:user\": \"admin\",\n \"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n \"specific:HTLMEncodingTest3\": \"@\",\n \"specific:HTMLEncodingTest1\": \"test \\u003ctest@test.test\\u003e\",\n \"specific:HTMLEncodingTest2\": \"\\u0026\",\n \"specific:SpecialCharacters\": \"\\\"ajkscbuiuXA34%%\\u0026\\u0026=\",\n \"specific:boolean\": \"True\",\n \"specific:null\": \"\",\n \"specific:number1\": \"123\",\n \"specific:number2\": \"123.456\",\n \"tokens:0:service\": \"service1\",\n \"tokens:0:token\": \"token1\",\n \"tokens:1:service\": \"service2\",\n \"tokens:1:token\": \"token2\"\n}", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/11-SECRET_RAW-json.json/11-SECRET_RAW-json.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/11-SECRET_RAW-json.json/11-SECRET_RAW-json.json.snap new file mode 100755 index 00000000..f6080ce6 --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/11-SECRET_RAW-json.json/11-SECRET_RAW-json.json.snap @@ -0,0 +1,18 @@ + +[TestHandleRequestWithClients/11-SECRET_RAW-json.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.json"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.json"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "11-SECRET_RAW-json": map[string]interface {}{ + "binary": bool(false), + "secretContent": "{\n\t\"apiKey\": \"sk-1234567890abcdef\",\n\t\"database\": {\n\t\t\"host\": \"db.example.com\",\n\t\t\"password\": \"P@ssw0rd!\",\n\t\t\"user\": \"admin\"\n\t},\n\t\"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n\t\"specific\": {\n\t\t\"HTLMEncodingTest3\": \"@\",\n\t\t\"HTMLEncodingTest1\": \"test \",\n\t\t\"HTMLEncodingTest2\": \"&\",\n\t\t\"SpecialCharacters\": \"\\\"ajkscbuiuXA34%%&&=\",\n\t\t\"boolean\": true,\n\t\t\"null\": null,\n\t\t\"number1\": 123,\n\t\t\"number2\": 123.456\n\t},\n\t\"tokens\": [\n\t\t{\n\t\t\t\"service\": \"service1\",\n\t\t\t\"token\": \"token1\"\n\t\t},\n\t\t{\n\t\t\t\"service\": \"service2\",\n\t\t\t\"token\": \"token2\"\n\t\t}\n\t]\n}", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/12-SECRET_RAW-yaml.json/12-SECRET_RAW-yaml.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/12-SECRET_RAW-yaml.json/12-SECRET_RAW-yaml.json.snap new file mode 100755 index 00000000..1bdba1ca --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/12-SECRET_RAW-yaml.json/12-SECRET_RAW-yaml.json.snap @@ -0,0 +1,18 @@ + +[TestHandleRequestWithClients/12-SECRET_RAW-yaml.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.yaml"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.yaml"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "12-SECRET_RAW-yaml": map[string]interface {}{ + "binary": bool(false), + "secretContent": "apiKey: sk-1234567890abcdef\ndatabase:\n user: admin\n password: P@ssw0rd!\n host: db.example.com\ntokens:\n - service: service1\n token: token1\n - service: service2\n token: token2\nsomeOtherKey: base64:aGFsbG8gd2VsdAo=\nspecific:\n SpecialCharacters: '\"ajkscbuiuXA34%%&&='\n HTMLEncodingTest1: test \n HTMLEncodingTest2: '&'\n HTLMEncodingTest3: '@'\n \"null\": null\n boolean: true\n number1: 123\n number2: 123.456\n", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/13-SECRET_RAW-dotenv.json/13-SECRET_RAW-dotenv.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/13-SECRET_RAW-dotenv.json/13-SECRET_RAW-dotenv.json.snap new file mode 100755 index 00000000..27e7552f --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/13-SECRET_RAW-dotenv.json/13-SECRET_RAW-dotenv.json.snap @@ -0,0 +1,18 @@ + +[TestHandleRequestWithClients/13-SECRET_RAW-dotenv.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.env"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.env"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "13-SECRET_RAW-dotenv": map[string]interface {}{ + "binary": bool(false), + "secretContent": "apiKey=sk-1234567890abcdef\ndatabase:host=db.example.com\ndatabase:password=P@ssw0rd!\ndatabase:user=admin\nsomeOtherKey=base64:aGFsbG8gd2VsdAo=\nspecific:boolean=True\nspecific:SpecialCharacters=\"ajkscbuiuXA34%%&&=\nspecific:HTLMEncodingTest3=@\nspecific:HTMLEncodingTest1=test \nspecific:HTMLEncodingTest2=&\nspecific:null=\nspecific:number1=123\nspecific:number2=123.456\ntokens:0:service=service1\ntokens:0:token=token1\ntokens:1:service=service2\ntokens:1:token=token2\n", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/21-SECRET_BINARY-json.json/21-SECRET_BINARY-json.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/21-SECRET_BINARY-json.json/21-SECRET_BINARY-json.json.snap new file mode 100755 index 00000000..65ba3039 --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/21-SECRET_BINARY-json.json/21-SECRET_BINARY-json.json.snap @@ -0,0 +1,18 @@ + +[TestHandleRequestWithClients/21-SECRET_BINARY-json.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.json"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.json"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "21-SECRET_BINARY-json": map[string]interface {}{ + "binary": bool(true), + "secretContent": "{\n\t\"apiKey\": \"sk-1234567890abcdef\",\n\t\"database\": {\n\t\t\"host\": \"db.example.com\",\n\t\t\"password\": \"P@ssw0rd!\",\n\t\t\"user\": \"admin\"\n\t},\n\t\"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n\t\"specific\": {\n\t\t\"HTLMEncodingTest3\": \"@\",\n\t\t\"HTMLEncodingTest1\": \"test \",\n\t\t\"HTMLEncodingTest2\": \"&\",\n\t\t\"SpecialCharacters\": \"\\\"ajkscbuiuXA34%%&&=\",\n\t\t\"boolean\": true,\n\t\t\"null\": null,\n\t\t\"number1\": 123,\n\t\t\"number2\": 123.456\n\t},\n\t\"tokens\": [\n\t\t{\n\t\t\t\"service\": \"service1\",\n\t\t\t\"token\": \"token1\"\n\t\t},\n\t\t{\n\t\t\t\"service\": \"service2\",\n\t\t\t\"token\": \"token2\"\n\t\t}\n\t]\n}", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/22-SECRET_BINARY-yaml.json/22-SECRET_BINARY-yaml.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/22-SECRET_BINARY-yaml.json/22-SECRET_BINARY-yaml.json.snap new file mode 100755 index 00000000..14f732de --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/22-SECRET_BINARY-yaml.json/22-SECRET_BINARY-yaml.json.snap @@ -0,0 +1,18 @@ + +[TestHandleRequestWithClients/22-SECRET_BINARY-yaml.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.yaml"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.yaml"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "22-SECRET_BINARY-yaml": map[string]interface {}{ + "binary": bool(true), + "secretContent": "apiKey: sk-1234567890abcdef\ndatabase:\n user: admin\n password: P@ssw0rd!\n host: db.example.com\ntokens:\n - service: service1\n token: token1\n - service: service2\n token: token2\nsomeOtherKey: base64:aGFsbG8gd2VsdAo=\nspecific:\n SpecialCharacters: '\"ajkscbuiuXA34%%&&='\n HTMLEncodingTest1: test \n HTMLEncodingTest2: '&'\n HTLMEncodingTest3: '@'\n \"null\": null\n boolean: true\n number1: 123\n number2: 123.456\n", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/23-SECRET_BINARY-dotenv.json/23-SECRET_BINARY-dotenv.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/23-SECRET_BINARY-dotenv.json/23-SECRET_BINARY-dotenv.json.snap new file mode 100755 index 00000000..ddc1afe2 --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/23-SECRET_BINARY-dotenv.json/23-SECRET_BINARY-dotenv.json.snap @@ -0,0 +1,18 @@ + +[TestHandleRequestWithClients/23-SECRET_BINARY-dotenv.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.env"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.env"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "23-SECRET_BINARY-dotenv": map[string]interface {}{ + "binary": bool(true), + "secretContent": "apiKey=sk-1234567890abcdef\ndatabase:host=db.example.com\ndatabase:password=P@ssw0rd!\ndatabase:user=admin\nsomeOtherKey=base64:aGFsbG8gd2VsdAo=\nspecific:boolean=True\nspecific:SpecialCharacters=\"ajkscbuiuXA34%%&&=\nspecific:HTLMEncodingTest3=@\nspecific:HTMLEncodingTest1=test \nspecific:HTMLEncodingTest2=&\nspecific:null=\nspecific:number1=123\nspecific:number2=123.456\ntokens:0:service=service1\ntokens:0:token=token1\ntokens:1:service=service2\ntokens:1:token=token2\n", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/31-PARAMETER-json.json/31-PARAMETER-json.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/31-PARAMETER-json.json/31-PARAMETER-json.json.snap new file mode 100755 index 00000000..113cb831 --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/31-PARAMETER-json.json/31-PARAMETER-json.json.snap @@ -0,0 +1,17 @@ + +[TestHandleRequestWithClients/31-PARAMETER-json.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.json"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.json"}, +} +main.putParameterCalls{ + "/31-PARAMETER-json": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "{\n\t\"apiKey\": \"sk-1234567890abcdef\",\n\t\"database\": {\n\t\t\"host\": \"db.example.com\",\n\t\t\"password\": \"P@ssw0rd!\",\n\t\t\"user\": \"admin\"\n\t},\n\t\"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n\t\"specific\": {\n\t\t\"HTLMEncodingTest3\": \"@\",\n\t\t\"HTMLEncodingTest1\": \"test \",\n\t\t\"HTMLEncodingTest2\": \"&\",\n\t\t\"SpecialCharacters\": \"\\\"ajkscbuiuXA34%%&&=\",\n\t\t\"boolean\": true,\n\t\t\"null\": null,\n\t\t\"number1\": 123,\n\t\t\"number2\": 123.456\n\t},\n\t\"tokens\": [\n\t\t{\n\t\t\t\"service\": \"service1\",\n\t\t\t\"token\": \"token1\"\n\t\t},\n\t\t{\n\t\t\t\"service\": \"service2\",\n\t\t\t\"token\": \"token2\"\n\t\t}\n\t]\n}", + }, +} +main.putSecretValueCalls{ +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/32-PARAMETER-yaml.json/32-PARAMETER-yaml.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/32-PARAMETER-yaml.json/32-PARAMETER-yaml.json.snap new file mode 100755 index 00000000..8b2a1068 --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/32-PARAMETER-yaml.json/32-PARAMETER-yaml.json.snap @@ -0,0 +1,17 @@ + +[TestHandleRequestWithClients/32-PARAMETER-yaml.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.yaml"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.yaml"}, +} +main.putParameterCalls{ + "/32-PARAMETER-yaml": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "apiKey: sk-1234567890abcdef\ndatabase:\n user: admin\n password: P@ssw0rd!\n host: db.example.com\ntokens:\n - service: service1\n token: token1\n - service: service2\n token: token2\nsomeOtherKey: base64:aGFsbG8gd2VsdAo=\nspecific:\n SpecialCharacters: '\"ajkscbuiuXA34%%&&='\n HTMLEncodingTest1: test \n HTMLEncodingTest2: '&'\n HTLMEncodingTest3: '@'\n \"null\": null\n boolean: true\n number1: 123\n number2: 123.456\n", + }, +} +main.putSecretValueCalls{ +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/33-PARAMETER-dotenv.json/33-PARAMETER-dotenv.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/33-PARAMETER-dotenv.json/33-PARAMETER-dotenv.json.snap new file mode 100755 index 00000000..4488c56f --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/33-PARAMETER-dotenv.json/33-PARAMETER-dotenv.json.snap @@ -0,0 +1,17 @@ + +[TestHandleRequestWithClients/33-PARAMETER-dotenv.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.env"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.env"}, +} +main.putParameterCalls{ + "/33-PARAMETER-dotenv": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "apiKey=sk-1234567890abcdef\ndatabase:host=db.example.com\ndatabase:password=P@ssw0rd!\ndatabase:user=admin\nsomeOtherKey=base64:aGFsbG8gd2VsdAo=\nspecific:boolean=True\nspecific:SpecialCharacters=\"ajkscbuiuXA34%%&&=\nspecific:HTLMEncodingTest3=@\nspecific:HTMLEncodingTest1=test \nspecific:HTMLEncodingTest2=&\nspecific:null=\nspecific:number1=123\nspecific:number2=123.456\ntokens:0:service=service1\ntokens:0:token=token1\ntokens:1:service=service2\ntokens:1:token=token2\n", + }, +} +main.putSecretValueCalls{ +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/34-PARAMETER-binary.json/34-PARAMETER-binary.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/34-PARAMETER-binary.json/34-PARAMETER-binary.json.snap new file mode 100755 index 00000000..5df09d2c --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/34-PARAMETER-binary.json/34-PARAMETER-binary.json.snap @@ -0,0 +1,17 @@ + +[TestHandleRequestWithClients/34-PARAMETER-binary.json - 1] +main.getObjectCalls{ + "test-secrets/README.sops.binary": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/README.sops.binary"}, +} +main.getObjectEtagCalls{ + "test-secrets/README.sops.binary": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/README.sops.binary"}, +} +main.putParameterCalls{ + "/34-PARAMETER-binary": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "# SOPS files for testing purpose\n\nThe sops files in this directory were created for testing purpose. As encryption algorithm [age](https://age-encryption.org/) is used, as it allows easy sharing of encryption information.\n\nThe following keys were used:\n\n```yaml\npublic: age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu\nprivate: AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3\n```\n", + }, +} +main.putSecretValueCalls{ +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/41-PARAMETER_MULTI-json.json/41-PARAMETER_MULTI-json.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/41-PARAMETER_MULTI-json.json/41-PARAMETER_MULTI-json.json.snap new file mode 100755 index 00000000..a914501f --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/41-PARAMETER_MULTI-json.json/41-PARAMETER_MULTI-json.json.snap @@ -0,0 +1,81 @@ + +[TestHandleRequestWithClients/41-PARAMETER_MULTI-json.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.json"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.json": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.json"}, +} +main.putParameterCalls{ + "/41-PARAMETER_MULTI-json/apiKey": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "sk-1234567890abcdef", + }, + "/41-PARAMETER_MULTI-json/database/host": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "db.example.com", + }, + "/41-PARAMETER_MULTI-json/database/password": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "P@ssw0rd!", + }, + "/41-PARAMETER_MULTI-json/database/user": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "admin", + }, + "/41-PARAMETER_MULTI-json/someOtherKey": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "base64:aGFsbG8gd2VsdAo=", + }, + "/41-PARAMETER_MULTI-json/specific/HTLMEncodingTest3": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "@", + }, + "/41-PARAMETER_MULTI-json/specific/HTMLEncodingTest1": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "test ", + }, + "/41-PARAMETER_MULTI-json/specific/HTMLEncodingTest2": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "&", + }, + "/41-PARAMETER_MULTI-json/specific/SpecialCharacters": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "\"ajkscbuiuXA34%%&&=", + }, + "/41-PARAMETER_MULTI-json/specific/boolean": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "true", + }, + "/41-PARAMETER_MULTI-json/specific/null": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "", + }, + "/41-PARAMETER_MULTI-json/specific/number1": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "123", + }, + "/41-PARAMETER_MULTI-json/specific/number2": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "123.456", + }, + "/41-PARAMETER_MULTI-json/tokens/0/service": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "service1", + }, + "/41-PARAMETER_MULTI-json/tokens/0/token": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "token1", + }, + "/41-PARAMETER_MULTI-json/tokens/1/service": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "service2", + }, + "/41-PARAMETER_MULTI-json/tokens/1/token": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "token2", + }, +} +main.putSecretValueCalls{ +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/42-PARAMETER_MULTI-yaml.json/42-PARAMETER_MULTI-yaml.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/42-PARAMETER_MULTI-yaml.json/42-PARAMETER_MULTI-yaml.json.snap new file mode 100755 index 00000000..4e7efa95 --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/42-PARAMETER_MULTI-yaml.json/42-PARAMETER_MULTI-yaml.json.snap @@ -0,0 +1,81 @@ + +[TestHandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.yaml"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.yaml": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.yaml"}, +} +main.putParameterCalls{ + "/42-PARAMETER_MULTI-yaml/apiKey": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "sk-1234567890abcdef", + }, + "/42-PARAMETER_MULTI-yaml/database/host": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "db.example.com", + }, + "/42-PARAMETER_MULTI-yaml/database/password": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "P@ssw0rd!", + }, + "/42-PARAMETER_MULTI-yaml/database/user": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "admin", + }, + "/42-PARAMETER_MULTI-yaml/someOtherKey": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "base64:aGFsbG8gd2VsdAo=", + }, + "/42-PARAMETER_MULTI-yaml/specific/HTLMEncodingTest3": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "@", + }, + "/42-PARAMETER_MULTI-yaml/specific/HTMLEncodingTest1": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "test ", + }, + "/42-PARAMETER_MULTI-yaml/specific/HTMLEncodingTest2": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "&", + }, + "/42-PARAMETER_MULTI-yaml/specific/SpecialCharacters": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "\"ajkscbuiuXA34%%&&=", + }, + "/42-PARAMETER_MULTI-yaml/specific/boolean": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "true", + }, + "/42-PARAMETER_MULTI-yaml/specific/null": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "", + }, + "/42-PARAMETER_MULTI-yaml/specific/number1": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "123", + }, + "/42-PARAMETER_MULTI-yaml/specific/number2": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "123.456", + }, + "/42-PARAMETER_MULTI-yaml/tokens/0/service": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "service1", + }, + "/42-PARAMETER_MULTI-yaml/tokens/0/token": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "token1", + }, + "/42-PARAMETER_MULTI-yaml/tokens/1/service": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "service2", + }, + "/42-PARAMETER_MULTI-yaml/tokens/1/token": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "token2", + }, +} +main.putSecretValueCalls{ +} +--- diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json/43-PARAMETER_MULTI-dotenv.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json/43-PARAMETER_MULTI-dotenv.json.snap new file mode 100755 index 00000000..b8cf0c80 --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json/43-PARAMETER_MULTI-dotenv.json.snap @@ -0,0 +1,81 @@ + +[TestHandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 1] +main.getObjectCalls{ + "test-secrets/testsecret.sops.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.env"}, +} +main.getObjectEtagCalls{ + "test-secrets/testsecret.sops.env": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/testsecret.sops.env"}, +} +main.putParameterCalls{ + "/43-PARAMETER_MULTI-dotenv/apiKey": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "sk-1234567890abcdef", + }, + "/43-PARAMETER_MULTI-dotenv/database_host": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "db.example.com", + }, + "/43-PARAMETER_MULTI-dotenv/database_password": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "P@ssw0rd!", + }, + "/43-PARAMETER_MULTI-dotenv/database_user": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "admin", + }, + "/43-PARAMETER_MULTI-dotenv/someOtherKey": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "base64:aGFsbG8gd2VsdAo=", + }, + "/43-PARAMETER_MULTI-dotenv/specific_HTLMEncodingTest3": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "@", + }, + "/43-PARAMETER_MULTI-dotenv/specific_HTMLEncodingTest1": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "test ", + }, + "/43-PARAMETER_MULTI-dotenv/specific_HTMLEncodingTest2": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "&", + }, + "/43-PARAMETER_MULTI-dotenv/specific_SpecialCharacters": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "\"ajkscbuiuXA34%%&&=", + }, + "/43-PARAMETER_MULTI-dotenv/specific_boolean": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "True", + }, + "/43-PARAMETER_MULTI-dotenv/specific_null": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "", + }, + "/43-PARAMETER_MULTI-dotenv/specific_number1": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "123", + }, + "/43-PARAMETER_MULTI-dotenv/specific_number2": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "123.456", + }, + "/43-PARAMETER_MULTI-dotenv/tokens_0_service": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "service1", + }, + "/43-PARAMETER_MULTI-dotenv/tokens_0_token": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "token1", + }, + "/43-PARAMETER_MULTI-dotenv/tokens_1_service": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "service2", + }, + "/43-PARAMETER_MULTI-dotenv/tokens_1_token": map[string]interface {}{ + "keyId": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "parameterContent": "token2", + }, +} +main.putSecretValueCalls{ +} +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/01-SECRET-json.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/01-SECRET-json.json.snap new file mode 100755 index 00000000..b04b754d --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/01-SECRET-json.json.snap @@ -0,0 +1,6 @@ + +[TestIntegration_HandleRequestWithClients/01-SECRET-json.json - 1] +&"01-SECRET-json" +[]uint8(nil) +&"{\n \"apiKey\": \"sk-1234567890abcdef\",\n \"database.host\": \"db.example.com\",\n \"database.password\": \"P@ssw0rd!\",\n \"database.user\": \"admin\",\n \"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n \"specific.HTLMEncodingTest3\": \"@\",\n \"specific.HTMLEncodingTest1\": \"test \\u003ctest@test.test\\u003e\",\n \"specific.HTMLEncodingTest2\": \"\\u0026\",\n \"specific.SpecialCharacters\": \"\\\"ajkscbuiuXA34%%\\u0026\\u0026=\",\n \"specific.boolean\": \"true\",\n \"specific.null\": \"\",\n \"specific.number1\": \"123\",\n \"specific.number2\": \"123.456\",\n \"tokens[0].service\": \"service1\",\n \"tokens[0].token\": \"token1\",\n \"tokens[1].service\": \"service2\",\n \"tokens[1].token\": \"token2\"\n}" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/02-SECRET-yaml.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/02-SECRET-yaml.json.snap new file mode 100755 index 00000000..3b5bfde4 --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/02-SECRET-yaml.json.snap @@ -0,0 +1,6 @@ + +[TestIntegration_HandleRequestWithClients/02-SECRET-yaml.json - 1] +&"02-SECRET-yaml" +[]uint8(nil) +&"{\n \"apiKey\": \"sk-1234567890abcdef\",\n \"database.host\": \"db.example.com\",\n \"database.password\": \"P@ssw0rd!\",\n \"database.user\": \"admin\",\n \"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n \"specific.HTLMEncodingTest3\": \"@\",\n \"specific.HTMLEncodingTest1\": \"test \\u003ctest@test.test\\u003e\",\n \"specific.HTMLEncodingTest2\": \"\\u0026\",\n \"specific.SpecialCharacters\": \"\\\"ajkscbuiuXA34%%\\u0026\\u0026=\",\n \"specific.boolean\": \"true\",\n \"specific.null\": \"\",\n \"specific.number1\": \"123\",\n \"specific.number2\": \"123.456\",\n \"tokens[0].service\": \"service1\",\n \"tokens[0].token\": \"token1\",\n \"tokens[1].service\": \"service2\",\n \"tokens[1].token\": \"token2\"\n}" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/03-SECRET-dotenv.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/03-SECRET-dotenv.json.snap new file mode 100755 index 00000000..4045689a --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/03-SECRET-dotenv.json.snap @@ -0,0 +1,6 @@ + +[TestIntegration_HandleRequestWithClients/03-SECRET-dotenv.json - 1] +&"03-SECRET-dotenv" +[]uint8(nil) +&"{\n \"apiKey\": \"sk-1234567890abcdef\",\n \"database:host\": \"db.example.com\",\n \"database:password\": \"P@ssw0rd!\",\n \"database:user\": \"admin\",\n \"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n \"specific:HTLMEncodingTest3\": \"@\",\n \"specific:HTMLEncodingTest1\": \"test \\u003ctest@test.test\\u003e\",\n \"specific:HTMLEncodingTest2\": \"\\u0026\",\n \"specific:SpecialCharacters\": \"\\\"ajkscbuiuXA34%%\\u0026\\u0026=\",\n \"specific:boolean\": \"True\",\n \"specific:null\": \"\",\n \"specific:number1\": \"123\",\n \"specific:number2\": \"123.456\",\n \"tokens:0:service\": \"service1\",\n \"tokens:0:token\": \"token1\",\n \"tokens:1:service\": \"service2\",\n \"tokens:1:token\": \"token2\"\n}" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/11-SECRET_RAW-json.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/11-SECRET_RAW-json.json.snap new file mode 100755 index 00000000..b8378595 --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/11-SECRET_RAW-json.json.snap @@ -0,0 +1,6 @@ + +[TestIntegration_HandleRequestWithClients/11-SECRET_RAW-json.json - 1] +&"11-SECRET_RAW-json" +[]uint8(nil) +&"{\n\t\"apiKey\": \"sk-1234567890abcdef\",\n\t\"database\": {\n\t\t\"host\": \"db.example.com\",\n\t\t\"password\": \"P@ssw0rd!\",\n\t\t\"user\": \"admin\"\n\t},\n\t\"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n\t\"specific\": {\n\t\t\"HTLMEncodingTest3\": \"@\",\n\t\t\"HTMLEncodingTest1\": \"test \",\n\t\t\"HTMLEncodingTest2\": \"&\",\n\t\t\"SpecialCharacters\": \"\\\"ajkscbuiuXA34%%&&=\",\n\t\t\"boolean\": true,\n\t\t\"null\": null,\n\t\t\"number1\": 123,\n\t\t\"number2\": 123.456\n\t},\n\t\"tokens\": [\n\t\t{\n\t\t\t\"service\": \"service1\",\n\t\t\t\"token\": \"token1\"\n\t\t},\n\t\t{\n\t\t\t\"service\": \"service2\",\n\t\t\t\"token\": \"token2\"\n\t\t}\n\t]\n}" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/12-SECRET_RAW-yaml.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/12-SECRET_RAW-yaml.json.snap new file mode 100755 index 00000000..3ea6cd76 --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/12-SECRET_RAW-yaml.json.snap @@ -0,0 +1,6 @@ + +[TestIntegration_HandleRequestWithClients/12-SECRET_RAW-yaml.json - 1] +&"12-SECRET_RAW-yaml" +[]uint8(nil) +&"apiKey: sk-1234567890abcdef\ndatabase:\n user: admin\n password: P@ssw0rd!\n host: db.example.com\ntokens:\n - service: service1\n token: token1\n - service: service2\n token: token2\nsomeOtherKey: base64:aGFsbG8gd2VsdAo=\nspecific:\n SpecialCharacters: '\"ajkscbuiuXA34%%&&='\n HTMLEncodingTest1: test \n HTMLEncodingTest2: '&'\n HTLMEncodingTest3: '@'\n \"null\": null\n boolean: true\n number1: 123\n number2: 123.456\n" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/13-SECRET_RAW-dotenv.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/13-SECRET_RAW-dotenv.json.snap new file mode 100755 index 00000000..eb7c7d1c --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/13-SECRET_RAW-dotenv.json.snap @@ -0,0 +1,6 @@ + +[TestIntegration_HandleRequestWithClients/13-SECRET_RAW-dotenv.json - 1] +&"13-SECRET_RAW-dotenv" +[]uint8(nil) +&"apiKey=sk-1234567890abcdef\ndatabase:host=db.example.com\ndatabase:password=P@ssw0rd!\ndatabase:user=admin\nsomeOtherKey=base64:aGFsbG8gd2VsdAo=\nspecific:boolean=True\nspecific:SpecialCharacters=\"ajkscbuiuXA34%%&&=\nspecific:HTLMEncodingTest3=@\nspecific:HTMLEncodingTest1=test \nspecific:HTMLEncodingTest2=&\nspecific:null=\nspecific:number1=123\nspecific:number2=123.456\ntokens:0:service=service1\ntokens:0:token=token1\ntokens:1:service=service2\ntokens:1:token=token2\n" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/21-SECRET_BINARY-json.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/21-SECRET_BINARY-json.json.snap new file mode 100755 index 00000000..ff2f32aa --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/21-SECRET_BINARY-json.json.snap @@ -0,0 +1,6 @@ + +[TestIntegration_HandleRequestWithClients/21-SECRET_BINARY-json.json - 1] +&"21-SECRET_BINARY-json" +[]uint8(nil) +&"{\n\t\"apiKey\": \"sk-1234567890abcdef\",\n\t\"database\": {\n\t\t\"host\": \"db.example.com\",\n\t\t\"password\": \"P@ssw0rd!\",\n\t\t\"user\": \"admin\"\n\t},\n\t\"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n\t\"specific\": {\n\t\t\"HTLMEncodingTest3\": \"@\",\n\t\t\"HTMLEncodingTest1\": \"test \",\n\t\t\"HTMLEncodingTest2\": \"&\",\n\t\t\"SpecialCharacters\": \"\\\"ajkscbuiuXA34%%&&=\",\n\t\t\"boolean\": true,\n\t\t\"null\": null,\n\t\t\"number1\": 123,\n\t\t\"number2\": 123.456\n\t},\n\t\"tokens\": [\n\t\t{\n\t\t\t\"service\": \"service1\",\n\t\t\t\"token\": \"token1\"\n\t\t},\n\t\t{\n\t\t\t\"service\": \"service2\",\n\t\t\t\"token\": \"token2\"\n\t\t}\n\t]\n}" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/22-SECRET_BINARY-yaml.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/22-SECRET_BINARY-yaml.json.snap new file mode 100755 index 00000000..cb72aacc --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/22-SECRET_BINARY-yaml.json.snap @@ -0,0 +1,6 @@ + +[TestIntegration_HandleRequestWithClients/22-SECRET_BINARY-yaml.json - 1] +&"22-SECRET_BINARY-yaml" +[]uint8(nil) +&"apiKey: sk-1234567890abcdef\ndatabase:\n user: admin\n password: P@ssw0rd!\n host: db.example.com\ntokens:\n - service: service1\n token: token1\n - service: service2\n token: token2\nsomeOtherKey: base64:aGFsbG8gd2VsdAo=\nspecific:\n SpecialCharacters: '\"ajkscbuiuXA34%%&&='\n HTMLEncodingTest1: test \n HTMLEncodingTest2: '&'\n HTLMEncodingTest3: '@'\n \"null\": null\n boolean: true\n number1: 123\n number2: 123.456\n" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/23-SECRET_BINARY-dotenv.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/23-SECRET_BINARY-dotenv.json.snap new file mode 100755 index 00000000..d4acab62 --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/23-SECRET_BINARY-dotenv.json.snap @@ -0,0 +1,6 @@ + +[TestIntegration_HandleRequestWithClients/23-SECRET_BINARY-dotenv.json - 1] +&"23-SECRET_BINARY-dotenv" +[]uint8(nil) +&"apiKey=sk-1234567890abcdef\ndatabase:host=db.example.com\ndatabase:password=P@ssw0rd!\ndatabase:user=admin\nsomeOtherKey=base64:aGFsbG8gd2VsdAo=\nspecific:boolean=True\nspecific:SpecialCharacters=\"ajkscbuiuXA34%%&&=\nspecific:HTLMEncodingTest3=@\nspecific:HTMLEncodingTest1=test \nspecific:HTMLEncodingTest2=&\nspecific:null=\nspecific:number1=123\nspecific:number2=123.456\ntokens:0:service=service1\ntokens:0:token=token1\ntokens:1:service=service2\ntokens:1:token=token2\n" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/31-PARAMETER-json.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/31-PARAMETER-json.json.snap new file mode 100755 index 00000000..9344076b --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/31-PARAMETER-json.json.snap @@ -0,0 +1,5 @@ + +[TestIntegration_HandleRequestWithClients/31-PARAMETER-json.json - 1] +&"/31-PARAMETER-json" +&"{\n\t\"apiKey\": \"sk-1234567890abcdef\",\n\t\"database\": {\n\t\t\"host\": \"db.example.com\",\n\t\t\"password\": \"P@ssw0rd!\",\n\t\t\"user\": \"admin\"\n\t},\n\t\"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n\t\"specific\": {\n\t\t\"HTLMEncodingTest3\": \"@\",\n\t\t\"HTMLEncodingTest1\": \"test \",\n\t\t\"HTMLEncodingTest2\": \"&\",\n\t\t\"SpecialCharacters\": \"\\\"ajkscbuiuXA34%%&&=\",\n\t\t\"boolean\": true,\n\t\t\"null\": null,\n\t\t\"number1\": 123,\n\t\t\"number2\": 123.456\n\t},\n\t\"tokens\": [\n\t\t{\n\t\t\t\"service\": \"service1\",\n\t\t\t\"token\": \"token1\"\n\t\t},\n\t\t{\n\t\t\t\"service\": \"service2\",\n\t\t\t\"token\": \"token2\"\n\t\t}\n\t]\n}" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/32-PARAMETER-yaml.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/32-PARAMETER-yaml.json.snap new file mode 100755 index 00000000..dd1d9e9f --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/32-PARAMETER-yaml.json.snap @@ -0,0 +1,5 @@ + +[TestIntegration_HandleRequestWithClients/32-PARAMETER-yaml.json - 1] +&"/32-PARAMETER-yaml" +&"apiKey: sk-1234567890abcdef\ndatabase:\n user: admin\n password: P@ssw0rd!\n host: db.example.com\ntokens:\n - service: service1\n token: token1\n - service: service2\n token: token2\nsomeOtherKey: base64:aGFsbG8gd2VsdAo=\nspecific:\n SpecialCharacters: '\"ajkscbuiuXA34%%&&='\n HTMLEncodingTest1: test \n HTMLEncodingTest2: '&'\n HTLMEncodingTest3: '@'\n \"null\": null\n boolean: true\n number1: 123\n number2: 123.456\n" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/33-PARAMETER-dotenv.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/33-PARAMETER-dotenv.json.snap new file mode 100755 index 00000000..a374127d --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/33-PARAMETER-dotenv.json.snap @@ -0,0 +1,5 @@ + +[TestIntegration_HandleRequestWithClients/33-PARAMETER-dotenv.json - 1] +&"/33-PARAMETER-dotenv" +&"apiKey=sk-1234567890abcdef\ndatabase:host=db.example.com\ndatabase:password=P@ssw0rd!\ndatabase:user=admin\nsomeOtherKey=base64:aGFsbG8gd2VsdAo=\nspecific:boolean=True\nspecific:SpecialCharacters=\"ajkscbuiuXA34%%&&=\nspecific:HTLMEncodingTest3=@\nspecific:HTMLEncodingTest1=test \nspecific:HTMLEncodingTest2=&\nspecific:null=\nspecific:number1=123\nspecific:number2=123.456\ntokens:0:service=service1\ntokens:0:token=token1\ntokens:1:service=service2\ntokens:1:token=token2\n" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/34-PARAMETER-binary.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/34-PARAMETER-binary.json.snap new file mode 100755 index 00000000..d57d4e53 --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/34-PARAMETER-binary.json.snap @@ -0,0 +1,5 @@ + +[TestIntegration_HandleRequestWithClients/34-PARAMETER-binary.json - 1] +&"/34-PARAMETER-binary" +&"# SOPS files for testing purpose\n\nThe sops files in this directory were created for testing purpose. As encryption algorithm [age](https://age-encryption.org/) is used, as it allows easy sharing of encryption information.\n\nThe following keys were used:\n\n```yaml\npublic: age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu\nprivate: AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3\n```\n" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json.snap new file mode 100755 index 00000000..9a5f26c1 --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json.snap @@ -0,0 +1,85 @@ + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 1] +&"/41-PARAMETER_MULTI-json/apiKey" +&"sk-1234567890abcdef" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 2] +&"/41-PARAMETER_MULTI-json/database/host" +&"db.example.com" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 3] +&"/41-PARAMETER_MULTI-json/database/password" +&"P@ssw0rd!" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 4] +&"/41-PARAMETER_MULTI-json/database/user" +&"admin" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 5] +&"/41-PARAMETER_MULTI-json/someOtherKey" +&"base64:aGFsbG8gd2VsdAo=" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 6] +&"/41-PARAMETER_MULTI-json/specific/HTMLEncodingTest2" +&"&" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 7] +&"/41-PARAMETER_MULTI-json/specific/HTLMEncodingTest3" +&"@" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 8] +&"/41-PARAMETER_MULTI-json/specific/HTMLEncodingTest1" +&"test " +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 9] +&"/41-PARAMETER_MULTI-json/specific/SpecialCharacters" +&"\"ajkscbuiuXA34%%&&=" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 10] +&"/41-PARAMETER_MULTI-json/specific/boolean" +&"true" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 11] +&"/41-PARAMETER_MULTI-json/specific/null" +&"" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 12] +&"/41-PARAMETER_MULTI-json/specific/number1" +&"123" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 13] +&"/41-PARAMETER_MULTI-json/specific/number2" +&"123.456" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 14] +&"/41-PARAMETER_MULTI-json/tokens/0/service" +&"service1" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 15] +&"/41-PARAMETER_MULTI-json/tokens/0/token" +&"token1" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 16] +&"/41-PARAMETER_MULTI-json/tokens/1/service" +&"service2" +--- + +[TestIntegration_HandleRequestWithClients/41-PARAMETER_MULTI-json.json - 17] +&"/41-PARAMETER_MULTI-json/tokens/1/token" +&"token2" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json.snap new file mode 100755 index 00000000..f46872ad --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json.snap @@ -0,0 +1,85 @@ + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 1] +&"/42-PARAMETER_MULTI-yaml/apiKey" +&"sk-1234567890abcdef" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 2] +&"/42-PARAMETER_MULTI-yaml/database/host" +&"db.example.com" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 3] +&"/42-PARAMETER_MULTI-yaml/database/password" +&"P@ssw0rd!" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 4] +&"/42-PARAMETER_MULTI-yaml/database/user" +&"admin" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 5] +&"/42-PARAMETER_MULTI-yaml/someOtherKey" +&"base64:aGFsbG8gd2VsdAo=" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 6] +&"/42-PARAMETER_MULTI-yaml/specific/HTMLEncodingTest2" +&"&" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 7] +&"/42-PARAMETER_MULTI-yaml/specific/boolean" +&"true" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 8] +&"/42-PARAMETER_MULTI-yaml/specific/null" +&"" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 9] +&"/42-PARAMETER_MULTI-yaml/specific/number2" +&"123.456" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 10] +&"/42-PARAMETER_MULTI-yaml/specific/HTLMEncodingTest3" +&"@" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 11] +&"/42-PARAMETER_MULTI-yaml/specific/HTMLEncodingTest1" +&"test " +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 12] +&"/42-PARAMETER_MULTI-yaml/specific/SpecialCharacters" +&"\"ajkscbuiuXA34%%&&=" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 13] +&"/42-PARAMETER_MULTI-yaml/specific/number1" +&"123" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 14] +&"/42-PARAMETER_MULTI-yaml/tokens/0/service" +&"service1" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 15] +&"/42-PARAMETER_MULTI-yaml/tokens/0/token" +&"token1" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 16] +&"/42-PARAMETER_MULTI-yaml/tokens/1/service" +&"service2" +--- + +[TestIntegration_HandleRequestWithClients/42-PARAMETER_MULTI-yaml.json - 17] +&"/42-PARAMETER_MULTI-yaml/tokens/1/token" +&"token2" +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json.snap new file mode 100755 index 00000000..1c3c1431 --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json.snap @@ -0,0 +1,85 @@ + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 1] +&"/43-PARAMETER_MULTI-dotenv/specific_number1" +&"123" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 2] +&"/43-PARAMETER_MULTI-dotenv/tokens_1_service" +&"service2" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 3] +&"/43-PARAMETER_MULTI-dotenv/apiKey" +&"sk-1234567890abcdef" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 4] +&"/43-PARAMETER_MULTI-dotenv/database_password" +&"P@ssw0rd!" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 5] +&"/43-PARAMETER_MULTI-dotenv/database_user" +&"admin" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 6] +&"/43-PARAMETER_MULTI-dotenv/specific_HTLMEncodingTest3" +&"@" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 7] +&"/43-PARAMETER_MULTI-dotenv/specific_HTMLEncodingTest1" +&"test " +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 8] +&"/43-PARAMETER_MULTI-dotenv/specific_HTMLEncodingTest2" +&"&" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 9] +&"/43-PARAMETER_MULTI-dotenv/specific_null" +&"" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 10] +&"/43-PARAMETER_MULTI-dotenv/specific_number2" +&"123.456" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 11] +&"/43-PARAMETER_MULTI-dotenv/tokens_0_service" +&"service1" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 12] +&"/43-PARAMETER_MULTI-dotenv/tokens_1_token" +&"token2" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 13] +&"/43-PARAMETER_MULTI-dotenv/database_host" +&"db.example.com" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 14] +&"/43-PARAMETER_MULTI-dotenv/someOtherKey" +&"base64:aGFsbG8gd2VsdAo=" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 15] +&"/43-PARAMETER_MULTI-dotenv/specific_SpecialCharacters" +&"\"ajkscbuiuXA34%%&&=" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 16] +&"/43-PARAMETER_MULTI-dotenv/specific_boolean" +&"True" +--- + +[TestIntegration_HandleRequestWithClients/43-PARAMETER_MULTI-dotenv.json - 17] +&"/43-PARAMETER_MULTI-dotenv/tokens_0_token" +&"token1" +--- diff --git a/lambda/events/21-secret-json-json-true-true.json b/lambda/events/01-SECRET-json.json similarity index 67% rename from lambda/events/21-secret-json-json-true-true.json rename to lambda/events/01-SECRET-json.json index 8a5c85e1..11da90f1 100644 --- a/lambda/events/21-secret-json-json-true-true.json +++ b/lambda/events/01-SECRET-json.json @@ -1,10 +1,10 @@ { "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", "Format": "json", - "Target": "21-secret-json-json-true-true", "ResourceType": "SECRET", "SopsS3File": { "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", - "Key": "test-secrets/json/sopsfile-complex.enc-age.json" - } -} \ No newline at end of file + "Key": "test-secrets/testsecret.sops.json" + }, + "Target": "01-SECRET-json" +} diff --git a/lambda/events/01-parameter-binary-binary-true-true.json b/lambda/events/01-parameter-binary-binary-true-true.json deleted file mode 100644 index 9dbec197..00000000 --- a/lambda/events/01-parameter-binary-binary-true-true.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "Format": "binary", - "Target": "01-parameter-binary-binary-true-true", - "ResourceType": "PARAMETER", - "SopsS3File": { - "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", - "Key": "test-secrets/binary/sopsfile.enc-age.binary" - }, - "ServiceToken": "arn:aws:lambda:eu-central-1:505755377845:function:SecretsManagerResourceHandler" - } \ No newline at end of file diff --git a/lambda/events/23-secret-yaml-json-true-true.json b/lambda/events/02-SECRET-yaml.json similarity index 67% rename from lambda/events/23-secret-yaml-json-true-true.json rename to lambda/events/02-SECRET-yaml.json index ac968334..485b805b 100644 --- a/lambda/events/23-secret-yaml-json-true-true.json +++ b/lambda/events/02-SECRET-yaml.json @@ -1,10 +1,10 @@ { "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", "Format": "yaml", - "Target": "23-secret-yaml-json-true-true", "ResourceType": "SECRET", "SopsS3File": { "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", - "Key": "test-secrets/yaml/sopsfile-complex.enc-age.yaml" - } -} \ No newline at end of file + "Key": "test-secrets/testsecret.sops.yaml" + }, + "Target": "02-SECRET-yaml" +} diff --git a/lambda/events/02-secret-binary-binary-true-true.json b/lambda/events/02-secret-binary-binary-true-true.json deleted file mode 100644 index 98a5e5c9..00000000 --- a/lambda/events/02-secret-binary-binary-true-true.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "Format": "binary", - "Target": "02-secret-binary-binary-true-true", - "ResourceType": "SECRET_BINARY", - "SopsS3File": { - "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", - "Key": "test-secrets/binary/sopsfile.enc-age.binary" - } - } \ No newline at end of file diff --git a/lambda/events/25-secret-dotenv-json-true-true.json b/lambda/events/03-SECRET-dotenv.json similarity index 63% rename from lambda/events/25-secret-dotenv-json-true-true.json rename to lambda/events/03-SECRET-dotenv.json index 1fc8e813..8cd4d002 100644 --- a/lambda/events/25-secret-dotenv-json-true-true.json +++ b/lambda/events/03-SECRET-dotenv.json @@ -1,11 +1,10 @@ { "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", - "FlattenSeparator": ".", "Format": "dotenv", - "Target": "25-secret-dotenv-json-true-true", "ResourceType": "SECRET", "SopsS3File": { "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", - "Key": "test-secrets/dotenv/encrypted-best-secret.env" - } -} \ No newline at end of file + "Key": "test-secrets/testsecret.sops.env" + }, + "Target": "03-SECRET-dotenv" +} diff --git a/lambda/events/11-SECRET_RAW-json.json b/lambda/events/11-SECRET_RAW-json.json new file mode 100644 index 00000000..a9f758e7 --- /dev/null +++ b/lambda/events/11-SECRET_RAW-json.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "json", + "ResourceType": "SECRET_RAW", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.json" + }, + "Target": "11-SECRET_RAW-json" +} diff --git a/lambda/events/12-SECRET_RAW-yaml.json b/lambda/events/12-SECRET_RAW-yaml.json new file mode 100644 index 00000000..554a5c95 --- /dev/null +++ b/lambda/events/12-SECRET_RAW-yaml.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "yaml", + "ResourceType": "SECRET_RAW", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.yaml" + }, + "Target": "12-SECRET_RAW-yaml" +} diff --git a/lambda/events/13-SECRET_RAW-dotenv.json b/lambda/events/13-SECRET_RAW-dotenv.json new file mode 100644 index 00000000..81294125 --- /dev/null +++ b/lambda/events/13-SECRET_RAW-dotenv.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "dotenv", + "ResourceType": "SECRET_RAW", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.env" + }, + "Target": "13-SECRET_RAW-dotenv" +} diff --git a/lambda/events/22-secret-json-binary-na-na.json b/lambda/events/21-SECRET_BINARY-json.json similarity index 67% rename from lambda/events/22-secret-json-binary-na-na.json rename to lambda/events/21-SECRET_BINARY-json.json index da081e08..326f5eff 100644 --- a/lambda/events/22-secret-json-binary-na-na.json +++ b/lambda/events/21-SECRET_BINARY-json.json @@ -1,10 +1,10 @@ { "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", "Format": "json", - "Target": "22-secret-json-binary-true-true", "ResourceType": "SECRET_BINARY", "SopsS3File": { "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", - "Key": "test-secrets/json/sopsfile-complex.enc-age.json" - } -} \ No newline at end of file + "Key": "test-secrets/testsecret.sops.json" + }, + "Target": "21-SECRET_BINARY-json" +} diff --git a/lambda/events/24-secret-yaml-binary-na-na.json b/lambda/events/22-SECRET_BINARY-yaml.json similarity index 68% rename from lambda/events/24-secret-yaml-binary-na-na.json rename to lambda/events/22-SECRET_BINARY-yaml.json index ba4da962..65cdbb29 100644 --- a/lambda/events/24-secret-yaml-binary-na-na.json +++ b/lambda/events/22-SECRET_BINARY-yaml.json @@ -1,10 +1,10 @@ { "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", "Format": "yaml", - "Target": "24-secret-yaml-binary-na-na", "ResourceType": "SECRET_BINARY", "SopsS3File": { "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", - "Key": "test-secrets/yaml/sopsfile-complex.enc-age.yaml" - } -} \ No newline at end of file + "Key": "test-secrets/testsecret.sops.yaml" + }, + "Target": "22-SECRET_BINARY-yaml" +} diff --git a/lambda/events/26-secret-dotenv-binary-na-na.json b/lambda/events/23-SECRET_BINARY-dotenv.json similarity index 68% rename from lambda/events/26-secret-dotenv-binary-na-na.json rename to lambda/events/23-SECRET_BINARY-dotenv.json index 6f38ef5e..e6b0cb7c 100644 --- a/lambda/events/26-secret-dotenv-binary-na-na.json +++ b/lambda/events/23-SECRET_BINARY-dotenv.json @@ -1,10 +1,10 @@ { "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", "Format": "dotenv", - "Target": "26-secret-dotenv-binary-true-true", "ResourceType": "SECRET_BINARY", "SopsS3File": { "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", - "Key": "test-secrets/dotenv/encrypted-best-secret.env" - } -} \ No newline at end of file + "Key": "test-secrets/testsecret.sops.env" + }, + "Target": "23-SECRET_BINARY-dotenv" +} diff --git a/lambda/events/31-PARAMETER-json.json b/lambda/events/31-PARAMETER-json.json new file mode 100644 index 00000000..128bdfcc --- /dev/null +++ b/lambda/events/31-PARAMETER-json.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "json", + "ResourceType": "PARAMETER", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.json" + }, + "Target": "/31-PARAMETER-json" +} diff --git a/lambda/events/32-PARAMETER-yaml.json b/lambda/events/32-PARAMETER-yaml.json new file mode 100644 index 00000000..b5ed42e5 --- /dev/null +++ b/lambda/events/32-PARAMETER-yaml.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "yaml", + "ResourceType": "PARAMETER", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.yaml" + }, + "Target": "/32-PARAMETER-yaml" +} diff --git a/lambda/events/33-PARAMETER-dotenv.json b/lambda/events/33-PARAMETER-dotenv.json new file mode 100644 index 00000000..2cc7bde6 --- /dev/null +++ b/lambda/events/33-PARAMETER-dotenv.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "dotenv", + "ResourceType": "PARAMETER", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/testsecret.sops.env" + }, + "Target": "/33-PARAMETER-dotenv" +} diff --git a/lambda/events/34-PARAMETER-binary.json b/lambda/events/34-PARAMETER-binary.json new file mode 100644 index 00000000..9fa36ba0 --- /dev/null +++ b/lambda/events/34-PARAMETER-binary.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "binary", + "ResourceType": "PARAMETER", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/README.sops.binary" + }, + "Target": "/34-PARAMETER-binary" +} diff --git a/lambda/events/11-parametermulti-json-na-true-na.json b/lambda/events/41-PARAMETER_MULTI-json.json similarity index 67% rename from lambda/events/11-parametermulti-json-na-true-na.json rename to lambda/events/41-PARAMETER_MULTI-json.json index 49431677..abc8ede1 100644 --- a/lambda/events/11-parametermulti-json-na-true-na.json +++ b/lambda/events/41-PARAMETER_MULTI-json.json @@ -1,10 +1,10 @@ { "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", "Format": "json", - "Target": "/11-parametermulti-json-na-true-na/", "ResourceType": "PARAMETER_MULTI", "SopsS3File": { "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", - "Key": "test-secrets/json/sopsfile-complex.enc-age.json" - } -} \ No newline at end of file + "Key": "test-secrets/testsecret.sops.json" + }, + "Target": "/41-PARAMETER_MULTI-json/" +} diff --git a/lambda/events/12-parametermulti-yaml-na-true-na.json b/lambda/events/42-PARAMETER_MULTI-yaml.json similarity index 67% rename from lambda/events/12-parametermulti-yaml-na-true-na.json rename to lambda/events/42-PARAMETER_MULTI-yaml.json index 8565d2d8..2a3f178b 100644 --- a/lambda/events/12-parametermulti-yaml-na-true-na.json +++ b/lambda/events/42-PARAMETER_MULTI-yaml.json @@ -1,10 +1,10 @@ { "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", "Format": "yaml", - "Target": "/12-parametermulti-yaml-na-true-true/", "ResourceType": "PARAMETER_MULTI", "SopsS3File": { "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", - "Key": "test-secrets/yaml/sopsfile-complex.enc-age.yaml" - } -} \ No newline at end of file + "Key": "test-secrets/testsecret.sops.yaml" + }, + "Target": "/42-PARAMETER_MULTI-yaml/" +} diff --git a/lambda/events/13-parametermulti-dotenv-na-true-na.json b/lambda/events/43-PARAMETER_MULTI-dotenv.json similarity index 67% rename from lambda/events/13-parametermulti-dotenv-na-true-na.json rename to lambda/events/43-PARAMETER_MULTI-dotenv.json index 9f58db0d..a7701b65 100644 --- a/lambda/events/13-parametermulti-dotenv-na-true-na.json +++ b/lambda/events/43-PARAMETER_MULTI-dotenv.json @@ -1,10 +1,10 @@ { "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", "Format": "dotenv", - "Target": "/13-parametermulti-dotenv-na-true-na/", "ResourceType": "PARAMETER_MULTI", "SopsS3File": { "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", - "Key": "test-secrets/dotenv/encrypted-best-secret.env" - } -} \ No newline at end of file + "Key": "test-secrets/testsecret.sops.env" + }, + "Target": "/43-PARAMETER_MULTI-dotenv/" +} diff --git a/lambda/handle.go b/lambda/handle.go index ff25e7c8..5ececdb8 100644 --- a/lambda/handle.go +++ b/lambda/handle.go @@ -5,6 +5,7 @@ import ( "log/slog" "strings" + "github.com/aws/smithy-go/ptr" "github.com/markussiebert/cdk-sops-secrets/internal/client" "github.com/markussiebert/cdk-sops-secrets/internal/data" "github.com/markussiebert/cdk-sops-secrets/internal/event" @@ -21,31 +22,42 @@ func handleSecret(props BaseProps) (physicalResourceID string, data map[string]i var outData *[]byte var outDataErr error logger.Info("Handling secret data", "ResourceType", props.properties.ResourceType) - if props.properties.ResourceType == event.SECRET { + + var binary *bool + switch props.properties.ResourceType { + case event.SECRET: seperator := "." if props.properties.FlattenSeparator != nil { seperator = *props.properties.FlattenSeparator } - logger.Info("Flattening secret data", "seperator", seperator) + logger.Info("Flattening secret data", "seperator", seperator, "ResourceType", props.properties.ResourceType) if err := props.secretDecryptedData.Flatten(seperator); err != nil { return props.properties.GeneratePhysicalResourceId(), nil, err } - logger.Info("Stringifying secret data") + logger.Info("Stringifying secret data", "ResourceType", props.properties.ResourceType) if err := props.secretDecryptedData.StringifyValues(); err != nil { return props.properties.GeneratePhysicalResourceId(), nil, err } - logger.Info("Converting secret data to JSON") + logger.Info("Converting secret data to JSON", "ResourceType", props.properties.ResourceType) outData, outDataErr = props.secretDecryptedData.ToJSON() - } else { - logger.Info("Getting raw secret data") + binary = ptr.Bool(false) + case event.SECRET_RAW: + logger.Info("Getting raw secret data", "ResourceType", props.properties.ResourceType) + outData, outDataErr = props.secretDecryptedData.GetRaw() + binary = ptr.Bool(false) + case event.SECRET_BINARY: + logger.Info("Getting raw secret data", "ResourceType", props.properties.ResourceType) outData, outDataErr = props.secretDecryptedData.GetRaw() + binary = ptr.Bool(true) + default: + return props.properties.GeneratePhysicalResourceId(), nil, fmt.Errorf("unknown ResourceType: %s", props.properties.ResourceType) } if outDataErr != nil { return props.properties.GeneratePhysicalResourceId(), nil, outDataErr } - putSecretValueResp, putSecretValueRespErr := props.clients.SecretsManagerPutSecretValue(*props.secretDecryptedData.Hash, props.properties.Target, outData) + putSecretValueResp, putSecretValueRespErr := props.clients.SecretsManagerPutSecretValue(*props.secretDecryptedData.Hash, props.properties.Target, outData, binary) if putSecretValueRespErr != nil { return props.properties.GeneratePhysicalResourceId(), nil, putSecretValueRespErr } @@ -70,6 +82,10 @@ func handleParameterMulti(props BaseProps) (physicalResourceID string, data map[ if err := props.secretDecryptedData.Flatten(seperator); err != nil { return props.properties.GeneratePhysicalResourceId(), nil, err } + logger.Info("Stringify values in data") + if err := props.secretDecryptedData.StringifyValues(); err != nil { + return props.properties.GeneratePhysicalResourceId(), nil, err + } logger.Info("Converting secret data to map") outData, outDataErr := props.secretDecryptedData.ToStringMap() if outDataErr != nil { @@ -85,12 +101,22 @@ func handleParameterMulti(props BaseProps) (physicalResourceID string, data map[ fixedKey = strings.ReplaceAll(fixedKey, "]", seperator) fixedKey = strings.TrimSuffix(fixedKey, seperator) fixedKey = strings.ReplaceAll(fixedKey, seperator+seperator, seperator) - // Whitespaces are also not allowed, maybe more characters - fixedKey = strings.ReplaceAll(fixedKey, " ", "_") + // The secret name can contain ASCII letters, numbers, and the following characters: /_+=.@- + allowedChars := "/_+=.@-" + for i, char := range fixedKey { + if !(char >= 'a' && char <= 'z') && !(char >= 'A' && char <= 'Z') && !(char >= '0' && char <= '9') && !strings.ContainsRune(allowedChars, char) { + fixedKey = fixedKey[:i] + "_" + fixedKey[i+1:] + } + } // Prefix with Target fixedKey = props.properties.Target + fixedKey + // FixValue (can't be empty) + if len(value) == 0 { + value = []byte("") + } _, err := props.clients.SsmPutParameter(fixedKey, &value, *props.properties.EncryptionKey) if err != nil { + logger.Error("Failed to write parameter", "Parameter", fixedKey, "Error", err) return props.properties.GeneratePhysicalResourceId(), nil, fmt.Errorf("failed to update ssm parameter:\n%v", err) } logger.Info("Parameter written", "Parameter", fixedKey) @@ -116,7 +142,8 @@ func handleParameter(props BaseProps) (physicalResourceID string, data map[strin } putParameterResponse, putParameterResponseErr := props.clients.SsmPutParameter(props.properties.Target, outData, *props.properties.EncryptionKey) if putParameterResponseErr != nil { - return props.properties.GeneratePhysicalResourceId(), nil, fmt.Errorf("failed to update ssm parameter:\n%v", err) + logger.Error("Failed to write parameter", "Parameter", props.properties.Target, "Error", putParameterResponseErr) + return props.properties.GeneratePhysicalResourceId(), nil, fmt.Errorf("failed to update ssm parameter:\n%v", putParameterResponseErr) } logger.Info("Parameter written", "Parameter", props.properties.Target) diff --git a/lambda/internal/client/client.go b/lambda/internal/client/client.go index 5f90d995..d75bbef3 100644 --- a/lambda/internal/client/client.go +++ b/lambda/internal/client/client.go @@ -8,6 +8,7 @@ import ( "log/slog" "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/aws/retry" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" s3Types "github.com/aws/aws-sdk-go-v2/service/s3/types" @@ -32,7 +33,7 @@ type SsmClient interface { type AwsClient interface { S3GetObject(file SopsS3File) (data []byte, err error) S3GetObjectETAG(file SopsS3File) (*string, error) - SecretsManagerPutSecretValue(sopsHash string, secretArn string, secretContent *[]byte) (data *secretsmanager.PutSecretValueOutput, err error) + SecretsManagerPutSecretValue(sopsHash string, secretArn string, secretContent *[]byte, binary *bool) (data *secretsmanager.PutSecretValueOutput, err error) SsmPutParameter(parameterName string, parameterContent *[]byte, keyId string) (response *ssm.PutParameterOutput, err error) } @@ -44,7 +45,9 @@ type Client struct { } func CreateAwsClients(context context.Context) AwsClient { - cfg, err := config.LoadDefaultConfig(context) + cfg, err := config.LoadDefaultConfig(context, config.WithRetryer(func() aws.Retryer { + return retry.AddWithMaxAttempts(retry.NewStandard(), 5) + })) if err != nil { log.Fatalf("unable to load SDK config, %v", err) } @@ -103,11 +106,18 @@ func (c *Client) S3GetObjectETAG(file SopsS3File) (*string, error) { return attr.ETag, nil } -func (c *Client) SecretsManagerPutSecretValue(sopsHash string, secretArn string, secretContent *[]byte) (data *secretsmanager.PutSecretValueOutput, err error) { - secretContentString := string(*secretContent) +func (c *Client) SecretsManagerPutSecretValue(sopsHash string, secretArn string, secretStringData *[]byte, binary *bool) (data *secretsmanager.PutSecretValueOutput, err error) { + if binary != nil && binary == aws.Bool(true) { + input := &secretsmanager.PutSecretValueInput{ + SecretId: &secretArn, + SecretBinary: *secretStringData, + ClientRequestToken: &sopsHash, + } + return c.secretsManager.PutSecretValue(c.ctx, input) + } input := &secretsmanager.PutSecretValueInput{ SecretId: &secretArn, - SecretString: &secretContentString, + SecretString: aws.String(string(*secretStringData)), ClientRequestToken: &sopsHash, } return c.secretsManager.PutSecretValue(c.ctx, input) diff --git a/lambda/internal/client/client_test.go b/lambda/internal/client/client_test.go index b7341dbb..53db1aa8 100644 --- a/lambda/internal/client/client_test.go +++ b/lambda/internal/client/client_test.go @@ -11,6 +11,7 @@ import ( "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go-v2/service/secretsmanager" "github.com/aws/aws-sdk-go-v2/service/ssm" + "github.com/aws/smithy-go/ptr" "github.com/stretchr/testify/assert" ) @@ -144,6 +145,7 @@ func TestSecretsManagerPutSecretValue(t *testing.T) { mockClient *MockAwsClient expectedARN *string expectedErrMsg string + binary *bool }{ { name: "successful put secret value", @@ -155,6 +157,7 @@ func TestSecretsManagerPutSecretValue(t *testing.T) { }, ReturnError: nil, }, + binary: ptr.Bool(false), expectedARN: aws.String("mock-arn"), }, { @@ -165,6 +168,7 @@ func TestSecretsManagerPutSecretValue(t *testing.T) { PutSecretValueRet: nil, ReturnError: fmt.Errorf("mock error"), }, + binary: ptr.Bool(false), expectedErrMsg: "failed to store secret value:\nsecretArn: test-arn\nClientRequestToken: test-hash\nmock error", }, } @@ -177,7 +181,7 @@ func TestSecretsManagerPutSecretValue(t *testing.T) { } content := []byte("content") - resp, err := client.SecretsManagerPutSecretValue("hash", "arn", &content) + resp, err := client.SecretsManagerPutSecretValue("hash", "arn", &content, tt.binary) assert.Equal(t, tt.mockClient.ReturnError, err) assert.Equal(t, tt.mockClient.PutSecretValueRet, resp) }) diff --git a/lambda/internal/data/data.go b/lambda/internal/data/data.go index 5acaa91a..41face28 100644 --- a/lambda/internal/data/data.go +++ b/lambda/internal/data/data.go @@ -237,6 +237,8 @@ func stringifyValues(input any) (any, error) { reflect.Float32, reflect.Float64, reflect.Bool, reflect.Complex64, reflect.Complex128: // If it's a primitive type, convert it to a string return fmt.Sprintf("%v", input), nil + case reflect.Invalid: + return "", nil default: // If it's an unsupported type, return an error return nil, fmt.Errorf("unsupported type: %v", v.Kind()) diff --git a/lambda/internal/event/config-schema.json b/lambda/internal/event/config-schema.json index 5ec3508e..209c6d78 100644 --- a/lambda/internal/event/config-schema.json +++ b/lambda/internal/event/config-schema.json @@ -40,6 +40,7 @@ "type": "string", "enum": [ "SECRET", + "SECRET_RAW", "SECRET_BINARY", "PARAMETER_MULTI", "PARAMETER" diff --git a/lambda/internal/event/event.go b/lambda/internal/event/event.go index 809b69e6..0ea72830 100644 --- a/lambda/internal/event/event.go +++ b/lambda/internal/event/event.go @@ -45,7 +45,9 @@ type ResourceType string const ( // Secret, flattened and stringified SECRET ResourceType = "SECRET" - // Secret, just the raw value + // Secret, just the raw value stored as binary + SECRET_RAW ResourceType = "SECRET_RAW" + // Secret, just the raw value stored as binary SECRET_BINARY ResourceType = "SECRET_BINARY" // The JSON object is flattened into multiple parameters PARAMETER_MULTI ResourceType = "PARAMETER_MULTI" @@ -54,7 +56,7 @@ const ( ) type SopsSyncResourcePropertys struct { - ResourceType ResourceType `json:"ResourceType" jsonschema:"enum=SECRET,enum=SECRET_BINARY,enum=PARAMETER_MULTI,enum=PARAMETER"` + ResourceType ResourceType `json:"ResourceType" jsonschema:"enum=SECRET,enum=SECRET_RAW,enum=SECRET_BINARY,enum=PARAMETER_MULTI,enum=PARAMETER"` Format sops.Format `json:"Format" jsonschema:"enum=json,enum=yaml,enum=dotenv,enum=binary"` Target string `json:"Target"` EncryptionKey *string `json:"EncryptionKey,omitempty"` diff --git a/lambda/internal/sops/__snapshots__/README.sops.binary.snap b/lambda/internal/sops/__snapshots__/README.sops.binary.snap new file mode 100755 index 00000000..f1db1e0b --- /dev/null +++ b/lambda/internal/sops/__snapshots__/README.sops.binary.snap @@ -0,0 +1,14 @@ + +[TestDecrypt/README.sops.binary - 1] +# SOPS files for testing purpose + +The sops files in this directory were created for testing purpose. As encryption algorithm [age](https://age-encryption.org/) is used, as it allows easy sharing of encryption information. + +The following keys were used: + +```yaml +public: age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu +private: AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3 +``` + +--- diff --git a/lambda/internal/sops/__snapshots__/binary/sopsfile.enc-age.binary.snap b/lambda/internal/sops/__snapshots__/binary/sopsfile.enc-age.binary.snap deleted file mode 100755 index 6488d8dd..00000000 --- a/lambda/internal/sops/__snapshots__/binary/sopsfile.enc-age.binary.snap +++ /dev/null @@ -1,18 +0,0 @@ - -[TestDecrypt/binary/sopsfile.enc-age.binary - 1] ------BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQDVd/OAdqlMznWINBDoyR+PESgQJlUptwnh/vzbgAaIuHl4gN7Q -W2Jx06bKFgv8yAQ4ouR0EaPv43X1pWFUyE/vK4e2A4M28Ciriy5r2TiBx57EL7bA -AiiCaEvpKx3uAtTgFYcdLdD5xYKUf51gymZ6wU8BBgYMkVlL5rpGmR7ddQIDAQAB -AoGAaeEXG+6/RmNZFHeOs4eeaZ2+21PIBerNshSBYnX7x7CIP2bcHUhWadLq9W0+ -AOFMhrL00UU2pPOTPIYM4rqAOl5PvPeV4GNMvI+9/619p/ZNMbnvj43KqUtaPp1g -JyT22CH4TqDC2io8S9xWxxh9AgvgOI/ekJ3h4PdYpmyVUXkCQQD6b1dkYhlgiy3u -Z84L5WM+7vXG2ivA3N3T5eYJdsQFvlV6gNSqbKcxIR+cFK0RaRiWrd7U2IOM67RF -YRvHNN0rAkEA2jZRXVjHjTZSuAVDMOA4cc6pgxOqByg14clWgRDtbueIMHNCYLJY -bi5YE0kqzjSaH2WbeT7LX1q3S7amoN4f3wJBALw9ZrYYmrSbyRmTQyhj8raCTZF7 -ujmMitzUyJVChVM/3uZm4fN8GivuluDuFaypj4brCDx6xl7taKJhvMx+quMCQF/C -ZoJoa2n05OgMpyfTvfFzl8AF6R+q7bpf+K47F3cL9CAO9JoqqdPwUoZkHXzQaLJO -jKPwgp8d2EJJrWX7FFECQQCRMPE4WsTCLXmVefZne7k000WPclZ4pIjggz1lpGgN -23bwNOla1k4/B10btnEzNi16/b01Kf3K4hYaicd46sLH ------END RSA PRIVATE KEY----- ---- diff --git a/lambda/internal/sops/__snapshots__/dotenv/encrypted-best-secret.env.snap b/lambda/internal/sops/__snapshots__/dotenv/encrypted-best-secret.env.snap deleted file mode 100755 index 0e6f63f9..00000000 --- a/lambda/internal/sops/__snapshots__/dotenv/encrypted-best-secret.env.snap +++ /dev/null @@ -1,6 +0,0 @@ - -[TestDecrypt/dotenv/encrypted-best-secret.env - 1] -banane=yellow -crypt="ajkscbuiuXA34%%&&= - ---- diff --git a/lambda/internal/sops/__snapshots__/encrypted-best-secret.env.snap b/lambda/internal/sops/__snapshots__/encrypted-best-secret.env.snap deleted file mode 100755 index 30fa84e2..00000000 --- a/lambda/internal/sops/__snapshots__/encrypted-best-secret.env.snap +++ /dev/null @@ -1,6 +0,0 @@ - -[TestDecrypt/encrypted-best-secret.env - 1] -banane=yellow -crypt="ajkscbuiuXA34%%&&= - ---- diff --git a/lambda/internal/sops/__snapshots__/json/sopsfile-complex.enc-age.json.snap b/lambda/internal/sops/__snapshots__/json/sopsfile-complex.enc-age.json.snap deleted file mode 100755 index ba501e91..00000000 --- a/lambda/internal/sops/__snapshots__/json/sopsfile-complex.enc-age.json.snap +++ /dev/null @@ -1,38 +0,0 @@ - -[TestDecrypt/json/sopsfile-complex.enc-age.json - 1] -{ - "some": { - "deep": { - "nested": { - "object": "structure", - "arrays": [ - "with", - "several", - { - "values": { - "and": "objects" - } - } - ] - } - }, - "notsodeep": "struct" - }, - "and now": { - "some": [ - { - "basic": false - }, - { - "nested": 12345 - }, - { - "type": 1.2345 - }, - { - "tests": "Finish!" - } - ] - } -} ---- diff --git a/lambda/internal/sops/__snapshots__/sopsfile-complex.enc-age.json.snap b/lambda/internal/sops/__snapshots__/sopsfile-complex.enc-age.json.snap deleted file mode 100755 index e46d5cba..00000000 --- a/lambda/internal/sops/__snapshots__/sopsfile-complex.enc-age.json.snap +++ /dev/null @@ -1,43 +0,0 @@ - -[TestDecrypt/sopsfile-complex.enc-age.json - 1] -{ - "and now": { - "some": [ - { - "basic": false - }, - { - "nested": 12345 - }, - { - "type": 1.2345 - }, - { - "tests": "Finish!" - } - ] - }, - "some": { - "deep": { - "nested": { - "arrays": [ - "with", - "several", - { - "values": { - "and": "objects" - } - } - ], - "object": "structure" - } - }, - "notsodeep": "struct" - }, - "with": { - "TestValue": "test ", - "TestValue2": "&", - "TestValue3": "@" - } -} ---- diff --git a/lambda/internal/sops/__snapshots__/sopsfile.enc-age.binary.snap b/lambda/internal/sops/__snapshots__/sopsfile.enc-age.binary.snap deleted file mode 100755 index 158ccc96..00000000 --- a/lambda/internal/sops/__snapshots__/sopsfile.enc-age.binary.snap +++ /dev/null @@ -1,18 +0,0 @@ - -[TestDecrypt/sopsfile.enc-age.binary - 1] ------BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQDVd/OAdqlMznWINBDoyR+PESgQJlUptwnh/vzbgAaIuHl4gN7Q -W2Jx06bKFgv8yAQ4ouR0EaPv43X1pWFUyE/vK4e2A4M28Ciriy5r2TiBx57EL7bA -AiiCaEvpKx3uAtTgFYcdLdD5xYKUf51gymZ6wU8BBgYMkVlL5rpGmR7ddQIDAQAB -AoGAaeEXG+6/RmNZFHeOs4eeaZ2+21PIBerNshSBYnX7x7CIP2bcHUhWadLq9W0+ -AOFMhrL00UU2pPOTPIYM4rqAOl5PvPeV4GNMvI+9/619p/ZNMbnvj43KqUtaPp1g -JyT22CH4TqDC2io8S9xWxxh9AgvgOI/ekJ3h4PdYpmyVUXkCQQD6b1dkYhlgiy3u -Z84L5WM+7vXG2ivA3N3T5eYJdsQFvlV6gNSqbKcxIR+cFK0RaRiWrd7U2IOM67RF -YRvHNN0rAkEA2jZRXVjHjTZSuAVDMOA4cc6pgxOqByg14clWgRDtbueIMHNCYLJY -bi5YE0kqzjSaH2WbeT7LX1q3S7amoN4f3wJBALw9ZrYYmrSbyRmTQyhj8raCTZF7 -ujmMitzUyJVChVM/3uZm4fN8GivuluDuFaypj4brCDx6xl7taKJhvMx+quMCQF/C -ZoJoa2n05OgMpyfTvfFzl8AF6R+q7bpf+K47F3cL9CAO9JoqqdPwUoZkHXzQaLJO -jKPwgp8d2EJJrWX7FFECQQCRMPE4WsTCLXmVefZne7k000WPclZ4pIjggz1lpGgN -23bwNOla1k4/B10btnEzNi16/b01Kf3K4hYaicd46sLH ------END RSA PRIVATE KEY----- ---- diff --git a/lambda/internal/sops/__snapshots__/sopsfile.enc-age.yaml.snap b/lambda/internal/sops/__snapshots__/sopsfile.enc-age.yaml.snap deleted file mode 100755 index ae4a3910..00000000 --- a/lambda/internal/sops/__snapshots__/sopsfile.enc-age.yaml.snap +++ /dev/null @@ -1,7 +0,0 @@ - -[TestDecrypt/sopsfile.enc-age.yaml - 1] -key1: value1 -key2: 12345 -key3: false - ---- diff --git a/lambda/internal/sops/__snapshots__/testsecret.sops.env.snap b/lambda/internal/sops/__snapshots__/testsecret.sops.env.snap new file mode 100755 index 00000000..cdf6b030 --- /dev/null +++ b/lambda/internal/sops/__snapshots__/testsecret.sops.env.snap @@ -0,0 +1,21 @@ + +[TestDecrypt/testsecret.sops.env - 1] +apiKey=sk-1234567890abcdef +database:host=db.example.com +database:password=P@ssw0rd! +database:user=admin +someOtherKey=base64:aGFsbG8gd2VsdAo= +specific:boolean=True +specific:SpecialCharacters="ajkscbuiuXA34%%&&= +specific:HTLMEncodingTest3=@ +specific:HTMLEncodingTest1=test +specific:HTMLEncodingTest2=& +specific:null= +specific:number1=123 +specific:number2=123.456 +tokens:0:service=service1 +tokens:0:token=token1 +tokens:1:service=service2 +tokens:1:token=token2 + +--- diff --git a/lambda/internal/sops/__snapshots__/testsecret.sops.json.snap b/lambda/internal/sops/__snapshots__/testsecret.sops.json.snap new file mode 100755 index 00000000..0d253c3a --- /dev/null +++ b/lambda/internal/sops/__snapshots__/testsecret.sops.json.snap @@ -0,0 +1,32 @@ + +[TestDecrypt/testsecret.sops.json - 1] +{ + "apiKey": "sk-1234567890abcdef", + "database": { + "host": "db.example.com", + "password": "P@ssw0rd!", + "user": "admin" + }, + "someOtherKey": "base64:aGFsbG8gd2VsdAo=", + "specific": { + "HTLMEncodingTest3": "@", + "HTMLEncodingTest1": "test ", + "HTMLEncodingTest2": "&", + "SpecialCharacters": "\"ajkscbuiuXA34%%&&=", + "boolean": true, + "null": null, + "number1": 123, + "number2": 123.456 + }, + "tokens": [ + { + "service": "service1", + "token": "token1" + }, + { + "service": "service2", + "token": "token2" + } + ] +} +--- diff --git a/lambda/internal/sops/__snapshots__/testsecret.sops.yaml.snap b/lambda/internal/sops/__snapshots__/testsecret.sops.yaml.snap new file mode 100755 index 00000000..043e7346 --- /dev/null +++ b/lambda/internal/sops/__snapshots__/testsecret.sops.yaml.snap @@ -0,0 +1,24 @@ + +[TestDecrypt/testsecret.sops.yaml - 1] +apiKey: sk-1234567890abcdef +database: + user: admin + password: P@ssw0rd! + host: db.example.com +tokens: + - service: service1 + token: token1 + - service: service2 + token: token2 +someOtherKey: base64:aGFsbG8gd2VsdAo= +specific: + SpecialCharacters: '"ajkscbuiuXA34%%&&=' + HTMLEncodingTest1: test + HTMLEncodingTest2: '&' + HTLMEncodingTest3: '@' + "null": null + boolean: true + number1: 123 + number2: 123.456 + +--- diff --git a/lambda/internal/sops/__snapshots__/yaml/sopsfile.enc-age.yaml.snap b/lambda/internal/sops/__snapshots__/yaml/sopsfile.enc-age.yaml.snap deleted file mode 100755 index 2e97dfb5..00000000 --- a/lambda/internal/sops/__snapshots__/yaml/sopsfile.enc-age.yaml.snap +++ /dev/null @@ -1,7 +0,0 @@ - -[TestDecrypt/yaml/sopsfile.enc-age.yaml - 1] -key1: value1 -key2: 12345 -key3: false - ---- diff --git a/lambda/internal/sops/sops_test.go b/lambda/internal/sops/sops_test.go index 3a884e8e..c1d2a4d3 100644 --- a/lambda/internal/sops/sops_test.go +++ b/lambda/internal/sops/sops_test.go @@ -1,7 +1,6 @@ package sops import ( - "fmt" "os" "testing" @@ -19,10 +18,10 @@ func read(filename string) ([]byte, error) { func TestDecrypt(t *testing.T) { tests := map[Format]string{ - BINARY: "sopsfile.enc-age.binary", - DOTENV: "encrypted-best-secret.env", - JSON: "sopsfile-complex.enc-age.json", - YAML: "sopsfile.enc-age.yaml", + BINARY: "README.sops.binary", + DOTENV: "testsecret.sops.env", + JSON: "testsecret.sops.json", + YAML: "testsecret.sops.yaml", } t.Setenv("SOPS_AGE_KEY", "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3") @@ -30,7 +29,7 @@ func TestDecrypt(t *testing.T) { for format, file := range tests { t.Run(file, func(t *testing.T) { - content, err := read(fmt.Sprintf("%s/%s", format, file)) + content, err := read(file) if err != nil { t.Fatalf("Failed to read file: %v", err) diff --git a/lambda/main.go b/lambda/main.go index e1e703ef..e505e1bf 100644 --- a/lambda/main.go +++ b/lambda/main.go @@ -54,7 +54,7 @@ func HandleRequestWithClients(clients client.AwsClient, e cfn.Event) (physicalRe } switch props.ResourceType { - case event.SECRET, event.SECRET_BINARY: + case event.SECRET, event.SECRET_RAW, event.SECRET_BINARY: return handleSecret(baseProps) case event.PARAMETER_MULTI: return handleParameterMulti(baseProps) diff --git a/lambda/main_integration_test.go b/lambda/main_integration_test.go index 28e9bf44..87da8907 100644 --- a/lambda/main_integration_test.go +++ b/lambda/main_integration_test.go @@ -4,15 +4,18 @@ import ( "context" "encoding/json" "os" + "slices" "strings" "testing" "time" "github.com/aws/aws-lambda-go/cfn" + "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/s3" "github.com/aws/aws-sdk-go-v2/service/secretsmanager" "github.com/aws/aws-sdk-go-v2/service/ssm" + "github.com/gkampitakis/go-snaps/snaps" "github.com/markussiebert/cdk-sops-secrets/internal/client" "github.com/stretchr/testify/assert" ) @@ -59,7 +62,7 @@ func prepareSecret(t *testing.T, resourceProps map[string]interface{}) { secretName := resourceProps["Target"].(string) ResourceType := resourceProps["ResourceType"].(string) - if ResourceType != "SECRET" && ResourceType != "SECRET_BINARY" { + if ResourceType != "SECRET" && ResourceType != "SECRET_BINARY" && ResourceType != "SECRET_RAW" { return } @@ -103,6 +106,31 @@ func cleanupSecret(t *testing.T, resourceProps map[string]interface{}) { } } +func snapshotSecret(t *testing.T, resourceProps map[string]interface{}) { + cfg, err := config.LoadDefaultConfig(context.Background()) + if err != nil { + t.Errorf("unable to load SDK config, %v", err) + } + + secretsManagerClient := secretsmanager.NewFromConfig(cfg) + + secretName := resourceProps["Target"].(string) + ResourceType := resourceProps["ResourceType"].(string) + + if ResourceType != "SECRET" && ResourceType != "SECRET_RAW" && ResourceType != "SECRET_BINARY" { + return + } + + resp, err := secretsManagerClient.GetSecretValue(context.Background(), &secretsmanager.GetSecretValueInput{ + SecretId: &secretName, + }) + snaps.WithConfig(snaps.Filename(t.Name())).MatchSnapshot(t, resp.Name, resp.SecretBinary, resp.SecretString) + + if err != nil { + t.Logf("failed to snapshot secret: %v", err) + } +} + func cleanupParameter(t *testing.T, resourceProps map[string]interface{}) { cfg, err := config.LoadDefaultConfig(context.Background()) if err != nil { @@ -150,7 +178,61 @@ func cleanupParameter(t *testing.T, resourceProps map[string]interface{}) { } } +func snapshotParameter(t *testing.T, resourceProps map[string]interface{}) { + + cfg, err := config.LoadDefaultConfig(context.Background()) + if err != nil { + t.Errorf("unable to load SDK config, %v", err) + } + + ssmClient := ssm.NewFromConfig(cfg) + parameterNames := []string{} + parameterName := resourceProps["Target"].(string) + ResourceType := resourceProps["ResourceType"].(string) + + if ResourceType == "PARAMETER_MULTI" { + input := &ssm.DescribeParametersInput{} + for { + output, err := ssmClient.DescribeParameters(context.Background(), input) + if err != nil { + t.Errorf("failed to describe parameters: %v", err) + return + } + for _, param := range output.Parameters { + if strings.HasPrefix(*param.Name, parameterName) { + parameterNames = append(parameterNames, *param.Name) + } + } + if output.NextToken == nil { + break + } + input.NextToken = output.NextToken + } + } else if ResourceType == "PARAMETER" { + parameterNames = append(parameterNames, parameterName) + } else { + t.Logf("unknown resource type: %s", ResourceType) + return + } + + for _, p := range parameterNames { + t.Logf("snapshotting parameter %s", p) + resp, err := ssmClient.GetParameter(context.Background(), &ssm.GetParameterInput{ + Name: &p, + WithDecryption: aws.Bool(true), + }) + snaps.WithConfig(snaps.Filename(t.Name())).MatchSnapshot(t, resp.Parameter.Name, resp.Parameter.Value) + if err != nil { + t.Logf("failed to snapshot parameter: %v", err) + } + } + +} + func TestIntegration_HandleRequestWithClients(t *testing.T) { + //if os.Getenv("INTEGRATION") == "" { + // return + //} t.Logf("Running at: %s", time.Now().String()) // Forces re-run os.Setenv("AWS_REGION", "eu-central-1") os.Setenv("SOPS_AGE_KEY", "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3") @@ -201,6 +283,9 @@ func TestIntegration_HandleRequestWithClients(t *testing.T) { physicalResourceID, data, err := HandleRequestWithClients(clients, tt.event) + snapshotSecret(t, tt.event.ResourceProperties) + snapshotParameter(t, tt.event.ResourceProperties) + assert.NoError(t, err) assert.NotEmpty(t, physicalResourceID) assert.NotNil(t, data) @@ -209,6 +294,9 @@ func TestIntegration_HandleRequestWithClients(t *testing.T) { } func TestIntegration_Cleanup(t *testing.T) { + if os.Getenv("INTEGRATION") == "" { + return + } t.Logf("Running at: %s", time.Now().String()) // Forces re-run os.Setenv("AWS_REGION", "eu-central-1") @@ -240,3 +328,76 @@ func TestIntegration_Cleanup(t *testing.T) { }) } } + +func Test_CleanUpHard(t *testing.T) { + if os.Getenv("DANGER_HARD_CLEAN") == "" { + return + } + deleteAllSecrets() + deleteAllParametersExcept([]string{"/cdk-bootstrap/hnb659fds/version"}) +} + +func deleteAllSecrets() { + cfg, err := config.LoadDefaultConfig(context.Background(), config.WithRetryMaxAttempts(5)) + + if err != nil { + panic(err) + } + + secretsManagerClient := secretsmanager.NewFromConfig(cfg) + + input := &secretsmanager.ListSecretsInput{ + IncludePlannedDeletion: aws.Bool(true), + } + for { + output, err := secretsManagerClient.ListSecrets(context.Background(), input) + if err != nil { + panic(err) + } + for _, secret := range output.SecretList { + _, err := secretsManagerClient.DeleteSecret(context.Background(), &secretsmanager.DeleteSecretInput{ + ForceDeleteWithoutRecovery: aws.Bool(true), + SecretId: secret.ARN, + }) + if err != nil { + panic(err) + } + } + if output.NextToken == nil { + break + } + input.NextToken = output.NextToken + } +} + +func deleteAllParametersExcept(except []string) { + cfg, err := config.LoadDefaultConfig(context.Background(), config.WithRetryMaxAttempts(5)) + + if err != nil { + panic(err) + } + + ssmClient := ssm.NewFromConfig(cfg) + + input := &ssm.DescribeParametersInput{} + for { + output, err := ssmClient.DescribeParameters(context.Background(), input) + if err != nil { + panic(err) + } + for _, param := range output.Parameters { + if !slices.Contains(except, *param.Name) { + _, err := ssmClient.DeleteParameter(context.Background(), &ssm.DeleteParameterInput{ + Name: param.Name, + }) + if err != nil { + panic(err) + } + } + } + if output.NextToken == nil { + break + } + input.NextToken = output.NextToken + } +} diff --git a/lambda/main_test.go b/lambda/main_test.go index cd136c7b..b4b9db3d 100644 --- a/lambda/main_test.go +++ b/lambda/main_test.go @@ -19,7 +19,6 @@ type putSecretValueCalls map[string]interface{} type getObjectEtagCalls map[string]client.SopsS3File type getObjectCalls map[string]client.SopsS3File type MockAwsClient struct { - snapsFileName string t *testing.T putParameter putParameterCalls putSecretValue putSecretValueCalls @@ -43,8 +42,8 @@ func (m *MockAwsClient) S3GetObjectETAG(file client.SopsS3File) (*string, error) return &etag, nil } -func (m *MockAwsClient) SecretsManagerPutSecretValue(sopsHash string, secretArn string, secretContent *[]byte) (*secretsmanager.PutSecretValueOutput, error) { - m.putSecretValue[secretArn] = map[string]interface{}{"sopsHash": sopsHash, "secretContent": string(*secretContent)} +func (m *MockAwsClient) SecretsManagerPutSecretValue(sopsHash string, secretArn string, secretContent *[]byte, binary *bool) (*secretsmanager.PutSecretValueOutput, error) { + m.putSecretValue[secretArn] = map[string]interface{}{"sopsHash": sopsHash, "secretContent": string(*secretContent), "binary": *binary} arn := "mock-arn" return &secretsmanager.PutSecretValueOutput{ ARN: &arn, @@ -103,7 +102,6 @@ func TestHandleRequestWithClients(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { clients := &MockAwsClient{ - snapsFileName: tt.name, t: t, putParameter: putParameterCalls{}, putSecretValue: putSecretValueCalls{}, @@ -112,7 +110,7 @@ func TestHandleRequestWithClients(t *testing.T) { } physicalResourceID, data, err := HandleRequestWithClients(clients, tt.event) - snaps.WithConfig(snaps.Filename(tt.name)).MatchSnapshot(t, clients.getObject, clients.getObjectEtag, clients.putParameter, clients.putSecretValue) + snaps.WithConfig(snaps.Filename(t.Name()+"/"+tt.name)).MatchSnapshot(t, clients.getObject, clients.getObjectEtag, clients.putParameter, clients.putSecretValue) assert.NoError(t, err) assert.NotEmpty(t, physicalResourceID) diff --git a/package.json b/package.json index 8fb06252..31d0a299 100644 --- a/package.json +++ b/package.json @@ -15,26 +15,21 @@ "docgen": "npx projen docgen", "eject": "npx projen eject", "eslint": "npx projen eslint", - "integ:secret-asset:assert": "npx projen integ:secret-asset:assert", - "integ:secret-asset:deploy": "npx projen integ:secret-asset:deploy", - "integ:secret-asset:destroy": "npx projen integ:secret-asset:destroy", - "integ:secret-asset:snapshot": "npx projen integ:secret-asset:snapshot", - "integ:secret-asset:watch": "npx projen integ:secret-asset:watch", - "integ:secret-inline:assert": "npx projen integ:secret-inline:assert", - "integ:secret-inline:deploy": "npx projen integ:secret-inline:deploy", - "integ:secret-inline:destroy": "npx projen integ:secret-inline:destroy", - "integ:secret-inline:snapshot": "npx projen integ:secret-inline:snapshot", - "integ:secret-inline:watch": "npx projen integ:secret-inline:watch", - "integ:secret-manual:assert": "npx projen integ:secret-manual:assert", - "integ:secret-manual:deploy": "npx projen integ:secret-manual:deploy", - "integ:secret-manual:destroy": "npx projen integ:secret-manual:destroy", - "integ:secret-manual:snapshot": "npx projen integ:secret-manual:snapshot", - "integ:secret-manual:watch": "npx projen integ:secret-manual:watch", - "integ:secret-multikms:assert": "npx projen integ:secret-multikms:assert", - "integ:secret-multikms:deploy": "npx projen integ:secret-multikms:deploy", - "integ:secret-multikms:destroy": "npx projen integ:secret-multikms:destroy", - "integ:secret-multikms:snapshot": "npx projen integ:secret-multikms:snapshot", - "integ:secret-multikms:watch": "npx projen integ:secret-multikms:watch", + "integ:PARAMETER_MULTI:assert": "npx projen integ:PARAMETER_MULTI:assert", + "integ:PARAMETER_MULTI:deploy": "npx projen integ:PARAMETER_MULTI:deploy", + "integ:PARAMETER_MULTI:destroy": "npx projen integ:PARAMETER_MULTI:destroy", + "integ:PARAMETER_MULTI:snapshot": "npx projen integ:PARAMETER_MULTI:snapshot", + "integ:PARAMETER_MULTI:watch": "npx projen integ:PARAMETER_MULTI:watch", + "integ:PARAMETER:assert": "npx projen integ:PARAMETER:assert", + "integ:PARAMETER:deploy": "npx projen integ:PARAMETER:deploy", + "integ:PARAMETER:destroy": "npx projen integ:PARAMETER:destroy", + "integ:PARAMETER:snapshot": "npx projen integ:PARAMETER:snapshot", + "integ:PARAMETER:watch": "npx projen integ:PARAMETER:watch", + "integ:SECRET:assert": "npx projen integ:SECRET:assert", + "integ:SECRET:deploy": "npx projen integ:SECRET:deploy", + "integ:SECRET:destroy": "npx projen integ:SECRET:destroy", + "integ:SECRET:snapshot": "npx projen integ:SECRET:snapshot", + "integ:SECRET:watch": "npx projen integ:SECRET:watch", "integ:snapshot-all": "npx projen integ:snapshot-all", "package": "npx projen package", "package-all": "npx projen package-all", @@ -59,8 +54,8 @@ "organization": false }, "devDependencies": { - "@types/jest": "^27", - "@types/node": "^16 <= 16.18.78", + "@types/jest": "^27.5.2", + "@types/node": "^16.18.78", "@typescript-eslint/eslint-plugin": "^8", "@typescript-eslint/parser": "^8", "aws-cdk": "^2", @@ -72,7 +67,7 @@ "eslint-import-resolver-typescript": "^2.7.1", "eslint-plugin-import": "^2.31.0", "eslint-plugin-prettier": "^4.2.1", - "jest": "^27", + "jest": "^27.5.1", "jest-junit": "^16", "jsii": "~5.6.0", "jsii-diff": "^1.106.0", @@ -82,7 +77,7 @@ "json-schema-to-typescript": "^15.0.4", "prettier": "^2.8.8", "projen": "^0.91.7", - "ts-jest": "^27", + "ts-jest": "^27.1.5", "ts-node": "^10.9.2", "typescript": "^4.9.5" }, diff --git a/src/MultiStringParameter.ts b/src/MultiStringParameter.ts index f944c970..31ba1c87 100644 --- a/src/MultiStringParameter.ts +++ b/src/MultiStringParameter.ts @@ -14,13 +14,13 @@ interface JSONObject { export interface MultiStringParameterProps extends SopsCommonParameterProps { /** * The seperator used to seperate keys - * + * * @default - '/' */ readonly keySeparator?: string; /** * The prefix used for all parameters - * + * * @default - '/' */ readonly keyPrefix?: string; @@ -76,11 +76,40 @@ export class MultiStringParameter extends Construct { const keys = this.parseFile(props.sopsFilePath!, this.keySeparator) .filter((key) => !key.startsWith('sops')) - .map((value) => `${this.keyPrefix}${value}`); + .map((value) => { + // Ass we flatten array to [number] path notations, we have to fix this for parameter store + let fixedKey = value.replace('[', this.keySeparator); + fixedKey = fixedKey.replace(']', this.keySeparator); + if (fixedKey.endsWith(this.keySeparator)) { + fixedKey = fixedKey.slice(0, -1); + } + fixedKey = fixedKey.replace( + this.keySeparator + this.keySeparator, + this.keySeparator, + ); + + // The secret name can contain ASCII letters, numbers, and the following characters: /_+=.@- + const allowedChars = '/_+=.@-'; + for (let i = 0; i < fixedKey.length; i++) { + const char = fixedKey[i]; + if ( + !( + (char >= 'a' && char <= 'z') || + (char >= 'A' && char <= 'Z') || + (char >= '0' && char <= '9') || + allowedChars.includes(char) + ) + ) { + fixedKey = fixedKey.slice(0, i) + '_' + fixedKey.slice(i + 1); + } + } + return `${this.keyPrefix}${fixedKey}`; + }); keys.forEach((key) => { new StringParameter(this, 'Resource' + key, { parameterName: key, + description: props.description, tier: ParameterTier.STANDARD, stringValue: ' ', }); diff --git a/src/SopsSecret.ts b/src/SopsSecret.ts index e09723a0..a5d7b7cd 100644 --- a/src/SopsSecret.ts +++ b/src/SopsSecret.ts @@ -8,6 +8,7 @@ import { IKey } from 'aws-cdk-lib/aws-kms'; import { ISecret, ISecretAttachmentTarget, + ReplicaRegion, RotationSchedule, RotationScheduleOptions, Secret, @@ -25,12 +26,43 @@ import { ResourceType, SopsSync, SopsSyncOptions } from './SopsSync'; /** * The configuration options of the SopsSecret */ -export interface SopsSecretProps extends SecretProps, SopsSyncOptions { +export interface SopsSecretProps extends SopsSyncOptions { /** * Should the secret parsed and transformed to json? * @default - true */ readonly rawOutput?: boolean; + /** + * An optional, human-friendly description of the secret. + * + * @default - No description. + */ + readonly description?: string; + /** + * The customer-managed encryption key to use for encrypting the secret value. + * + * @default - A default KMS key for the account and region is used. + */ + readonly encryptionKey?: IKey; + /** + * A name for the secret. Note that deleting secrets from SecretsManager does not happen immediately, but after a 7 to + * 30 days blackout period. During that period, it is not possible to create another secret that shares the same name. + * + * @default - A name is generated by CloudFormation. + */ + readonly secretName?: string; + /** + * Policy to apply when the secret is removed from this stack. + * + * @default - Not set. + */ + readonly removalPolicy?: RemovalPolicy; + /** + * A list of regions where to replicate this secret. + * + * @default - Secret is not replicated + */ + readonly replicaRegions?: ReplicaRegion[]; } /** @@ -49,7 +81,7 @@ export class SopsSecret extends Construct implements ISecret { readonly sync: SopsSync; public constructor(scope: Construct, id: string, props: SopsSecretProps) { super(scope, id); - this.secret = new Secret(this, 'Resource', props as SecretProps); + this.secret = new Secret(this, 'Resource', props satisfies SecretProps); // Fullfill secret Interface this.encryptionKey = this.secret.encryptionKey; @@ -63,7 +95,10 @@ export class SopsSecret extends Construct implements ISecret { this.sync = new SopsSync(this, 'SopsSync', { target: this.secret.secretArn, - resourceType: props.rawOutput === true? ResourceType.SECRET_BINARY : ResourceType.SECRET, + resourceType: + props.rawOutput === true + ? ResourceType.SECRET_BINARY + : ResourceType.SECRET, flattenSeparator: '.', secret: this.secret, ...(props as SopsSyncOptions), diff --git a/src/SopsStringParameter.ts b/src/SopsStringParameter.ts index db5648cf..704877b1 100644 --- a/src/SopsStringParameter.ts +++ b/src/SopsStringParameter.ts @@ -25,10 +25,15 @@ export interface SopsCommonParameterProps extends SopsSyncOptions { * @default none */ readonly description?: string; + /** + * The customer-managed encryption key to use for encrypting the secret value. + * + * @default - A default KMS key for the account and region is used. + */ readonly encryptionKey: IKey; } -export interface SopsStringParameterProps extends SopsCommonParameterProps{ +export interface SopsStringParameterProps extends SopsCommonParameterProps { /** * The name of the parameter. * @@ -72,7 +77,7 @@ export class SopsStringParameter extends Construct implements IStringParameter { tier: props.tier, stringValue: ' ', }); - + this.parameterArn = this.parameter.parameterArn; this.parameterName = this.parameter.parameterName; this.parameterType = this.parameter.parameterType; @@ -82,7 +87,7 @@ export class SopsStringParameter extends Construct implements IStringParameter { encryptionKey: this.parameter.encryptionKey, target: this.parameter.parameterName, resourceType: ResourceType.PARAMETER, - parameterNames: [this.parameter.parameterName], + parameterNames: [props.parameterName ?? this.parameter.parameterName], ...(props as SopsSyncOptions), }); } diff --git a/src/SopsSync.ts b/src/SopsSync.ts index b9dd1f4b..62ddbc14 100644 --- a/src/SopsSync.ts +++ b/src/SopsSync.ts @@ -98,13 +98,6 @@ export interface SopsSyncOptions { */ readonly sopsAgeKey?: SecretValue; - /** - * If the structure should be flattened use the provided separator between keys. - * - * @default - undefined - */ - readonly flattenSeparator?: string; - /** * Should this construct automatically create IAM permissions? * @@ -117,13 +110,20 @@ export interface SopsSyncOptions { * The configuration options extended by the target Secret / Parameter */ export interface SopsSyncProps extends SopsSyncOptions { - /** + /** * The target to populate with the sops file content. * - for secret, it's the name or arn of the secret * - for parameter, it's the name of the parameter * - for parameter multi, it's the prefix of the parameters */ - readonly target: string + readonly target: string; + + /** + * If the structure should be flattened use the provided separator between keys. + * + * @default - undefined + */ + readonly flattenSeparator?: string; /** * The encryption key used for encrypting the ssm parameter if `parameterName` is set. @@ -135,7 +135,7 @@ export interface SopsSyncProps extends SopsSyncOptions { */ readonly resourceType: ResourceType; - readonly secret?: ISecret, + readonly secret?: ISecret; readonly parameterNames?: string[]; } @@ -267,7 +267,9 @@ export class SopsSync extends Construct { break; } default: { - Annotations.of(this).addError("Failed to determine sops file format. Please specify 'sopsFileFormat'!"); + Annotations.of(this).addError( + "Failed to determine sops file format. Please specify 'sopsFileFormat'!", + ); } } } diff --git a/test-secrets/README.md b/test-secrets/README.md index 4745d778..029b9b99 100644 --- a/test-secrets/README.md +++ b/test-secrets/README.md @@ -7,4 +7,4 @@ The following keys were used: ```yaml public: age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu private: AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3 -``` \ No newline at end of file +``` diff --git a/test-secrets/README.sops.binary b/test-secrets/README.sops.binary new file mode 100644 index 00000000..ce5d437b --- /dev/null +++ b/test-secrets/README.sops.binary @@ -0,0 +1,20 @@ +{ + "data": "ENC[AES256_GCM,data:M9gzDsRd9oCruM1DhYiUA4YCAGvSuAWORbpXepreT3NxIfD8Y63pz00LHh/t9Y+WrTBApJuOOD3UYhU1Jrvu638HedrB1A5sq1tOuAVsYz9+KUaOjaoyeyMhvwrNzvlzaH6J06S2qb2q/G1pUHWVPkoEOUhiGNyXTbQch4nHUBbUZpUSkmqwtvzkIYOx0FbxRhf0FwZXay4S+XOMcDuKbfQx8hA1gXXdgZal2nleujE4kXWah7gB/q0AcfjIjhytPaeieElPXrNcJdyIRKllOWtpmowDxaRmqU4iqUYg5k/OybtKwPvbg2mjYxLwJZr57xjzEX2tFJi9kuoxl4HP04qVERPbaPuy3q61Zb9+FwtW85ebnViOAITp//R78KkmrQVzGx6VKY+2JxbPGsQ6HfeSm7WWWGCXteuTDYAgpoEKlZHMd/6hY07D92tlna8vadBPOcLAl7+cxVfCJaZ7Ob63jFgzPo6/LOTzYjqDKvLIEKdFGj08PwiED3vUiX4hO4oi2MUkfNuI1jyjP9Aqwj/H2QwvqpbtGDjD2+CdyOdw5pBEQQ==,iv:ntwa7TSFVDDAhd79X5GLD2B61FM19QajO2BKROjF7sk=,tag:4NfwoTRNzKK1UP2GxaQRXw==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBXNUEyT09PR3pZYmN1ZU9S\neURCWUdZYnhmMzBiSm1FcENYNGliNGtNZzFRCk52TVZCSDRBOWk5TTB2dGRGTFgz\nMklsZUV0ZForUkxaM0ZiSTRIcW5id3MKLS0tIHdFMHFMMUdEYllUaGRRSEl6UGZw\ndFF2ODBPZGRrTnBGbWJvdVZvdWVGUW8Km5PYXRuTBvjmMDYmg6NEKhIbUU/SHPSZ\nTtgwos8id+MYTpudG+aKVTKSx91Gnx9ekLcTkafEw/YULU9crybYtg==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-02-07T14:50:25Z", + "mac": "ENC[AES256_GCM,data:NjLPZL5bdkc+ebNrpT9sjsOZjUE/Z1t/Oq1q4CEs731jgbW0lolLZ3Dr7EFVNLoC5eunhQxvn7E6ZA1bpmqpijtMNSkqqVQdG1JszF7YGhF9Yj+Tyz9RHhvNFuH8AFcl4f1ksD7GmnV7dYsj1r1YP3wwFY+UhEqlq4+Kd87Vna0=,iv:8IMB37V4kxLHrNiIV0cVZtB2VCfuq8SYANsyDyl3m1o=,tag:EGBXVOIayzn2lh5Zi5+Gxg==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.9.4" + } +} \ No newline at end of file diff --git a/test-secrets/_testsecret.env b/test-secrets/_testsecret.env new file mode 100644 index 00000000..703d0ea0 --- /dev/null +++ b/test-secrets/_testsecret.env @@ -0,0 +1,17 @@ +apiKey=sk-1234567890abcdef +database:host=db.example.com +database:password=P@ssw0rd! +database:user=admin +someOtherKey=base64:aGFsbG8gd2VsdAo= +specific:boolean=True +specific:SpecialCharacters="ajkscbuiuXA34%%&&= +specific:HTLMEncodingTest3=@ +specific:HTMLEncodingTest1=test +specific:HTMLEncodingTest2=& +specific:null= +specific:number1=123 +specific:number2=123.456 +tokens:0:service=service1 +tokens:0:token=token1 +tokens:1:service=service2 +tokens:1:token=token2 diff --git a/test-secrets/_testsecret.json b/test-secrets/_testsecret.json new file mode 100644 index 00000000..89659261 --- /dev/null +++ b/test-secrets/_testsecret.json @@ -0,0 +1,29 @@ +{ + "apiKey": "sk-1234567890abcdef", + "database": { + "user": "admin", + "password": "P@ssw0rd!", + "host": "db.example.com" + }, + "tokens": [ + { + "service": "service1", + "token": "token1" + }, + { + "service": "service2", + "token": "token2" + } + ], + "someOtherKey": "base64:aGFsbG8gd2VsdAo=", + "specific": { + "SpecialCharacters": "\"ajkscbuiuXA34%%&&=", + "HTMLEncodingTest1": "test ", + "HTMLEncodingTest2": "&", + "HTLMEncodingTest3": "@", + "null": null, + "boolean": true, + "number1": 123, + "number2": 123.456 + } +} \ No newline at end of file diff --git a/test-secrets/_testsecret.yaml b/test-secrets/_testsecret.yaml new file mode 100644 index 00000000..71cc8a85 --- /dev/null +++ b/test-secrets/_testsecret.yaml @@ -0,0 +1,21 @@ +--- +apiKey: sk-1234567890abcdef +database: + user: admin + password: P@ssw0rd! + host: db.example.com +tokens: +- service: service1 + token: token1 +- service: service2 + token: token2 +someOtherKey: base64:aGFsbG8gd2VsdAo= +specific: + SpecialCharacters: '"ajkscbuiuXA34%%&&=' + HTMLEncodingTest1: test + HTMLEncodingTest2: "&" + HTLMEncodingTest3: "@" + 'null': + boolean: true + number1: 123 + number2: 123.456 diff --git a/test-secrets/binary/sopsfile.binary b/test-secrets/binary/sopsfile.binary deleted file mode 100644 index 73e6592d..00000000 --- a/test-secrets/binary/sopsfile.binary +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQDVd/OAdqlMznWINBDoyR+PESgQJlUptwnh/vzbgAaIuHl4gN7Q -W2Jx06bKFgv8yAQ4ouR0EaPv43X1pWFUyE/vK4e2A4M28Ciriy5r2TiBx57EL7bA -AiiCaEvpKx3uAtTgFYcdLdD5xYKUf51gymZ6wU8BBgYMkVlL5rpGmR7ddQIDAQAB -AoGAaeEXG+6/RmNZFHeOs4eeaZ2+21PIBerNshSBYnX7x7CIP2bcHUhWadLq9W0+ -AOFMhrL00UU2pPOTPIYM4rqAOl5PvPeV4GNMvI+9/619p/ZNMbnvj43KqUtaPp1g -JyT22CH4TqDC2io8S9xWxxh9AgvgOI/ekJ3h4PdYpmyVUXkCQQD6b1dkYhlgiy3u -Z84L5WM+7vXG2ivA3N3T5eYJdsQFvlV6gNSqbKcxIR+cFK0RaRiWrd7U2IOM67RF -YRvHNN0rAkEA2jZRXVjHjTZSuAVDMOA4cc6pgxOqByg14clWgRDtbueIMHNCYLJY -bi5YE0kqzjSaH2WbeT7LX1q3S7amoN4f3wJBALw9ZrYYmrSbyRmTQyhj8raCTZF7 -ujmMitzUyJVChVM/3uZm4fN8GivuluDuFaypj4brCDx6xl7taKJhvMx+quMCQF/C -ZoJoa2n05OgMpyfTvfFzl8AF6R+q7bpf+K47F3cL9CAO9JoqqdPwUoZkHXzQaLJO -jKPwgp8d2EJJrWX7FFECQQCRMPE4WsTCLXmVefZne7k000WPclZ4pIjggz1lpGgN -23bwNOla1k4/B10btnEzNi16/b01Kf3K4hYaicd46sLH ------END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/test-secrets/binary/sopsfile.enc-age.binary b/test-secrets/binary/sopsfile.enc-age.binary deleted file mode 100644 index f1805d71..00000000 --- a/test-secrets/binary/sopsfile.enc-age.binary +++ /dev/null @@ -1,20 +0,0 @@ -{ - "data": "ENC[AES256_GCM,data:1szZY1Vg1DsmbynG4Dw9qvHVuzXh6vWngLoUMEnR87VFB7/Nu/SfnD2s0n/KvhQuz7bZie1wvtJoFZD6hgjdA/kzMOOJTSWH40drn/Cx6mmFSDlVCD3f3K3jn6Xg8uZGQaW/X9jmYkTTyRGQhrLuhLEmgHeM+BK3gF12zMSDyjij9BkGh+GgXo07Md2Z7F84UO6PQdEebc8YteIVk1zN/IQVFTNUa9tu9TDNSL6xfMWjBF1hmKQuH0OS/6B/RohBExPjxxIT5yA0LjVG1kijCdwcfDfuWMA/wv0jrdWGABBipju5VDXU8lepc5w+WIHq59yNDqMYXkb2s7YgHY9Uwt+nUEqn68pXA4IqXL4pdnnZjyEGCqnG0ltt+7bcjNORIwPTMRxl6bXCXRNSFtANUxVvBvyV3rvFee4G6SZMfG2QThraIKdx3p1C+ZnmJCwldFooCVXCW33n2jTiTcNlgEQfoGAyKL95ZOlct+pedAjFkGuDlpn9DGvbBQgGbLx7IdCX/RvCuYATLaUjf118/W2djStJOio2qr6ql06J6nZamDIBoxdQ2NHNHWTJsKMDF8Ya0mzUlfdTzJtn/ZQFtY5R+u10iCPiZOF9dY3jSBy8Oa6XHicKnpl6iXfw2SwGMJ0MXvS+TPfjsgLIFboDHD/1aFbaceMS57D83z8FHqU03xnb3HWs6J2G00Oj0Ow6AA7+/oo9hEdDC4pGQSjXLwbZilwoKRjamaJ35EMOkywiMeIvtQggyaf0g37lS4Hlflrop3vlvh5pInY2qb4fROHmE76nhIQ4Ek1AXPOLPkd3Wu6bIqGm+WsNYtsTn4c5btuLYFP+XXHkhrE5Z9oRX2U+go4tdlGy4nCTsUVhOIFDJPJQndjppSwBGUXDyf4qJSzSfYVHXboBD6glV+2iEBvq5Ewfr7s9vOgAu8U/mJ1eYEVauigDxcup/t85EpXPeFZIIn/g1aPXHtvujW/B7HuaAWcAmSb+t/YZ7MHEcJnQgHRNstIdiVuJWVoielvR6+7/SZzcmkTahTu+3g99R4pLEeNB4poj3kv+/A/TihnUWhyLuGpKRAAgscMqxBo/wgD4f7mcG8OAfQcGVKerc5pwDhTEbcjlXPcuMTJ8pbBJFebxIl2eL8LbcbcG/Fu1WstdA93leQ2NwPmX3SSNclwTf7yR/A==,iv:QLfsbEB7wLwwXT2+1Tf92L/abYF6ewC2658e0CxlRvE=,tag:Z4BdO/nT8HukvgTHi8sLFg==,type:str]", - "sops": { - "kms": null, - "gcp_kms": null, - "azure_kv": null, - "hc_vault": null, - "age": [ - { - "recipient": "age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu", - "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBONWJSL2xVOFVablVpbFBr\nZ3cxVzVEZ2ZxVTRzWU1NVjdua1hEczBhNmdRCmFEYS9YS1AweWVDVXFRRTV2c01T\nZVBoa3ZRelJXOUNCVk9VNGtLWnlrRG8KLS0tIFdtT0tjMjA4Y2NkMVpyOFdKY2Nm\nbld4RjRraDlrYkJHRm9PRjUxVm0wUk0KLWT517HtucD/VDU08s4zNqQ8rVhmQaaQ\nLfgVbIjVFsQb0MUdIMHQovJ4OLIXaKSo+PMHswU/uxMvaEjD+ulTyA==\n-----END AGE ENCRYPTED FILE-----\n" - } - ], - "lastmodified": "2024-05-31T18:07:09Z", - "mac": "ENC[AES256_GCM,data:qmwxSfIs+OlIxq7LlG2vZPLelEtXylOLuLBBJoZn6ZGaV9I75umIb+vHYcbmtYUHZRMiEAvv1kMLprVR66burD/pxa4oNjXuVhSXR1nxpb7bhimgqKmw5mN2Kk4Dx7cq4lqIfLfEZhPqRKgPOdCBpEMYbqGNsOOMXqDRRyroeC0=,iv:Fsmb0IGbjCYc3tKIEF17rcPZfe5QeyJ+ZMpYjiSofyI=,tag:TMfwecLKdL1MDisnQioB2Q==,type:str]", - "pgp": null, - "unencrypted_suffix": "_unencrypted", - "version": "3.8.1" - } -} \ No newline at end of file diff --git a/test-secrets/dotenv/best-secret.env b/test-secrets/dotenv/best-secret.env deleted file mode 100644 index c2619162..00000000 --- a/test-secrets/dotenv/best-secret.env +++ /dev/null @@ -1,2 +0,0 @@ -banane=yellow -crypt="ajkscbuiuXA34%%&&= \ No newline at end of file diff --git a/test-secrets/dotenv/encrypted-best-secret.env b/test-secrets/dotenv/encrypted-best-secret.env deleted file mode 100644 index 9e9ba6a6..00000000 --- a/test-secrets/dotenv/encrypted-best-secret.env +++ /dev/null @@ -1,8 +0,0 @@ -banane=ENC[AES256_GCM,data:KfCbo7Z8,iv:ewDKVZH7/fL4wRksCySb4M9HIhZ4+w43mXgmYUtKzU8=,tag:KuoFFUA47LJLWpDJJwb7cA==,type:str] -crypt=ENC[AES256_GCM,data:2BpWV4wG7Go59fyxTmQaqKnIug==,iv:IfEHwS+Re2G8IHcOuyomvWfgb0G6X6slRSNoNclDNj4=,tag:541QTPLUJcunvp8LZIv+xQ==,type:str] -sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAwVEJBcXBqMEt6L3lQTFZM\nYUplSGRPRDVsL2Y0NFBNYWF5cmZLcXphcjFFCmFyUTUvRjRRRVhsOVdmd09nbkZr\ndG5wTjdCYlZxTnlMQWNFd3FaT3FtK00KLS0tIEIyS2pjYTlSSDN5R0FrejZMdUZk\nMlpmRDVjZk1SZUVGR0NDdnVhWjhvVTgKsB2MvVrUiJU2qvN8x8kUhZdvKP1Rqqfd\nuHvaXnVZ0puLCyW6bJPPH408N+nsmzcZIS9XPw9aRptQvUV53O5NVw==\n-----END AGE ENCRYPTED FILE-----\n -sops_age__list_0__map_recipient=age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu -sops_lastmodified=2024-04-29T11:58:27Z -sops_mac=ENC[AES256_GCM,data:WEYgLvSAiZpbgTq67oawPYie3vujHViYFR51q1KNYCvptZ9XVm6wUCfuVenD79MgSSySTEFxV7BXcbqMIKTP+aG7K5PKeHuuA91uEPwKuv/X2ErcQ0ttHVd+RDDlov97w8NOKWrgqNhWlQ8PM4uCoyspt0DRTLDFmEdLy9/LJnY=,iv:UDIQJDWn0mggYZStz9x0zJ9OJQQ7GLq0eur8M4K1u0o=,tag:kpYoKN9AuX+I6XpRQfWODQ==,type:str] -sops_unencrypted_suffix=_unencrypted -sops_version=3.8.1 diff --git a/test-secrets/json/complex.sops.binary b/test-secrets/json/complex.sops.binary new file mode 100644 index 00000000..7bf22bf8 --- /dev/null +++ b/test-secrets/json/complex.sops.binary @@ -0,0 +1,20 @@ +{ + "data": "ENC[AES256_GCM,data:zomC/advyRjbi+7BhnHjYGPiRKGgpsY2GbBVUi/7A4EKYOXOf4870xhRkxAHBUA+CllzjfLsVc3GbYPsdJ1VzymbQL5dCNOMMbn/KgMIq1eSYpnYWZ3kOMPpVJZi9HVMEOVa4rRQbmjqnY640XEvv1mjN0/8AmJdp1vPABLmCiLCka++sIrkdFzFOwI3GlKa7mfrn137Q5VaDb3RnOzfT9lvC2ymuvFVu/Wpk6WANpID0PwGa8AZD5EHBqTYG2LbFY3CDkKMgRRurrRsRr8dih4KyF4CckyE1mo2WoxpaN9JFAS985IEYvVZZbzxSfVxved2K4qLp5xCBlE8mp3rvkDIdtGywQlm56B8Vra7sXije4/RuS8yhxW3HG3K0mZ1rvxKdZigZaWM/1De6H842QmkuIHABkbi8G60HtIiGkTCoqeS0MrqmoFS+c5+Fb3wA/cfTgstcFWbYVafhZUOkO8KfoEbWFnvCnKhCBsJWq0bve2rGKMSCFcXX5I1DDJ/XC7WQBc5PcsImKnuByu+4pgrMimz1Ah50SJM3eM/GYpcJvvhfZyEf5ustnzKvVSK04RKIXIX+G2hFawgj8gm2uw079vF2WkWslrJepA7xh338D5f0DMurvTkujiLq9DtkrW4FrxB1dsplpcl7CHyUdXPK7/Ii1V9BTvpdvLqPR7by75s64xClJt5GijkWBWUJitxrwG+Szufnv3Bbj++MRUrhEiSvGoR052bpmk=,iv:ei7B9c6t9hLtnDYJWnkRl1Wf7SWDUPlKkisDjYORZds=,tag:sMBkA3dZ8hMZWA6dF7EOyQ==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBFMVBqMWNaanp1MktqRXBE\nYlVWWWxjUW1NZS9oVmMwMDdnWko5UzRjMGlJCjJaS0FWVDQvS2RoMHBHMEV3VG1M\nTml0dVhlUGdENzk2bzFTS05CSE5OYXcKLS0tIDRLRHBHYTQ3aXROV3VwMis3UVlZ\nZnNZQkZqWENjaGRwcWJ6SDB2VmJOcHMKlqxMDLaL4vdsmpKZct986r5CqlnwROXB\neYzxlSDP/48hTej56BzCsVYOHHOcFBud255HaVINXu9mHjsov0XYGA==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-02-07T14:07:37Z", + "mac": "ENC[AES256_GCM,data:dJGBOZbUlZ1TCq2ZCzl7Giwwkjvh9nCaqkj4ZfSSxbsstOg1cUPUhwYzyxBLwj0tl/tmPjMiyz0MlY8ZtL/CFfjktWJbzZL3AGGU+Eq2WRt0sH6skpymy07w381HiWJfzz10GC0+yRXCQWWSmdQ3bNlyGIrXIT9eAtU83VnvTmE=,iv:tIe0mulg3snFbpfW7Qk1W7tSkM3tOIFv5OQwK3wVLz4=,tag:pRkSBsjR/1WZ5QLKITd2Mg==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.9.4" + } +} \ No newline at end of file diff --git a/test-secrets/json/complex.sops.json b/test-secrets/json/complex.sops.json new file mode 100644 index 00000000..39deadfa --- /dev/null +++ b/test-secrets/json/complex.sops.json @@ -0,0 +1,20 @@ +{ + "data": "ENC[AES256_GCM,data:9PHZv0Okb/u2GbUKLtimcD+e/j+QbV8f5F7GBaE7BYmFX0Ft1p58b83AyBALjcKmldUQTQVLvkVEROHyZvQXM5HMEgGMJqu2aaCJgvaUVd7d0c8L4WppylxvzfPLzZFtE+m+H07Ab6FgmL/EtEmzLaNJX+d31gyfCNXO7svY8VnctDMMHWflXNGMmQbo5UPTsKasx9U5xmQJRFEPJXWJPXBWtpYXRiMYn0t5ZTrrPJf9I2suKzCFx0I+t2yga4iJEdTPiW8Xcdu2P8VTY3YboEBgvMMqj9W2ZlWYy0uPt9ACcmec1EhNB1IfB6lQM+siLlGZyrI/4gBtmX+Z5fIMYYBcm2oj2VSdSFErAHtmbQVJ3vYKVuT/ztGHx42SNExpeS5pIHYlKkCFsbvHo222r1d4FelbxLOcIaXs9a0bdIco4s5tYDy92vRTjYp6MjozzWixpou/bZzY3kwHVTSFXv7MxD/o+vN/W+Cgw/XnYY/VdLjyWmdYWOc+zKncZC0NuCxSWOGmS3C/nH1w3lnm8HQ4trksrm0/XFzyqbsDLfGaxz1LQJiEnTC3QS8plcWit2SZYIWH9azc/PGa4095/gCUcvGDfCqoswNAuKPyFDEPHqQPkh4x3qLQY6xHLC9IO2kWWyxsFWM5EGXMTxeKFW3q5N+3xbr5KuK3yyoFf9Rk/2wd2qDEhWPx0RwuGxXv+rjadwIkZxWAVLY8iKHAiKqrCTDt67cO/T/eTm8=,iv:CQtbsFV0L+VkrsG2HyYDqMyXZiaAPDLCyYYJjUMw2mY=,tag:GfZwBt/vJim2jZX9WYEdNA==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAvcDcrc0pFbXJkbHk0K00x\nNkRMcmlQQVlVRGlDTEoyeVFwMWdUSHU5cTM0CmxhWGdGVDZndzlxYzNlS0xuSElv\nOU9JM1I2WERIY3hmcTdFTzRoSTgreEEKLS0tIGJJUkdMeUluMGJ5Z3dUM3lrakJh\nMVd4UENwQ1dvNFdkeWVFL05uU3I2cGcKuM1BUeQilKGIVstjC6wU368ovRx9upJr\nTga8aeE62fxDrp4gRRHqAw6KhT5OOnDdaZs5Ze5pFxkeO90csLj55Q==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-02-07T14:07:08Z", + "mac": "ENC[AES256_GCM,data:8ztXnA+XO8v74aLFeeCOn2VBIeXvk4vMiASOPftwQgZFTaesVvQRszAPNpVrdr0JmMiTHNfyMOeJd4pEOSClzcynYLkEurxJIAXIWgFaGg2pZS9yO0Ybg/gJLsApV+s4FPtFSLSJjd42QlNwCUex6noUIR/kSchXOMs9qbyxdrc=,iv:5L71jZk+jVrK8vNCCKESj4mBavZ0RCTqio445TKkr8I=,tag:PVBvVFXtgt0SetwjxUy2fw==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.9.4" + } +} \ No newline at end of file diff --git a/test-secrets/testsecret.notsupported b/test-secrets/testsecret.notsupported new file mode 100644 index 00000000..e69de29b diff --git a/test-secrets/testsecret.sops.env b/test-secrets/testsecret.sops.env new file mode 100644 index 00000000..d9a2d1ff --- /dev/null +++ b/test-secrets/testsecret.sops.env @@ -0,0 +1,23 @@ +apiKey=ENC[AES256_GCM,data:yMjVmvg8ngplsw6A2Ed/L9xrFg==,iv:CqIREmvd4vtMmXR0sKFW4BzZVa9g0rTj558RfwBAyp8=,tag:uDdkA/HTENFIaFzqlHUTdw==,type:str] +database:host=ENC[AES256_GCM,data:NQGBJcEmb3Mk96XLPKs=,iv:lhkq8kcH/axV+wR8d/qcXD0isSn+BAFT+j4gD1kCqVc=,tag:WK9Cd9xQo20C726TYNBwbw==,type:str] +database:password=ENC[AES256_GCM,data:o6Cw6lRCKwW3,iv:ab1xLcrf9XWrjXAddW/vFhzOQHqbOyRiMT1WDZ2E94U=,tag:xay4qqpXVFG5SAXswtKuWg==,type:str] +database:user=ENC[AES256_GCM,data:YakZvFU=,iv:/UkM6EE2v9miMngg5hrFW+TNC6O9SHgJvpEpbBS4iZk=,tag:cQ7BgN/rlfppBaI2eXNB4A==,type:str] +someOtherKey=ENC[AES256_GCM,data:jbrUQ2ZN3G+2ms1ktUbB4n4GKMhzs1Q=,iv:nxBr7hYaKWIQ+w2R9ydqRgE8WY3wWJYHRLEML4oXvCE=,tag:h8xX0ENw30JvPUBVbn3RcA==,type:str] +specific:boolean=ENC[AES256_GCM,data:6hJZpA==,iv:Jn7vcGhG/KHuIvnWtLm4KutBcXOMGGa03VexDEfoELw=,tag:yVYbrdDc8lZQcr5M90hLpA==,type:str] +specific:SpecialCharacters=ENC[AES256_GCM,data:iVnV8R4wUo4Hmj+hNBgVhqsK/Q==,iv:2qnJFP07q+bidV6QHva8xg/6Kut01vySqoUbrJiVdd4=,tag:ODPHGLs3yU9BKAXjvH8aaQ==,type:str] +specific:HTLMEncodingTest3=ENC[AES256_GCM,data:Og==,iv:OsijRbaUtX2fNNzsI02Bm81Bx9ZpMCLl9oEYfEgoygM=,tag:W5yrTTCt8xpEyDWpmCrSbg==,type:str] +specific:HTMLEncodingTest1=ENC[AES256_GCM,data:Gtc5yOSZrpRQZRWpbFP9QCk52Dpq,iv:zs/FMO5S92w/DOmT/RhEuWQ4WXDtHYWmglyp8bmW6SQ=,tag:4nQCdkMJLnRK5RAWTmbNVA==,type:str] +specific:HTMLEncodingTest2=ENC[AES256_GCM,data:Kg==,iv:RQRy8LWFvoKd4UaWSIKL/5js6I8Wvi+r+T7uF/ox+rA=,tag:TKMdUm/83MkBnP9VtPAHWg==,type:str] +specific:null= +specific:number1=ENC[AES256_GCM,data:236O,iv:/X1jDyMOvcqfve673BjCP5r1zjj0h1KtVjMD+4rbIZI=,tag:rWBT0Rs5hhlKBTyvNwBqiw==,type:str] +specific:number2=ENC[AES256_GCM,data:iIqKlmwRCA==,iv:usF+X0flWIg9Ki7O18K01x8m/WT/kQd/aVWBSdXabww=,tag:BPHFXTeq7qru6OWG3DfUsQ==,type:str] +tokens:0:service=ENC[AES256_GCM,data:MlgbuTr1d4s=,iv:e/YjEvEtEhMQdu4obTW3BzkStSk843krefETISmxxVw=,tag:cg4E2clFJ5GWUc+iFm78Tw==,type:str] +tokens:0:token=ENC[AES256_GCM,data:Kde9qHN8,iv:HWGei+RhxWfEY+YgKT75QfwWh1piE1UJ8q4lVc4Gu7M=,tag:DLYPwmYlhRlJK6COxd9waw==,type:str] +tokens:1:service=ENC[AES256_GCM,data:d0AWlJz+nt4=,iv:BQzKHbBDTlR+8z1LTkhBLLo/7vAcOjLTfB/9qR7MdGg=,tag:s2NeOPlR1IwZiUnCs4E1eg==,type:str] +tokens:1:token=ENC[AES256_GCM,data:G4vIDVtl,iv:ihV/tjPSwSazsc/Df+dXpnepwSkP6n1KccDG8GKWRMg=,tag:RDl9c3P9kok1zWWUbifEcA==,type:str] +sops_age__list_0__map_enc=-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRcTUrRWtwSHdPOTNGVXVp\nemJQWlY4aXg0ZEVSSGxsUzl4MW9ydlVYR2lBCkFDdkl4bjVVYWpja3FObC9nVFVK\nMks5ck5mSXI4QUk5R1R0c2JCVC9ZK0EKLS0tIERNODdLaWJmZ1R3NFZET3F1YVMy\nRitBcEVhNGt6UUNlc2szZUJjd1RTT1kKAYk+D7gqF+prdNAF7OdOHima/A92Njpw\nqh57Rk5C7NXvVeeJk0xKdS2zFm86IIST/KgSw7QK80IUx8iGCHf6kg==\n-----END AGE ENCRYPTED FILE-----\n +sops_age__list_0__map_recipient=age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu +sops_lastmodified=2025-02-07T14:46:04Z +sops_mac=ENC[AES256_GCM,data:vmJOTGI56UNeTSU5f3OFQ2Kqgl6N51TKHpCZ2eGD9W0sBzvri4usD9cOiiOsr1cOIVk9tjfdpjcs8/SMVLPY2D4nMfBdUO6e32tNo3V0DpR1BUPYcUykPogDF4psrJ3h1WG8+n1Y1KgVDo0+RawHp4WxeBi8/myxFvE+m067rso=,iv:MeiPPTwepzHU0rrtiVpOIngVMrGO/LGXu/5FDKe+k6A=,tag:vYSKk1/g7TPaNrninFx1Gg==,type:str] +sops_unencrypted_suffix=_unencrypted +sops_version=3.9.4 diff --git a/test-secrets/testsecret.sops.json b/test-secrets/testsecret.sops.json new file mode 100644 index 00000000..fef6f6e6 --- /dev/null +++ b/test-secrets/testsecret.sops.json @@ -0,0 +1,46 @@ +{ + "apiKey": "ENC[AES256_GCM,data:lLbXVEhBRKXiGGkBh5KltgUBoA==,iv:luayJniiXHwA3Z0rZyxeF00xlHfMwrYMiYh+ahP6Ayo=,tag:l3k3pSnzRTAKeAHOxw+fGw==,type:str]", + "database": { + "user": "ENC[AES256_GCM,data:kQtkQas=,iv:+qyJ9FUXoMtcpcfdT7ZTONHf3SsGbAfJznJFt5e/pVE=,tag:2CinmzVeqn654MfYdhkqxg==,type:str]", + "password": "ENC[AES256_GCM,data:jHwCEJh02A8s,iv:imwHW4U7DV09m5NCzO5k0AuRZdY/TK2+F28VbWFH6yg=,tag:pcQ3h40D9AvBFQEniRxMow==,type:str]", + "host": "ENC[AES256_GCM,data:U3Jx/GkByKLPnebsp5U=,iv:cCuW99ktyAI4dVQzDt1/jsgLP5pMdYYCsi6AhqsgVXs=,tag:v16zyYu5A1TVBP4baOxB1g==,type:str]" + }, + "tokens": [ + { + "service": "ENC[AES256_GCM,data:MLQW8tocgCc=,iv:+/foQyR7q0hvbOkGivauUAWdihfoHKzwgSYdv1Gq29c=,tag:O2ebmT2u9NfVqoo0q4J97w==,type:str]", + "token": "ENC[AES256_GCM,data:pcrFQQDk,iv:+q/3i7niTwn/jyOqeHJ8hUVA4jN8CqPXufWsIRkkpJA=,tag:buIs8G4OfiuJPf108/sDhQ==,type:str]" + }, + { + "service": "ENC[AES256_GCM,data:gyRnIigPXh8=,iv:oTNrXTZKX77yynvcQwhzXio2rEJXsIBMUD6DOCRr4fA=,tag:2OchZmbqdcHdljC6CKkulA==,type:str]", + "token": "ENC[AES256_GCM,data:EwGCYT3k,iv:1HMzUDqmXrI3bhGaxknMftwEZ8Cc1szxaMV6A164mfc=,tag:0b5eRwxZD4j9ujixTjfFZg==,type:str]" + } + ], + "someOtherKey": "ENC[AES256_GCM,data:vVlp3EE1mgTQP9JSDGdPf/+h2FSqajY=,iv:xYGIoTYPEn+4ax2LTKixlQb5NaotVw+0QVfFSm9QNWo=,tag:+U4JQbm/8mFWAmlMryg7LA==,type:str]", + "specific": { + "SpecialCharacters": "ENC[AES256_GCM,data:uPqFOSjUMgVdroUBIM6qernOsA==,iv:rSScNgl3g66+ITAYYjjyU2HzBWYDy8lBcCGGXFvHIgo=,tag:JEw3yYdiLK+F+MCyWcth6w==,type:str]", + "HTMLEncodingTest1": "ENC[AES256_GCM,data:ksCu3G0rG2Nf5+c/9vSs0aol+xnv,iv:7+PJt3Q91CHmvRHqDIbApSMaYLoZq3D1/BnaA3CfsMw=,tag:S/At2clSsGAvHSkjLwetqQ==,type:str]", + "HTMLEncodingTest2": "ENC[AES256_GCM,data:Zw==,iv:jH3RkRJsMDL+gPPzpLv1gPX/TLy9U1zSPqIpF97wTb4=,tag:3Xaf7JWYYxIQQR88eb+FDg==,type:str]", + "HTLMEncodingTest3": "ENC[AES256_GCM,data:UA==,iv:ZYqChMLBfQoKHclu94sbcI98sVGvymM37Esshvz0Iuw=,tag:UV1zFimcgETD0ncTjpgDvg==,type:str]", + "null": null, + "boolean": "ENC[AES256_GCM,data:w2sY/A==,iv:K+2AL8Da70+1mBVzuq2eOgzkEFwembEcyX8HXKIAqR8=,tag:KYCw3m6PT8rcu1i/mGZJ5g==,type:bool]", + "number1": "ENC[AES256_GCM,data:3Y1f,iv:MCCT+EwNnpVLeu/KkiQNlIGGokimh6U7PNEFEyr1u4A=,tag:jZVaMNn4rgh+5kWgNziIig==,type:float]", + "number2": "ENC[AES256_GCM,data:EPgTD7ZxVQ==,iv:+ZJgfD2V/s3XBjQuzq0ysS5fYtS2P2hX72dj9qmuHCE=,tag:fM9g+wtubjAfjXPHCvsXVA==,type:float]" + }, + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjSCttMFlYZE9FZjdHS2gw\nQjdjeFNmRmlQVnVYMHIvUzlLTEJFZVFxZ1E0CmFxWnRwejNMZXpBNnplaUVDdzZt\nQWZGVEJ5QzMzUUhud0hkSW5vdGFiU00KLS0tIDVpRTJHMlhqTGJZSytranZaSW1a\nclA0YWFUNXIrY2x2emh5dGFTd1VjYzAKA9R9C+42bZ2bKDUn8K6SDfQ5KkrICY3r\n0N27V58ZPAo48tqkhea/o0DBtkdllrBHOxGeOIJm/wFOfnETrZ68Vw==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-02-07T14:47:14Z", + "mac": "ENC[AES256_GCM,data:7CuCj7sJeKFZFpFp6ji3BfGzDY+X6Z5efccpTsbDj4ck/QYu+x3iLkirhhrGH0hEuN6xHKAjry/jmCRJpGh+7EGm3ffQoSYu9oC+ujSX3+7aWfhOv8ROt7R38Z9jzEn1qphKEX9lK3O+IruXHfUE+6t/zqwlIVjMGaI1ARbLBKA=,iv:n8ceHb4WwXy4VIx/mJNWNMwGbF6IvMuOw/YQa7JxRiY=,tag:hfU3SbZE7cAJ9QTXRGZj7w==,type:str]", + "pgp": null, + "unencrypted_suffix": "_unencrypted", + "version": "3.9.4" + } +} \ No newline at end of file diff --git a/test-secrets/testsecret.sops.yaml b/test-secrets/testsecret.sops.yaml new file mode 100644 index 00000000..036c1ee5 --- /dev/null +++ b/test-secrets/testsecret.sops.yaml @@ -0,0 +1,40 @@ +apiKey: ENC[AES256_GCM,data:r6YfrwGkVFxBF8mHEcsPaxMtUQ==,iv:/8rr4K5mBxLi3jR2lHfeeyVO/wQY00pc//Ow5vqY17Q=,tag:+dgLaKeSxNNBuOEFIftOZw==,type:str] +database: + user: ENC[AES256_GCM,data:sdsUyvo=,iv:IVioJCVyROehAtG6xbmAZzd52HQvk0eZItMBjBAvqx8=,tag:0pumzdyH5wiEArMmmra3UQ==,type:str] + password: ENC[AES256_GCM,data:CSQ8jFrxnLQY,iv:hXLENmG8qLGsGdWv3wbrj5Lf2zbF1ToNIwS4y1uWEXg=,tag:8QDCMyA69dYl58xIuP1DcA==,type:str] + host: ENC[AES256_GCM,data:xfU2eC+/+uvCkHY8QHY=,iv:ULWdvoa6r8F1g2+ZF3xPwak1EdhDWmndsO5RUxAVPE8=,tag:KGlJG1IMSWn4nEtMaOSsdg==,type:str] +tokens: + - service: ENC[AES256_GCM,data:tRSUpGKIEmc=,iv:hi/38iC/Glc4nxUkRYBV2cy946k+azXFtEdJONP1g/w=,tag:GQ0/WEhteyqCpsEv/SFrbA==,type:str] + token: ENC[AES256_GCM,data:CGnSO4HE,iv:LH0xVWNTbBmHPQ1OiP5+uRFfG/E7K7OGYqKHXOKje8Q=,tag:sOYhgKKV1ogOs7PJrBrsjw==,type:str] + - service: ENC[AES256_GCM,data:ohqXvZ/7HWw=,iv:CpjUdTbGL4TGRIWtEJxZ8923tw/Qomw+kCtiHuFiGQc=,tag:95TQUa3NSW1qGT8LNsEgbQ==,type:str] + token: ENC[AES256_GCM,data:I0I/XgWl,iv:87E/c7DiGKT22tddCFqBuPOC736yv5YD9M/+g3PiZX4=,tag:Z1prIHfH39m2U6i2KeV22Q==,type:str] +someOtherKey: ENC[AES256_GCM,data:HSMFwMXHni18tTOPw2DAE0g5XQR9oUw=,iv:4xTRO8TYhbla01gzathf7UBHh8Gthd97GIxX/0kCXwg=,tag:4psEFW3O2RqqYN68U23Pxw==,type:str] +specific: + SpecialCharacters: ENC[AES256_GCM,data:E/jqkPvUSbhZPbm0vrCjX1soLA==,iv:Rto0EyQT2ozFmk1tvk3xRDwVnNprA5xjpCNGTZieb0A=,tag:pRvhsXnVrb2qGG1ocu5mKw==,type:str] + HTMLEncodingTest1: ENC[AES256_GCM,data:Zdc5vZOBIQR8mclrPytvmyg4HQeD,iv:WGzS0+LSP9XaFeqh1aZmmgO54ZDn8Tf2YIOiwmJHp0I=,tag:ZdA/xX72JzBYxGVcV2a2RA==,type:str] + HTMLEncodingTest2: ENC[AES256_GCM,data:Xw==,iv:blYJXwT+wErgVswaCW8oWYnny88oL1yvFx8e3JcE09Q=,tag:+YUy02xaJhqqatBtkj972A==,type:str] + HTLMEncodingTest3: ENC[AES256_GCM,data:/w==,iv:/4eSVtFQ7cGoNI7UOMw8ly0+aiX7WivU4ihMlVKUD5k=,tag:cLSO8CR0IM+Y5LZfdM43BQ==,type:str] + "null": null + boolean: ENC[AES256_GCM,data:D1iaUA==,iv:SurUABhqM+UYiCZaEmjyGKZai2jDJL3nnZJ41tMNHBQ=,tag:gewFlccUdb3IyX7kP+SP3w==,type:bool] + number1: ENC[AES256_GCM,data:McBM,iv:VjYEpdVgLsjXGm2VRD9Lu0BXyOMFjkUMQIjvuVod5cs=,tag:7EfnK0qcITRg1Obriu7Egg==,type:int] + number2: ENC[AES256_GCM,data:wLcu0XjyJg==,iv:tZT/AMYMToZi5nuo6jUxwB01HPX4HhHpdt6v7uzZ9SE=,tag:fgK4Gfi5YBA1LupJBX2sBA==,type:float] +sops: + kms: [] + gcp_kms: [] + azure_kv: [] + hc_vault: [] + age: + - recipient: age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu + enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBYc3F6ZFY4RFllbStpMzEz + WmxuNzduMytjRkh1Y24xMUNoVndCYUNhaGtJCjJwZ1AzZlBVcVd6Y2NFbGR4MmVF + bW9OWWh2bmRjaFRrOFoyeWVWbnJTeWMKLS0tIExyVDNFRXpFTEpRMzYvWG1PaWNz + TW96d0tqajBLc01paVlEZHFXR1F2bXcKLIJg7yTm0uCiiPiKsnsAyRM/aDZ/fNvw + iilKTB5wP1qds7StcVLJ18RGUo9vuAA9iP0NZCP6kKLVgZbcJ/aSdw== + -----END AGE ENCRYPTED FILE----- + lastmodified: "2025-02-07T14:47:09Z" + mac: ENC[AES256_GCM,data:Sx2D6SF+pQHQ+oux7lNexshPodcge3w2g6ixLTjK/NkEgyBMmgsVyBGWMl+kSk6PY58HT4AQpyBtuiUKj3jSJ4pZmepgWIAdxKpB3slqy38gghYP2/AHSbHYRzhLQIOxxDO0inUwroHa13HttJCzDfXKNiKrbMRAQKk+FWF6x3w=,iv:7sBjShVWrW177wZBv+rxW6eqK0VQcjjGWVtHw9dbGTY=,tag:Bo3oYFgbATbNVwDtP2RAaw==,type:str] + pgp: [] + unencrypted_suffix: _unencrypted + version: 3.9.4 diff --git a/test/secret-manual.integ.snapshot/SecretIntegrationAsset.assets.json b/test/PARAMETER.integ.snapshot/PARAMETER.assets.json similarity index 62% rename from test/secret-manual.integ.snapshot/SecretIntegrationAsset.assets.json rename to test/PARAMETER.integ.snapshot/PARAMETER.assets.json index 5d4f2d77..4ff7f3c0 100644 --- a/test/secret-manual.integ.snapshot/SecretIntegrationAsset.assets.json +++ b/test/PARAMETER.integ.snapshot/PARAMETER.assets.json @@ -1,28 +1,28 @@ { "version": "39.0.0", "files": { - "87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186": { + "d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4": { "source": { - "path": "asset.87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186.zip", + "path": "asset.d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4.zip", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186.zip", + "objectKey": "d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "19a59647220be293c0e14415e45809167fb8f8a037a3d0497e45cef7a555515e": { + "9fd7420fdde16dec1a7971d76c5395a3d449336ffbf9d03938d55a930701d259": { "source": { - "path": "SecretIntegrationAsset.template.json", + "path": "PARAMETER.template.json", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "19a59647220be293c0e14415e45809167fb8f8a037a3d0497e45cef7a555515e.json", + "objectKey": "9fd7420fdde16dec1a7971d76c5395a3d449336ffbf9d03938d55a930701d259.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/test/PARAMETER.integ.snapshot/PARAMETER.template.json b/test/PARAMETER.integ.snapshot/PARAMETER.template.json new file mode 100644 index 00000000..e7b0bd0e --- /dev/null +++ b/test/PARAMETER.integ.snapshot/PARAMETER.template.json @@ -0,0 +1,388 @@ +{ + "Resources": { + "Json7D959341": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json", + "Type": "String", + "Value": " " + } + }, + "JsonSopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess0B4B19A62": { + "Type": "AWS::IAM::ManagedPolicy", + "Properties": { + "Description": "Policy to grant parameter provider permissions to put parameter", + "Path": "/", + "PolicyDocument": { + "Statement": [ + { + "Action": "ssm:PutParameter", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json" + ] + ] + } + } + ], + "Version": "2012-10-17" + } + } + }, + "JsonSopsSync13335C85": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "ewoJImFwaUtleSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOmxMYlhWRWhCUktYaUdHa0JoNUtsdGdVQm9BPT0saXY6bHVheUpuaWlYSHdBM1owclp5eGVGMDB4bEhmTXdyWU1pWWgrYWhQNkF5bz0sdGFnOmwzazNwU256UlRBS2VBSE94dytmR3c9PSx0eXBlOnN0cl0iLAoJImRhdGFiYXNlIjogewoJCSJ1c2VyIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6a1F0a1Fhcz0saXY6K3F5SjlGVVhvTXRjcGNmZFQ3WlRPTkhmM1NzR2JBZkp6bkpGdDVlL3BWRT0sdGFnOjJDaW5telZlcW42NTRNZllkaGtxeGc9PSx0eXBlOnN0cl0iLAoJCSJwYXNzd29yZCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOmpId0NFSmgwMkE4cyxpdjppbXdIVzRVN0RWMDltNU5Dek81azBBdVJaZFkvVEsyK0YyOFZiV0ZINnlnPSx0YWc6cGNRM2g0MEQ5QXZCRlFFbmlSeE1vdz09LHR5cGU6c3RyXSIsCgkJImhvc3QiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpVM0p4L0drQnlLTFBuZWJzcDVVPSxpdjpjQ3VXOTlrdHlBSTRkVlF6RHQxL2pzZ0xQNXBNZFlZQ3NpNkFocXNnVlhzPSx0YWc6djE2enlZdTVBMVRWQlA0YmFPeEIxZz09LHR5cGU6c3RyXSIKCX0sCgkidG9rZW5zIjogWwoJCXsKCQkJInNlcnZpY2UiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpNTFFXOHRvY2dDYz0saXY6Ky9mb1F5UjdxMGh2Yk9rR2l2YXVVQVdkaWhmb0hLendnU1lkdjFHcTI5Yz0sdGFnOk8yZWJtVDJ1OU5mVnFvbzBxNEo5N3c9PSx0eXBlOnN0cl0iLAoJCQkidG9rZW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpwY3JGUVFEayxpdjorcS8zaTduaVR3bi9qeU9xZUhKOGhVVkE0ak44Q3FQWHVmV3NJUmtrcEpBPSx0YWc6YnVJczhHNE9maXVKUGYxMDgvc0RoUT09LHR5cGU6c3RyXSIKCQl9LAoJCXsKCQkJInNlcnZpY2UiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpneVJuSWlnUFhoOD0saXY6b1ROclhUWktYNzd5eW52Y1F3aHpYaW8yckVKWHNJQk1VRDZET0NScjRmQT0sdGFnOjJPY2habWJxZGNIZGxqQzZDS2t1bEE9PSx0eXBlOnN0cl0iLAoJCQkidG9rZW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpFd0dDWVQzayxpdjoxSE16VURxbVhySTNiaEdheGtuTWZ0d0VaOENjMXN6eGFNVjZBMTY0bWZjPSx0YWc6MGI1ZVJ3eFpENGo5dWppeFRqZkZaZz09LHR5cGU6c3RyXSIKCQl9CgldLAoJInNvbWVPdGhlcktleSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOnZWbHAzRUUxbWdUUVA5SlNER2RQZi8raDJGU3Fhalk9LGl2OnhZR0lvVFlQRW4rNGF4MkxUS2l4bFFiNU5hb3RWdyswUVZmRlNtOVFOV289LHRhZzorVTRKUWJtLzhtRldBbWxNcnlnN0xBPT0sdHlwZTpzdHJdIiwKCSJzcGVjaWZpYyI6IHsKCQkiU3BlY2lhbENoYXJhY3RlcnMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp1UHFGT1NqVU1nVmRyb1VCSU02cWVybk9zQT09LGl2OnJTU2NOZ2wzZzY2K0lUQVlZamp5VTJIekJXWUR5OGxCY0NHR1hGdkhJZ289LHRhZzpKRXczeVlkaUxLK0YrTUN5V2N0aDZ3PT0sdHlwZTpzdHJdIiwKCQkiSFRNTEVuY29kaW5nVGVzdDEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTprc0N1M0cwckcyTmY1K2MvOXZTczBhb2wreG52LGl2OjcrUEp0M1E5MUNIbXZSSHFESWJBcFNNYVlMb1pxM0QxL0JuYUEzQ2ZzTXc9LHRhZzpTL0F0MmNsU3NHQXZIU2tqTHdldHFRPT0sdHlwZTpzdHJdIiwKCQkiSFRNTEVuY29kaW5nVGVzdDIiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpadz09LGl2OmpIM1JrUkpzTURMK2dQUHpwTHYxZ1BYL1RMeTlVMXpTUHFJcEY5N3dUYjQ9LHRhZzozWGFmN0pXWVl4SVFRUjg4ZWIrRkRnPT0sdHlwZTpzdHJdIiwKCQkiSFRMTUVuY29kaW5nVGVzdDMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpVQT09LGl2OlpZcUNoTUxCZlFvS0hjbHU5NHNiY0k5OHNWR3Z5bU0zN0Vzc2h2ejBJdXc9LHRhZzpVVjF6RmltY2dFVEQwbmNUanBnRHZnPT0sdHlwZTpzdHJdIiwKCQkibnVsbCI6IG51bGwsCgkJImJvb2xlYW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp3MnNZL0E9PSxpdjpLKzJBTDhEYTcwKzFtQlZ6dXEyZU9nemtFRndlbWJFY3lYOEhYS0lBcVI4PSx0YWc6S1lDdzNtNlBUOHJjdTFpL21HWko1Zz09LHR5cGU6Ym9vbF0iLAoJCSJudW1iZXIxIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6M1kxZixpdjpNQ0NUK0V3Tm5wVkxldS9La2lRTmxJR0dva2ltaDZVN1BORUZFeXIxdTRBPSx0YWc6alpWYU1ObjRyZ2grNWtXZ056aUlpZz09LHR5cGU6ZmxvYXRdIiwKCQkibnVtYmVyMiI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOkVQZ1REN1p4VlE9PSxpdjorWkpnZkQyVi9zM1hCalF1enEweXNTNWZZdFMyUDJoWDcyZGo5cW11SENFPSx0YWc6Zk05Zyt3dHViakFmalhQSEN2c1hWQT09LHR5cGU6ZmxvYXRdIgoJfSwKCSJzb3BzIjogewoJCSJrbXMiOiBudWxsLAoJCSJnY3Bfa21zIjogbnVsbCwKCQkiYXp1cmVfa3YiOiBudWxsLAoJCSJoY192YXVsdCI6IG51bGwsCgkJImFnZSI6IFsKCQkJewoJCQkJInJlY2lwaWVudCI6ICJhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dSIsCgkJCQkiZW5jIjogIi0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS1cbllXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JqU0N0dE1GbFlaRTlGWmpkSFMyZ3dcblFqZGplRk5tUm1sUVZuVllNSEl2VXpsTFRFSkZaVkZ4WjFFMENtRnhXblJ3ZWpOTVpYcEJObnBsYVVWRGR6WnRcblFXWkdWRUo1UXpNelVVaHVkMGhrU1c1dmRHRmlVMDBLTFMwdElEVnBSVEpITWxocVRHSlpTeXRyYW5aYVNXMWFcbmNsQTBZV0ZVTlhJclkyeDJlbWg1ZEdGVGQxVmpZekFLQTlSOUMrNDJiWjJiS0RVbjhLNlNEZlE1S2tySUNZM3JcbjBOMjdWNThaUEFvNDh0cWtoZWEvbzBEQnRrZGxsckJIT3hHZU9JSm0vd0ZPZm5FVHJaNjhWdz09XG4tLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuIgoJCQl9CgkJXSwKCQkibGFzdG1vZGlmaWVkIjogIjIwMjUtMDItMDdUMTQ6NDc6MTRaIiwKCQkibWFjIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6N0N1Q2o3c0plS0ZaRnBGcDZqaTNCZkd6RFkrWDZaNWVmY2NwVHNiRGo0Y2svUVl1K3gzaUxraXJoaHJHSDBoRXVONnhIS0Fqcnkvam1DUkpwR2grN0VHbTNmZlFvU1l1OW9DK3VqU1gzKzdhV2ZoT3Y4Uk90N1IzOFo5anpFbjFxcGhLRVg5bEszTytJcnVYSGZVRSs2dC96cXdsSVZqTUdhSTFBUmJMQktBPSxpdjpuOGNlSGI0V3dYeTRWSXgvbUpOV05Nd0diRjZJdk11T3cvWVFhN0p4UmlZPSx0YWc6aGZVM1NiWkU3Y0FKOVFUWFJHWmo3dz09LHR5cGU6c3RyXSIsCgkJInBncCI6IG51bGwsCgkJInVuZW5jcnlwdGVkX3N1ZmZpeCI6ICJfdW5lbmNyeXB0ZWQiLAoJCSJ2ZXJzaW9uIjogIjMuOS40IgoJfQp9", + "Hash": "e79149a81c3a4f62383c195070a39111284086e5c754f516b315c09943583dfb" + }, + "Format": "json", + "EncryptionKey": "58b75958-883a-440c-842c-85af5d33a5bb", + "ResourceType": "PARAMETER", + "Target": { + "Ref": "Json7D959341" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + }, + { + "Ref": "JsonSopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess0B4B19A62" + }, + { + "Ref": "YamlSopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess0A22A1629" + }, + { + "Ref": "DotEnvSopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess096D6CB67" + }, + { + "Ref": "BinarySopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess0957B5711" + } + ] + } + }, + "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "kms:Decrypt", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Resource": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", + "Roles": [ + { + "Ref": "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" + } + ] + } + }, + "SingletonLambdaSopsSyncProviderAA18D140": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4.zip" + }, + "Environment": { + "Variables": { + "SOPS_AGE_KEY": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" + } + }, + "Handler": "bootstrap", + "Role": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25", + "Arn" + ] + }, + "Runtime": "provided.al2", + "Timeout": 60 + }, + "DependsOn": [ + "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", + "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" + ] + }, + "Yaml8A8E441C": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml", + "Type": "String", + "Value": " " + } + }, + "YamlSopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess0A22A1629": { + "Type": "AWS::IAM::ManagedPolicy", + "Properties": { + "Description": "Policy to grant parameter provider permissions to put parameter", + "Path": "/", + "PolicyDocument": { + "Statement": [ + { + "Action": "ssm:PutParameter", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml" + ] + ] + } + } + ], + "Version": "2012-10-17" + } + } + }, + "YamlSopsSync65050259": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "YXBpS2V5OiBFTkNbQUVTMjU2X0dDTSxkYXRhOnI2WWZyd0drVkZ4QkY4bUhFY3NQYXhNdFVRPT0saXY6LzhycjRLNW1CeExpM2pSMmxIZmVleVZPL3dRWTAwcGMvL093NXZxWTE3UT0sdGFnOitkZ0xhS2VTeE5OQnVPRUZJZnRPWnc9PSx0eXBlOnN0cl0KZGF0YWJhc2U6CiAgICB1c2VyOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNkc1V5dm89LGl2OklWaW9KQ1Z5Uk9laEF0RzZ4Ym1BWnpkNTJIUXZrMGVaSXRNQmpCQXZxeDg9LHRhZzowcHVtemR5SDV3aUVBck1tbXJhM1VRPT0sdHlwZTpzdHJdCiAgICBwYXNzd29yZDogRU5DW0FFUzI1Nl9HQ00sZGF0YTpDU1E4akZyeG5MUVksaXY6aFhMRU5tRzhxTEdzR2RXdjN3YnJqNUxmMnpiRjFUb05Jd1M0eTF1V0VYZz0sdGFnOjhRRENNeUE2OWRZbDU4eEl1UDFEY0E9PSx0eXBlOnN0cl0KICAgIGhvc3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6eGZVMmVDKy8rdXZDa0hZOFFIWT0saXY6VUxXZHZvYTZyOEYxZzIrWkYzeFB3YWsxRWRoRFdtbmRzTzVSVXhBVlBFOD0sdGFnOktHbEpHMUlNU1duNG5FdE1hT1NzZGc9PSx0eXBlOnN0cl0KdG9rZW5zOgogICAgLSBzZXJ2aWNlOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnRSU1VwR0tJRW1jPSxpdjpoaS8zOGlDL0dsYzRueFVrUllCVjJjeTk0NmsrYXpYRnRFZEpPTlAxZy93PSx0YWc6R1EwL1dFaHRleXFDcHNFdi9TRnJiQT09LHR5cGU6c3RyXQogICAgICB0b2tlbjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpDR25TTzRIRSxpdjpMSDB4VldOVGJCbUhQUTFPaVA1K3VSRmZHL0U3SzdPR1lxS0hYT0tqZThRPSx0YWc6c09ZaGdLS1Yxb2dPczdQSnJCcnNqdz09LHR5cGU6c3RyXQogICAgLSBzZXJ2aWNlOiBFTkNbQUVTMjU2X0dDTSxkYXRhOm9ocVh2Wi83SFd3PSxpdjpDcGpVZFRiR0w0VEdSSVd0RUp4Wjg5MjN0dy9Rb213K2tDdGlIdUZpR1FjPSx0YWc6OTVUUVVhM05TVzFxR1Q4TE5zRWdiUT09LHR5cGU6c3RyXQogICAgICB0b2tlbjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpJMEkvWGdXbCxpdjo4N0UvYzdEaUdLVDIydGRkQ0ZxQnVQT0M3MzZ5djVZRDlNLytnM1BpWlg0PSx0YWc6WjFwcklIZkgzOW0yVTZpMktlVjIyUT09LHR5cGU6c3RyXQpzb21lT3RoZXJLZXk6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6SFNNRndNWEhuaTE4dFRPUHcyREFFMGc1WFFSOW9Vdz0saXY6NHhUUk84VFloYmxhMDFnemF0aGY3VUJIaDhHdGhkOTdHSXhYLzBrQ1h3Zz0sdGFnOjRwc0VGVzNPMlJxcVlONjhVMjNQeHc9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6CiAgICBTcGVjaWFsQ2hhcmFjdGVyczogRU5DW0FFUzI1Nl9HQ00sZGF0YTpFL2pxa1B2VVNiaFpQYm0wdnJDalgxc29MQT09LGl2OlJ0bzBFeVFUMm96Rm1rMXR2azN4UkR3Vm5OcHJBNXhqcENOR1RaaWViMEE9LHRhZzpwUnZoc1huVnJiMnFHRzFvY3U1bUt3PT0sdHlwZTpzdHJdCiAgICBIVE1MRW5jb2RpbmdUZXN0MTogRU5DW0FFUzI1Nl9HQ00sZGF0YTpaZGM1dlpPQklRUjhtY2xyUHl0dm15ZzRIUWVELGl2OldHelMwK0xTUDlYYUZlcWgxYVptbWdPNTRaRG44VGYyWUlPaXdtSkhwMEk9LHRhZzpaZEEveFg3Mkp6Qll4R1ZjVjJhMlJBPT0sdHlwZTpzdHJdCiAgICBIVE1MRW5jb2RpbmdUZXN0MjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpYdz09LGl2OmJsWUpYd1Qrd0VyZ1Zzd2FDVzhvV1lubnk4OG9MMXl2Rng4ZTNKY0UwOVE9LHRhZzorWVV5MDJ4YUpocXFhdEJ0a2o5NzJBPT0sdHlwZTpzdHJdCiAgICBIVExNRW5jb2RpbmdUZXN0MzogRU5DW0FFUzI1Nl9HQ00sZGF0YTovdz09LGl2Oi80ZVNWdEZRN2NHb05JN1VPTXc4bHkwK2FpWDdXaXZVNGloTWxWS1VENWs9LHRhZzpjTFNPOENSMElNK1k1TFpmZE00M0JRPT0sdHlwZTpzdHJdCiAgICAibnVsbCI6IG51bGwKICAgIGJvb2xlYW46IEVOQ1tBRVMyNTZfR0NNLGRhdGE6RDFpYVVBPT0saXY6U3VyVUFCaHFNK1VZaUNaYUVtanlHS1phaTJqREpMM25uWko0MXRNTkhCUT0sdGFnOmdld0ZsY2NVZGIzSXlYN2tQK1NQM3c9PSx0eXBlOmJvb2xdCiAgICBudW1iZXIxOiBFTkNbQUVTMjU2X0dDTSxkYXRhOk1jQk0saXY6VmpZRXBkVmdMc2pYR20yVlJEOUx1MEJYeU9NRmprVU1RSWp2dVZvZDVjcz0sdGFnOjdFZm5LMHFjSVRSZzFPYnJpdTdFZ2c9PSx0eXBlOmludF0KICAgIG51bWJlcjI6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6d0xjdTBYanlKZz09LGl2OnRaVC9BTVlNVG9aaTVudW82alV4d0IwMUhQWDRIaEhwZHQ2djd1elo5U0U9LHRhZzpmZ0s0R2ZpNVlCQTFMdXBKQlgyc0JBPT0sdHlwZTpmbG9hdF0Kc29wczoKICAgIGttczogW10KICAgIGdjcF9rbXM6IFtdCiAgICBhenVyZV9rdjogW10KICAgIGhjX3ZhdWx0OiBbXQogICAgYWdlOgogICAgICAgIC0gcmVjaXBpZW50OiBhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dQogICAgICAgICAgZW5jOiB8CiAgICAgICAgICAgIC0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgICAgICAgICAgWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQlljM0Y2WkZZNFJGbGxiU3RwTXpFegogICAgICAgICAgICBXbXh1TnpkdU15dGpSa2gxWTI0eE1VTm9WbmRDWVVOaGFHdEpDakp3WjFBelpsQlZjVmQ2WTJORmJHUjRNbVZGCiAgICAgICAgICAgIGJXOU9XV2gyYm1SamFGUnJPRm95ZVdWV2JuSlRlV01LTFMwdElFeHlWRE5GUlhwRlRFcFJNell2V0cxUGFXTnoKICAgICAgICAgICAgVFc5NmQwdHFhakJMYzAxcGFWbEVaSEZYUjFGMmJYY0tMSUpnN3lUbTB1Q2lpUGlLc25zQXlSTS9hRFovZk52dwogICAgICAgICAgICBpaWxLVEI1d1AxcWRzN1N0Y1ZMSjE4UkdVbzl2dUFBOWlQME5aQ1A2a0tMVmdaYmNKL2FTZHc9PQogICAgICAgICAgICAtLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLQogICAgbGFzdG1vZGlmaWVkOiAiMjAyNS0wMi0wN1QxNDo0NzowOVoiCiAgICBtYWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6U3gyRDZTRitwUUhRK291eDdsTmV4c2hQb2RjZ2UzdzJnNml4TFRqSy9Oa0VneUJNbWdzVnlCR1dNbCtrU2s2UFk1OEhUNEFRcHlCdHVpVUtqM2pTSjRwWm1lcGdXSUFkeEtwQjNzbHF5MzhnZ2hZUDIvQUhTYkhZUnpoTFFJT3h4RE8waW5Vd3JvSGExM0h0dEpDekRmWEtOaUtyYk1SQVFLaytGV0Y2eDN3PSxpdjo3c0JqU2hWV3JXMTc3d1pCdityeFc2ZXFLMFZRY2pqR1dWdEh3OWRiR1RZPSx0YWc6Qm8zb1lGZ2JBVGJOVndEdFAyUkFhdz09LHR5cGU6c3RyXQogICAgcGdwOiBbXQogICAgdW5lbmNyeXB0ZWRfc3VmZml4OiBfdW5lbmNyeXB0ZWQKICAgIHZlcnNpb246IDMuOS40Cg==", + "Hash": "9912a0ccf8001b767579817f902a5d7e030019cc7b6db34c028f4a0f9079fddf" + }, + "Format": "yaml", + "EncryptionKey": "58b75958-883a-440c-842c-85af5d33a5bb", + "ResourceType": "PARAMETER", + "Target": { + "Ref": "Yaml8A8E441C" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "DotEnv36F67242": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/DotEnv", + "Type": "String", + "Value": " " + } + }, + "DotEnvSopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess096D6CB67": { + "Type": "AWS::IAM::ManagedPolicy", + "Properties": { + "Description": "Policy to grant parameter provider permissions to put parameter", + "Path": "/", + "PolicyDocument": { + "Statement": [ + { + "Action": "ssm:PutParameter", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/DotEnv" + ] + ] + } + } + ], + "Version": "2012-10-17" + } + } + }, + "DotEnvSopsSyncBB91B728": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "YXBpS2V5PUVOQ1tBRVMyNTZfR0NNLGRhdGE6eU1qVm12ZzhuZ3Bsc3c2QTJFZC9MOXhyRmc9PSxpdjpDcUlSRW12ZDR2dE1tWFIwc0tGVzRCelpWYTlnMHJUajU1OFJmd0JBeXA4PSx0YWc6dURka0EvSFRFTkZJYUZ6cWxIVVRkdz09LHR5cGU6c3RyXQpkYXRhYmFzZTpob3N0PUVOQ1tBRVMyNTZfR0NNLGRhdGE6TlFHQkpjRW1iM01rOTZYTFBLcz0saXY6bGhrcThrY0gvYXhWK3dSOGQvcWNYRDBpc1NuK0JBRlQrajRnRDFrQ3FWYz0sdGFnOldLOUNkOXhRbzIwQzcyNlRZTkJ3Ync9PSx0eXBlOnN0cl0KZGF0YWJhc2U6cGFzc3dvcmQ9RU5DW0FFUzI1Nl9HQ00sZGF0YTpvNkN3NmxSQ0t3VzMsaXY6YWIxeExjcmY5WFdyalhBZGRXL3ZGaHpPUUhxYk95UmlNVDFXRFoyRTk0VT0sdGFnOnhheTRxcXBYVkZHNVNBWHN3dEt1V2c9PSx0eXBlOnN0cl0KZGF0YWJhc2U6dXNlcj1FTkNbQUVTMjU2X0dDTSxkYXRhOllha1p2RlU9LGl2Oi9Va002RUUydjltaU1uZ2c1aHJGVytUTkM2TzlTSGdKdnBFcGJCUzRpWms9LHRhZzpjUTdCZ04vcmxmcHBCYUkyZVhOQjRBPT0sdHlwZTpzdHJdCnNvbWVPdGhlcktleT1FTkNbQUVTMjU2X0dDTSxkYXRhOmpiclVRMlpOM0crMm1zMWt0VWJCNG40R0tNaHpzMVE9LGl2Om54QnI3aFlhS1dJUSt3MlI5eWRxUmdFOFdZM3dXSllIUkxFTUw0b1h2Q0U9LHRhZzpoOHhYMEVOdzMwSnZQVUJWYm4zUmNBPT0sdHlwZTpzdHJdCnNwZWNpZmljOmJvb2xlYW49RU5DW0FFUzI1Nl9HQ00sZGF0YTo2aEpacEE9PSxpdjpKbjd2Y0doRy9LSHVJdm5XdExtNEt1dEJjWE9NR0dhMDNWZXhERWZvRUx3PSx0YWc6eVZZYnJkRGM4bFpRY3I1TTkwaExwQT09LHR5cGU6c3RyXQpzcGVjaWZpYzpTcGVjaWFsQ2hhcmFjdGVycz1FTkNbQUVTMjU2X0dDTSxkYXRhOmlWblY4UjR3VW80SG1qK2hOQmdWaHFzSy9RPT0saXY6MnFuSkZQMDdxK2JpZFY2UUh2YTh4Zy82S3V0MDF2eVNxb1VickppVmRkND0sdGFnOk9EUEhHTHMzeVU5QktBWGp2SDhhYVE9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6SFRMTUVuY29kaW5nVGVzdDM9RU5DW0FFUzI1Nl9HQ00sZGF0YTpPZz09LGl2Ok9zaWpSYmFVdFgyZk5OenNJMDJCbTgxQng5WnBNQ0xsOW9FWWZFZ295Z009LHRhZzpXNXlyVFRDdDh4cEV5RFdwbUNyU2JnPT0sdHlwZTpzdHJdCnNwZWNpZmljOkhUTUxFbmNvZGluZ1Rlc3QxPUVOQ1tBRVMyNTZfR0NNLGRhdGE6R3RjNXlPU1pycFJRWlJXcGJGUDlRQ2s1MkRwcSxpdjp6cy9GTU81Uzkydy9ET21UL1JoRXVXUTRXWER0SFlXbWdseXA4Ym1XNlNRPSx0YWc6NG5RQ2RrTUpMblJLNVJBV1RtYk5WQT09LHR5cGU6c3RyXQpzcGVjaWZpYzpIVE1MRW5jb2RpbmdUZXN0Mj1FTkNbQUVTMjU2X0dDTSxkYXRhOktnPT0saXY6UlFSeThMV0Z2b0tkNFVhV1NJS0wvNWpzNkk4V3ZpK3IrVDd1Ri9veCtyQT0sdGFnOlRLTWRVbS84M01rQm5QOVZ0UEFIV2c9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6bnVsbD0Kc3BlY2lmaWM6bnVtYmVyMT1FTkNbQUVTMjU2X0dDTSxkYXRhOjIzNk8saXY6L1gxakR5TU92Y3FmdmU2NzNCakNQNXIxempqMGgxS3RWak1EKzRyYklaST0sdGFnOnJXQlQwUnM1aGhsS0JUeXZOd0JxaXc9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6bnVtYmVyMj1FTkNbQUVTMjU2X0dDTSxkYXRhOmlJcUtsbXdSQ0E9PSxpdjp1c0YrWDBmbFdJZzlLaTdPMThLMDF4OG0vV1Qva1FkL2FWV0JTZFhhYnd3PSx0YWc6QlBIRlhUZXE3cXJ1Nk9XRzNEZlVzUT09LHR5cGU6c3RyXQp0b2tlbnM6MDpzZXJ2aWNlPUVOQ1tBRVMyNTZfR0NNLGRhdGE6TWxnYnVUcjFkNHM9LGl2OmUvWWpFdkV0RWhNUWR1NG9iVFczQnprU3RTazg0M2tyZWZFVElTbXh4Vnc9LHRhZzpjZzRFMmNsRko1R1dVYytpRm03OFR3PT0sdHlwZTpzdHJdCnRva2VuczowOnRva2VuPUVOQ1tBRVMyNTZfR0NNLGRhdGE6S2RlOXFITjgsaXY6SFdHZWkrUmh4V2ZFWStZZ0tUNzVRZndXaDFwaUUxVUo4cTRsVmM0R3U3TT0sdGFnOkRMWVB3bVlsaFJsSks2Q094ZDl3YXc9PSx0eXBlOnN0cl0KdG9rZW5zOjE6c2VydmljZT1FTkNbQUVTMjU2X0dDTSxkYXRhOmQwQVdsSnorbnQ0PSxpdjpCUXpLSGJCRFRsUis4ejFMVGtoQkxMby83dkFjT2pMVGZCLzlxUjdNZEdnPSx0YWc6czJOZU9QbFIxSXdaaVVuQ3M0RTFlZz09LHR5cGU6c3RyXQp0b2tlbnM6MTp0b2tlbj1FTkNbQUVTMjU2X0dDTSxkYXRhOkc0dklEVnRsLGl2OmloVi90alBTd1NhenNjL0RmK2RYcG5lcHdTa1A2bjFLY2NERzhHS1dSTWc9LHRhZzpSRGw5YzNQOWtvazF6V1dVYmlmRWNBPT0sdHlwZTpzdHJdCnNvcHNfYWdlX19saXN0XzBfX21hcF9lbmM9LS0tLS1CRUdJTiBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQlJjVFVyUld0d1NIZFBPVE5HVlhWcFxuZW1KUVdsWTRhWGcwWkVWU1NHeHNVemw0TVc5eWRsVllSMmxCQ2tGRGRrbDRialZWWVdwamEzRk9iQzluVkZWS1xuTWtzNWNrNW1TWEk0UVVrNVIxUjBjMkpDVkM5WkswRUtMUzB0SUVSTk9EZExhV0ptWjFSM05GWkVUM0YxWVZNeVxuUml0QmNFVmhOR3Q2VVVObGMyc3paVUpqZDFSVFQxa0tBWWsrRDdncUYrcHJkTkFGN09kT0hpbWEvQTkyTmpwd1xucWg1N1JrNUM3Tlh2VmVlSmsweEtkUzJ6Rm04NklJU1QvS2dTdzdRSzgwSVV4OGlHQ0hmNmtnPT1cbi0tLS0tRU5EIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG4Kc29wc19hZ2VfX2xpc3RfMF9fbWFwX3JlY2lwaWVudD1hZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dQpzb3BzX2xhc3Rtb2RpZmllZD0yMDI1LTAyLTA3VDE0OjQ2OjA0Wgpzb3BzX21hYz1FTkNbQUVTMjU2X0dDTSxkYXRhOnZtSk9UR0k1NlVOZVRTVTVmM09GUTJLcWdsNk41MVRLSHBDWjJlR0Q5VzBzQnp2cmk0dXNEOWNPaWlPc3IxY09JVms5dGpmZHBqY3M4L1NNVkxQWTJENG5NZkJkVU82ZTMydE5vM1YwRHBSMUJVUFljVXlrUG9nREY0cHNySjNoMVdHOCtuMVkxS2dWRG8wK1Jhd0hwNFd4ZUJpOC9teXhGdkUrbTA2N3Jzbz0saXY6TWVpUFBUd2VwekhVMHJydGlWcE9JbmdWTXJHTy9MR1h1LzVGREtlK2s2QT0sdGFnOnZZU0trMS9nN1RQYU5ybmluRngxR2c9PSx0eXBlOnN0cl0Kc29wc191bmVuY3J5cHRlZF9zdWZmaXg9X3VuZW5jcnlwdGVkCnNvcHNfdmVyc2lvbj0zLjkuNAo=", + "Hash": "8503036ebdb63922730f2d820336b67f3a28a6713b1d92133fc311b2a04ff62c" + }, + "Format": "dotenv", + "EncryptionKey": "58b75958-883a-440c-842c-85af5d33a5bb", + "ResourceType": "PARAMETER", + "Target": { + "Ref": "DotEnv36F67242" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Binary266F49CD": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Binary", + "Type": "String", + "Value": " " + } + }, + "BinarySopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess0957B5711": { + "Type": "AWS::IAM::ManagedPolicy", + "Properties": { + "Description": "Policy to grant parameter provider permissions to put parameter", + "Path": "/", + "PolicyDocument": { + "Statement": [ + { + "Action": "ssm:PutParameter", + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Binary" + ] + ] + } + } + ], + "Version": "2012-10-17" + } + } + }, + "BinarySopsSyncC6FD2267": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "ewoJImRhdGEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpNOWd6RHNSZDlvQ3J1TTFEaFlpVUE0WUNBR3ZTdUFXT1JicFhlcHJlVDNOeElmRDhZNjNwejAwTEhoL3Q5WStXclRCQXBKdU9PRDNVWWhVMUpydnU2MzhIZWRyQjFBNXNxMXRPdUFWc1l6OStLVWFPamFveWV5TWh2d3JOenZsemFINkowNlMycWIycS9HMXBVSFdWUGtvRU9VaGlHTnlYVGJRY2g0bkhVQmJVWnBVU2ttcXd0dnprSVlPeDBGYnhSaGYwRndaWGF5NFMrWE9NY0R1S2JmUXg4aEExZ1hYZGdaYWwybmxldWpFNGtYV2FoN2dCL3EwQWNmaklqaHl0UGFlaWVFbFBYck5jSmR5SVJLbGxPV3RwbW93RHhhUm1xVTRpcVVZZzVrL095YnRLd1B2YmcybWpZeEx3SlpyNTd4anpFWDJ0RkppOWt1b3hsNEhQMDRxVkVSUGJhUHV5M3E2MVpiOStGd3RXODVlYm5WaU9BSVRwLy9SNzhLa21yUVZ6R3g2VktZKzJKeGJQR3NRNkhmZVNtN1dXV0dDWHRldVREWUFncG9FS2xaSE1kLzZoWTA3RDkydGxuYTh2YWRCUE9jTEFsNytjeFZmQ0phWjdPYjYzakZnelBvNi9MT1R6WWpxREt2TElFS2RGR2owOFB3aUVEM3ZVaVg0aE80b2kyTVVrZk51STFqeWpQOUFxd2ovSDJRd3ZxcGJ0R0RqRDIrQ2R5T2R3NXBCRVFRPT0saXY6bnR3YTdUU0ZWRERBaGQ3OVg1R0xEMkI2MUZNMTlRYWpPMkJLUk9qRjdzaz0sdGFnOjROZndvVFJOektLMVVQMkd4YVFSWHc9PSx0eXBlOnN0cl0iLAoJInNvcHMiOiB7CgkJImttcyI6IG51bGwsCgkJImdjcF9rbXMiOiBudWxsLAoJCSJhenVyZV9rdiI6IG51bGwsCgkJImhjX3ZhdWx0IjogbnVsbCwKCQkiYWdlIjogWwoJCQl7CgkJCQkicmVjaXBpZW50IjogImFnZTFkamxsdzJwenVwcnJxYzBlbjVtOHZjOGs1Z2UzdG0wZjZnN2NqMGMwZ2xmenA0NHZkYzRxbDhuZ3Z1IiwKCQkJCSJlbmMiOiAiLS0tLS1CRUdJTiBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQlhOVUV5VDA5UFIzcFpZbU4xWlU5U1xuZVVSQ1dVZFpZbmhtTXpCaVNtMUZjRU5ZTkdsaU5HdE5aekZSQ2s1MlRWWkNTRFJCT1drNVRUQjJkR1JHVEZnelxuTWtsc1pVVjBaRm9yVWt4YU0wWmlTVFJJY1c1aWQzTUtMUzB0SUhkRk1IRk1NVWRFWWxsVWFHUlJTRWw2VUdad1xuZEZGMk9EQlBaR1JyVG5CR2JXSnZkVlp2ZFdWR1VXOEttNVBZWFJ1VEJ2am1NRFltZzZORUtoSWJVVS9TSFBTWlxuVHRnd29zOGlkK01ZVHB1ZEcrYUtWVEtTeDkxR254OWVrTGNUa2FmRXcvWVVMVTljcnliWXRnPT1cbi0tLS0tRU5EIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG4iCgkJCX0KCQldLAoJCSJsYXN0bW9kaWZpZWQiOiAiMjAyNS0wMi0wN1QxNDo1MDoyNVoiLAoJCSJtYWMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpOakxQWkw1YmRrYytlYk5ycFQ5c2pzT1pqVUUvWjF0L09xMXE0Q0VzNzMxamdiVzBsb2xMWjNEcjdFRlZOTG9DNWV1bmhReHZuN0U2WkExYnBtcXBpanRNTlNrcXFWUWRHMUpzekY3WUdoRjlZaitUeXo5Ukhodk5GdUg4QUZjbDRmMWtzRDdHbW5WN2RZc2oxcjFZUDN3d0ZZK1VoRXFscTQrS2Q4N1ZuYTA9LGl2OjhJTUIzN1Y0a3hMSHJOaUlWMGNWWnRCMlZDZnVxOFNZQU5zeUR5bDNtMW89LHRhZzpFR0JYVk9JYXl6bjJsaDVaaTUrR3hnPT0sdHlwZTpzdHJdIiwKCQkicGdwIjogbnVsbCwKCQkidW5lbmNyeXB0ZWRfc3VmZml4IjogIl91bmVuY3J5cHRlZCIsCgkJInZlcnNpb24iOiAiMy45LjQiCgl9Cn0=", + "Hash": "a62d06dea56fc1e8018c1ec402c92887c6477cff4923a1d8acb7ccd082ba8552" + }, + "Format": "binary", + "EncryptionKey": "58b75958-883a-440c-842c-85af5d33a5bb", + "ResourceType": "PARAMETER", + "Target": { + "Ref": "Binary266F49CD" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "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/test/PARAMETER.integ.ts b/test/PARAMETER.integ.ts new file mode 100644 index 00000000..20ab88d4 --- /dev/null +++ b/test/PARAMETER.integ.ts @@ -0,0 +1,49 @@ +import * as cdk from 'aws-cdk-lib'; +import { Key } from 'aws-cdk-lib/aws-kms'; +import { SopsStringParameter } from '../src/index'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'PARAMETER'); + +interface TestCase { + name: string; + sopsFilePath: string; +} + +const tc = [ + { + name: 'Json', + sopsFilePath: 'test-secrets/testsecret.sops.json', + }, + { + name: 'Yaml', + sopsFilePath: 'test-secrets/testsecret.sops.yaml', + }, + { + name: 'DotEnv', + sopsFilePath: 'test-secrets/testsecret.sops.env', + }, + { + name: 'Binary', + sopsFilePath: 'test-secrets/README.sops.binary', + }, +] satisfies TestCase[]; + +const encryptionKey = Key.fromKeyArn( + stack, + 'Key', + 'arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb', +); + +tc.forEach((t) => { + new SopsStringParameter(stack, t.name, { + parameterName: `/${t.name}`, + sopsFilePath: t.sopsFilePath, + sopsAgeKey: cdk.SecretValue.unsafePlainText( + 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', + ), + encryptionKey, + }); +}); + +app.synth(); diff --git a/test/secret-inline.integ.snapshot/SecretIntegrationInline.assets.json b/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.assets.json similarity index 62% rename from test/secret-inline.integ.snapshot/SecretIntegrationInline.assets.json rename to test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.assets.json index 1af921c5..6cd115d5 100644 --- a/test/secret-inline.integ.snapshot/SecretIntegrationInline.assets.json +++ b/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.assets.json @@ -1,28 +1,28 @@ { "version": "39.0.0", "files": { - "87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186": { + "d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4": { "source": { - "path": "asset.87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186.zip", + "path": "asset.d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4.zip", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186.zip", + "objectKey": "d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "4c92c042db4db86f1084ca0562e63918e871e3ee0a0066735d556df1737079f1": { + "4721826719b9692e7b57c518a8cd8688ebd74f5c9c38eb13a8630f8c3ff07d32": { "source": { - "path": "SecretIntegrationInline.template.json", + "path": "PARAMETERMULTI.template.json", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "4c92c042db4db86f1084ca0562e63918e871e3ee0a0066735d556df1737079f1.json", + "objectKey": "4721826719b9692e7b57c518a8cd8688ebd74f5c9c38eb13a8630f8c3ff07d32.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.template.json b/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.template.json new file mode 100644 index 00000000..a46eaffe --- /dev/null +++ b/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.template.json @@ -0,0 +1,1060 @@ +{ + "Resources": { + "JsonResourceJsonapiKeyEB6B5C10": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/apiKey", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsondatabaseuserD88F8D25": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/database/user", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsondatabasepassword12EBC48E": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/database/password", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsondatabasehost37888D7D": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/database/host", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsontokens0service92C0D936": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/tokens/0/service", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsontokens0token105295EA": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/tokens/0/token", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsontokens1service387D7891": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/tokens/1/service", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsontokens1token4D4522D2": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/tokens/1/token", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsonsomeOtherKey8C556C1F": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/someOtherKey", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsonspecificSpecialCharacters340895B2": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/specific/SpecialCharacters", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsonspecificHTMLEncodingTest101B8C7B8": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/specific/HTMLEncodingTest1", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsonspecificHTMLEncodingTest2479B055F": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/specific/HTMLEncodingTest2", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsonspecificHTLMEncodingTest3773A92F2": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/specific/HTLMEncodingTest3", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsonspecificnullEFE6F24D": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/specific/null", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsonspecificbooleanDCCAF95E": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/specific/boolean", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsonspecificnumber120FA2919": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/specific/number1", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonResourceJsonspecificnumber2B2EBD3ED": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Json/specific/number2", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "JsonSopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess0B4B19A62": { + "Type": "AWS::IAM::ManagedPolicy", + "Properties": { + "Description": "Policy to grant parameter provider permissions to put parameter", + "Path": "/", + "PolicyDocument": { + "Statement": [ + { + "Action": "ssm:PutParameter", + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/apiKey" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/database/user" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/database/password" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/database/host" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/tokens/0/service" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/tokens/0/token" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/tokens/1/service" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/tokens/1/token" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/someOtherKey" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/specific/SpecialCharacters" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/specific/HTMLEncodingTest1" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/specific/HTMLEncodingTest2" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/specific/HTLMEncodingTest3" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/specific/null" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/specific/boolean" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/specific/number1" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Json/specific/number2" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + } + } + }, + "JsonSopsSync13335C85": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "ewoJImFwaUtleSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOmxMYlhWRWhCUktYaUdHa0JoNUtsdGdVQm9BPT0saXY6bHVheUpuaWlYSHdBM1owclp5eGVGMDB4bEhmTXdyWU1pWWgrYWhQNkF5bz0sdGFnOmwzazNwU256UlRBS2VBSE94dytmR3c9PSx0eXBlOnN0cl0iLAoJImRhdGFiYXNlIjogewoJCSJ1c2VyIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6a1F0a1Fhcz0saXY6K3F5SjlGVVhvTXRjcGNmZFQ3WlRPTkhmM1NzR2JBZkp6bkpGdDVlL3BWRT0sdGFnOjJDaW5telZlcW42NTRNZllkaGtxeGc9PSx0eXBlOnN0cl0iLAoJCSJwYXNzd29yZCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOmpId0NFSmgwMkE4cyxpdjppbXdIVzRVN0RWMDltNU5Dek81azBBdVJaZFkvVEsyK0YyOFZiV0ZINnlnPSx0YWc6cGNRM2g0MEQ5QXZCRlFFbmlSeE1vdz09LHR5cGU6c3RyXSIsCgkJImhvc3QiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpVM0p4L0drQnlLTFBuZWJzcDVVPSxpdjpjQ3VXOTlrdHlBSTRkVlF6RHQxL2pzZ0xQNXBNZFlZQ3NpNkFocXNnVlhzPSx0YWc6djE2enlZdTVBMVRWQlA0YmFPeEIxZz09LHR5cGU6c3RyXSIKCX0sCgkidG9rZW5zIjogWwoJCXsKCQkJInNlcnZpY2UiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpNTFFXOHRvY2dDYz0saXY6Ky9mb1F5UjdxMGh2Yk9rR2l2YXVVQVdkaWhmb0hLendnU1lkdjFHcTI5Yz0sdGFnOk8yZWJtVDJ1OU5mVnFvbzBxNEo5N3c9PSx0eXBlOnN0cl0iLAoJCQkidG9rZW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpwY3JGUVFEayxpdjorcS8zaTduaVR3bi9qeU9xZUhKOGhVVkE0ak44Q3FQWHVmV3NJUmtrcEpBPSx0YWc6YnVJczhHNE9maXVKUGYxMDgvc0RoUT09LHR5cGU6c3RyXSIKCQl9LAoJCXsKCQkJInNlcnZpY2UiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpneVJuSWlnUFhoOD0saXY6b1ROclhUWktYNzd5eW52Y1F3aHpYaW8yckVKWHNJQk1VRDZET0NScjRmQT0sdGFnOjJPY2habWJxZGNIZGxqQzZDS2t1bEE9PSx0eXBlOnN0cl0iLAoJCQkidG9rZW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpFd0dDWVQzayxpdjoxSE16VURxbVhySTNiaEdheGtuTWZ0d0VaOENjMXN6eGFNVjZBMTY0bWZjPSx0YWc6MGI1ZVJ3eFpENGo5dWppeFRqZkZaZz09LHR5cGU6c3RyXSIKCQl9CgldLAoJInNvbWVPdGhlcktleSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOnZWbHAzRUUxbWdUUVA5SlNER2RQZi8raDJGU3Fhalk9LGl2OnhZR0lvVFlQRW4rNGF4MkxUS2l4bFFiNU5hb3RWdyswUVZmRlNtOVFOV289LHRhZzorVTRKUWJtLzhtRldBbWxNcnlnN0xBPT0sdHlwZTpzdHJdIiwKCSJzcGVjaWZpYyI6IHsKCQkiU3BlY2lhbENoYXJhY3RlcnMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp1UHFGT1NqVU1nVmRyb1VCSU02cWVybk9zQT09LGl2OnJTU2NOZ2wzZzY2K0lUQVlZamp5VTJIekJXWUR5OGxCY0NHR1hGdkhJZ289LHRhZzpKRXczeVlkaUxLK0YrTUN5V2N0aDZ3PT0sdHlwZTpzdHJdIiwKCQkiSFRNTEVuY29kaW5nVGVzdDEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTprc0N1M0cwckcyTmY1K2MvOXZTczBhb2wreG52LGl2OjcrUEp0M1E5MUNIbXZSSHFESWJBcFNNYVlMb1pxM0QxL0JuYUEzQ2ZzTXc9LHRhZzpTL0F0MmNsU3NHQXZIU2tqTHdldHFRPT0sdHlwZTpzdHJdIiwKCQkiSFRNTEVuY29kaW5nVGVzdDIiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpadz09LGl2OmpIM1JrUkpzTURMK2dQUHpwTHYxZ1BYL1RMeTlVMXpTUHFJcEY5N3dUYjQ9LHRhZzozWGFmN0pXWVl4SVFRUjg4ZWIrRkRnPT0sdHlwZTpzdHJdIiwKCQkiSFRMTUVuY29kaW5nVGVzdDMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpVQT09LGl2OlpZcUNoTUxCZlFvS0hjbHU5NHNiY0k5OHNWR3Z5bU0zN0Vzc2h2ejBJdXc9LHRhZzpVVjF6RmltY2dFVEQwbmNUanBnRHZnPT0sdHlwZTpzdHJdIiwKCQkibnVsbCI6IG51bGwsCgkJImJvb2xlYW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp3MnNZL0E9PSxpdjpLKzJBTDhEYTcwKzFtQlZ6dXEyZU9nemtFRndlbWJFY3lYOEhYS0lBcVI4PSx0YWc6S1lDdzNtNlBUOHJjdTFpL21HWko1Zz09LHR5cGU6Ym9vbF0iLAoJCSJudW1iZXIxIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6M1kxZixpdjpNQ0NUK0V3Tm5wVkxldS9La2lRTmxJR0dva2ltaDZVN1BORUZFeXIxdTRBPSx0YWc6alpWYU1ObjRyZ2grNWtXZ056aUlpZz09LHR5cGU6ZmxvYXRdIiwKCQkibnVtYmVyMiI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOkVQZ1REN1p4VlE9PSxpdjorWkpnZkQyVi9zM1hCalF1enEweXNTNWZZdFMyUDJoWDcyZGo5cW11SENFPSx0YWc6Zk05Zyt3dHViakFmalhQSEN2c1hWQT09LHR5cGU6ZmxvYXRdIgoJfSwKCSJzb3BzIjogewoJCSJrbXMiOiBudWxsLAoJCSJnY3Bfa21zIjogbnVsbCwKCQkiYXp1cmVfa3YiOiBudWxsLAoJCSJoY192YXVsdCI6IG51bGwsCgkJImFnZSI6IFsKCQkJewoJCQkJInJlY2lwaWVudCI6ICJhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dSIsCgkJCQkiZW5jIjogIi0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS1cbllXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JqU0N0dE1GbFlaRTlGWmpkSFMyZ3dcblFqZGplRk5tUm1sUVZuVllNSEl2VXpsTFRFSkZaVkZ4WjFFMENtRnhXblJ3ZWpOTVpYcEJObnBsYVVWRGR6WnRcblFXWkdWRUo1UXpNelVVaHVkMGhrU1c1dmRHRmlVMDBLTFMwdElEVnBSVEpITWxocVRHSlpTeXRyYW5aYVNXMWFcbmNsQTBZV0ZVTlhJclkyeDJlbWg1ZEdGVGQxVmpZekFLQTlSOUMrNDJiWjJiS0RVbjhLNlNEZlE1S2tySUNZM3JcbjBOMjdWNThaUEFvNDh0cWtoZWEvbzBEQnRrZGxsckJIT3hHZU9JSm0vd0ZPZm5FVHJaNjhWdz09XG4tLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuIgoJCQl9CgkJXSwKCQkibGFzdG1vZGlmaWVkIjogIjIwMjUtMDItMDdUMTQ6NDc6MTRaIiwKCQkibWFjIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6N0N1Q2o3c0plS0ZaRnBGcDZqaTNCZkd6RFkrWDZaNWVmY2NwVHNiRGo0Y2svUVl1K3gzaUxraXJoaHJHSDBoRXVONnhIS0Fqcnkvam1DUkpwR2grN0VHbTNmZlFvU1l1OW9DK3VqU1gzKzdhV2ZoT3Y4Uk90N1IzOFo5anpFbjFxcGhLRVg5bEszTytJcnVYSGZVRSs2dC96cXdsSVZqTUdhSTFBUmJMQktBPSxpdjpuOGNlSGI0V3dYeTRWSXgvbUpOV05Nd0diRjZJdk11T3cvWVFhN0p4UmlZPSx0YWc6aGZVM1NiWkU3Y0FKOVFUWFJHWmo3dz09LHR5cGU6c3RyXSIsCgkJInBncCI6IG51bGwsCgkJInVuZW5jcnlwdGVkX3N1ZmZpeCI6ICJfdW5lbmNyeXB0ZWQiLAoJCSJ2ZXJzaW9uIjogIjMuOS40IgoJfQp9", + "Hash": "e79149a81c3a4f62383c195070a39111284086e5c754f516b315c09943583dfb" + }, + "FlattenSeparator": "/", + "Format": "json", + "EncryptionKey": "58b75958-883a-440c-842c-85af5d33a5bb", + "ResourceType": "PARAMETER_MULTI", + "Target": "/Json/" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + }, + { + "Ref": "JsonSopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess0B4B19A62" + }, + { + "Ref": "YamlSopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess0A22A1629" + } + ] + } + }, + "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "kms:Decrypt", + "kms:Encrypt", + "kms:ReEncrypt*", + "kms:GenerateDataKey*" + ], + "Effect": "Allow", + "Resource": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", + "Roles": [ + { + "Ref": "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" + } + ] + } + }, + "SingletonLambdaSopsSyncProviderAA18D140": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4.zip" + }, + "Environment": { + "Variables": { + "SOPS_AGE_KEY": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" + } + }, + "Handler": "bootstrap", + "Role": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25", + "Arn" + ] + }, + "Runtime": "provided.al2", + "Timeout": 60 + }, + "DependsOn": [ + "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", + "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" + ] + }, + "YamlResourceYamlapiKey6387C0EA": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/apiKey", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamldatabaseuser0BD59C5D": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/database/user", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamldatabasepassword99035603": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/database/password", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamldatabasehostB5A0FE91": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/database/host", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamltokens0service8AE519C3": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/tokens/0/service", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamltokens0token8810E18D": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/tokens/0/token", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamltokens1service870E3CC4": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/tokens/1/service", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamltokens1tokenAC2DFE7E": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/tokens/1/token", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamlsomeOtherKey98D03965": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/someOtherKey", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamlspecificSpecialCharacters5B206BEA": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/specific/SpecialCharacters", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamlspecificHTMLEncodingTest10D2233FA": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/specific/HTMLEncodingTest1", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamlspecificHTMLEncodingTest2761B8FA7": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/specific/HTMLEncodingTest2", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamlspecificHTLMEncodingTest32407BA78": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/specific/HTLMEncodingTest3", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamlspecificnull5A2012DC": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/specific/null", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamlspecificboolean377BB393": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/specific/boolean", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamlspecificnumber1E294648B": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/specific/number1", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlResourceYamlspecificnumber28F676023": { + "Type": "AWS::SSM::Parameter", + "Properties": { + "Name": "/Yaml/specific/number2", + "Tier": "Standard", + "Type": "String", + "Value": " " + } + }, + "YamlSopsSyncSopsSecretParameterProviderManagedPolicyParameterAccess0A22A1629": { + "Type": "AWS::IAM::ManagedPolicy", + "Properties": { + "Description": "Policy to grant parameter provider permissions to put parameter", + "Path": "/", + "PolicyDocument": { + "Statement": [ + { + "Action": "ssm:PutParameter", + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/apiKey" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/database/user" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/database/password" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/database/host" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/tokens/0/service" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/tokens/0/token" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/tokens/1/service" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/tokens/1/token" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/someOtherKey" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/specific/SpecialCharacters" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/specific/HTMLEncodingTest1" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/specific/HTMLEncodingTest2" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/specific/HTLMEncodingTest3" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/specific/null" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/specific/boolean" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/specific/number1" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:aws:ssm:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":parameter/Yaml/specific/number2" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + } + } + }, + "YamlSopsSync65050259": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "YXBpS2V5OiBFTkNbQUVTMjU2X0dDTSxkYXRhOnI2WWZyd0drVkZ4QkY4bUhFY3NQYXhNdFVRPT0saXY6LzhycjRLNW1CeExpM2pSMmxIZmVleVZPL3dRWTAwcGMvL093NXZxWTE3UT0sdGFnOitkZ0xhS2VTeE5OQnVPRUZJZnRPWnc9PSx0eXBlOnN0cl0KZGF0YWJhc2U6CiAgICB1c2VyOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNkc1V5dm89LGl2OklWaW9KQ1Z5Uk9laEF0RzZ4Ym1BWnpkNTJIUXZrMGVaSXRNQmpCQXZxeDg9LHRhZzowcHVtemR5SDV3aUVBck1tbXJhM1VRPT0sdHlwZTpzdHJdCiAgICBwYXNzd29yZDogRU5DW0FFUzI1Nl9HQ00sZGF0YTpDU1E4akZyeG5MUVksaXY6aFhMRU5tRzhxTEdzR2RXdjN3YnJqNUxmMnpiRjFUb05Jd1M0eTF1V0VYZz0sdGFnOjhRRENNeUE2OWRZbDU4eEl1UDFEY0E9PSx0eXBlOnN0cl0KICAgIGhvc3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6eGZVMmVDKy8rdXZDa0hZOFFIWT0saXY6VUxXZHZvYTZyOEYxZzIrWkYzeFB3YWsxRWRoRFdtbmRzTzVSVXhBVlBFOD0sdGFnOktHbEpHMUlNU1duNG5FdE1hT1NzZGc9PSx0eXBlOnN0cl0KdG9rZW5zOgogICAgLSBzZXJ2aWNlOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnRSU1VwR0tJRW1jPSxpdjpoaS8zOGlDL0dsYzRueFVrUllCVjJjeTk0NmsrYXpYRnRFZEpPTlAxZy93PSx0YWc6R1EwL1dFaHRleXFDcHNFdi9TRnJiQT09LHR5cGU6c3RyXQogICAgICB0b2tlbjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpDR25TTzRIRSxpdjpMSDB4VldOVGJCbUhQUTFPaVA1K3VSRmZHL0U3SzdPR1lxS0hYT0tqZThRPSx0YWc6c09ZaGdLS1Yxb2dPczdQSnJCcnNqdz09LHR5cGU6c3RyXQogICAgLSBzZXJ2aWNlOiBFTkNbQUVTMjU2X0dDTSxkYXRhOm9ocVh2Wi83SFd3PSxpdjpDcGpVZFRiR0w0VEdSSVd0RUp4Wjg5MjN0dy9Rb213K2tDdGlIdUZpR1FjPSx0YWc6OTVUUVVhM05TVzFxR1Q4TE5zRWdiUT09LHR5cGU6c3RyXQogICAgICB0b2tlbjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpJMEkvWGdXbCxpdjo4N0UvYzdEaUdLVDIydGRkQ0ZxQnVQT0M3MzZ5djVZRDlNLytnM1BpWlg0PSx0YWc6WjFwcklIZkgzOW0yVTZpMktlVjIyUT09LHR5cGU6c3RyXQpzb21lT3RoZXJLZXk6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6SFNNRndNWEhuaTE4dFRPUHcyREFFMGc1WFFSOW9Vdz0saXY6NHhUUk84VFloYmxhMDFnemF0aGY3VUJIaDhHdGhkOTdHSXhYLzBrQ1h3Zz0sdGFnOjRwc0VGVzNPMlJxcVlONjhVMjNQeHc9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6CiAgICBTcGVjaWFsQ2hhcmFjdGVyczogRU5DW0FFUzI1Nl9HQ00sZGF0YTpFL2pxa1B2VVNiaFpQYm0wdnJDalgxc29MQT09LGl2OlJ0bzBFeVFUMm96Rm1rMXR2azN4UkR3Vm5OcHJBNXhqcENOR1RaaWViMEE9LHRhZzpwUnZoc1huVnJiMnFHRzFvY3U1bUt3PT0sdHlwZTpzdHJdCiAgICBIVE1MRW5jb2RpbmdUZXN0MTogRU5DW0FFUzI1Nl9HQ00sZGF0YTpaZGM1dlpPQklRUjhtY2xyUHl0dm15ZzRIUWVELGl2OldHelMwK0xTUDlYYUZlcWgxYVptbWdPNTRaRG44VGYyWUlPaXdtSkhwMEk9LHRhZzpaZEEveFg3Mkp6Qll4R1ZjVjJhMlJBPT0sdHlwZTpzdHJdCiAgICBIVE1MRW5jb2RpbmdUZXN0MjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpYdz09LGl2OmJsWUpYd1Qrd0VyZ1Zzd2FDVzhvV1lubnk4OG9MMXl2Rng4ZTNKY0UwOVE9LHRhZzorWVV5MDJ4YUpocXFhdEJ0a2o5NzJBPT0sdHlwZTpzdHJdCiAgICBIVExNRW5jb2RpbmdUZXN0MzogRU5DW0FFUzI1Nl9HQ00sZGF0YTovdz09LGl2Oi80ZVNWdEZRN2NHb05JN1VPTXc4bHkwK2FpWDdXaXZVNGloTWxWS1VENWs9LHRhZzpjTFNPOENSMElNK1k1TFpmZE00M0JRPT0sdHlwZTpzdHJdCiAgICAibnVsbCI6IG51bGwKICAgIGJvb2xlYW46IEVOQ1tBRVMyNTZfR0NNLGRhdGE6RDFpYVVBPT0saXY6U3VyVUFCaHFNK1VZaUNaYUVtanlHS1phaTJqREpMM25uWko0MXRNTkhCUT0sdGFnOmdld0ZsY2NVZGIzSXlYN2tQK1NQM3c9PSx0eXBlOmJvb2xdCiAgICBudW1iZXIxOiBFTkNbQUVTMjU2X0dDTSxkYXRhOk1jQk0saXY6VmpZRXBkVmdMc2pYR20yVlJEOUx1MEJYeU9NRmprVU1RSWp2dVZvZDVjcz0sdGFnOjdFZm5LMHFjSVRSZzFPYnJpdTdFZ2c9PSx0eXBlOmludF0KICAgIG51bWJlcjI6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6d0xjdTBYanlKZz09LGl2OnRaVC9BTVlNVG9aaTVudW82alV4d0IwMUhQWDRIaEhwZHQ2djd1elo5U0U9LHRhZzpmZ0s0R2ZpNVlCQTFMdXBKQlgyc0JBPT0sdHlwZTpmbG9hdF0Kc29wczoKICAgIGttczogW10KICAgIGdjcF9rbXM6IFtdCiAgICBhenVyZV9rdjogW10KICAgIGhjX3ZhdWx0OiBbXQogICAgYWdlOgogICAgICAgIC0gcmVjaXBpZW50OiBhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dQogICAgICAgICAgZW5jOiB8CiAgICAgICAgICAgIC0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgICAgICAgICAgWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQlljM0Y2WkZZNFJGbGxiU3RwTXpFegogICAgICAgICAgICBXbXh1TnpkdU15dGpSa2gxWTI0eE1VTm9WbmRDWVVOaGFHdEpDakp3WjFBelpsQlZjVmQ2WTJORmJHUjRNbVZGCiAgICAgICAgICAgIGJXOU9XV2gyYm1SamFGUnJPRm95ZVdWV2JuSlRlV01LTFMwdElFeHlWRE5GUlhwRlRFcFJNell2V0cxUGFXTnoKICAgICAgICAgICAgVFc5NmQwdHFhakJMYzAxcGFWbEVaSEZYUjFGMmJYY0tMSUpnN3lUbTB1Q2lpUGlLc25zQXlSTS9hRFovZk52dwogICAgICAgICAgICBpaWxLVEI1d1AxcWRzN1N0Y1ZMSjE4UkdVbzl2dUFBOWlQME5aQ1A2a0tMVmdaYmNKL2FTZHc9PQogICAgICAgICAgICAtLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLQogICAgbGFzdG1vZGlmaWVkOiAiMjAyNS0wMi0wN1QxNDo0NzowOVoiCiAgICBtYWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6U3gyRDZTRitwUUhRK291eDdsTmV4c2hQb2RjZ2UzdzJnNml4TFRqSy9Oa0VneUJNbWdzVnlCR1dNbCtrU2s2UFk1OEhUNEFRcHlCdHVpVUtqM2pTSjRwWm1lcGdXSUFkeEtwQjNzbHF5MzhnZ2hZUDIvQUhTYkhZUnpoTFFJT3h4RE8waW5Vd3JvSGExM0h0dEpDekRmWEtOaUtyYk1SQVFLaytGV0Y2eDN3PSxpdjo3c0JqU2hWV3JXMTc3d1pCdityeFc2ZXFLMFZRY2pqR1dWdEh3OWRiR1RZPSx0YWc6Qm8zb1lGZ2JBVGJOVndEdFAyUkFhdz09LHR5cGU6c3RyXQogICAgcGdwOiBbXQogICAgdW5lbmNyeXB0ZWRfc3VmZml4OiBfdW5lbmNyeXB0ZWQKICAgIHZlcnNpb246IDMuOS40Cg==", + "Hash": "9912a0ccf8001b767579817f902a5d7e030019cc7b6db34c028f4a0f9079fddf" + }, + "FlattenSeparator": "/", + "Format": "yaml", + "EncryptionKey": "58b75958-883a-440c-842c-85af5d33a5bb", + "ResourceType": "PARAMETER_MULTI", + "Target": "/Yaml/" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "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/test/PARAMETER_MULTI.integ.ts b/test/PARAMETER_MULTI.integ.ts new file mode 100644 index 00000000..1fc76764 --- /dev/null +++ b/test/PARAMETER_MULTI.integ.ts @@ -0,0 +1,46 @@ +import * as cdk from 'aws-cdk-lib'; +import { Key } from 'aws-cdk-lib/aws-kms'; +import { MultiStringParameter } from '../src/index'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'PARAMETERMULTI'); + +interface TestCase { + name: string; + sopsFilePath: string; +} + +const tc = [ + { + name: 'Json', + sopsFilePath: 'test-secrets/testsecret.sops.json', + }, + { + name: 'Yaml', + sopsFilePath: 'test-secrets/testsecret.sops.yaml', + }, + // { NotSupported right now + // name: 'DotEnv', + // sopsFilePath: 'test-secrets/testsecret.sops.env', + // }, +] satisfies TestCase[]; + +const encryptionKey = Key.fromKeyArn( + stack, + 'Key', + 'arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb', +); + +tc.forEach((t) => { + new MultiStringParameter(stack, t.name, { + keyPrefix: `/${t.name}/`, + keySeparator: '/', + sopsFilePath: t.sopsFilePath, + sopsAgeKey: cdk.SecretValue.unsafePlainText( + 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', + ), + encryptionKey, + }); +}); + +app.synth(); diff --git a/test/SECRET.integ.snapshot/SECRET.assets.json b/test/SECRET.integ.snapshot/SECRET.assets.json new file mode 100644 index 00000000..626aee1a --- /dev/null +++ b/test/SECRET.integ.snapshot/SECRET.assets.json @@ -0,0 +1,32 @@ +{ + "version": "39.0.0", + "files": { + "d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4": { + "source": { + "path": "asset.d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4.zip", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "d7acf0346faeebfc056b5d712c021c29e4bb77ab9db7f766d78d483539fb7fc9": { + "source": { + "path": "SECRET.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "d7acf0346faeebfc056b5d712c021c29e4bb77ab9db7f766d78d483539fb7fc9.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/test/SECRET.integ.snapshot/SECRET.template.json b/test/SECRET.integ.snapshot/SECRET.template.json new file mode 100644 index 00000000..05fad039 --- /dev/null +++ b/test/SECRET.integ.snapshot/SECRET.template.json @@ -0,0 +1,408 @@ +{ + "Resources": { + "Json2JsonAD09CFF1": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "GenerateSecretString": {}, + "Name": "Json2Json" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Json2JsonSopsSync5CFFDB9D": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "ewoJImFwaUtleSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOmxMYlhWRWhCUktYaUdHa0JoNUtsdGdVQm9BPT0saXY6bHVheUpuaWlYSHdBM1owclp5eGVGMDB4bEhmTXdyWU1pWWgrYWhQNkF5bz0sdGFnOmwzazNwU256UlRBS2VBSE94dytmR3c9PSx0eXBlOnN0cl0iLAoJImRhdGFiYXNlIjogewoJCSJ1c2VyIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6a1F0a1Fhcz0saXY6K3F5SjlGVVhvTXRjcGNmZFQ3WlRPTkhmM1NzR2JBZkp6bkpGdDVlL3BWRT0sdGFnOjJDaW5telZlcW42NTRNZllkaGtxeGc9PSx0eXBlOnN0cl0iLAoJCSJwYXNzd29yZCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOmpId0NFSmgwMkE4cyxpdjppbXdIVzRVN0RWMDltNU5Dek81azBBdVJaZFkvVEsyK0YyOFZiV0ZINnlnPSx0YWc6cGNRM2g0MEQ5QXZCRlFFbmlSeE1vdz09LHR5cGU6c3RyXSIsCgkJImhvc3QiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpVM0p4L0drQnlLTFBuZWJzcDVVPSxpdjpjQ3VXOTlrdHlBSTRkVlF6RHQxL2pzZ0xQNXBNZFlZQ3NpNkFocXNnVlhzPSx0YWc6djE2enlZdTVBMVRWQlA0YmFPeEIxZz09LHR5cGU6c3RyXSIKCX0sCgkidG9rZW5zIjogWwoJCXsKCQkJInNlcnZpY2UiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpNTFFXOHRvY2dDYz0saXY6Ky9mb1F5UjdxMGh2Yk9rR2l2YXVVQVdkaWhmb0hLendnU1lkdjFHcTI5Yz0sdGFnOk8yZWJtVDJ1OU5mVnFvbzBxNEo5N3c9PSx0eXBlOnN0cl0iLAoJCQkidG9rZW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpwY3JGUVFEayxpdjorcS8zaTduaVR3bi9qeU9xZUhKOGhVVkE0ak44Q3FQWHVmV3NJUmtrcEpBPSx0YWc6YnVJczhHNE9maXVKUGYxMDgvc0RoUT09LHR5cGU6c3RyXSIKCQl9LAoJCXsKCQkJInNlcnZpY2UiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpneVJuSWlnUFhoOD0saXY6b1ROclhUWktYNzd5eW52Y1F3aHpYaW8yckVKWHNJQk1VRDZET0NScjRmQT0sdGFnOjJPY2habWJxZGNIZGxqQzZDS2t1bEE9PSx0eXBlOnN0cl0iLAoJCQkidG9rZW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpFd0dDWVQzayxpdjoxSE16VURxbVhySTNiaEdheGtuTWZ0d0VaOENjMXN6eGFNVjZBMTY0bWZjPSx0YWc6MGI1ZVJ3eFpENGo5dWppeFRqZkZaZz09LHR5cGU6c3RyXSIKCQl9CgldLAoJInNvbWVPdGhlcktleSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOnZWbHAzRUUxbWdUUVA5SlNER2RQZi8raDJGU3Fhalk9LGl2OnhZR0lvVFlQRW4rNGF4MkxUS2l4bFFiNU5hb3RWdyswUVZmRlNtOVFOV289LHRhZzorVTRKUWJtLzhtRldBbWxNcnlnN0xBPT0sdHlwZTpzdHJdIiwKCSJzcGVjaWZpYyI6IHsKCQkiU3BlY2lhbENoYXJhY3RlcnMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp1UHFGT1NqVU1nVmRyb1VCSU02cWVybk9zQT09LGl2OnJTU2NOZ2wzZzY2K0lUQVlZamp5VTJIekJXWUR5OGxCY0NHR1hGdkhJZ289LHRhZzpKRXczeVlkaUxLK0YrTUN5V2N0aDZ3PT0sdHlwZTpzdHJdIiwKCQkiSFRNTEVuY29kaW5nVGVzdDEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTprc0N1M0cwckcyTmY1K2MvOXZTczBhb2wreG52LGl2OjcrUEp0M1E5MUNIbXZSSHFESWJBcFNNYVlMb1pxM0QxL0JuYUEzQ2ZzTXc9LHRhZzpTL0F0MmNsU3NHQXZIU2tqTHdldHFRPT0sdHlwZTpzdHJdIiwKCQkiSFRNTEVuY29kaW5nVGVzdDIiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpadz09LGl2OmpIM1JrUkpzTURMK2dQUHpwTHYxZ1BYL1RMeTlVMXpTUHFJcEY5N3dUYjQ9LHRhZzozWGFmN0pXWVl4SVFRUjg4ZWIrRkRnPT0sdHlwZTpzdHJdIiwKCQkiSFRMTUVuY29kaW5nVGVzdDMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpVQT09LGl2OlpZcUNoTUxCZlFvS0hjbHU5NHNiY0k5OHNWR3Z5bU0zN0Vzc2h2ejBJdXc9LHRhZzpVVjF6RmltY2dFVEQwbmNUanBnRHZnPT0sdHlwZTpzdHJdIiwKCQkibnVsbCI6IG51bGwsCgkJImJvb2xlYW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp3MnNZL0E9PSxpdjpLKzJBTDhEYTcwKzFtQlZ6dXEyZU9nemtFRndlbWJFY3lYOEhYS0lBcVI4PSx0YWc6S1lDdzNtNlBUOHJjdTFpL21HWko1Zz09LHR5cGU6Ym9vbF0iLAoJCSJudW1iZXIxIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6M1kxZixpdjpNQ0NUK0V3Tm5wVkxldS9La2lRTmxJR0dva2ltaDZVN1BORUZFeXIxdTRBPSx0YWc6alpWYU1ObjRyZ2grNWtXZ056aUlpZz09LHR5cGU6ZmxvYXRdIiwKCQkibnVtYmVyMiI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOkVQZ1REN1p4VlE9PSxpdjorWkpnZkQyVi9zM1hCalF1enEweXNTNWZZdFMyUDJoWDcyZGo5cW11SENFPSx0YWc6Zk05Zyt3dHViakFmalhQSEN2c1hWQT09LHR5cGU6ZmxvYXRdIgoJfSwKCSJzb3BzIjogewoJCSJrbXMiOiBudWxsLAoJCSJnY3Bfa21zIjogbnVsbCwKCQkiYXp1cmVfa3YiOiBudWxsLAoJCSJoY192YXVsdCI6IG51bGwsCgkJImFnZSI6IFsKCQkJewoJCQkJInJlY2lwaWVudCI6ICJhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dSIsCgkJCQkiZW5jIjogIi0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS1cbllXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JqU0N0dE1GbFlaRTlGWmpkSFMyZ3dcblFqZGplRk5tUm1sUVZuVllNSEl2VXpsTFRFSkZaVkZ4WjFFMENtRnhXblJ3ZWpOTVpYcEJObnBsYVVWRGR6WnRcblFXWkdWRUo1UXpNelVVaHVkMGhrU1c1dmRHRmlVMDBLTFMwdElEVnBSVEpITWxocVRHSlpTeXRyYW5aYVNXMWFcbmNsQTBZV0ZVTlhJclkyeDJlbWg1ZEdGVGQxVmpZekFLQTlSOUMrNDJiWjJiS0RVbjhLNlNEZlE1S2tySUNZM3JcbjBOMjdWNThaUEFvNDh0cWtoZWEvbzBEQnRrZGxsckJIT3hHZU9JSm0vd0ZPZm5FVHJaNjhWdz09XG4tLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuIgoJCQl9CgkJXSwKCQkibGFzdG1vZGlmaWVkIjogIjIwMjUtMDItMDdUMTQ6NDc6MTRaIiwKCQkibWFjIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6N0N1Q2o3c0plS0ZaRnBGcDZqaTNCZkd6RFkrWDZaNWVmY2NwVHNiRGo0Y2svUVl1K3gzaUxraXJoaHJHSDBoRXVONnhIS0Fqcnkvam1DUkpwR2grN0VHbTNmZlFvU1l1OW9DK3VqU1gzKzdhV2ZoT3Y4Uk90N1IzOFo5anpFbjFxcGhLRVg5bEszTytJcnVYSGZVRSs2dC96cXdsSVZqTUdhSTFBUmJMQktBPSxpdjpuOGNlSGI0V3dYeTRWSXgvbUpOV05Nd0diRjZJdk11T3cvWVFhN0p4UmlZPSx0YWc6aGZVM1NiWkU3Y0FKOVFUWFJHWmo3dz09LHR5cGU6c3RyXSIsCgkJInBncCI6IG51bGwsCgkJInVuZW5jcnlwdGVkX3N1ZmZpeCI6ICJfdW5lbmNyeXB0ZWQiLAoJCSJ2ZXJzaW9uIjogIjMuOS40IgoJfQp9", + "Hash": "e79149a81c3a4f62383c195070a39111284086e5c754f516b315c09943583dfb" + }, + "FlattenSeparator": ".", + "Format": "json", + "ResourceType": "SECRET", + "Target": { + "Ref": "Json2JsonAD09CFF1" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "secretsmanager:PutSecretValue", + "secretsmanager:UpdateSecret" + ], + "Effect": "Allow", + "Resource": { + "Ref": "Json2JsonAD09CFF1" + } + }, + { + "Action": [ + "secretsmanager:PutSecretValue", + "secretsmanager:UpdateSecret" + ], + "Effect": "Allow", + "Resource": { + "Ref": "Yaml2Json4AC73F66" + } + }, + { + "Action": [ + "secretsmanager:PutSecretValue", + "secretsmanager:UpdateSecret" + ], + "Effect": "Allow", + "Resource": { + "Ref": "Json2Raw339EA21E" + } + }, + { + "Action": [ + "secretsmanager:PutSecretValue", + "secretsmanager:UpdateSecret" + ], + "Effect": "Allow", + "Resource": { + "Ref": "Yaml2RawEB5BB054" + } + }, + { + "Action": [ + "secretsmanager:PutSecretValue", + "secretsmanager:UpdateSecret" + ], + "Effect": "Allow", + "Resource": { + "Ref": "DotEnv2Json0B50F63B" + } + }, + { + "Action": [ + "secretsmanager:PutSecretValue", + "secretsmanager:UpdateSecret" + ], + "Effect": "Allow", + "Resource": { + "Ref": "DotEnv2RawF7654593" + } + }, + { + "Action": [ + "secretsmanager:PutSecretValue", + "secretsmanager:UpdateSecret" + ], + "Effect": "Allow", + "Resource": { + "Ref": "Binary2RawA83E0B31" + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", + "Roles": [ + { + "Ref": "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" + } + ] + } + }, + "SingletonLambdaSopsSyncProviderAA18D140": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4.zip" + }, + "Environment": { + "Variables": { + "SOPS_AGE_KEY": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" + } + }, + "Handler": "bootstrap", + "Role": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25", + "Arn" + ] + }, + "Runtime": "provided.al2", + "Timeout": 60 + }, + "DependsOn": [ + "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", + "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" + ] + }, + "Yaml2Json4AC73F66": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "GenerateSecretString": {}, + "Name": "Yaml2Json" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Yaml2JsonSopsSync33E502C1": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "YXBpS2V5OiBFTkNbQUVTMjU2X0dDTSxkYXRhOnI2WWZyd0drVkZ4QkY4bUhFY3NQYXhNdFVRPT0saXY6LzhycjRLNW1CeExpM2pSMmxIZmVleVZPL3dRWTAwcGMvL093NXZxWTE3UT0sdGFnOitkZ0xhS2VTeE5OQnVPRUZJZnRPWnc9PSx0eXBlOnN0cl0KZGF0YWJhc2U6CiAgICB1c2VyOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNkc1V5dm89LGl2OklWaW9KQ1Z5Uk9laEF0RzZ4Ym1BWnpkNTJIUXZrMGVaSXRNQmpCQXZxeDg9LHRhZzowcHVtemR5SDV3aUVBck1tbXJhM1VRPT0sdHlwZTpzdHJdCiAgICBwYXNzd29yZDogRU5DW0FFUzI1Nl9HQ00sZGF0YTpDU1E4akZyeG5MUVksaXY6aFhMRU5tRzhxTEdzR2RXdjN3YnJqNUxmMnpiRjFUb05Jd1M0eTF1V0VYZz0sdGFnOjhRRENNeUE2OWRZbDU4eEl1UDFEY0E9PSx0eXBlOnN0cl0KICAgIGhvc3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6eGZVMmVDKy8rdXZDa0hZOFFIWT0saXY6VUxXZHZvYTZyOEYxZzIrWkYzeFB3YWsxRWRoRFdtbmRzTzVSVXhBVlBFOD0sdGFnOktHbEpHMUlNU1duNG5FdE1hT1NzZGc9PSx0eXBlOnN0cl0KdG9rZW5zOgogICAgLSBzZXJ2aWNlOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnRSU1VwR0tJRW1jPSxpdjpoaS8zOGlDL0dsYzRueFVrUllCVjJjeTk0NmsrYXpYRnRFZEpPTlAxZy93PSx0YWc6R1EwL1dFaHRleXFDcHNFdi9TRnJiQT09LHR5cGU6c3RyXQogICAgICB0b2tlbjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpDR25TTzRIRSxpdjpMSDB4VldOVGJCbUhQUTFPaVA1K3VSRmZHL0U3SzdPR1lxS0hYT0tqZThRPSx0YWc6c09ZaGdLS1Yxb2dPczdQSnJCcnNqdz09LHR5cGU6c3RyXQogICAgLSBzZXJ2aWNlOiBFTkNbQUVTMjU2X0dDTSxkYXRhOm9ocVh2Wi83SFd3PSxpdjpDcGpVZFRiR0w0VEdSSVd0RUp4Wjg5MjN0dy9Rb213K2tDdGlIdUZpR1FjPSx0YWc6OTVUUVVhM05TVzFxR1Q4TE5zRWdiUT09LHR5cGU6c3RyXQogICAgICB0b2tlbjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpJMEkvWGdXbCxpdjo4N0UvYzdEaUdLVDIydGRkQ0ZxQnVQT0M3MzZ5djVZRDlNLytnM1BpWlg0PSx0YWc6WjFwcklIZkgzOW0yVTZpMktlVjIyUT09LHR5cGU6c3RyXQpzb21lT3RoZXJLZXk6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6SFNNRndNWEhuaTE4dFRPUHcyREFFMGc1WFFSOW9Vdz0saXY6NHhUUk84VFloYmxhMDFnemF0aGY3VUJIaDhHdGhkOTdHSXhYLzBrQ1h3Zz0sdGFnOjRwc0VGVzNPMlJxcVlONjhVMjNQeHc9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6CiAgICBTcGVjaWFsQ2hhcmFjdGVyczogRU5DW0FFUzI1Nl9HQ00sZGF0YTpFL2pxa1B2VVNiaFpQYm0wdnJDalgxc29MQT09LGl2OlJ0bzBFeVFUMm96Rm1rMXR2azN4UkR3Vm5OcHJBNXhqcENOR1RaaWViMEE9LHRhZzpwUnZoc1huVnJiMnFHRzFvY3U1bUt3PT0sdHlwZTpzdHJdCiAgICBIVE1MRW5jb2RpbmdUZXN0MTogRU5DW0FFUzI1Nl9HQ00sZGF0YTpaZGM1dlpPQklRUjhtY2xyUHl0dm15ZzRIUWVELGl2OldHelMwK0xTUDlYYUZlcWgxYVptbWdPNTRaRG44VGYyWUlPaXdtSkhwMEk9LHRhZzpaZEEveFg3Mkp6Qll4R1ZjVjJhMlJBPT0sdHlwZTpzdHJdCiAgICBIVE1MRW5jb2RpbmdUZXN0MjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpYdz09LGl2OmJsWUpYd1Qrd0VyZ1Zzd2FDVzhvV1lubnk4OG9MMXl2Rng4ZTNKY0UwOVE9LHRhZzorWVV5MDJ4YUpocXFhdEJ0a2o5NzJBPT0sdHlwZTpzdHJdCiAgICBIVExNRW5jb2RpbmdUZXN0MzogRU5DW0FFUzI1Nl9HQ00sZGF0YTovdz09LGl2Oi80ZVNWdEZRN2NHb05JN1VPTXc4bHkwK2FpWDdXaXZVNGloTWxWS1VENWs9LHRhZzpjTFNPOENSMElNK1k1TFpmZE00M0JRPT0sdHlwZTpzdHJdCiAgICAibnVsbCI6IG51bGwKICAgIGJvb2xlYW46IEVOQ1tBRVMyNTZfR0NNLGRhdGE6RDFpYVVBPT0saXY6U3VyVUFCaHFNK1VZaUNaYUVtanlHS1phaTJqREpMM25uWko0MXRNTkhCUT0sdGFnOmdld0ZsY2NVZGIzSXlYN2tQK1NQM3c9PSx0eXBlOmJvb2xdCiAgICBudW1iZXIxOiBFTkNbQUVTMjU2X0dDTSxkYXRhOk1jQk0saXY6VmpZRXBkVmdMc2pYR20yVlJEOUx1MEJYeU9NRmprVU1RSWp2dVZvZDVjcz0sdGFnOjdFZm5LMHFjSVRSZzFPYnJpdTdFZ2c9PSx0eXBlOmludF0KICAgIG51bWJlcjI6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6d0xjdTBYanlKZz09LGl2OnRaVC9BTVlNVG9aaTVudW82alV4d0IwMUhQWDRIaEhwZHQ2djd1elo5U0U9LHRhZzpmZ0s0R2ZpNVlCQTFMdXBKQlgyc0JBPT0sdHlwZTpmbG9hdF0Kc29wczoKICAgIGttczogW10KICAgIGdjcF9rbXM6IFtdCiAgICBhenVyZV9rdjogW10KICAgIGhjX3ZhdWx0OiBbXQogICAgYWdlOgogICAgICAgIC0gcmVjaXBpZW50OiBhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dQogICAgICAgICAgZW5jOiB8CiAgICAgICAgICAgIC0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgICAgICAgICAgWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQlljM0Y2WkZZNFJGbGxiU3RwTXpFegogICAgICAgICAgICBXbXh1TnpkdU15dGpSa2gxWTI0eE1VTm9WbmRDWVVOaGFHdEpDakp3WjFBelpsQlZjVmQ2WTJORmJHUjRNbVZGCiAgICAgICAgICAgIGJXOU9XV2gyYm1SamFGUnJPRm95ZVdWV2JuSlRlV01LTFMwdElFeHlWRE5GUlhwRlRFcFJNell2V0cxUGFXTnoKICAgICAgICAgICAgVFc5NmQwdHFhakJMYzAxcGFWbEVaSEZYUjFGMmJYY0tMSUpnN3lUbTB1Q2lpUGlLc25zQXlSTS9hRFovZk52dwogICAgICAgICAgICBpaWxLVEI1d1AxcWRzN1N0Y1ZMSjE4UkdVbzl2dUFBOWlQME5aQ1A2a0tMVmdaYmNKL2FTZHc9PQogICAgICAgICAgICAtLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLQogICAgbGFzdG1vZGlmaWVkOiAiMjAyNS0wMi0wN1QxNDo0NzowOVoiCiAgICBtYWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6U3gyRDZTRitwUUhRK291eDdsTmV4c2hQb2RjZ2UzdzJnNml4TFRqSy9Oa0VneUJNbWdzVnlCR1dNbCtrU2s2UFk1OEhUNEFRcHlCdHVpVUtqM2pTSjRwWm1lcGdXSUFkeEtwQjNzbHF5MzhnZ2hZUDIvQUhTYkhZUnpoTFFJT3h4RE8waW5Vd3JvSGExM0h0dEpDekRmWEtOaUtyYk1SQVFLaytGV0Y2eDN3PSxpdjo3c0JqU2hWV3JXMTc3d1pCdityeFc2ZXFLMFZRY2pqR1dWdEh3OWRiR1RZPSx0YWc6Qm8zb1lGZ2JBVGJOVndEdFAyUkFhdz09LHR5cGU6c3RyXQogICAgcGdwOiBbXQogICAgdW5lbmNyeXB0ZWRfc3VmZml4OiBfdW5lbmNyeXB0ZWQKICAgIHZlcnNpb246IDMuOS40Cg==", + "Hash": "9912a0ccf8001b767579817f902a5d7e030019cc7b6db34c028f4a0f9079fddf" + }, + "FlattenSeparator": ".", + "Format": "yaml", + "ResourceType": "SECRET", + "Target": { + "Ref": "Yaml2Json4AC73F66" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Json2Raw339EA21E": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "GenerateSecretString": {}, + "Name": "Json2Raw" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Json2RawSopsSyncD3A7B74E": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "ewoJImFwaUtleSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOmxMYlhWRWhCUktYaUdHa0JoNUtsdGdVQm9BPT0saXY6bHVheUpuaWlYSHdBM1owclp5eGVGMDB4bEhmTXdyWU1pWWgrYWhQNkF5bz0sdGFnOmwzazNwU256UlRBS2VBSE94dytmR3c9PSx0eXBlOnN0cl0iLAoJImRhdGFiYXNlIjogewoJCSJ1c2VyIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6a1F0a1Fhcz0saXY6K3F5SjlGVVhvTXRjcGNmZFQ3WlRPTkhmM1NzR2JBZkp6bkpGdDVlL3BWRT0sdGFnOjJDaW5telZlcW42NTRNZllkaGtxeGc9PSx0eXBlOnN0cl0iLAoJCSJwYXNzd29yZCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOmpId0NFSmgwMkE4cyxpdjppbXdIVzRVN0RWMDltNU5Dek81azBBdVJaZFkvVEsyK0YyOFZiV0ZINnlnPSx0YWc6cGNRM2g0MEQ5QXZCRlFFbmlSeE1vdz09LHR5cGU6c3RyXSIsCgkJImhvc3QiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpVM0p4L0drQnlLTFBuZWJzcDVVPSxpdjpjQ3VXOTlrdHlBSTRkVlF6RHQxL2pzZ0xQNXBNZFlZQ3NpNkFocXNnVlhzPSx0YWc6djE2enlZdTVBMVRWQlA0YmFPeEIxZz09LHR5cGU6c3RyXSIKCX0sCgkidG9rZW5zIjogWwoJCXsKCQkJInNlcnZpY2UiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpNTFFXOHRvY2dDYz0saXY6Ky9mb1F5UjdxMGh2Yk9rR2l2YXVVQVdkaWhmb0hLendnU1lkdjFHcTI5Yz0sdGFnOk8yZWJtVDJ1OU5mVnFvbzBxNEo5N3c9PSx0eXBlOnN0cl0iLAoJCQkidG9rZW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpwY3JGUVFEayxpdjorcS8zaTduaVR3bi9qeU9xZUhKOGhVVkE0ak44Q3FQWHVmV3NJUmtrcEpBPSx0YWc6YnVJczhHNE9maXVKUGYxMDgvc0RoUT09LHR5cGU6c3RyXSIKCQl9LAoJCXsKCQkJInNlcnZpY2UiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpneVJuSWlnUFhoOD0saXY6b1ROclhUWktYNzd5eW52Y1F3aHpYaW8yckVKWHNJQk1VRDZET0NScjRmQT0sdGFnOjJPY2habWJxZGNIZGxqQzZDS2t1bEE9PSx0eXBlOnN0cl0iLAoJCQkidG9rZW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpFd0dDWVQzayxpdjoxSE16VURxbVhySTNiaEdheGtuTWZ0d0VaOENjMXN6eGFNVjZBMTY0bWZjPSx0YWc6MGI1ZVJ3eFpENGo5dWppeFRqZkZaZz09LHR5cGU6c3RyXSIKCQl9CgldLAoJInNvbWVPdGhlcktleSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOnZWbHAzRUUxbWdUUVA5SlNER2RQZi8raDJGU3Fhalk9LGl2OnhZR0lvVFlQRW4rNGF4MkxUS2l4bFFiNU5hb3RWdyswUVZmRlNtOVFOV289LHRhZzorVTRKUWJtLzhtRldBbWxNcnlnN0xBPT0sdHlwZTpzdHJdIiwKCSJzcGVjaWZpYyI6IHsKCQkiU3BlY2lhbENoYXJhY3RlcnMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp1UHFGT1NqVU1nVmRyb1VCSU02cWVybk9zQT09LGl2OnJTU2NOZ2wzZzY2K0lUQVlZamp5VTJIekJXWUR5OGxCY0NHR1hGdkhJZ289LHRhZzpKRXczeVlkaUxLK0YrTUN5V2N0aDZ3PT0sdHlwZTpzdHJdIiwKCQkiSFRNTEVuY29kaW5nVGVzdDEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTprc0N1M0cwckcyTmY1K2MvOXZTczBhb2wreG52LGl2OjcrUEp0M1E5MUNIbXZSSHFESWJBcFNNYVlMb1pxM0QxL0JuYUEzQ2ZzTXc9LHRhZzpTL0F0MmNsU3NHQXZIU2tqTHdldHFRPT0sdHlwZTpzdHJdIiwKCQkiSFRNTEVuY29kaW5nVGVzdDIiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpadz09LGl2OmpIM1JrUkpzTURMK2dQUHpwTHYxZ1BYL1RMeTlVMXpTUHFJcEY5N3dUYjQ9LHRhZzozWGFmN0pXWVl4SVFRUjg4ZWIrRkRnPT0sdHlwZTpzdHJdIiwKCQkiSFRMTUVuY29kaW5nVGVzdDMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpVQT09LGl2OlpZcUNoTUxCZlFvS0hjbHU5NHNiY0k5OHNWR3Z5bU0zN0Vzc2h2ejBJdXc9LHRhZzpVVjF6RmltY2dFVEQwbmNUanBnRHZnPT0sdHlwZTpzdHJdIiwKCQkibnVsbCI6IG51bGwsCgkJImJvb2xlYW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp3MnNZL0E9PSxpdjpLKzJBTDhEYTcwKzFtQlZ6dXEyZU9nemtFRndlbWJFY3lYOEhYS0lBcVI4PSx0YWc6S1lDdzNtNlBUOHJjdTFpL21HWko1Zz09LHR5cGU6Ym9vbF0iLAoJCSJudW1iZXIxIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6M1kxZixpdjpNQ0NUK0V3Tm5wVkxldS9La2lRTmxJR0dva2ltaDZVN1BORUZFeXIxdTRBPSx0YWc6alpWYU1ObjRyZ2grNWtXZ056aUlpZz09LHR5cGU6ZmxvYXRdIiwKCQkibnVtYmVyMiI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOkVQZ1REN1p4VlE9PSxpdjorWkpnZkQyVi9zM1hCalF1enEweXNTNWZZdFMyUDJoWDcyZGo5cW11SENFPSx0YWc6Zk05Zyt3dHViakFmalhQSEN2c1hWQT09LHR5cGU6ZmxvYXRdIgoJfSwKCSJzb3BzIjogewoJCSJrbXMiOiBudWxsLAoJCSJnY3Bfa21zIjogbnVsbCwKCQkiYXp1cmVfa3YiOiBudWxsLAoJCSJoY192YXVsdCI6IG51bGwsCgkJImFnZSI6IFsKCQkJewoJCQkJInJlY2lwaWVudCI6ICJhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dSIsCgkJCQkiZW5jIjogIi0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS1cbllXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JqU0N0dE1GbFlaRTlGWmpkSFMyZ3dcblFqZGplRk5tUm1sUVZuVllNSEl2VXpsTFRFSkZaVkZ4WjFFMENtRnhXblJ3ZWpOTVpYcEJObnBsYVVWRGR6WnRcblFXWkdWRUo1UXpNelVVaHVkMGhrU1c1dmRHRmlVMDBLTFMwdElEVnBSVEpITWxocVRHSlpTeXRyYW5aYVNXMWFcbmNsQTBZV0ZVTlhJclkyeDJlbWg1ZEdGVGQxVmpZekFLQTlSOUMrNDJiWjJiS0RVbjhLNlNEZlE1S2tySUNZM3JcbjBOMjdWNThaUEFvNDh0cWtoZWEvbzBEQnRrZGxsckJIT3hHZU9JSm0vd0ZPZm5FVHJaNjhWdz09XG4tLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuIgoJCQl9CgkJXSwKCQkibGFzdG1vZGlmaWVkIjogIjIwMjUtMDItMDdUMTQ6NDc6MTRaIiwKCQkibWFjIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6N0N1Q2o3c0plS0ZaRnBGcDZqaTNCZkd6RFkrWDZaNWVmY2NwVHNiRGo0Y2svUVl1K3gzaUxraXJoaHJHSDBoRXVONnhIS0Fqcnkvam1DUkpwR2grN0VHbTNmZlFvU1l1OW9DK3VqU1gzKzdhV2ZoT3Y4Uk90N1IzOFo5anpFbjFxcGhLRVg5bEszTytJcnVYSGZVRSs2dC96cXdsSVZqTUdhSTFBUmJMQktBPSxpdjpuOGNlSGI0V3dYeTRWSXgvbUpOV05Nd0diRjZJdk11T3cvWVFhN0p4UmlZPSx0YWc6aGZVM1NiWkU3Y0FKOVFUWFJHWmo3dz09LHR5cGU6c3RyXSIsCgkJInBncCI6IG51bGwsCgkJInVuZW5jcnlwdGVkX3N1ZmZpeCI6ICJfdW5lbmNyeXB0ZWQiLAoJCSJ2ZXJzaW9uIjogIjMuOS40IgoJfQp9", + "Hash": "e79149a81c3a4f62383c195070a39111284086e5c754f516b315c09943583dfb" + }, + "FlattenSeparator": ".", + "Format": "json", + "ResourceType": "SECRET_BINARY", + "Target": { + "Ref": "Json2Raw339EA21E" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Yaml2RawEB5BB054": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "GenerateSecretString": {}, + "Name": "Yaml2Raw" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Yaml2RawSopsSyncD824DA28": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "YXBpS2V5OiBFTkNbQUVTMjU2X0dDTSxkYXRhOnI2WWZyd0drVkZ4QkY4bUhFY3NQYXhNdFVRPT0saXY6LzhycjRLNW1CeExpM2pSMmxIZmVleVZPL3dRWTAwcGMvL093NXZxWTE3UT0sdGFnOitkZ0xhS2VTeE5OQnVPRUZJZnRPWnc9PSx0eXBlOnN0cl0KZGF0YWJhc2U6CiAgICB1c2VyOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNkc1V5dm89LGl2OklWaW9KQ1Z5Uk9laEF0RzZ4Ym1BWnpkNTJIUXZrMGVaSXRNQmpCQXZxeDg9LHRhZzowcHVtemR5SDV3aUVBck1tbXJhM1VRPT0sdHlwZTpzdHJdCiAgICBwYXNzd29yZDogRU5DW0FFUzI1Nl9HQ00sZGF0YTpDU1E4akZyeG5MUVksaXY6aFhMRU5tRzhxTEdzR2RXdjN3YnJqNUxmMnpiRjFUb05Jd1M0eTF1V0VYZz0sdGFnOjhRRENNeUE2OWRZbDU4eEl1UDFEY0E9PSx0eXBlOnN0cl0KICAgIGhvc3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6eGZVMmVDKy8rdXZDa0hZOFFIWT0saXY6VUxXZHZvYTZyOEYxZzIrWkYzeFB3YWsxRWRoRFdtbmRzTzVSVXhBVlBFOD0sdGFnOktHbEpHMUlNU1duNG5FdE1hT1NzZGc9PSx0eXBlOnN0cl0KdG9rZW5zOgogICAgLSBzZXJ2aWNlOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnRSU1VwR0tJRW1jPSxpdjpoaS8zOGlDL0dsYzRueFVrUllCVjJjeTk0NmsrYXpYRnRFZEpPTlAxZy93PSx0YWc6R1EwL1dFaHRleXFDcHNFdi9TRnJiQT09LHR5cGU6c3RyXQogICAgICB0b2tlbjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpDR25TTzRIRSxpdjpMSDB4VldOVGJCbUhQUTFPaVA1K3VSRmZHL0U3SzdPR1lxS0hYT0tqZThRPSx0YWc6c09ZaGdLS1Yxb2dPczdQSnJCcnNqdz09LHR5cGU6c3RyXQogICAgLSBzZXJ2aWNlOiBFTkNbQUVTMjU2X0dDTSxkYXRhOm9ocVh2Wi83SFd3PSxpdjpDcGpVZFRiR0w0VEdSSVd0RUp4Wjg5MjN0dy9Rb213K2tDdGlIdUZpR1FjPSx0YWc6OTVUUVVhM05TVzFxR1Q4TE5zRWdiUT09LHR5cGU6c3RyXQogICAgICB0b2tlbjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpJMEkvWGdXbCxpdjo4N0UvYzdEaUdLVDIydGRkQ0ZxQnVQT0M3MzZ5djVZRDlNLytnM1BpWlg0PSx0YWc6WjFwcklIZkgzOW0yVTZpMktlVjIyUT09LHR5cGU6c3RyXQpzb21lT3RoZXJLZXk6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6SFNNRndNWEhuaTE4dFRPUHcyREFFMGc1WFFSOW9Vdz0saXY6NHhUUk84VFloYmxhMDFnemF0aGY3VUJIaDhHdGhkOTdHSXhYLzBrQ1h3Zz0sdGFnOjRwc0VGVzNPMlJxcVlONjhVMjNQeHc9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6CiAgICBTcGVjaWFsQ2hhcmFjdGVyczogRU5DW0FFUzI1Nl9HQ00sZGF0YTpFL2pxa1B2VVNiaFpQYm0wdnJDalgxc29MQT09LGl2OlJ0bzBFeVFUMm96Rm1rMXR2azN4UkR3Vm5OcHJBNXhqcENOR1RaaWViMEE9LHRhZzpwUnZoc1huVnJiMnFHRzFvY3U1bUt3PT0sdHlwZTpzdHJdCiAgICBIVE1MRW5jb2RpbmdUZXN0MTogRU5DW0FFUzI1Nl9HQ00sZGF0YTpaZGM1dlpPQklRUjhtY2xyUHl0dm15ZzRIUWVELGl2OldHelMwK0xTUDlYYUZlcWgxYVptbWdPNTRaRG44VGYyWUlPaXdtSkhwMEk9LHRhZzpaZEEveFg3Mkp6Qll4R1ZjVjJhMlJBPT0sdHlwZTpzdHJdCiAgICBIVE1MRW5jb2RpbmdUZXN0MjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpYdz09LGl2OmJsWUpYd1Qrd0VyZ1Zzd2FDVzhvV1lubnk4OG9MMXl2Rng4ZTNKY0UwOVE9LHRhZzorWVV5MDJ4YUpocXFhdEJ0a2o5NzJBPT0sdHlwZTpzdHJdCiAgICBIVExNRW5jb2RpbmdUZXN0MzogRU5DW0FFUzI1Nl9HQ00sZGF0YTovdz09LGl2Oi80ZVNWdEZRN2NHb05JN1VPTXc4bHkwK2FpWDdXaXZVNGloTWxWS1VENWs9LHRhZzpjTFNPOENSMElNK1k1TFpmZE00M0JRPT0sdHlwZTpzdHJdCiAgICAibnVsbCI6IG51bGwKICAgIGJvb2xlYW46IEVOQ1tBRVMyNTZfR0NNLGRhdGE6RDFpYVVBPT0saXY6U3VyVUFCaHFNK1VZaUNaYUVtanlHS1phaTJqREpMM25uWko0MXRNTkhCUT0sdGFnOmdld0ZsY2NVZGIzSXlYN2tQK1NQM3c9PSx0eXBlOmJvb2xdCiAgICBudW1iZXIxOiBFTkNbQUVTMjU2X0dDTSxkYXRhOk1jQk0saXY6VmpZRXBkVmdMc2pYR20yVlJEOUx1MEJYeU9NRmprVU1RSWp2dVZvZDVjcz0sdGFnOjdFZm5LMHFjSVRSZzFPYnJpdTdFZ2c9PSx0eXBlOmludF0KICAgIG51bWJlcjI6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6d0xjdTBYanlKZz09LGl2OnRaVC9BTVlNVG9aaTVudW82alV4d0IwMUhQWDRIaEhwZHQ2djd1elo5U0U9LHRhZzpmZ0s0R2ZpNVlCQTFMdXBKQlgyc0JBPT0sdHlwZTpmbG9hdF0Kc29wczoKICAgIGttczogW10KICAgIGdjcF9rbXM6IFtdCiAgICBhenVyZV9rdjogW10KICAgIGhjX3ZhdWx0OiBbXQogICAgYWdlOgogICAgICAgIC0gcmVjaXBpZW50OiBhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dQogICAgICAgICAgZW5jOiB8CiAgICAgICAgICAgIC0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgICAgICAgICAgWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQlljM0Y2WkZZNFJGbGxiU3RwTXpFegogICAgICAgICAgICBXbXh1TnpkdU15dGpSa2gxWTI0eE1VTm9WbmRDWVVOaGFHdEpDakp3WjFBelpsQlZjVmQ2WTJORmJHUjRNbVZGCiAgICAgICAgICAgIGJXOU9XV2gyYm1SamFGUnJPRm95ZVdWV2JuSlRlV01LTFMwdElFeHlWRE5GUlhwRlRFcFJNell2V0cxUGFXTnoKICAgICAgICAgICAgVFc5NmQwdHFhakJMYzAxcGFWbEVaSEZYUjFGMmJYY0tMSUpnN3lUbTB1Q2lpUGlLc25zQXlSTS9hRFovZk52dwogICAgICAgICAgICBpaWxLVEI1d1AxcWRzN1N0Y1ZMSjE4UkdVbzl2dUFBOWlQME5aQ1A2a0tMVmdaYmNKL2FTZHc9PQogICAgICAgICAgICAtLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLQogICAgbGFzdG1vZGlmaWVkOiAiMjAyNS0wMi0wN1QxNDo0NzowOVoiCiAgICBtYWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6U3gyRDZTRitwUUhRK291eDdsTmV4c2hQb2RjZ2UzdzJnNml4TFRqSy9Oa0VneUJNbWdzVnlCR1dNbCtrU2s2UFk1OEhUNEFRcHlCdHVpVUtqM2pTSjRwWm1lcGdXSUFkeEtwQjNzbHF5MzhnZ2hZUDIvQUhTYkhZUnpoTFFJT3h4RE8waW5Vd3JvSGExM0h0dEpDekRmWEtOaUtyYk1SQVFLaytGV0Y2eDN3PSxpdjo3c0JqU2hWV3JXMTc3d1pCdityeFc2ZXFLMFZRY2pqR1dWdEh3OWRiR1RZPSx0YWc6Qm8zb1lGZ2JBVGJOVndEdFAyUkFhdz09LHR5cGU6c3RyXQogICAgcGdwOiBbXQogICAgdW5lbmNyeXB0ZWRfc3VmZml4OiBfdW5lbmNyeXB0ZWQKICAgIHZlcnNpb246IDMuOS40Cg==", + "Hash": "9912a0ccf8001b767579817f902a5d7e030019cc7b6db34c028f4a0f9079fddf" + }, + "FlattenSeparator": ".", + "Format": "yaml", + "ResourceType": "SECRET_BINARY", + "Target": { + "Ref": "Yaml2RawEB5BB054" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "DotEnv2Json0B50F63B": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "GenerateSecretString": {}, + "Name": "DotEnv2Json" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "DotEnv2JsonSopsSyncE88E8A73": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "YXBpS2V5PUVOQ1tBRVMyNTZfR0NNLGRhdGE6eU1qVm12ZzhuZ3Bsc3c2QTJFZC9MOXhyRmc9PSxpdjpDcUlSRW12ZDR2dE1tWFIwc0tGVzRCelpWYTlnMHJUajU1OFJmd0JBeXA4PSx0YWc6dURka0EvSFRFTkZJYUZ6cWxIVVRkdz09LHR5cGU6c3RyXQpkYXRhYmFzZTpob3N0PUVOQ1tBRVMyNTZfR0NNLGRhdGE6TlFHQkpjRW1iM01rOTZYTFBLcz0saXY6bGhrcThrY0gvYXhWK3dSOGQvcWNYRDBpc1NuK0JBRlQrajRnRDFrQ3FWYz0sdGFnOldLOUNkOXhRbzIwQzcyNlRZTkJ3Ync9PSx0eXBlOnN0cl0KZGF0YWJhc2U6cGFzc3dvcmQ9RU5DW0FFUzI1Nl9HQ00sZGF0YTpvNkN3NmxSQ0t3VzMsaXY6YWIxeExjcmY5WFdyalhBZGRXL3ZGaHpPUUhxYk95UmlNVDFXRFoyRTk0VT0sdGFnOnhheTRxcXBYVkZHNVNBWHN3dEt1V2c9PSx0eXBlOnN0cl0KZGF0YWJhc2U6dXNlcj1FTkNbQUVTMjU2X0dDTSxkYXRhOllha1p2RlU9LGl2Oi9Va002RUUydjltaU1uZ2c1aHJGVytUTkM2TzlTSGdKdnBFcGJCUzRpWms9LHRhZzpjUTdCZ04vcmxmcHBCYUkyZVhOQjRBPT0sdHlwZTpzdHJdCnNvbWVPdGhlcktleT1FTkNbQUVTMjU2X0dDTSxkYXRhOmpiclVRMlpOM0crMm1zMWt0VWJCNG40R0tNaHpzMVE9LGl2Om54QnI3aFlhS1dJUSt3MlI5eWRxUmdFOFdZM3dXSllIUkxFTUw0b1h2Q0U9LHRhZzpoOHhYMEVOdzMwSnZQVUJWYm4zUmNBPT0sdHlwZTpzdHJdCnNwZWNpZmljOmJvb2xlYW49RU5DW0FFUzI1Nl9HQ00sZGF0YTo2aEpacEE9PSxpdjpKbjd2Y0doRy9LSHVJdm5XdExtNEt1dEJjWE9NR0dhMDNWZXhERWZvRUx3PSx0YWc6eVZZYnJkRGM4bFpRY3I1TTkwaExwQT09LHR5cGU6c3RyXQpzcGVjaWZpYzpTcGVjaWFsQ2hhcmFjdGVycz1FTkNbQUVTMjU2X0dDTSxkYXRhOmlWblY4UjR3VW80SG1qK2hOQmdWaHFzSy9RPT0saXY6MnFuSkZQMDdxK2JpZFY2UUh2YTh4Zy82S3V0MDF2eVNxb1VickppVmRkND0sdGFnOk9EUEhHTHMzeVU5QktBWGp2SDhhYVE9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6SFRMTUVuY29kaW5nVGVzdDM9RU5DW0FFUzI1Nl9HQ00sZGF0YTpPZz09LGl2Ok9zaWpSYmFVdFgyZk5OenNJMDJCbTgxQng5WnBNQ0xsOW9FWWZFZ295Z009LHRhZzpXNXlyVFRDdDh4cEV5RFdwbUNyU2JnPT0sdHlwZTpzdHJdCnNwZWNpZmljOkhUTUxFbmNvZGluZ1Rlc3QxPUVOQ1tBRVMyNTZfR0NNLGRhdGE6R3RjNXlPU1pycFJRWlJXcGJGUDlRQ2s1MkRwcSxpdjp6cy9GTU81Uzkydy9ET21UL1JoRXVXUTRXWER0SFlXbWdseXA4Ym1XNlNRPSx0YWc6NG5RQ2RrTUpMblJLNVJBV1RtYk5WQT09LHR5cGU6c3RyXQpzcGVjaWZpYzpIVE1MRW5jb2RpbmdUZXN0Mj1FTkNbQUVTMjU2X0dDTSxkYXRhOktnPT0saXY6UlFSeThMV0Z2b0tkNFVhV1NJS0wvNWpzNkk4V3ZpK3IrVDd1Ri9veCtyQT0sdGFnOlRLTWRVbS84M01rQm5QOVZ0UEFIV2c9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6bnVsbD0Kc3BlY2lmaWM6bnVtYmVyMT1FTkNbQUVTMjU2X0dDTSxkYXRhOjIzNk8saXY6L1gxakR5TU92Y3FmdmU2NzNCakNQNXIxempqMGgxS3RWak1EKzRyYklaST0sdGFnOnJXQlQwUnM1aGhsS0JUeXZOd0JxaXc9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6bnVtYmVyMj1FTkNbQUVTMjU2X0dDTSxkYXRhOmlJcUtsbXdSQ0E9PSxpdjp1c0YrWDBmbFdJZzlLaTdPMThLMDF4OG0vV1Qva1FkL2FWV0JTZFhhYnd3PSx0YWc6QlBIRlhUZXE3cXJ1Nk9XRzNEZlVzUT09LHR5cGU6c3RyXQp0b2tlbnM6MDpzZXJ2aWNlPUVOQ1tBRVMyNTZfR0NNLGRhdGE6TWxnYnVUcjFkNHM9LGl2OmUvWWpFdkV0RWhNUWR1NG9iVFczQnprU3RTazg0M2tyZWZFVElTbXh4Vnc9LHRhZzpjZzRFMmNsRko1R1dVYytpRm03OFR3PT0sdHlwZTpzdHJdCnRva2VuczowOnRva2VuPUVOQ1tBRVMyNTZfR0NNLGRhdGE6S2RlOXFITjgsaXY6SFdHZWkrUmh4V2ZFWStZZ0tUNzVRZndXaDFwaUUxVUo4cTRsVmM0R3U3TT0sdGFnOkRMWVB3bVlsaFJsSks2Q094ZDl3YXc9PSx0eXBlOnN0cl0KdG9rZW5zOjE6c2VydmljZT1FTkNbQUVTMjU2X0dDTSxkYXRhOmQwQVdsSnorbnQ0PSxpdjpCUXpLSGJCRFRsUis4ejFMVGtoQkxMby83dkFjT2pMVGZCLzlxUjdNZEdnPSx0YWc6czJOZU9QbFIxSXdaaVVuQ3M0RTFlZz09LHR5cGU6c3RyXQp0b2tlbnM6MTp0b2tlbj1FTkNbQUVTMjU2X0dDTSxkYXRhOkc0dklEVnRsLGl2OmloVi90alBTd1NhenNjL0RmK2RYcG5lcHdTa1A2bjFLY2NERzhHS1dSTWc9LHRhZzpSRGw5YzNQOWtvazF6V1dVYmlmRWNBPT0sdHlwZTpzdHJdCnNvcHNfYWdlX19saXN0XzBfX21hcF9lbmM9LS0tLS1CRUdJTiBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQlJjVFVyUld0d1NIZFBPVE5HVlhWcFxuZW1KUVdsWTRhWGcwWkVWU1NHeHNVemw0TVc5eWRsVllSMmxCQ2tGRGRrbDRialZWWVdwamEzRk9iQzluVkZWS1xuTWtzNWNrNW1TWEk0UVVrNVIxUjBjMkpDVkM5WkswRUtMUzB0SUVSTk9EZExhV0ptWjFSM05GWkVUM0YxWVZNeVxuUml0QmNFVmhOR3Q2VVVObGMyc3paVUpqZDFSVFQxa0tBWWsrRDdncUYrcHJkTkFGN09kT0hpbWEvQTkyTmpwd1xucWg1N1JrNUM3Tlh2VmVlSmsweEtkUzJ6Rm04NklJU1QvS2dTdzdRSzgwSVV4OGlHQ0hmNmtnPT1cbi0tLS0tRU5EIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG4Kc29wc19hZ2VfX2xpc3RfMF9fbWFwX3JlY2lwaWVudD1hZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dQpzb3BzX2xhc3Rtb2RpZmllZD0yMDI1LTAyLTA3VDE0OjQ2OjA0Wgpzb3BzX21hYz1FTkNbQUVTMjU2X0dDTSxkYXRhOnZtSk9UR0k1NlVOZVRTVTVmM09GUTJLcWdsNk41MVRLSHBDWjJlR0Q5VzBzQnp2cmk0dXNEOWNPaWlPc3IxY09JVms5dGpmZHBqY3M4L1NNVkxQWTJENG5NZkJkVU82ZTMydE5vM1YwRHBSMUJVUFljVXlrUG9nREY0cHNySjNoMVdHOCtuMVkxS2dWRG8wK1Jhd0hwNFd4ZUJpOC9teXhGdkUrbTA2N3Jzbz0saXY6TWVpUFBUd2VwekhVMHJydGlWcE9JbmdWTXJHTy9MR1h1LzVGREtlK2s2QT0sdGFnOnZZU0trMS9nN1RQYU5ybmluRngxR2c9PSx0eXBlOnN0cl0Kc29wc191bmVuY3J5cHRlZF9zdWZmaXg9X3VuZW5jcnlwdGVkCnNvcHNfdmVyc2lvbj0zLjkuNAo=", + "Hash": "8503036ebdb63922730f2d820336b67f3a28a6713b1d92133fc311b2a04ff62c" + }, + "FlattenSeparator": ".", + "Format": "dotenv", + "ResourceType": "SECRET", + "Target": { + "Ref": "DotEnv2Json0B50F63B" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "DotEnv2RawF7654593": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "GenerateSecretString": {}, + "Name": "DotEnv2Raw" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "DotEnv2RawSopsSync731ED9C1": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "ewoJImRhdGEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpNOWd6RHNSZDlvQ3J1TTFEaFlpVUE0WUNBR3ZTdUFXT1JicFhlcHJlVDNOeElmRDhZNjNwejAwTEhoL3Q5WStXclRCQXBKdU9PRDNVWWhVMUpydnU2MzhIZWRyQjFBNXNxMXRPdUFWc1l6OStLVWFPamFveWV5TWh2d3JOenZsemFINkowNlMycWIycS9HMXBVSFdWUGtvRU9VaGlHTnlYVGJRY2g0bkhVQmJVWnBVU2ttcXd0dnprSVlPeDBGYnhSaGYwRndaWGF5NFMrWE9NY0R1S2JmUXg4aEExZ1hYZGdaYWwybmxldWpFNGtYV2FoN2dCL3EwQWNmaklqaHl0UGFlaWVFbFBYck5jSmR5SVJLbGxPV3RwbW93RHhhUm1xVTRpcVVZZzVrL095YnRLd1B2YmcybWpZeEx3SlpyNTd4anpFWDJ0RkppOWt1b3hsNEhQMDRxVkVSUGJhUHV5M3E2MVpiOStGd3RXODVlYm5WaU9BSVRwLy9SNzhLa21yUVZ6R3g2VktZKzJKeGJQR3NRNkhmZVNtN1dXV0dDWHRldVREWUFncG9FS2xaSE1kLzZoWTA3RDkydGxuYTh2YWRCUE9jTEFsNytjeFZmQ0phWjdPYjYzakZnelBvNi9MT1R6WWpxREt2TElFS2RGR2owOFB3aUVEM3ZVaVg0aE80b2kyTVVrZk51STFqeWpQOUFxd2ovSDJRd3ZxcGJ0R0RqRDIrQ2R5T2R3NXBCRVFRPT0saXY6bnR3YTdUU0ZWRERBaGQ3OVg1R0xEMkI2MUZNMTlRYWpPMkJLUk9qRjdzaz0sdGFnOjROZndvVFJOektLMVVQMkd4YVFSWHc9PSx0eXBlOnN0cl0iLAoJInNvcHMiOiB7CgkJImttcyI6IG51bGwsCgkJImdjcF9rbXMiOiBudWxsLAoJCSJhenVyZV9rdiI6IG51bGwsCgkJImhjX3ZhdWx0IjogbnVsbCwKCQkiYWdlIjogWwoJCQl7CgkJCQkicmVjaXBpZW50IjogImFnZTFkamxsdzJwenVwcnJxYzBlbjVtOHZjOGs1Z2UzdG0wZjZnN2NqMGMwZ2xmenA0NHZkYzRxbDhuZ3Z1IiwKCQkJCSJlbmMiOiAiLS0tLS1CRUdJTiBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQlhOVUV5VDA5UFIzcFpZbU4xWlU5U1xuZVVSQ1dVZFpZbmhtTXpCaVNtMUZjRU5ZTkdsaU5HdE5aekZSQ2s1MlRWWkNTRFJCT1drNVRUQjJkR1JHVEZnelxuTWtsc1pVVjBaRm9yVWt4YU0wWmlTVFJJY1c1aWQzTUtMUzB0SUhkRk1IRk1NVWRFWWxsVWFHUlJTRWw2VUdad1xuZEZGMk9EQlBaR1JyVG5CR2JXSnZkVlp2ZFdWR1VXOEttNVBZWFJ1VEJ2am1NRFltZzZORUtoSWJVVS9TSFBTWlxuVHRnd29zOGlkK01ZVHB1ZEcrYUtWVEtTeDkxR254OWVrTGNUa2FmRXcvWVVMVTljcnliWXRnPT1cbi0tLS0tRU5EIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG4iCgkJCX0KCQldLAoJCSJsYXN0bW9kaWZpZWQiOiAiMjAyNS0wMi0wN1QxNDo1MDoyNVoiLAoJCSJtYWMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpOakxQWkw1YmRrYytlYk5ycFQ5c2pzT1pqVUUvWjF0L09xMXE0Q0VzNzMxamdiVzBsb2xMWjNEcjdFRlZOTG9DNWV1bmhReHZuN0U2WkExYnBtcXBpanRNTlNrcXFWUWRHMUpzekY3WUdoRjlZaitUeXo5Ukhodk5GdUg4QUZjbDRmMWtzRDdHbW5WN2RZc2oxcjFZUDN3d0ZZK1VoRXFscTQrS2Q4N1ZuYTA9LGl2OjhJTUIzN1Y0a3hMSHJOaUlWMGNWWnRCMlZDZnVxOFNZQU5zeUR5bDNtMW89LHRhZzpFR0JYVk9JYXl6bjJsaDVaaTUrR3hnPT0sdHlwZTpzdHJdIiwKCQkicGdwIjogbnVsbCwKCQkidW5lbmNyeXB0ZWRfc3VmZml4IjogIl91bmVuY3J5cHRlZCIsCgkJInZlcnNpb24iOiAiMy45LjQiCgl9Cn0=", + "Hash": "a62d06dea56fc1e8018c1ec402c92887c6477cff4923a1d8acb7ccd082ba8552" + }, + "FlattenSeparator": ".", + "Format": "binary", + "ResourceType": "SECRET_BINARY", + "Target": { + "Ref": "DotEnv2RawF7654593" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Binary2RawA83E0B31": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "GenerateSecretString": {}, + "Name": "Binary2Raw" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Binary2RawSopsSyncD810F28A": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "ewoJImRhdGEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpNOWd6RHNSZDlvQ3J1TTFEaFlpVUE0WUNBR3ZTdUFXT1JicFhlcHJlVDNOeElmRDhZNjNwejAwTEhoL3Q5WStXclRCQXBKdU9PRDNVWWhVMUpydnU2MzhIZWRyQjFBNXNxMXRPdUFWc1l6OStLVWFPamFveWV5TWh2d3JOenZsemFINkowNlMycWIycS9HMXBVSFdWUGtvRU9VaGlHTnlYVGJRY2g0bkhVQmJVWnBVU2ttcXd0dnprSVlPeDBGYnhSaGYwRndaWGF5NFMrWE9NY0R1S2JmUXg4aEExZ1hYZGdaYWwybmxldWpFNGtYV2FoN2dCL3EwQWNmaklqaHl0UGFlaWVFbFBYck5jSmR5SVJLbGxPV3RwbW93RHhhUm1xVTRpcVVZZzVrL095YnRLd1B2YmcybWpZeEx3SlpyNTd4anpFWDJ0RkppOWt1b3hsNEhQMDRxVkVSUGJhUHV5M3E2MVpiOStGd3RXODVlYm5WaU9BSVRwLy9SNzhLa21yUVZ6R3g2VktZKzJKeGJQR3NRNkhmZVNtN1dXV0dDWHRldVREWUFncG9FS2xaSE1kLzZoWTA3RDkydGxuYTh2YWRCUE9jTEFsNytjeFZmQ0phWjdPYjYzakZnelBvNi9MT1R6WWpxREt2TElFS2RGR2owOFB3aUVEM3ZVaVg0aE80b2kyTVVrZk51STFqeWpQOUFxd2ovSDJRd3ZxcGJ0R0RqRDIrQ2R5T2R3NXBCRVFRPT0saXY6bnR3YTdUU0ZWRERBaGQ3OVg1R0xEMkI2MUZNMTlRYWpPMkJLUk9qRjdzaz0sdGFnOjROZndvVFJOektLMVVQMkd4YVFSWHc9PSx0eXBlOnN0cl0iLAoJInNvcHMiOiB7CgkJImttcyI6IG51bGwsCgkJImdjcF9rbXMiOiBudWxsLAoJCSJhenVyZV9rdiI6IG51bGwsCgkJImhjX3ZhdWx0IjogbnVsbCwKCQkiYWdlIjogWwoJCQl7CgkJCQkicmVjaXBpZW50IjogImFnZTFkamxsdzJwenVwcnJxYzBlbjVtOHZjOGs1Z2UzdG0wZjZnN2NqMGMwZ2xmenA0NHZkYzRxbDhuZ3Z1IiwKCQkJCSJlbmMiOiAiLS0tLS1CRUdJTiBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQlhOVUV5VDA5UFIzcFpZbU4xWlU5U1xuZVVSQ1dVZFpZbmhtTXpCaVNtMUZjRU5ZTkdsaU5HdE5aekZSQ2s1MlRWWkNTRFJCT1drNVRUQjJkR1JHVEZnelxuTWtsc1pVVjBaRm9yVWt4YU0wWmlTVFJJY1c1aWQzTUtMUzB0SUhkRk1IRk1NVWRFWWxsVWFHUlJTRWw2VUdad1xuZEZGMk9EQlBaR1JyVG5CR2JXSnZkVlp2ZFdWR1VXOEttNVBZWFJ1VEJ2am1NRFltZzZORUtoSWJVVS9TSFBTWlxuVHRnd29zOGlkK01ZVHB1ZEcrYUtWVEtTeDkxR254OWVrTGNUa2FmRXcvWVVMVTljcnliWXRnPT1cbi0tLS0tRU5EIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG4iCgkJCX0KCQldLAoJCSJsYXN0bW9kaWZpZWQiOiAiMjAyNS0wMi0wN1QxNDo1MDoyNVoiLAoJCSJtYWMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpOakxQWkw1YmRrYytlYk5ycFQ5c2pzT1pqVUUvWjF0L09xMXE0Q0VzNzMxamdiVzBsb2xMWjNEcjdFRlZOTG9DNWV1bmhReHZuN0U2WkExYnBtcXBpanRNTlNrcXFWUWRHMUpzekY3WUdoRjlZaitUeXo5Ukhodk5GdUg4QUZjbDRmMWtzRDdHbW5WN2RZc2oxcjFZUDN3d0ZZK1VoRXFscTQrS2Q4N1ZuYTA9LGl2OjhJTUIzN1Y0a3hMSHJOaUlWMGNWWnRCMlZDZnVxOFNZQU5zeUR5bDNtMW89LHRhZzpFR0JYVk9JYXl6bjJsaDVaaTUrR3hnPT0sdHlwZTpzdHJdIiwKCQkicGdwIjogbnVsbCwKCQkidW5lbmNyeXB0ZWRfc3VmZml4IjogIl91bmVuY3J5cHRlZCIsCgkJInZlcnNpb24iOiAiMy45LjQiCgl9Cn0=", + "Hash": "a62d06dea56fc1e8018c1ec402c92887c6477cff4923a1d8acb7ccd082ba8552" + }, + "FlattenSeparator": ".", + "Format": "binary", + "ResourceType": "SECRET_BINARY", + "Target": { + "Ref": "Binary2RawA83E0B31" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "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/test/SECRET.integ.ts b/test/SECRET.integ.ts new file mode 100644 index 00000000..19107e61 --- /dev/null +++ b/test/SECRET.integ.ts @@ -0,0 +1,70 @@ +import * as cdk from 'aws-cdk-lib'; +import { SopsSecret } from '../src/index'; + +const app = new cdk.App(); +const stack = new cdk.Stack(app, 'SECRET'); + +interface TestCase { + name: string; + sopsFilePath: string; + additionalProperties: Record; +} + +const tc = [ + { + name: 'Json2Json', + sopsFilePath: 'test-secrets/testsecret.sops.json', + additionalProperties: {}, + }, + { + name: 'Yaml2Json', + sopsFilePath: 'test-secrets/testsecret.sops.yaml', + additionalProperties: {}, + }, + { + name: 'Json2Raw', + sopsFilePath: 'test-secrets/testsecret.sops.json', + additionalProperties: { + rawOutput: true, + }, + }, + { + name: 'Yaml2Raw', + sopsFilePath: 'test-secrets/testsecret.sops.yaml', + additionalProperties: { + rawOutput: true, + }, + }, + { + name: 'DotEnv2Json', + sopsFilePath: 'test-secrets/testsecret.sops.env', + additionalProperties: {}, + }, + { + name: 'DotEnv2Raw', + sopsFilePath: 'test-secrets/README.sops.binary', + additionalProperties: { + rawOutput: true, + }, + }, + { + name: 'Binary2Raw', + sopsFilePath: 'test-secrets/README.sops.binary', + additionalProperties: { + rawOutput: true, + }, + }, +] satisfies TestCase[]; + +tc.forEach((t) => { + new SopsSecret(stack, t.name, { + secretName: t.name, + sopsFilePath: t.sopsFilePath, + sopsAgeKey: cdk.SecretValue.unsafePlainText( + 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', + ), + ...t.additionalProperties, + }); +}); + +app.synth(); diff --git a/test/secret-asset.integ.snapshot/SecretIntegrationAsset.assets.json b/test/secret-asset.integ.snapshot/SecretIntegrationAsset.assets.json deleted file mode 100644 index 3166351a..00000000 --- a/test/secret-asset.integ.snapshot/SecretIntegrationAsset.assets.json +++ /dev/null @@ -1,97 +0,0 @@ -{ - "version": "39.0.0", - "files": { - "2f5ea59cc41c6a2ba0e5f9363d4f3836e8883e03cd54cc5e9789115b0979c218": { - "source": { - "path": "asset.2f5ea59cc41c6a2ba0e5f9363d4f3836e8883e03cd54cc5e9789115b0979c218.zip", - "packaging": "file" - }, - "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "2f5ea59cc41c6a2ba0e5f9363d4f3836e8883e03cd54cc5e9789115b0979c218.zip", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" - } - } - }, - "2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649": { - "source": { - "path": "asset.2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649.json", - "packaging": "file" - }, - "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649.json", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" - } - } - }, - "c0d63dcd2d506c5d270284d70d1805688ff5d3a2e0d7515bfa56b1b3ed416c4f": { - "source": { - "path": "asset.c0d63dcd2d506c5d270284d70d1805688ff5d3a2e0d7515bfa56b1b3ed416c4f.yaml", - "packaging": "file" - }, - "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "c0d63dcd2d506c5d270284d70d1805688ff5d3a2e0d7515bfa56b1b3ed416c4f.yaml", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" - } - } - }, - "313aad921c737076a990ead756b250f1677aecc927177440df0c809cd56bf282": { - "source": { - "path": "asset.313aad921c737076a990ead756b250f1677aecc927177440df0c809cd56bf282.json", - "packaging": "file" - }, - "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "313aad921c737076a990ead756b250f1677aecc927177440df0c809cd56bf282.json", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" - } - } - }, - "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2": { - "source": { - "path": "asset.4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2.yaml", - "packaging": "file" - }, - "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2.yaml", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" - } - } - }, - "a8aece61894327fcfc2c7fab967a72583c0f795025e4d5f2e87c248b6e916d4b": { - "source": { - "path": "asset.a8aece61894327fcfc2c7fab967a72583c0f795025e4d5f2e87c248b6e916d4b.binary", - "packaging": "file" - }, - "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "a8aece61894327fcfc2c7fab967a72583c0f795025e4d5f2e87c248b6e916d4b.binary", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" - } - } - }, - "5ca3964bb939bad69e0ce4cca4833760895d0e5d11890d89fa18e56079d585ed": { - "source": { - "path": "SecretIntegrationAsset.template.json", - "packaging": "file" - }, - "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "5ca3964bb939bad69e0ce4cca4833760895d0e5d11890d89fa18e56079d585ed.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/test/secret-asset.integ.snapshot/SecretIntegrationAsset.template.json b/test/secret-asset.integ.snapshot/SecretIntegrationAsset.template.json deleted file mode 100644 index daa9dd66..00000000 --- a/test/secret-asset.integ.snapshot/SecretIntegrationAsset.template.json +++ /dev/null @@ -1,981 +0,0 @@ -{ - "Resources": { - "SopsSecretJSON72040543": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretJSONSopsSync701F9A56": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "Key": "2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649.json" - }, - "FlattenSeparator": ".", - "Format": "json", - "ResourceType": "SECRET", - "Target": { - "Ref": "SopsSecretJSON72040543" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - } - }, - "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "s3:GetObject*", - "s3:GetBucket*", - "s3:List*" - ], - "Effect": "Allow", - "Resource": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":s3:::", - { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - } - ] - ] - }, - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":s3:::", - { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "/*" - ] - ] - } - ] - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsSecretJSON72040543" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsSecretYAMLC392F558" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsSecretYAMLasJSON64419C04" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsComplexSecretJSONAD4C2662" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopComplexSecretYAMLF52D88F2" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopComplexSecretYAMLFlatD9CE8782" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsComplexSecretYAMLasJSONEAE81DB0" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsBinaryAsBinary6FB08519" - } - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", - "Roles": [ - { - "Ref": "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" - } - ] - } - }, - "SingletonLambdaSopsSyncProviderAA18D140": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "S3Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "S3Key": "2f5ea59cc41c6a2ba0e5f9363d4f3836e8883e03cd54cc5e9789115b0979c218.zip" - }, - "Environment": { - "Variables": { - "SOPS_AGE_KEY": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - } - }, - "Handler": "bootstrap", - "Role": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25", - "Arn" - ] - }, - "Runtime": "provided.al2", - "Timeout": 60 - }, - "DependsOn": [ - "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" - ] - }, - "SopsSecretYAMLC392F558": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretYAMLSopsSyncD61C4640": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "Key": "c0d63dcd2d506c5d270284d70d1805688ff5d3a2e0d7515bfa56b1b3ed416c4f.yaml" - }, - "FlattenSeparator": ".", - "Format": "yaml", - "ResourceType": "SECRET_BINARY", - "Target": { - "Ref": "SopsSecretYAMLC392F558" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretYAMLasJSON64419C04": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretYAMLasJSONSopsSync5F0877FF": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "Key": "c0d63dcd2d506c5d270284d70d1805688ff5d3a2e0d7515bfa56b1b3ed416c4f.yaml" - }, - "FlattenSeparator": ".", - "Format": "yaml", - "ResourceType": "SECRET", - "Target": { - "Ref": "SopsSecretYAMLasJSON64419C04" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONAD4C2662": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONSopsSyncCABA63FF": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "Key": "313aad921c737076a990ead756b250f1677aecc927177440df0c809cd56bf282.json" - }, - "FlattenSeparator": ".", - "Format": "json", - "ResourceType": "SECRET", - "Target": { - "Ref": "SopsComplexSecretJSONAD4C2662" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONFlatF5FC1D69": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONFlatSopsSyncC4165B67": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "Key": "313aad921c737076a990ead756b250f1677aecc927177440df0c809cd56bf282.json" - }, - "FlattenSeparator": ".", - "Format": "json", - "ResourceType": "SECRET", - "Target": { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLF52D88F2": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLSopsSync4B881273": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "Key": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2.yaml" - }, - "FlattenSeparator": ".", - "Format": "yaml", - "ResourceType": "SECRET_BINARY", - "Target": { - "Ref": "SopComplexSecretYAMLF52D88F2" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLFlatD9CE8782": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLFlatSopsSync8B86CE19": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "Key": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2.yaml" - }, - "FlattenSeparator": ".", - "Format": "yaml", - "ResourceType": "SECRET_BINARY", - "Target": { - "Ref": "SopComplexSecretYAMLFlatD9CE8782" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONEAE81DB0": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONSopsSyncC4061B33": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "Key": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2.yaml" - }, - "FlattenSeparator": ".", - "Format": "yaml", - "ResourceType": "SECRET_BINARY", - "Target": { - "Ref": "SopsComplexSecretYAMLasJSONEAE81DB0" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONFlat9FD04B78": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "Key": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2.yaml" - }, - "FlattenSeparator": ".", - "Format": "yaml", - "ResourceType": "SECRET", - "Target": { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsBinaryAsBinary6FB08519": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsBinaryAsBinarySopsSyncEC998F91": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "Key": "a8aece61894327fcfc2c7fab967a72583c0f795025e4d5f2e87c248b6e916d4b.binary" - }, - "FlattenSeparator": ".", - "Format": "binary", - "ResourceType": "SECRET_BINARY", - "Target": { - "Ref": "SopsBinaryAsBinary6FB08519" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "TestFunctionServiceRole6ABD93C7": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - } - }, - "TestFunction22AD90FC": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "ZipFile": "test" - }, - "Environment": { - "Variables": { - "SopsComplexSecretJSONFlat_and_now_some_0_basic": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[0].basic::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_and_now_some_1_nested": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[1].nested::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_and_now_some_2_type": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[2].type::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_and_now_some_3_tests": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[3].tests::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_arrays_0": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.arrays[0]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_arrays_1": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.arrays[1]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_arrays_2_values_and": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.arrays[2].values.and::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_object": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.object::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_notsodeep": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.notsodeep::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_0_basic": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[0].basic::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_1_nested": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[1].nested::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_2_type": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[2].type::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_3_tests": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[3].tests::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_arrays_0": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.arrays[0]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_arrays_1": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.arrays[1]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_arrays_2_values_and": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.arrays[2].values.and::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_object": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.object::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_notsodeep": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.notsodeep::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - } - } - }, - "Handler": "test", - "Role": { - "Fn::GetAtt": [ - "TestFunctionServiceRole6ABD93C7", - "Arn" - ] - }, - "Runtime": "nodejs20.x" - }, - "DependsOn": [ - "TestFunctionServiceRole6ABD93C7" - ] - } - }, - "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/test/secret-asset.integ.ts b/test/secret-asset.integ.ts deleted file mode 100644 index c8585330..00000000 --- a/test/secret-asset.integ.ts +++ /dev/null @@ -1,156 +0,0 @@ -import { App, SecretValue, Stack } from 'aws-cdk-lib'; -import { Code, Function, Runtime } from 'aws-cdk-lib/aws-lambda'; -import { SopsSecret, UploadType } from '../src/index'; - -const app = new App(); - -const stack = new Stack(app, 'SecretIntegrationAsset'); - -new SopsSecret(stack, 'SopsSecretJSON', { - sopsFilePath: 'test-secrets/json/sopsfile.enc-age.json', - uploadType: UploadType.ASSET, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsSecretYAML', { - sopsFilePath: 'test-secrets/yaml/sopsfile.enc-age.yaml', - rawOutput: true, - uploadType: UploadType.ASSET, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsSecretYAMLasJSON', { - sopsFilePath: 'test-secrets/yaml/sopsfile.enc-age.yaml', - uploadType: UploadType.ASSET, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsComplexSecretJSON', { - sopsFilePath: 'test-secrets/json/sopsfile-complex.enc-age.json', - uploadType: UploadType.ASSET, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -const sopsComplexSecretJSONFlat = new SopsSecret( - stack, - 'SopsComplexSecretJSONFlat', - { - sopsFilePath: 'test-secrets/json/sopsfile-complex.enc-age.json', - uploadType: UploadType.ASSET, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - }, -); - -new SopsSecret(stack, 'SopComplexSecretYAML', { - sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - rawOutput: true, - uploadType: UploadType.ASSET, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopComplexSecretYAMLFlat', { - sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - rawOutput: true, - uploadType: UploadType.ASSET, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsComplexSecretYAMLasJSON', { - sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - rawOutput: true, - uploadType: UploadType.ASSET, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -const sopsComplexSecretYAMLasJSONFlat = new SopsSecret( - stack, - 'SopsComplexSecretYAMLasJSONFlat', - { - sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - uploadType: UploadType.ASSET, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - - }, -); - -new SopsSecret(stack, 'SopsBinaryAsBinary', { - sopsFilePath: 'test-secrets/binary/sopsfile.enc-age.binary', - rawOutput: true, - uploadType: UploadType.ASSET, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new Function(stack, 'TestFunction', { - code: Code.fromInline('test'), - handler: 'test', - runtime: Runtime.NODEJS_20_X, - environment: { - ...createMapComplex('SopsComplexSecretJSONFlat', sopsComplexSecretJSONFlat), - ...createMapComplex( - 'sopsComplexSecretYAMLasJSONFlat', - sopsComplexSecretYAMLasJSONFlat, - ), - }, -}); - -function createMapComplex(prefix: string, secret: SopsSecret) { - return { - [`${prefix}_and_now_some_0_basic`]: secret - .secretValueFromJson('and now.some[0].basic') - .toString(), - [`${prefix}_and_now_some_1_nested`]: secret - .secretValueFromJson('and now.some[1].nested') - .toString(), - [`${prefix}_and_now_some_2_type`]: secret - .secretValueFromJson('and now.some[2].type') - .toString(), - [`${prefix}_and_now_some_3_tests`]: secret - .secretValueFromJson('and now.some[3].tests') - .toString(), - [`${prefix}_some_deep_nested_arrays_0`]: secret - .secretValueFromJson('some.deep.nested.arrays[0]') - .toString(), - [`${prefix}_some_deep_nested_arrays_1`]: secret - .secretValueFromJson('some.deep.nested.arrays[1]') - .toString(), - [`${prefix}_some_deep_nested_arrays_2_values_and`]: secret - .secretValueFromJson('some.deep.nested.arrays[2].values.and') - .toString(), - [`${prefix}_some_deep_nested_object`]: secret - .secretValueFromJson('some.deep.nested.object') - .toString(), - [`${prefix}_some_notsodeep`]: secret - .secretValueFromJson('some.notsodeep') - .toString(), - }; -} diff --git a/test/secret-inline.integ.snapshot/SecretIntegrationInline.template.json b/test/secret-inline.integ.snapshot/SecretIntegrationInline.template.json deleted file mode 100644 index ff1d0475..00000000 --- a/test/secret-inline.integ.snapshot/SecretIntegrationInline.template.json +++ /dev/null @@ -1,961 +0,0 @@ -{ - "Resources": { - "SopsSecretJSON72040543": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretJSONSopsSync701F9A56": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsInline": { - "Content": "ewoJImtleTEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpBclNqQzBWZCxpdjpORnJJajFla00yZFU4SkNVNk5wbW5IRm13Y0ZhRVFhZ0N3L2Z4S1YyYjZBPSx0YWc6R3JHZ2VObXRxRnV5aVRqS0ovNzhrdz09LHR5cGU6c3RyXSIsCgkia2V5MiI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOk5lb2FuZFk9LGl2OjJvQ2NCazBSL1h4dkgvTythYUNJYTdWOXBGc3k3ZGhDS1o3MGViamM1RHM9LHRhZzpHVlpYVUZGd2JwTVZZL0tDTE5FTkFRPT0sdHlwZTpmbG9hdF0iLAoJImtleTMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp5NHRCYU5nPSxpdjptSHVZcnRmMEtlL29IQmN1bnBnZFBwemFZa0J4N1VqTWNPUWdwbVZjOC9RPSx0YWc6Y3VFZzJVRTE3UG82b3BmcEg4aWtvZz09LHR5cGU6Ym9vbF0iLAoJInNvcHMiOiB7CgkJImttcyI6IG51bGwsCgkJImdjcF9rbXMiOiBudWxsLAoJCSJhenVyZV9rdiI6IG51bGwsCgkJImhjX3ZhdWx0IjogbnVsbCwKCQkiYWdlIjogWwoJCQl7CgkJCQkicmVjaXBpZW50IjogImFnZTFkamxsdzJwenVwcnJxYzBlbjVtOHZjOGs1Z2UzdG0wZjZnN2NqMGMwZ2xmenA0NHZkYzRxbDhuZ3Z1IiwKCQkJCSJlbmMiOiAiLS0tLS1CRUdJTiBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQk9XbEF4ZWtWTk5YZGplblY1Y21kUlxuWkRsUVUzTjVXQzlvZUVOVWJVcFljV3hrZVU5a1ZTOVRlVVIzQ201emJHaElMMEo2V0c5VFdpOUtSM1pVVFZwaFxuYmxwaVVEWnRRa2xuV2xSclNHWnpUWGxaTjJaNldqZ0tMUzB0SURJM1pITkhSME5tV1RNemRUZzBkRXRYY1U5M1xuYkVkTlduZEtkV1JPV0dkTGRIQXdUR0Z0Ukdsc2FEUUtWN0hKRzYyOXJQV0RCWTA0Nkh4ajR1dHhVa2V4M1N3VVxuVlVRUlgwMHA2cjlmZmMraUM1REdVbS9LT2tldEFIdW5PNEtuMHVPUzRXSGcrSmcyQ3d1NzJRPT1cbi0tLS0tRU5EIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG4iCgkJCX0KCQldLAoJCSJsYXN0bW9kaWZpZWQiOiAiMjAyMi0wMy0yOVQyMTowMjozMloiLAoJCSJtYWMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YToydm16d1c3NE9TSnExOEdFY1NjcE1INzZBV3JoSmRFTmxLdzJ2UnpHclFmUGl4VE5jcndKMG5lVEgrQnZHS2ZSOU9sTFIyRVpUaGVScGhRMElrYjRTZGhmSW5vRGpIbyswalhON1JRNG5lVGxrbzRqL1lSVmVrNjFvZVBnQUtBcWNtdkwySWh6UkdPMlZSOG5EUHVKdXZSQ21QNXdPTU9Ca2VyeWRSS0hlRGM9LGl2Ok5IV1BOV0RtdWhla0pVSUpwQzFjREo1MWxMS1RzWExFNmRDNHRwdy9xU0k9LHRhZzp5VjVuZ1JkSVlaZlVnajZudHNZNUNRPT0sdHlwZTpzdHJdIiwKCQkicGdwIjogbnVsbCwKCQkidW5lbmNyeXB0ZWRfc3VmZml4IjogIl91bmVuY3J5cHRlZCIsCgkJInZlcnNpb24iOiAiMy43LjIiCgl9Cn0=", - "Hash": "2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649" - }, - "FlattenSeparator": ".", - "Format": "json", - "ResourceType": "SECRET", - "Target": { - "Ref": "SopsSecretJSON72040543" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - } - }, - "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsSecretJSON72040543" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsSecretYAMLC392F558" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsSecretYAMLasJSON64419C04" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsSecretDOTENV13EC93B6" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsSecretDOTENVasJSONC46F5173" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsComplexSecretJSONAD4C2662" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopComplexSecretYAMLF52D88F2" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopComplexSecretYAMLFlatD9CE8782" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsComplexSecretYAMLasJSONEAE81DB0" - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - } - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", - "Roles": [ - { - "Ref": "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" - } - ] - } - }, - "SingletonLambdaSopsSyncProviderAA18D140": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "S3Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "S3Key": "87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186.zip" - }, - "Environment": { - "Variables": { - "SOPS_AGE_KEY": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - } - }, - "Handler": "bootstrap", - "Role": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25", - "Arn" - ] - }, - "Runtime": "provided.al2", - "Timeout": 60 - }, - "DependsOn": [ - "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" - ] - }, - "SopsSecretYAMLC392F558": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretYAMLSopsSyncD61C4640": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsInline": { - "Content": "a2V5MTogRU5DW0FFUzI1Nl9HQ00sZGF0YTpod2ZNM2JEMCxpdjo1T0JEMjg4c1B5TGhXdE82b2FWTkduT2NtazFOcmFCQ2QyVnhvcFd2S0R3PSx0YWc6a1JrYnNwK09Jd0l3aGUvaVhKbFB4UT09LHR5cGU6c3RyXQprZXkyOiBFTkNbQUVTMjU2X0dDTSxkYXRhOkgrdlpWTVU9LGl2Omxub08xckc4LzY0MDU0R3B2enA3SGRvd2g2TmhJQWNhYW5YZUZ3KzZWM3M9LHRhZzpNZkQrZmVKeDZDcGtnMTNyMkw1bENnPT0sdHlwZTppbnRdCmtleTM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6UnE4Y2FhMD0saXY6OW56c1ArSElYN3o1RjNzdHlSa1U0NDd0WE44NkdaL3l5bnN4QlFLM1lvTT0sdGFnOjhOUW1Hd2M0SEY5a3d5ZDF4dGk5aHc9PSx0eXBlOmJvb2xdCnNvcHM6CiAgICBrbXM6IFtdCiAgICBnY3Bfa21zOiBbXQogICAgYXp1cmVfa3Y6IFtdCiAgICBoY192YXVsdDogW10KICAgIGFnZToKICAgICAgICAtIHJlY2lwaWVudDogYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUKICAgICAgICAgIGVuYzogfAogICAgICAgICAgICAtLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tCiAgICAgICAgICAgIFlXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JOZVdkM2RHVjZNVTFzZERCWU5EVnQKICAgICAgICAgICAgYzJGNlMxSlNTazVqU25FMk0wVlZTMDgxZEZKT1dXTlllbXhWQ201TVVVWlVVRFZOT1Vod2RXRmFZalpRZDFWdwogICAgICAgICAgICBOWGtySzJJdmJtZ3hRVk5pVWxKa1pWaFRhbFJLU2trS0xTMHRJRkpIYVhneVRrMUhkMk5yZUV4V1dIRnVOVUp6CiAgICAgICAgICAgIFJVcFpUVVJ5VjFkRVRFMDVjbFZ1UTNScmVHc3JTbThLWjkxMFZXekZaajd1QU9oRTRvblBwemVmb2t1SCt4bnoKICAgICAgICAgICAgQlBKUFRodkQ4MFF3UFdVZGpKN1Fua1p6VzhGaGROM01JU2QwRzZ2TElqcTNTcUthY2RjcjZnPT0KICAgICAgICAgICAgLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgIGxhc3Rtb2RpZmllZDogIjIwMjItMDQtMDFUMjA6NDA6MTlaIgogICAgbWFjOiBFTkNbQUVTMjU2X0dDTSxkYXRhOjM5ZS9FbVdYeGVZZHpIZ01WRGQ4WUtRNW8zNk9DZGdGSk9HamU1cm5uRVU2bi8raWhmUDhUQlhBYTYySml0WFJEUW15Vm4wbWx2K3MrYjFJbzB6THNjd3d5ZHBLOUI2a25laFpBMjlwd1dJUy9hRkF1WStGMDhja2c5TjhIUUhRcXFaL0FLd0Q4UnRUMWdET0hXeG54MEpnQ2grdkw2Z0NOMlZIVzJpQzlIND0saXY6dEhnbjNqcEJJUTcyTHhRVjJHMTBrVzIxekMwbVNtQTZlNTVBUTNGcjJhMD0sdGFnOktraFhhVFpFS2kvSG5xVXpnWVJVTnc9PSx0eXBlOnN0cl0KICAgIHBncDogW10KICAgIHVuZW5jcnlwdGVkX3N1ZmZpeDogX3VuZW5jcnlwdGVkCiAgICB2ZXJzaW9uOiAzLjcuMgo=", - "Hash": "c0d63dcd2d506c5d270284d70d1805688ff5d3a2e0d7515bfa56b1b3ed416c4f" - }, - "FlattenSeparator": ".", - "Format": "yaml", - "ResourceType": "SECRET_BINARY", - "Target": { - "Ref": "SopsSecretYAMLC392F558" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretYAMLasJSON64419C04": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretYAMLasJSONSopsSync5F0877FF": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsInline": { - "Content": "a2V5MTogRU5DW0FFUzI1Nl9HQ00sZGF0YTpod2ZNM2JEMCxpdjo1T0JEMjg4c1B5TGhXdE82b2FWTkduT2NtazFOcmFCQ2QyVnhvcFd2S0R3PSx0YWc6a1JrYnNwK09Jd0l3aGUvaVhKbFB4UT09LHR5cGU6c3RyXQprZXkyOiBFTkNbQUVTMjU2X0dDTSxkYXRhOkgrdlpWTVU9LGl2Omxub08xckc4LzY0MDU0R3B2enA3SGRvd2g2TmhJQWNhYW5YZUZ3KzZWM3M9LHRhZzpNZkQrZmVKeDZDcGtnMTNyMkw1bENnPT0sdHlwZTppbnRdCmtleTM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6UnE4Y2FhMD0saXY6OW56c1ArSElYN3o1RjNzdHlSa1U0NDd0WE44NkdaL3l5bnN4QlFLM1lvTT0sdGFnOjhOUW1Hd2M0SEY5a3d5ZDF4dGk5aHc9PSx0eXBlOmJvb2xdCnNvcHM6CiAgICBrbXM6IFtdCiAgICBnY3Bfa21zOiBbXQogICAgYXp1cmVfa3Y6IFtdCiAgICBoY192YXVsdDogW10KICAgIGFnZToKICAgICAgICAtIHJlY2lwaWVudDogYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUKICAgICAgICAgIGVuYzogfAogICAgICAgICAgICAtLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tCiAgICAgICAgICAgIFlXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JOZVdkM2RHVjZNVTFzZERCWU5EVnQKICAgICAgICAgICAgYzJGNlMxSlNTazVqU25FMk0wVlZTMDgxZEZKT1dXTlllbXhWQ201TVVVWlVVRFZOT1Vod2RXRmFZalpRZDFWdwogICAgICAgICAgICBOWGtySzJJdmJtZ3hRVk5pVWxKa1pWaFRhbFJLU2trS0xTMHRJRkpIYVhneVRrMUhkMk5yZUV4V1dIRnVOVUp6CiAgICAgICAgICAgIFJVcFpUVVJ5VjFkRVRFMDVjbFZ1UTNScmVHc3JTbThLWjkxMFZXekZaajd1QU9oRTRvblBwemVmb2t1SCt4bnoKICAgICAgICAgICAgQlBKUFRodkQ4MFF3UFdVZGpKN1Fua1p6VzhGaGROM01JU2QwRzZ2TElqcTNTcUthY2RjcjZnPT0KICAgICAgICAgICAgLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgIGxhc3Rtb2RpZmllZDogIjIwMjItMDQtMDFUMjA6NDA6MTlaIgogICAgbWFjOiBFTkNbQUVTMjU2X0dDTSxkYXRhOjM5ZS9FbVdYeGVZZHpIZ01WRGQ4WUtRNW8zNk9DZGdGSk9HamU1cm5uRVU2bi8raWhmUDhUQlhBYTYySml0WFJEUW15Vm4wbWx2K3MrYjFJbzB6THNjd3d5ZHBLOUI2a25laFpBMjlwd1dJUy9hRkF1WStGMDhja2c5TjhIUUhRcXFaL0FLd0Q4UnRUMWdET0hXeG54MEpnQ2grdkw2Z0NOMlZIVzJpQzlIND0saXY6dEhnbjNqcEJJUTcyTHhRVjJHMTBrVzIxekMwbVNtQTZlNTVBUTNGcjJhMD0sdGFnOktraFhhVFpFS2kvSG5xVXpnWVJVTnc9PSx0eXBlOnN0cl0KICAgIHBncDogW10KICAgIHVuZW5jcnlwdGVkX3N1ZmZpeDogX3VuZW5jcnlwdGVkCiAgICB2ZXJzaW9uOiAzLjcuMgo=", - "Hash": "c0d63dcd2d506c5d270284d70d1805688ff5d3a2e0d7515bfa56b1b3ed416c4f" - }, - "FlattenSeparator": ".", - "Format": "yaml", - "ResourceType": "SECRET_BINARY", - "Target": { - "Ref": "SopsSecretYAMLasJSON64419C04" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretDOTENV13EC93B6": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretDOTENVSopsSyncCF15A60A": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsInline": { - "Content": "YmFuYW5lPUVOQ1tBRVMyNTZfR0NNLGRhdGE6S2ZDYm83WjgsaXY6ZXdES1ZaSDcvZkw0d1Jrc0N5U2I0TTlISWhaNCt3NDNtWGdtWVV0S3pVOD0sdGFnOkt1b0ZGVUE0N0xKTFdwREpKd2I3Y0E9PSx0eXBlOnN0cl0KY3J5cHQ9RU5DW0FFUzI1Nl9HQ00sZGF0YToyQnBXVjR3RzdHbzU5Znl4VG1RYXFLbkl1Zz09LGl2OklmRUh3UytSZTJHOElIY091eW9tdldmZ2IwRzZYNnNsUlNOb05jbEROajQ9LHRhZzo1NDFRVFBMVUpjdW52cDhMWkl2K3hRPT0sdHlwZTpzdHJdCnNvcHNfYWdlX19saXN0XzBfX21hcF9lbmM9LS0tLS1CRUdJTiBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQXdWRUpCY1hCcU1FdDZMM2xRVEZaTVxuWVVwbFNHUlBSRFZzTDJZME5GQk5ZV0Y1Y21aTGNYcGhjakZGQ21GeVVUVXZSalJSUlZoc09WZG1kMDluYmtaclxuZEc1d1RqZENZbFp4VG5sTVFXTkZkM0ZhVDNGdEswMEtMUzB0SUVJeVMycGpZVGxTU0RONVIwRnJlalpNZFVaa1xuTWxwbVJEVmpaazFTWlVWR1IwTkRkblZoV2podlZUZ0tzQjJNdlZyVWlKVTJxdk44eDhrVWhaZHZLUDFScXFmZFxudUh2YVhuVlowcHVMQ3lXNmJKUFBINDA4Tituc216Y1pJUzlYUHc5YVJwdFF2VVY1M081TlZ3PT1cbi0tLS0tRU5EIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG4Kc29wc19hZ2VfX2xpc3RfMF9fbWFwX3JlY2lwaWVudD1hZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dQpzb3BzX2xhc3Rtb2RpZmllZD0yMDI0LTA0LTI5VDExOjU4OjI3Wgpzb3BzX21hYz1FTkNbQUVTMjU2X0dDTSxkYXRhOldFWWdMdlNBaVpwYmdUcTY3b2F3UFlpZTN2dWpIVmlZRlI1MXExS05ZQ3ZwdFo5WFZtNndVQ2Z1VmVuRDc5TWdTU3lTVEVGeFY3QlhjYnFNSUtUUCthRzdLNVBLZUh1dUE5MXVFUHdLdXYvWDJFcmNRMHR0SFZkK1JERGxvdjk3dzhOT0tXcmdxTmhXbFE4UE00dUNveXNwdDBEUlRMREZtRWRMeTkvTEpuWT0saXY6VURJUUpEV24wbWdnWVpTdHo5eDB6SjlPSlFRN0dMcTBldXI4TTRLMXUwbz0sdGFnOmtwWW9LTjlBdVgrSTZYcFJRZldPRFE9PSx0eXBlOnN0cl0Kc29wc191bmVuY3J5cHRlZF9zdWZmaXg9X3VuZW5jcnlwdGVkCnNvcHNfdmVyc2lvbj0zLjguMQo=", - "Hash": "50e5eafdf09ae2e57258067e3833ee033c15faeff45ae85f22a3b74c7302d7fd" - }, - "FlattenSeparator": ".", - "Format": "dotenv", - "ResourceType": "SECRET_BINARY", - "Target": { - "Ref": "SopsSecretDOTENV13EC93B6" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretDOTENVasJSONC46F5173": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretDOTENVasJSONSopsSync598B1279": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsInline": { - "Content": "YmFuYW5lPUVOQ1tBRVMyNTZfR0NNLGRhdGE6S2ZDYm83WjgsaXY6ZXdES1ZaSDcvZkw0d1Jrc0N5U2I0TTlISWhaNCt3NDNtWGdtWVV0S3pVOD0sdGFnOkt1b0ZGVUE0N0xKTFdwREpKd2I3Y0E9PSx0eXBlOnN0cl0KY3J5cHQ9RU5DW0FFUzI1Nl9HQ00sZGF0YToyQnBXVjR3RzdHbzU5Znl4VG1RYXFLbkl1Zz09LGl2OklmRUh3UytSZTJHOElIY091eW9tdldmZ2IwRzZYNnNsUlNOb05jbEROajQ9LHRhZzo1NDFRVFBMVUpjdW52cDhMWkl2K3hRPT0sdHlwZTpzdHJdCnNvcHNfYWdlX19saXN0XzBfX21hcF9lbmM9LS0tLS1CRUdJTiBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQXdWRUpCY1hCcU1FdDZMM2xRVEZaTVxuWVVwbFNHUlBSRFZzTDJZME5GQk5ZV0Y1Y21aTGNYcGhjakZGQ21GeVVUVXZSalJSUlZoc09WZG1kMDluYmtaclxuZEc1d1RqZENZbFp4VG5sTVFXTkZkM0ZhVDNGdEswMEtMUzB0SUVJeVMycGpZVGxTU0RONVIwRnJlalpNZFVaa1xuTWxwbVJEVmpaazFTWlVWR1IwTkRkblZoV2podlZUZ0tzQjJNdlZyVWlKVTJxdk44eDhrVWhaZHZLUDFScXFmZFxudUh2YVhuVlowcHVMQ3lXNmJKUFBINDA4Tituc216Y1pJUzlYUHc5YVJwdFF2VVY1M081TlZ3PT1cbi0tLS0tRU5EIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG4Kc29wc19hZ2VfX2xpc3RfMF9fbWFwX3JlY2lwaWVudD1hZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dQpzb3BzX2xhc3Rtb2RpZmllZD0yMDI0LTA0LTI5VDExOjU4OjI3Wgpzb3BzX21hYz1FTkNbQUVTMjU2X0dDTSxkYXRhOldFWWdMdlNBaVpwYmdUcTY3b2F3UFlpZTN2dWpIVmlZRlI1MXExS05ZQ3ZwdFo5WFZtNndVQ2Z1VmVuRDc5TWdTU3lTVEVGeFY3QlhjYnFNSUtUUCthRzdLNVBLZUh1dUE5MXVFUHdLdXYvWDJFcmNRMHR0SFZkK1JERGxvdjk3dzhOT0tXcmdxTmhXbFE4UE00dUNveXNwdDBEUlRMREZtRWRMeTkvTEpuWT0saXY6VURJUUpEV24wbWdnWVpTdHo5eDB6SjlPSlFRN0dMcTBldXI4TTRLMXUwbz0sdGFnOmtwWW9LTjlBdVgrSTZYcFJRZldPRFE9PSx0eXBlOnN0cl0Kc29wc191bmVuY3J5cHRlZF9zdWZmaXg9X3VuZW5jcnlwdGVkCnNvcHNfdmVyc2lvbj0zLjguMQo=", - "Hash": "50e5eafdf09ae2e57258067e3833ee033c15faeff45ae85f22a3b74c7302d7fd" - }, - "FlattenSeparator": ".", - "Format": "dotenv", - "ResourceType": "SECRET", - "Target": { - "Ref": "SopsSecretDOTENVasJSONC46F5173" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONAD4C2662": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONSopsSyncCABA63FF": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsInline": { - "Content": "ewoJInNvbWUiOiB7CgkJImRlZXAiOiB7CgkJCSJuZXN0ZWQiOiB7CgkJCQkib2JqZWN0IjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6eXVrSHVHc0Qwd2dZLGl2OlVnaG44T2dOY2RJUFN6MWhYQ3BjbkpPRFNEcmsxOXkwVU1jd1F6VFJKRmM9LHRhZzp3T3BhMDNQZHA2M2VlVkwxdDlHUHdBPT0sdHlwZTpzdHJdIiwKCQkJCSJhcnJheXMiOiBbCgkJCQkJIkVOQ1tBRVMyNTZfR0NNLGRhdGE6TTMrOHZnPT0saXY6R0RyUWxSbkgwUDMybWxEOWVaTW92aEo0Tms2ck1iL0U3OUdRNXVQYmEwND0sdGFnOmFiT3YzeXNVMVlrOTZtdXhMR3lPSFE9PSx0eXBlOnN0cl0iLAoJCQkJCSJFTkNbQUVTMjU2X0dDTSxkYXRhOjBOQzBHTDVwUkE9PSxpdjorSkg2MlJTa253NkFYTjZ2TVBEQjJnbTlSUnRuQ2h4UHo4dHc5OVgvNnkwPSx0YWc6WlBLekhDWTY2SEswQmF1a2p2Wmx2UT09LHR5cGU6c3RyXSIsCgkJCQkJewoJCQkJCQkidmFsdWVzIjogewoJCQkJCQkJImFuZCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOlBWam5aMlptOWc9PSxpdjpXQWVORFQ0eGw5WEtYbmtHQXJzREthTjZUeFJUSTh1V090bjh4K0cwaG5NPSx0YWc6U3lMaWI4UlBONjVweXFrRmdQaGxWQT09LHR5cGU6c3RyXSIKCQkJCQkJfQoJCQkJCX0KCQkJCV0KCQkJfQoJCX0sCgkJIm5vdHNvZGVlcCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOktTZjZwbDFlLGl2Ok9LUjUraHc2R0N6Ym03NTBzQWxBWFc4L0c0U2U4QnUxRldISHRFZW5ZZVU9LHRhZzo1aGxGMDNPbTdxVmNKVUczVTk1dXZRPT0sdHlwZTpzdHJdIgoJfSwKCSJhbmQgbm93IjogewoJCSJzb21lIjogWwoJCQl7CgkJCQkiYmFzaWMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpLQm80L2swPSxpdjprcDRneGhDcFduUC9WdkluRkJObHdYVEU2c2s0OE4zMjJzQWFHc05lZWJrPSx0YWc6RTQ1encxMmxrUmdLZEVJSC9BUm55QT09LHR5cGU6Ym9vbF0iCgkJCX0sCgkJCXsKCQkJCSJuZXN0ZWQiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpyekpzMW04PSxpdjorb1JuWFlQYTZKYnYvaU50MVFrbnloZFI3WjY3ZlZIVnEybnZxM0daT1RVPSx0YWc6QVdMaHRENEUvK0VISURKZ2lwcU0xQT09LHR5cGU6ZmxvYXRdIgoJCQl9LAoJCQl7CgkJCQkidHlwZSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOm5haFYzQk5FLGl2OmlkZGppenRqUmFVcVRhUzZ1VlRQUERpWEhOWVJEQytvSVBEODE5L0dDUnM9LHRhZzpxRDRienRDR3c5QzR3aTBLbDd2TFV3PT0sdHlwZTpmbG9hdF0iCgkJCX0sCgkJCXsKCQkJCSJ0ZXN0cyI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOjhvZlhUSE5ENnc9PSxpdjpEcktvNHJ2M3ZWL044YjFTNWRUaUpHeUxITmx2bnJYOGdJWkRxTnpxMWVnPSx0YWc6Z0ZQbmRWOTZyT2sxUjBkQXplZm11QT09LHR5cGU6c3RyXSIKCQkJfQoJCV0KCX0sCgkic29wcyI6IHsKCQkia21zIjogbnVsbCwKCQkiZ2NwX2ttcyI6IG51bGwsCgkJImF6dXJlX2t2IjogbnVsbCwKCQkiaGNfdmF1bHQiOiBudWxsLAoJCSJhZ2UiOiBbCgkJCXsKCQkJCSJyZWNpcGllbnQiOiAiYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUiLAoJCQkJImVuYyI6ICItLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG5ZV2RsTFdWdVkzSjVjSFJwYjI0dWIzSm5MM1l4Q2kwK0lGZ3lOVFV4T1NBeFQzTkdVMEpFVDBOaVkxTlFjbTluXG5aRlpRU0NzMU56ZFphRWt2U0dobVREVjZiRkJIWTJWWmEyZGpDa2xDWmtKNFZ5OVNUbEJ1ZDJwclNtNUtSMWhyXG5OMGhwYURkb1dHdHhha1I2TVdnNVVqSTBTWEJpYlVVS0xTMHRJSGR0UjI5U1dUSXhXbWhNZW5sYWVVNXhlbTl1XG5LemhLYTNOS2JHcDJkRlZ4TVRWdVdpOVZkWEozTVc4S2FuejNEcElnUFhPOXU0NFRVc1RQdGd3VExiUDZZcFVmXG5Kb3Y0VDJvTHk0VW82NjhSTkNCMWZiS250NW55Y21SSnhlK3JZbU92bjJWZUw5dldjdzBrWnc9PVxuLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS1cbiIKCQkJfQoJCV0sCgkJImxhc3Rtb2RpZmllZCI6ICIyMDIyLTA0LTAzVDE3OjI0OjI0WiIsCgkJIm1hYyI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOm1VU0tGeVlxYnhRV2lyZnpOdnlOTXZySjkraiszUTlzL0FSak9XSlpPSnJBeXBKWVB0YlphL2R1U0w0Q3pCVzZLZExmOVlSZkk3SGppS1g1RzhTVUw5ZjVCekFYSUdCcS9EQUVmYVhaOEFyekhmSzR0dHg5UGUydEwrRGpPLy9tSEdFSjg4SllFVmpyRU1MRytORGE5YXJwREtLOCtPNEx1RUNTb0NhYWFxST0saXY6MlcyVnRDVkdmc2tvb1dNQWlMb0xMY0RndTlQdXcyQ2YzZGkyaVRZdlBjVT0sdGFnOjVlcG44U2FFOERFMkVLUm1iSW8xZ2c9PSx0eXBlOnN0cl0iLAoJCSJwZ3AiOiBudWxsLAoJCSJ1bmVuY3J5cHRlZF9zdWZmaXgiOiAiX3VuZW5jcnlwdGVkIiwKCQkidmVyc2lvbiI6ICIzLjcuMiIKCX0KfQ==", - "Hash": "313aad921c737076a990ead756b250f1677aecc927177440df0c809cd56bf282" - }, - "FlattenSeparator": ".", - "Format": "json", - "ResourceType": "SECRET", - "Target": { - "Ref": "SopsComplexSecretJSONAD4C2662" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONFlatF5FC1D69": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONFlatSopsSyncC4165B67": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsInline": { - "Content": "ewoJInNvbWUiOiB7CgkJImRlZXAiOiB7CgkJCSJuZXN0ZWQiOiB7CgkJCQkib2JqZWN0IjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6eXVrSHVHc0Qwd2dZLGl2OlVnaG44T2dOY2RJUFN6MWhYQ3BjbkpPRFNEcmsxOXkwVU1jd1F6VFJKRmM9LHRhZzp3T3BhMDNQZHA2M2VlVkwxdDlHUHdBPT0sdHlwZTpzdHJdIiwKCQkJCSJhcnJheXMiOiBbCgkJCQkJIkVOQ1tBRVMyNTZfR0NNLGRhdGE6TTMrOHZnPT0saXY6R0RyUWxSbkgwUDMybWxEOWVaTW92aEo0Tms2ck1iL0U3OUdRNXVQYmEwND0sdGFnOmFiT3YzeXNVMVlrOTZtdXhMR3lPSFE9PSx0eXBlOnN0cl0iLAoJCQkJCSJFTkNbQUVTMjU2X0dDTSxkYXRhOjBOQzBHTDVwUkE9PSxpdjorSkg2MlJTa253NkFYTjZ2TVBEQjJnbTlSUnRuQ2h4UHo4dHc5OVgvNnkwPSx0YWc6WlBLekhDWTY2SEswQmF1a2p2Wmx2UT09LHR5cGU6c3RyXSIsCgkJCQkJewoJCQkJCQkidmFsdWVzIjogewoJCQkJCQkJImFuZCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOlBWam5aMlptOWc9PSxpdjpXQWVORFQ0eGw5WEtYbmtHQXJzREthTjZUeFJUSTh1V090bjh4K0cwaG5NPSx0YWc6U3lMaWI4UlBONjVweXFrRmdQaGxWQT09LHR5cGU6c3RyXSIKCQkJCQkJfQoJCQkJCX0KCQkJCV0KCQkJfQoJCX0sCgkJIm5vdHNvZGVlcCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOktTZjZwbDFlLGl2Ok9LUjUraHc2R0N6Ym03NTBzQWxBWFc4L0c0U2U4QnUxRldISHRFZW5ZZVU9LHRhZzo1aGxGMDNPbTdxVmNKVUczVTk1dXZRPT0sdHlwZTpzdHJdIgoJfSwKCSJhbmQgbm93IjogewoJCSJzb21lIjogWwoJCQl7CgkJCQkiYmFzaWMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpLQm80L2swPSxpdjprcDRneGhDcFduUC9WdkluRkJObHdYVEU2c2s0OE4zMjJzQWFHc05lZWJrPSx0YWc6RTQ1encxMmxrUmdLZEVJSC9BUm55QT09LHR5cGU6Ym9vbF0iCgkJCX0sCgkJCXsKCQkJCSJuZXN0ZWQiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpyekpzMW04PSxpdjorb1JuWFlQYTZKYnYvaU50MVFrbnloZFI3WjY3ZlZIVnEybnZxM0daT1RVPSx0YWc6QVdMaHRENEUvK0VISURKZ2lwcU0xQT09LHR5cGU6ZmxvYXRdIgoJCQl9LAoJCQl7CgkJCQkidHlwZSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOm5haFYzQk5FLGl2OmlkZGppenRqUmFVcVRhUzZ1VlRQUERpWEhOWVJEQytvSVBEODE5L0dDUnM9LHRhZzpxRDRienRDR3c5QzR3aTBLbDd2TFV3PT0sdHlwZTpmbG9hdF0iCgkJCX0sCgkJCXsKCQkJCSJ0ZXN0cyI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOjhvZlhUSE5ENnc9PSxpdjpEcktvNHJ2M3ZWL044YjFTNWRUaUpHeUxITmx2bnJYOGdJWkRxTnpxMWVnPSx0YWc6Z0ZQbmRWOTZyT2sxUjBkQXplZm11QT09LHR5cGU6c3RyXSIKCQkJfQoJCV0KCX0sCgkic29wcyI6IHsKCQkia21zIjogbnVsbCwKCQkiZ2NwX2ttcyI6IG51bGwsCgkJImF6dXJlX2t2IjogbnVsbCwKCQkiaGNfdmF1bHQiOiBudWxsLAoJCSJhZ2UiOiBbCgkJCXsKCQkJCSJyZWNpcGllbnQiOiAiYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUiLAoJCQkJImVuYyI6ICItLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tXG5ZV2RsTFdWdVkzSjVjSFJwYjI0dWIzSm5MM1l4Q2kwK0lGZ3lOVFV4T1NBeFQzTkdVMEpFVDBOaVkxTlFjbTluXG5aRlpRU0NzMU56ZFphRWt2U0dobVREVjZiRkJIWTJWWmEyZGpDa2xDWmtKNFZ5OVNUbEJ1ZDJwclNtNUtSMWhyXG5OMGhwYURkb1dHdHhha1I2TVdnNVVqSTBTWEJpYlVVS0xTMHRJSGR0UjI5U1dUSXhXbWhNZW5sYWVVNXhlbTl1XG5LemhLYTNOS2JHcDJkRlZ4TVRWdVdpOVZkWEozTVc4S2FuejNEcElnUFhPOXU0NFRVc1RQdGd3VExiUDZZcFVmXG5Kb3Y0VDJvTHk0VW82NjhSTkNCMWZiS250NW55Y21SSnhlK3JZbU92bjJWZUw5dldjdzBrWnc9PVxuLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS1cbiIKCQkJfQoJCV0sCgkJImxhc3Rtb2RpZmllZCI6ICIyMDIyLTA0LTAzVDE3OjI0OjI0WiIsCgkJIm1hYyI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOm1VU0tGeVlxYnhRV2lyZnpOdnlOTXZySjkraiszUTlzL0FSak9XSlpPSnJBeXBKWVB0YlphL2R1U0w0Q3pCVzZLZExmOVlSZkk3SGppS1g1RzhTVUw5ZjVCekFYSUdCcS9EQUVmYVhaOEFyekhmSzR0dHg5UGUydEwrRGpPLy9tSEdFSjg4SllFVmpyRU1MRytORGE5YXJwREtLOCtPNEx1RUNTb0NhYWFxST0saXY6MlcyVnRDVkdmc2tvb1dNQWlMb0xMY0RndTlQdXcyQ2YzZGkyaVRZdlBjVT0sdGFnOjVlcG44U2FFOERFMkVLUm1iSW8xZ2c9PSx0eXBlOnN0cl0iLAoJCSJwZ3AiOiBudWxsLAoJCSJ1bmVuY3J5cHRlZF9zdWZmaXgiOiAiX3VuZW5jcnlwdGVkIiwKCQkidmVyc2lvbiI6ICIzLjcuMiIKCX0KfQ==", - "Hash": "313aad921c737076a990ead756b250f1677aecc927177440df0c809cd56bf282" - }, - "FlattenSeparator": ".", - "Format": "json", - "ResourceType": "SECRET", - "Target": { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLF52D88F2": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLSopsSync4B881273": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsInline": { - "Content": "c29tZToKICAgIGRlZXA6CiAgICAgICAgbmVzdGVkOgogICAgICAgICAgICBvYmplY3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6WW1kZVJGRUdLS1VULGl2OjhPOVFVdlU3ZzFFK2F3WUtYU3hra3pVS3pCYzhhZFVEdG1QaXdqdFBQYjA9LHRhZzozT3Q4eU5DbzJwM1JIMERUNStBa2JRPT0sdHlwZTpzdHJdCiAgICAgICAgICAgIGFycmF5czoKICAgICAgICAgICAgICAgIC0gRU5DW0FFUzI1Nl9HQ00sZGF0YTpoYWFEWnc9PSxpdjo0L2FVZ3NFbXNVcEUvMUs1aUdiQjJJQmNiWm0wUDdrM2lMNElSOWtPbkFJPSx0YWc6bkFhc1MvLzEvWEFBU3Myc2I2dklUQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSBFTkNbQUVTMjU2X0dDTSxkYXRhOlZvalRZbUVpbHc9PSxpdjppMi9zRm05TXBMYjRML1dZeWtCNGJ4THVvN3FadjVOcmRTSGNNK2dZaGh3PSx0YWc6NS8rTTZlRUlkc2IvYjN3clhQanNtQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSB2YWx1ZXM6CiAgICAgICAgICAgICAgICAgICAgYW5kOiBFTkNbQUVTMjU2X0dDTSxkYXRhOkJnOTI0dExUWmc9PSxpdjprOEFFYkw4Vkd0NXViS0tOV1JYVVBlTVF4ODRjeFBDb1EweVd4NkR2d29jPSx0YWc6bzhjUnRHSnh0Q3RKYTdCajNaMG0yQT09LHR5cGU6c3RyXQogICAgbm90c29kZWVwOiBFTkNbQUVTMjU2X0dDTSxkYXRhOndwaU15cExoLGl2OmhpTG9BZGd6RTlQYlNrMjEydTNJamlnRXp4aU5nYUtWZysyU2pqRUZ1bkU9LHRhZzpkTGwxdTVSOUYxMDVKN3FJNWMzb0V3PT0sdHlwZTpzdHJdCmFuZCBub3c6CiAgICBzb21lOgogICAgICAgIC0gYmFzaWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6bU9od0duYz0saXY6ZGdNaklaTkl6QlZUZE0wTHllVHdKYk92cmh0TDNDZUVWSlFRYVplRkdvWT0sdGFnOm9CU3dEanlEQXlGZ2xJVFlCdnNIZVE9PSx0eXBlOmJvb2xdCiAgICAgICAgLSBuZXN0ZWQ6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6c2dzcTJLYz0saXY6MmoxQ0R6cXdDU3dvK1E4eHpOV2FpUVB3ZUMvOFZSMGlwMjVmeFFuNitubz0sdGFnOjl4RHFyZERjSDA3VkVock9hSzdMemc9PSx0eXBlOmludF0KICAgICAgICAtIHR5cGU6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6dDlpSUpVazAsaXY6NVl1K2tDV1BJNzZ1QzR0OUZqMTdnRVdWYytScHB2eXNZSFluMVJQV1ZRMD0sdGFnOlRCaHowb0d2aGJPRWZoU0FsMEFsd3c9PSx0eXBlOmZsb2F0XQogICAgICAgIC0gdGVzdHM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6S2xoa21RREQxQT09LGl2Om1zT1dBb0duc0I4bGNreTBIZUJ1WFlYN0JYY2xxVmZNMm95cldKcm5FNzA9LHRhZzphcENTNlFtYVZiVXpkc3VsOWw5V0NnPT0sdHlwZTpzdHJdCnNvcHM6CiAgICBrbXM6IFtdCiAgICBnY3Bfa21zOiBbXQogICAgYXp1cmVfa3Y6IFtdCiAgICBoY192YXVsdDogW10KICAgIGFnZToKICAgICAgICAtIHJlY2lwaWVudDogYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUKICAgICAgICAgIGVuYzogfAogICAgICAgICAgICAtLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tCiAgICAgICAgICAgIFlXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JhVVZCQ1JWaDFTbVZxYkc1RGVuRmEKICAgICAgICAgICAgYnk5SVUyNHJPSGRWTWtjMFkxTkNhQ3RxUVRFd2R6WnFXVzF2Q2t4NU5YQk1aa1pDZVRrdlFXMXRVRWR2UjJseQogICAgICAgICAgICBNV2xTVEUxalZXdEhkMFJvYTNSUFMzVktRalJUWWxVS0xTMHRJRGhDWjNNMlFWZFZiMmwwUzBOUE1ETlNhbFZTCiAgICAgICAgICAgIE5WbzRaVlZTTkhGUFJHRnllbkJxTjJ0UE5XUndOemdLeHBUZmlKRkJtTjlPd1F5SDJrSVMxUHBoTmllQ0tNcFoKICAgICAgICAgICAgeWtXQXRoS1oyYTM1dnpHcGRiMFVWVFVjM2hReG93Nm5KQ0dlUExndkxHQ05FSytCWDluUTV3PT0KICAgICAgICAgICAgLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgIGxhc3Rtb2RpZmllZDogIjIwMjItMDQtMDNUMTc6MjU6MjRaIgogICAgbWFjOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNZRGo5eGsrUktYZ3pCR0JOVHpzcUNjSGdMVjBqak9JMXE1U3lTTGhsYnNHNjNjaDdmWGVkWkxzT0p0V2hGNXgxdjIyZmZVU1lVK0hITVFnQnBQUklsa0h1R1FDU1hrOEt5dGg0eUlmUnBZcmVKYlUzaC9ZNmNEMjcycWNYWHJqK0V5QlFEM3k1dzZiU2RGYXRLeFgvVmk0VG1uZ3JNL2F6ajRqTHp1L3UrST0saXY6ajBiMFd2d0paa3RuNWwxcG91V2RFOE1xNllsMXlqdWxDNTlKbENUMGhFdz0sdGFnOmY2RzBEQjc3bURwcWxvV25hZGMzVWc9PSx0eXBlOnN0cl0KICAgIHBncDogW10KICAgIHVuZW5jcnlwdGVkX3N1ZmZpeDogX3VuZW5jcnlwdGVkCiAgICB2ZXJzaW9uOiAzLjcuMgo=", - "Hash": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2" - }, - "FlattenSeparator": ".", - "Format": "yaml", - "ResourceType": "SECRET", - "Target": { - "Ref": "SopComplexSecretYAMLF52D88F2" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLFlatD9CE8782": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLFlatSopsSync8B86CE19": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsInline": { - "Content": "c29tZToKICAgIGRlZXA6CiAgICAgICAgbmVzdGVkOgogICAgICAgICAgICBvYmplY3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6WW1kZVJGRUdLS1VULGl2OjhPOVFVdlU3ZzFFK2F3WUtYU3hra3pVS3pCYzhhZFVEdG1QaXdqdFBQYjA9LHRhZzozT3Q4eU5DbzJwM1JIMERUNStBa2JRPT0sdHlwZTpzdHJdCiAgICAgICAgICAgIGFycmF5czoKICAgICAgICAgICAgICAgIC0gRU5DW0FFUzI1Nl9HQ00sZGF0YTpoYWFEWnc9PSxpdjo0L2FVZ3NFbXNVcEUvMUs1aUdiQjJJQmNiWm0wUDdrM2lMNElSOWtPbkFJPSx0YWc6bkFhc1MvLzEvWEFBU3Myc2I2dklUQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSBFTkNbQUVTMjU2X0dDTSxkYXRhOlZvalRZbUVpbHc9PSxpdjppMi9zRm05TXBMYjRML1dZeWtCNGJ4THVvN3FadjVOcmRTSGNNK2dZaGh3PSx0YWc6NS8rTTZlRUlkc2IvYjN3clhQanNtQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSB2YWx1ZXM6CiAgICAgICAgICAgICAgICAgICAgYW5kOiBFTkNbQUVTMjU2X0dDTSxkYXRhOkJnOTI0dExUWmc9PSxpdjprOEFFYkw4Vkd0NXViS0tOV1JYVVBlTVF4ODRjeFBDb1EweVd4NkR2d29jPSx0YWc6bzhjUnRHSnh0Q3RKYTdCajNaMG0yQT09LHR5cGU6c3RyXQogICAgbm90c29kZWVwOiBFTkNbQUVTMjU2X0dDTSxkYXRhOndwaU15cExoLGl2OmhpTG9BZGd6RTlQYlNrMjEydTNJamlnRXp4aU5nYUtWZysyU2pqRUZ1bkU9LHRhZzpkTGwxdTVSOUYxMDVKN3FJNWMzb0V3PT0sdHlwZTpzdHJdCmFuZCBub3c6CiAgICBzb21lOgogICAgICAgIC0gYmFzaWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6bU9od0duYz0saXY6ZGdNaklaTkl6QlZUZE0wTHllVHdKYk92cmh0TDNDZUVWSlFRYVplRkdvWT0sdGFnOm9CU3dEanlEQXlGZ2xJVFlCdnNIZVE9PSx0eXBlOmJvb2xdCiAgICAgICAgLSBuZXN0ZWQ6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6c2dzcTJLYz0saXY6MmoxQ0R6cXdDU3dvK1E4eHpOV2FpUVB3ZUMvOFZSMGlwMjVmeFFuNitubz0sdGFnOjl4RHFyZERjSDA3VkVock9hSzdMemc9PSx0eXBlOmludF0KICAgICAgICAtIHR5cGU6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6dDlpSUpVazAsaXY6NVl1K2tDV1BJNzZ1QzR0OUZqMTdnRVdWYytScHB2eXNZSFluMVJQV1ZRMD0sdGFnOlRCaHowb0d2aGJPRWZoU0FsMEFsd3c9PSx0eXBlOmZsb2F0XQogICAgICAgIC0gdGVzdHM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6S2xoa21RREQxQT09LGl2Om1zT1dBb0duc0I4bGNreTBIZUJ1WFlYN0JYY2xxVmZNMm95cldKcm5FNzA9LHRhZzphcENTNlFtYVZiVXpkc3VsOWw5V0NnPT0sdHlwZTpzdHJdCnNvcHM6CiAgICBrbXM6IFtdCiAgICBnY3Bfa21zOiBbXQogICAgYXp1cmVfa3Y6IFtdCiAgICBoY192YXVsdDogW10KICAgIGFnZToKICAgICAgICAtIHJlY2lwaWVudDogYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUKICAgICAgICAgIGVuYzogfAogICAgICAgICAgICAtLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tCiAgICAgICAgICAgIFlXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JhVVZCQ1JWaDFTbVZxYkc1RGVuRmEKICAgICAgICAgICAgYnk5SVUyNHJPSGRWTWtjMFkxTkNhQ3RxUVRFd2R6WnFXVzF2Q2t4NU5YQk1aa1pDZVRrdlFXMXRVRWR2UjJseQogICAgICAgICAgICBNV2xTVEUxalZXdEhkMFJvYTNSUFMzVktRalJUWWxVS0xTMHRJRGhDWjNNMlFWZFZiMmwwUzBOUE1ETlNhbFZTCiAgICAgICAgICAgIE5WbzRaVlZTTkhGUFJHRnllbkJxTjJ0UE5XUndOemdLeHBUZmlKRkJtTjlPd1F5SDJrSVMxUHBoTmllQ0tNcFoKICAgICAgICAgICAgeWtXQXRoS1oyYTM1dnpHcGRiMFVWVFVjM2hReG93Nm5KQ0dlUExndkxHQ05FSytCWDluUTV3PT0KICAgICAgICAgICAgLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgIGxhc3Rtb2RpZmllZDogIjIwMjItMDQtMDNUMTc6MjU6MjRaIgogICAgbWFjOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNZRGo5eGsrUktYZ3pCR0JOVHpzcUNjSGdMVjBqak9JMXE1U3lTTGhsYnNHNjNjaDdmWGVkWkxzT0p0V2hGNXgxdjIyZmZVU1lVK0hITVFnQnBQUklsa0h1R1FDU1hrOEt5dGg0eUlmUnBZcmVKYlUzaC9ZNmNEMjcycWNYWHJqK0V5QlFEM3k1dzZiU2RGYXRLeFgvVmk0VG1uZ3JNL2F6ajRqTHp1L3UrST0saXY6ajBiMFd2d0paa3RuNWwxcG91V2RFOE1xNllsMXlqdWxDNTlKbENUMGhFdz0sdGFnOmY2RzBEQjc3bURwcWxvV25hZGMzVWc9PSx0eXBlOnN0cl0KICAgIHBncDogW10KICAgIHVuZW5jcnlwdGVkX3N1ZmZpeDogX3VuZW5jcnlwdGVkCiAgICB2ZXJzaW9uOiAzLjcuMgo=", - "Hash": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2" - }, - "FlattenSeparator": ".", - "Format": "yaml", - "ResourceType": "SECRET", - "Target": { - "Ref": "SopComplexSecretYAMLFlatD9CE8782" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONEAE81DB0": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONSopsSyncC4061B33": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsInline": { - "Content": "c29tZToKICAgIGRlZXA6CiAgICAgICAgbmVzdGVkOgogICAgICAgICAgICBvYmplY3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6WW1kZVJGRUdLS1VULGl2OjhPOVFVdlU3ZzFFK2F3WUtYU3hra3pVS3pCYzhhZFVEdG1QaXdqdFBQYjA9LHRhZzozT3Q4eU5DbzJwM1JIMERUNStBa2JRPT0sdHlwZTpzdHJdCiAgICAgICAgICAgIGFycmF5czoKICAgICAgICAgICAgICAgIC0gRU5DW0FFUzI1Nl9HQ00sZGF0YTpoYWFEWnc9PSxpdjo0L2FVZ3NFbXNVcEUvMUs1aUdiQjJJQmNiWm0wUDdrM2lMNElSOWtPbkFJPSx0YWc6bkFhc1MvLzEvWEFBU3Myc2I2dklUQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSBFTkNbQUVTMjU2X0dDTSxkYXRhOlZvalRZbUVpbHc9PSxpdjppMi9zRm05TXBMYjRML1dZeWtCNGJ4THVvN3FadjVOcmRTSGNNK2dZaGh3PSx0YWc6NS8rTTZlRUlkc2IvYjN3clhQanNtQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSB2YWx1ZXM6CiAgICAgICAgICAgICAgICAgICAgYW5kOiBFTkNbQUVTMjU2X0dDTSxkYXRhOkJnOTI0dExUWmc9PSxpdjprOEFFYkw4Vkd0NXViS0tOV1JYVVBlTVF4ODRjeFBDb1EweVd4NkR2d29jPSx0YWc6bzhjUnRHSnh0Q3RKYTdCajNaMG0yQT09LHR5cGU6c3RyXQogICAgbm90c29kZWVwOiBFTkNbQUVTMjU2X0dDTSxkYXRhOndwaU15cExoLGl2OmhpTG9BZGd6RTlQYlNrMjEydTNJamlnRXp4aU5nYUtWZysyU2pqRUZ1bkU9LHRhZzpkTGwxdTVSOUYxMDVKN3FJNWMzb0V3PT0sdHlwZTpzdHJdCmFuZCBub3c6CiAgICBzb21lOgogICAgICAgIC0gYmFzaWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6bU9od0duYz0saXY6ZGdNaklaTkl6QlZUZE0wTHllVHdKYk92cmh0TDNDZUVWSlFRYVplRkdvWT0sdGFnOm9CU3dEanlEQXlGZ2xJVFlCdnNIZVE9PSx0eXBlOmJvb2xdCiAgICAgICAgLSBuZXN0ZWQ6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6c2dzcTJLYz0saXY6MmoxQ0R6cXdDU3dvK1E4eHpOV2FpUVB3ZUMvOFZSMGlwMjVmeFFuNitubz0sdGFnOjl4RHFyZERjSDA3VkVock9hSzdMemc9PSx0eXBlOmludF0KICAgICAgICAtIHR5cGU6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6dDlpSUpVazAsaXY6NVl1K2tDV1BJNzZ1QzR0OUZqMTdnRVdWYytScHB2eXNZSFluMVJQV1ZRMD0sdGFnOlRCaHowb0d2aGJPRWZoU0FsMEFsd3c9PSx0eXBlOmZsb2F0XQogICAgICAgIC0gdGVzdHM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6S2xoa21RREQxQT09LGl2Om1zT1dBb0duc0I4bGNreTBIZUJ1WFlYN0JYY2xxVmZNMm95cldKcm5FNzA9LHRhZzphcENTNlFtYVZiVXpkc3VsOWw5V0NnPT0sdHlwZTpzdHJdCnNvcHM6CiAgICBrbXM6IFtdCiAgICBnY3Bfa21zOiBbXQogICAgYXp1cmVfa3Y6IFtdCiAgICBoY192YXVsdDogW10KICAgIGFnZToKICAgICAgICAtIHJlY2lwaWVudDogYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUKICAgICAgICAgIGVuYzogfAogICAgICAgICAgICAtLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tCiAgICAgICAgICAgIFlXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JhVVZCQ1JWaDFTbVZxYkc1RGVuRmEKICAgICAgICAgICAgYnk5SVUyNHJPSGRWTWtjMFkxTkNhQ3RxUVRFd2R6WnFXVzF2Q2t4NU5YQk1aa1pDZVRrdlFXMXRVRWR2UjJseQogICAgICAgICAgICBNV2xTVEUxalZXdEhkMFJvYTNSUFMzVktRalJUWWxVS0xTMHRJRGhDWjNNMlFWZFZiMmwwUzBOUE1ETlNhbFZTCiAgICAgICAgICAgIE5WbzRaVlZTTkhGUFJHRnllbkJxTjJ0UE5XUndOemdLeHBUZmlKRkJtTjlPd1F5SDJrSVMxUHBoTmllQ0tNcFoKICAgICAgICAgICAgeWtXQXRoS1oyYTM1dnpHcGRiMFVWVFVjM2hReG93Nm5KQ0dlUExndkxHQ05FSytCWDluUTV3PT0KICAgICAgICAgICAgLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgIGxhc3Rtb2RpZmllZDogIjIwMjItMDQtMDNUMTc6MjU6MjRaIgogICAgbWFjOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNZRGo5eGsrUktYZ3pCR0JOVHpzcUNjSGdMVjBqak9JMXE1U3lTTGhsYnNHNjNjaDdmWGVkWkxzT0p0V2hGNXgxdjIyZmZVU1lVK0hITVFnQnBQUklsa0h1R1FDU1hrOEt5dGg0eUlmUnBZcmVKYlUzaC9ZNmNEMjcycWNYWHJqK0V5QlFEM3k1dzZiU2RGYXRLeFgvVmk0VG1uZ3JNL2F6ajRqTHp1L3UrST0saXY6ajBiMFd2d0paa3RuNWwxcG91V2RFOE1xNllsMXlqdWxDNTlKbENUMGhFdz0sdGFnOmY2RzBEQjc3bURwcWxvV25hZGMzVWc9PSx0eXBlOnN0cl0KICAgIHBncDogW10KICAgIHVuZW5jcnlwdGVkX3N1ZmZpeDogX3VuZW5jcnlwdGVkCiAgICB2ZXJzaW9uOiAzLjcuMgo=", - "Hash": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2" - }, - "FlattenSeparator": ".", - "Format": "yaml", - "ResourceType": "SECRET", - "Target": { - "Ref": "SopsComplexSecretYAMLasJSONEAE81DB0" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONFlat9FD04B78": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsInline": { - "Content": "c29tZToKICAgIGRlZXA6CiAgICAgICAgbmVzdGVkOgogICAgICAgICAgICBvYmplY3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6WW1kZVJGRUdLS1VULGl2OjhPOVFVdlU3ZzFFK2F3WUtYU3hra3pVS3pCYzhhZFVEdG1QaXdqdFBQYjA9LHRhZzozT3Q4eU5DbzJwM1JIMERUNStBa2JRPT0sdHlwZTpzdHJdCiAgICAgICAgICAgIGFycmF5czoKICAgICAgICAgICAgICAgIC0gRU5DW0FFUzI1Nl9HQ00sZGF0YTpoYWFEWnc9PSxpdjo0L2FVZ3NFbXNVcEUvMUs1aUdiQjJJQmNiWm0wUDdrM2lMNElSOWtPbkFJPSx0YWc6bkFhc1MvLzEvWEFBU3Myc2I2dklUQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSBFTkNbQUVTMjU2X0dDTSxkYXRhOlZvalRZbUVpbHc9PSxpdjppMi9zRm05TXBMYjRML1dZeWtCNGJ4THVvN3FadjVOcmRTSGNNK2dZaGh3PSx0YWc6NS8rTTZlRUlkc2IvYjN3clhQanNtQT09LHR5cGU6c3RyXQogICAgICAgICAgICAgICAgLSB2YWx1ZXM6CiAgICAgICAgICAgICAgICAgICAgYW5kOiBFTkNbQUVTMjU2X0dDTSxkYXRhOkJnOTI0dExUWmc9PSxpdjprOEFFYkw4Vkd0NXViS0tOV1JYVVBlTVF4ODRjeFBDb1EweVd4NkR2d29jPSx0YWc6bzhjUnRHSnh0Q3RKYTdCajNaMG0yQT09LHR5cGU6c3RyXQogICAgbm90c29kZWVwOiBFTkNbQUVTMjU2X0dDTSxkYXRhOndwaU15cExoLGl2OmhpTG9BZGd6RTlQYlNrMjEydTNJamlnRXp4aU5nYUtWZysyU2pqRUZ1bkU9LHRhZzpkTGwxdTVSOUYxMDVKN3FJNWMzb0V3PT0sdHlwZTpzdHJdCmFuZCBub3c6CiAgICBzb21lOgogICAgICAgIC0gYmFzaWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6bU9od0duYz0saXY6ZGdNaklaTkl6QlZUZE0wTHllVHdKYk92cmh0TDNDZUVWSlFRYVplRkdvWT0sdGFnOm9CU3dEanlEQXlGZ2xJVFlCdnNIZVE9PSx0eXBlOmJvb2xdCiAgICAgICAgLSBuZXN0ZWQ6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6c2dzcTJLYz0saXY6MmoxQ0R6cXdDU3dvK1E4eHpOV2FpUVB3ZUMvOFZSMGlwMjVmeFFuNitubz0sdGFnOjl4RHFyZERjSDA3VkVock9hSzdMemc9PSx0eXBlOmludF0KICAgICAgICAtIHR5cGU6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6dDlpSUpVazAsaXY6NVl1K2tDV1BJNzZ1QzR0OUZqMTdnRVdWYytScHB2eXNZSFluMVJQV1ZRMD0sdGFnOlRCaHowb0d2aGJPRWZoU0FsMEFsd3c9PSx0eXBlOmZsb2F0XQogICAgICAgIC0gdGVzdHM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6S2xoa21RREQxQT09LGl2Om1zT1dBb0duc0I4bGNreTBIZUJ1WFlYN0JYY2xxVmZNMm95cldKcm5FNzA9LHRhZzphcENTNlFtYVZiVXpkc3VsOWw5V0NnPT0sdHlwZTpzdHJdCnNvcHM6CiAgICBrbXM6IFtdCiAgICBnY3Bfa21zOiBbXQogICAgYXp1cmVfa3Y6IFtdCiAgICBoY192YXVsdDogW10KICAgIGFnZToKICAgICAgICAtIHJlY2lwaWVudDogYWdlMWRqbGx3MnB6dXBycnFjMGVuNW04dmM4azVnZTN0bTBmNmc3Y2owYzBnbGZ6cDQ0dmRjNHFsOG5ndnUKICAgICAgICAgIGVuYzogfAogICAgICAgICAgICAtLS0tLUJFR0lOIEFHRSBFTkNSWVBURUQgRklMRS0tLS0tCiAgICAgICAgICAgIFlXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JhVVZCQ1JWaDFTbVZxYkc1RGVuRmEKICAgICAgICAgICAgYnk5SVUyNHJPSGRWTWtjMFkxTkNhQ3RxUVRFd2R6WnFXVzF2Q2t4NU5YQk1aa1pDZVRrdlFXMXRVRWR2UjJseQogICAgICAgICAgICBNV2xTVEUxalZXdEhkMFJvYTNSUFMzVktRalJUWWxVS0xTMHRJRGhDWjNNMlFWZFZiMmwwUzBOUE1ETlNhbFZTCiAgICAgICAgICAgIE5WbzRaVlZTTkhGUFJHRnllbkJxTjJ0UE5XUndOemdLeHBUZmlKRkJtTjlPd1F5SDJrSVMxUHBoTmllQ0tNcFoKICAgICAgICAgICAgeWtXQXRoS1oyYTM1dnpHcGRiMFVWVFVjM2hReG93Nm5KQ0dlUExndkxHQ05FSytCWDluUTV3PT0KICAgICAgICAgICAgLS0tLS1FTkQgQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgIGxhc3Rtb2RpZmllZDogIjIwMjItMDQtMDNUMTc6MjU6MjRaIgogICAgbWFjOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNZRGo5eGsrUktYZ3pCR0JOVHpzcUNjSGdMVjBqak9JMXE1U3lTTGhsYnNHNjNjaDdmWGVkWkxzT0p0V2hGNXgxdjIyZmZVU1lVK0hITVFnQnBQUklsa0h1R1FDU1hrOEt5dGg0eUlmUnBZcmVKYlUzaC9ZNmNEMjcycWNYWHJqK0V5QlFEM3k1dzZiU2RGYXRLeFgvVmk0VG1uZ3JNL2F6ajRqTHp1L3UrST0saXY6ajBiMFd2d0paa3RuNWwxcG91V2RFOE1xNllsMXlqdWxDNTlKbENUMGhFdz0sdGFnOmY2RzBEQjc3bURwcWxvV25hZGMzVWc9PSx0eXBlOnN0cl0KICAgIHBncDogW10KICAgIHVuZW5jcnlwdGVkX3N1ZmZpeDogX3VuZW5jcnlwdGVkCiAgICB2ZXJzaW9uOiAzLjcuMgo=", - "Hash": "4547532a137611d83958d17095c6c2d38ae0036a760c3b79c9dd5957d1c20cf2" - }, - "FlattenSeparator": ".", - "Format": "yaml", - "ResourceType": "SECRET", - "Target": { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "TestFunctionServiceRole6ABD93C7": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - } - }, - "TestFunction22AD90FC": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "ZipFile": "test" - }, - "Environment": { - "Variables": { - "SopsComplexSecretJSONFlat_and_now_some_0_basic": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[0].basic::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_and_now_some_1_nested": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[1].nested::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_and_now_some_2_type": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[2].type::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_and_now_some_3_tests": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[3].tests::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_arrays_0": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.arrays[0]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_arrays_1": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.arrays[1]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_arrays_2_values_and": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.arrays[2].values.and::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_object": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.object::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_notsodeep": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.notsodeep::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_0_basic": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[0].basic::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_1_nested": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[1].nested::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_2_type": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[2].type::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_3_tests": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[3].tests::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_arrays_0": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.arrays[0]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_arrays_1": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.arrays[1]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_arrays_2_values_and": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.arrays[2].values.and::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_object": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.object::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_notsodeep": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.notsodeep::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - } - } - }, - "Handler": "test", - "Role": { - "Fn::GetAtt": [ - "TestFunctionServiceRole6ABD93C7", - "Arn" - ] - }, - "Runtime": "nodejs14.x" - }, - "DependsOn": [ - "TestFunctionServiceRole6ABD93C7" - ] - } - }, - "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/test/secret-inline.integ.ts b/test/secret-inline.integ.ts deleted file mode 100644 index d6f7b057..00000000 --- a/test/secret-inline.integ.ts +++ /dev/null @@ -1,151 +0,0 @@ -import { App, SecretValue, Stack } from 'aws-cdk-lib'; -import { Code, Function, Runtime } from 'aws-cdk-lib/aws-lambda'; -import { SopsSecret } from '../src/index'; - -const app = new App(); - -const stack = new Stack(app, 'SecretIntegrationInline'); - -new SopsSecret(stack, 'SopsSecretJSON', { - sopsFilePath: 'test-secrets/json/sopsfile.enc-age.json', - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsSecretYAML', { - sopsFilePath: 'test-secrets/yaml/sopsfile.enc-age.yaml', - rawOutput: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsSecretYAMLasJSON', { - sopsFilePath: 'test-secrets/yaml/sopsfile.enc-age.yaml', - rawOutput: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsSecretDOTENV', { - sopsFilePath: 'test-secrets/dotenv/encrypted-best-secret.env', - rawOutput: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsSecretDOTENVasJSON', { - sopsFilePath: 'test-secrets/dotenv/encrypted-best-secret.env', - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsComplexSecretJSON', { - sopsFilePath: 'test-secrets/json/sopsfile-complex.enc-age.json', - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -const sopsComplexSecretJSONFlat = new SopsSecret( - stack, - 'SopsComplexSecretJSONFlat', - { - sopsFilePath: 'test-secrets/json/sopsfile-complex.enc-age.json', - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - }, -); - -new SopsSecret(stack, 'SopComplexSecretYAML', { - sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopComplexSecretYAMLFlat', { - sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsComplexSecretYAMLasJSON', { - sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -const sopsComplexSecretYAMLasJSONFlat = new SopsSecret( - stack, - 'SopsComplexSecretYAMLasJSONFlat', - { - sopsFilePath: 'test-secrets/yaml/sopsfile-complex.enc-age.yaml', - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - }, -); - -new Function(stack, 'TestFunction', { - code: Code.fromInline('test'), - handler: 'test', - runtime: Runtime.NODEJS_14_X, - environment: { - ...createMapComplex('SopsComplexSecretJSONFlat', sopsComplexSecretJSONFlat), - ...createMapComplex( - 'sopsComplexSecretYAMLasJSONFlat', - sopsComplexSecretYAMLasJSONFlat, - ), - }, -}); - -function createMapComplex(prefix: string, secret: SopsSecret) { - return { - [`${prefix}_and_now_some_0_basic`]: secret - .secretValueFromJson('and now.some[0].basic') - .toString(), - [`${prefix}_and_now_some_1_nested`]: secret - .secretValueFromJson('and now.some[1].nested') - .toString(), - [`${prefix}_and_now_some_2_type`]: secret - .secretValueFromJson('and now.some[2].type') - .toString(), - [`${prefix}_and_now_some_3_tests`]: secret - .secretValueFromJson('and now.some[3].tests') - .toString(), - [`${prefix}_some_deep_nested_arrays_0`]: secret - .secretValueFromJson('some.deep.nested.arrays[0]') - .toString(), - [`${prefix}_some_deep_nested_arrays_1`]: secret - .secretValueFromJson('some.deep.nested.arrays[1]') - .toString(), - [`${prefix}_some_deep_nested_arrays_2_values_and`]: secret - .secretValueFromJson('some.deep.nested.arrays[2].values.and') - .toString(), - [`${prefix}_some_deep_nested_object`]: secret - .secretValueFromJson('some.deep.nested.object') - .toString(), - [`${prefix}_some_notsodeep`]: secret - .secretValueFromJson('some.notsodeep') - .toString(), - }; -} diff --git a/test/secret-manual.integ.snapshot/SecretIntegrationAsset.template.json b/test/secret-manual.integ.snapshot/SecretIntegrationAsset.template.json deleted file mode 100644 index 8c0e21de..00000000 --- a/test/secret-manual.integ.snapshot/SecretIntegrationAsset.template.json +++ /dev/null @@ -1,772 +0,0 @@ -{ - "Resources": { - "SopsSecretJSON72040543": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretJSONSopsSync701F9A56": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": "testbucket", - "Key": "secret.json" - }, - "FlattenSeparator": ".", - "Format": "json", - "ResourceType": "SECRET", - "Target": { - "Ref": "SopsSecretJSON72040543" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - } - }, - "SingletonLambdaSopsSyncProviderAA18D140": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "S3Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "S3Key": "87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186.zip" - }, - "Environment": { - "Variables": { - "SOPS_AGE_KEY": "" - } - }, - "Handler": "bootstrap", - "Role": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25", - "Arn" - ] - }, - "Runtime": "provided.al2", - "Timeout": 60 - }, - "DependsOn": [ - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" - ] - }, - "SopsSecretYAMLC392F558": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretYAMLSopsSyncD61C4640": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": "testbucket", - "Key": "secret.json" - }, - "FlattenSeparator": ".", - "Format": "json", - "ResourceType": "SECRET_BINARY", - "Target": { - "Ref": "SopsSecretYAMLC392F558" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretYAMLasJSON64419C04": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretYAMLasJSONSopsSync5F0877FF": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": "testbucket", - "Key": "secret.json" - }, - "FlattenSeparator": ".", - "Format": "yaml", - "ResourceType": "SECRET_BINARY", - "Target": { - "Ref": "SopsSecretYAMLasJSON64419C04" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONAD4C2662": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONSopsSyncCABA63FF": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": "testbucket", - "Key": "secret.json" - }, - "FlattenSeparator": ".", - "Format": "json", - "ResourceType": "SECRET_BINARY", - "Target": { - "Ref": "SopsComplexSecretJSONAD4C2662" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONFlatF5FC1D69": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretJSONFlatSopsSyncC4165B67": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": "testbucket", - "Key": "secret.json" - }, - "FlattenSeparator": ".", - "Format": "json", - "ResourceType": "SECRET_BINARY", - "Target": { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLF52D88F2": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLSopsSync4B881273": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": "testbucket", - "Key": "secret.yaml" - }, - "FlattenSeparator": ".", - "Format": "yaml", - "ResourceType": "SECRET_BINARY", - "Target": { - "Ref": "SopComplexSecretYAMLF52D88F2" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLFlatD9CE8782": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopComplexSecretYAMLFlatSopsSync8B86CE19": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": "testbucket", - "Key": "secret.yaml" - }, - "FlattenSeparator": ".", - "Format": "yaml", - "ResourceType": "SECRET_BINARY", - "Target": { - "Ref": "SopComplexSecretYAMLFlatD9CE8782" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONEAE81DB0": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONSopsSyncC4061B33": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": "testbucket", - "Key": "secret.yaml" - }, - "FlattenSeparator": ".", - "Format": "yaml", - "ResourceType": "SECRET_BINARY", - "Target": { - "Ref": "SopsComplexSecretYAMLasJSONEAE81DB0" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONFlat9FD04B78": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {} - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": "testbucket", - "Key": "secret.yaml" - }, - "FlattenSeparator": ".", - "Format": "yaml", - "ResourceType": "SECRET", - "Target": { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "TestFunctionServiceRole6ABD93C7": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - } - }, - "TestFunction22AD90FC": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "ZipFile": "test" - }, - "Environment": { - "Variables": { - "SopsComplexSecretJSONFlat_and_now_some_0_basic": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[0].basic::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_and_now_some_1_nested": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[1].nested::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_and_now_some_2_type": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[2].type::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_and_now_some_3_tests": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:and now.some[3].tests::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_arrays_0": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.arrays[0]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_arrays_1": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.arrays[1]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_arrays_2_values_and": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.arrays[2].values.and::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_deep_nested_object": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.deep.nested.object::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "SopsComplexSecretJSONFlat_some_notsodeep": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretJSONFlatF5FC1D69" - }, - ":SecretString:some.notsodeep::", - { - "Fn::GetAtt": [ - "SopsComplexSecretJSONFlatSopsSyncC4165B67", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_0_basic": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[0].basic::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_1_nested": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[1].nested::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_2_type": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[2].type::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_and_now_some_3_tests": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:and now.some[3].tests::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_arrays_0": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.arrays[0]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_arrays_1": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.arrays[1]::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_arrays_2_values_and": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.arrays[2].values.and::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_deep_nested_object": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.deep.nested.object::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - }, - "sopsComplexSecretYAMLasJSONFlat_some_notsodeep": { - "Fn::Join": [ - "", - [ - "{{resolve:secretsmanager:", - { - "Ref": "SopsComplexSecretYAMLasJSONFlat9FD04B78" - }, - ":SecretString:some.notsodeep::", - { - "Fn::GetAtt": [ - "SopsComplexSecretYAMLasJSONFlatSopsSync05F4A91A", - "VersionId" - ] - }, - "}}" - ] - ] - } - } - }, - "Handler": "test", - "Role": { - "Fn::GetAtt": [ - "TestFunctionServiceRole6ABD93C7", - "Arn" - ] - }, - "Runtime": "nodejs14.x" - }, - "DependsOn": [ - "TestFunctionServiceRole6ABD93C7" - ] - } - }, - "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/test/secret-manual.integ.ts b/test/secret-manual.integ.ts deleted file mode 100644 index 77b98cf3..00000000 --- a/test/secret-manual.integ.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { App, SecretValue, Stack } from 'aws-cdk-lib'; -import { Code, Function, Runtime } from 'aws-cdk-lib/aws-lambda'; -import { SopsSecret } from '../src/index'; - -const app = new App(); - -const stack = new Stack(app, 'SecretIntegrationAsset'); - -new SopsSecret(stack, 'SopsSecretJSON', { - sopsS3Bucket: 'testbucket', - sopsS3Key: 'secret.json', - sopsFileFormat: 'json', - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsSecretYAML', { - sopsS3Bucket: 'testbucket', - sopsS3Key: 'secret.json', - sopsFileFormat: 'json', - rawOutput: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsSecretYAMLasJSON', { - sopsS3Bucket: 'testbucket', - sopsS3Key: 'secret.json', - sopsFileFormat: 'yaml', - rawOutput: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsComplexSecretJSON', { - sopsS3Bucket: 'testbucket', - sopsS3Key: 'secret.json', - sopsFileFormat: 'json', - rawOutput: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -const sopsComplexSecretJSONFlat = new SopsSecret( - stack, - 'SopsComplexSecretJSONFlat', - { - sopsS3Bucket: 'testbucket', - sopsS3Key: 'secret.json', - sopsFileFormat: 'json', - rawOutput: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - }, -); - -new SopsSecret(stack, 'SopComplexSecretYAML', { - sopsS3Bucket: 'testbucket', - sopsS3Key: 'secret.yaml', - sopsFileFormat: 'yaml', - rawOutput: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopComplexSecretYAMLFlat', { - sopsS3Bucket: 'testbucket', - sopsS3Key: 'secret.yaml', - sopsFileFormat: 'yaml', - rawOutput: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -new SopsSecret(stack, 'SopsComplexSecretYAMLasJSON', { - sopsS3Bucket: 'testbucket', - sopsS3Key: 'secret.yaml', - sopsFileFormat: 'yaml', - rawOutput: true, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), -}); - -const sopsComplexSecretYAMLasJSONFlat = new SopsSecret( - stack, - 'SopsComplexSecretYAMLasJSONFlat', - { - sopsS3Bucket: 'testbucket', - sopsS3Key: 'secret.yaml', - sopsFileFormat: 'yaml', - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - }, -); - -new Function(stack, 'TestFunction', { - code: Code.fromInline('test'), - handler: 'test', - runtime: Runtime.NODEJS_14_X, - environment: { - ...createMapComplex('SopsComplexSecretJSONFlat', sopsComplexSecretJSONFlat), - ...createMapComplex( - 'sopsComplexSecretYAMLasJSONFlat', - sopsComplexSecretYAMLasJSONFlat, - ), - }, -}); - -function createMapComplex(prefix: string, secret: SopsSecret) { - return { - [`${prefix}_and_now_some_0_basic`]: secret - .secretValueFromJson('and now.some[0].basic') - .toString(), - [`${prefix}_and_now_some_1_nested`]: secret - .secretValueFromJson('and now.some[1].nested') - .toString(), - [`${prefix}_and_now_some_2_type`]: secret - .secretValueFromJson('and now.some[2].type') - .toString(), - [`${prefix}_and_now_some_3_tests`]: secret - .secretValueFromJson('and now.some[3].tests') - .toString(), - [`${prefix}_some_deep_nested_arrays_0`]: secret - .secretValueFromJson('some.deep.nested.arrays[0]') - .toString(), - [`${prefix}_some_deep_nested_arrays_1`]: secret - .secretValueFromJson('some.deep.nested.arrays[1]') - .toString(), - [`${prefix}_some_deep_nested_arrays_2_values_and`]: secret - .secretValueFromJson('some.deep.nested.arrays[2].values.and') - .toString(), - [`${prefix}_some_deep_nested_object`]: secret - .secretValueFromJson('some.deep.nested.object') - .toString(), - [`${prefix}_some_notsodeep`]: secret - .secretValueFromJson('some.notsodeep') - .toString(), - }; -} diff --git a/test/secret-multikms.integ.snapshot/SecretMultiKms.assets.json b/test/secret-multikms.integ.snapshot/SecretMultiKms.assets.json deleted file mode 100644 index ad4c24e5..00000000 --- a/test/secret-multikms.integ.snapshot/SecretMultiKms.assets.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "version": "39.0.0", - "files": { - "87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186": { - "source": { - "path": "asset.87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186.zip", - "packaging": "file" - }, - "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186.zip", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" - } - } - }, - "2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649": { - "source": { - "path": "asset.2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649.json", - "packaging": "file" - }, - "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649.json", - "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" - } - } - }, - "145eaec53312b66209121447805f22cf621c21f83a764ac0782eda0516ae54bd": { - "source": { - "path": "SecretMultiKms.template.json", - "packaging": "file" - }, - "destinations": { - "current_account-current_region": { - "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "145eaec53312b66209121447805f22cf621c21f83a764ac0782eda0516ae54bd.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/test/secret-multikms.integ.snapshot/SecretMultiKms.template.json b/test/secret-multikms.integ.snapshot/SecretMultiKms.template.json deleted file mode 100644 index d6807534..00000000 --- a/test/secret-multikms.integ.snapshot/SecretMultiKms.template.json +++ /dev/null @@ -1,431 +0,0 @@ -{ - "Resources": { - "CustomKey1E6D0D07": { - "Type": "AWS::KMS::Key", - "Properties": { - "KeyPolicy": { - "Statement": [ - { - "Action": "kms:*", - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::", - { - "Ref": "AWS::AccountId" - }, - ":root" - ] - ] - } - }, - "Resource": "*" - }, - { - "Action": [ - "kms:Decrypt", - "kms:Encrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*" - ], - "Condition": { - "StringEquals": { - "kms:ViaService": { - "Fn::Join": [ - "", - [ - "secretsmanager.", - { - "Ref": "AWS::Region" - }, - ".amazonaws.com" - ] - ] - } - } - }, - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::", - { - "Ref": "AWS::AccountId" - }, - ":root" - ] - ] - } - }, - "Resource": "*" - }, - { - "Action": [ - "kms:CreateGrant", - "kms:DescribeKey" - ], - "Condition": { - "StringEquals": { - "kms:ViaService": { - "Fn::Join": [ - "", - [ - "secretsmanager.", - { - "Ref": "AWS::Region" - }, - ".amazonaws.com" - ] - ] - } - } - }, - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::", - { - "Ref": "AWS::AccountId" - }, - ":root" - ] - ] - } - }, - "Resource": "*" - }, - { - "Action": [ - "kms:Encrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*" - ], - "Condition": { - "StringEquals": { - "kms:ViaService": { - "Fn::Join": [ - "", - [ - "secretsmanager.", - { - "Ref": "AWS::Region" - }, - ".amazonaws.com" - ] - ] - } - } - }, - "Effect": "Allow", - "Principal": { - "AWS": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25", - "Arn" - ] - } - }, - "Resource": "*" - } - ], - "Version": "2012-10-17" - } - }, - "UpdateReplacePolicy": "Retain", - "DeletionPolicy": "Retain" - }, - "SopsSecretOwnKmsMey0B320436": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {}, - "KmsKeyId": { - "Fn::GetAtt": [ - "CustomKey1E6D0D07", - "Arn" - ] - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretOwnKmsMeySopsSync52A94247": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "Key": "2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649.json" - }, - "FlattenSeparator": ".", - "Format": "json", - "EncryptionKey": { - "Ref": "CustomKey1E6D0D07" - }, - "ResourceType": "SECRET", - "Target": { - "Ref": "SopsSecretOwnKmsMey0B320436" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - } - }, - "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": [ - "s3:GetObject*", - "s3:GetBucket*", - "s3:List*" - ], - "Effect": "Allow", - "Resource": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":s3:::", - { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - } - ] - ] - }, - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":s3:::", - { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "/*" - ] - ] - } - ] - }, - { - "Action": [ - "kms:Decrypt", - "kms:Encrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*" - ], - "Effect": "Allow", - "Resource": { - "Fn::GetAtt": [ - "CustomKey1E6D0D07", - "Arn" - ] - } - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsSecretOwnKmsMey0B320436" - } - }, - { - "Action": [ - "kms:Decrypt", - "kms:Encrypt", - "kms:ReEncrypt*", - "kms:GenerateDataKey*" - ], - "Effect": "Allow", - "Resource": "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012" - }, - { - "Action": [ - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecret" - ], - "Effect": "Allow", - "Resource": { - "Ref": "SopsSecretForeignKmsMey8C3BA0B7" - } - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", - "Roles": [ - { - "Ref": "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" - } - ] - } - }, - "SingletonLambdaSopsSyncProviderAA18D140": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "S3Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "S3Key": "87f001085ab077a0114e52cdc11c1afe71bf57e525e47a755268ddf390f7c186.zip" - }, - "Environment": { - "Variables": { - "SOPS_AGE_KEY": "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3" - } - }, - "Handler": "bootstrap", - "Role": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25", - "Arn" - ] - }, - "Runtime": "provided.al2", - "Timeout": 60 - }, - "DependsOn": [ - "SingletonLambdaSopsSyncProviderServiceRoleDefaultPolicy45D64FF6", - "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" - ] - }, - "SopsSecretForeignKmsMey8C3BA0B7": { - "Type": "AWS::SecretsManager::Secret", - "Properties": { - "GenerateSecretString": {}, - "KmsKeyId": "arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012" - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - }, - "SopsSecretForeignKmsMeySopsSync7493861B": { - "Type": "Custom::SopsSync", - "Properties": { - "ServiceToken": { - "Fn::GetAtt": [ - "SingletonLambdaSopsSyncProviderAA18D140", - "Arn" - ] - }, - "SopsS3File": { - "Bucket": { - "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" - }, - "Key": "2e0bdd84bc2fecdd9795887da1814888ec0b5d184a7324c5fda69c4bd54fa649.json" - }, - "FlattenSeparator": ".", - "Format": "json", - "EncryptionKey": "12345678-1234-1234-1234-123456789012", - "ResourceType": "SECRET", - "Target": { - "Ref": "SopsSecretForeignKmsMey8C3BA0B7" - } - }, - "UpdateReplacePolicy": "Delete", - "DeletionPolicy": "Delete" - } - }, - "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/test/secret-multikms.integ.ts b/test/secret-multikms.integ.ts deleted file mode 100644 index 313fadb3..00000000 --- a/test/secret-multikms.integ.ts +++ /dev/null @@ -1,34 +0,0 @@ -/** - * Caution - this test can only be used for snapshots - you can't deploy this - */ -import { App, SecretValue, Stack } from 'aws-cdk-lib'; -import { Key } from 'aws-cdk-lib/aws-kms'; -import { SopsSecret, UploadType } from '../src/index'; - -const app = new App(); - -const stack = new Stack(app, 'SecretMultiKms'); - -new SopsSecret(stack, 'SopsSecretOwnKmsMey', { - sopsFilePath: 'test-secrets/json/sopsfile.enc-age.json', - uploadType: UploadType.ASSET, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - encryptionKey: new Key(stack, 'CustomKey'), -}); - -new SopsSecret(stack, 'SopsSecretForeignKmsMey', { - sopsFilePath: 'test-secrets/json/sopsfile.enc-age.json', - uploadType: UploadType.ASSET, - // see test-secrets/README.md for further information regarding the test file - sopsAgeKey: SecretValue.unsafePlainText( - 'AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3', - ), - encryptionKey: Key.fromKeyArn( - stack, - 'ForeignKey', - 'arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012', - ), -}); diff --git a/test/secret.test.ts b/test/secret.test.ts index 92cfcdcd..b2436119 100644 --- a/test/secret.test.ts +++ b/test/secret.test.ts @@ -32,6 +32,7 @@ test('Upload type ASSET', () => { new SopsSecret(stack, 'SopsSecret', { sopsFilePath: 'test-secrets/yaml/sopsfile.enc-kms.yaml', uploadType: UploadType.ASSET, + rawOutput: true, }); Template.fromStack(stack).hasResource('Custom::SopsSync', { Properties: Match.objectLike({ @@ -219,9 +220,9 @@ test('Exception when derive format: notsupported', () => { expect( () => new SopsSecret(stack, 'SopsSecret', { - sopsFilePath: 'test-secrets/json/sopsfile.enc-age.notsupported', + sopsFilePath: 'test-secrets/testsecret.notsupported', }), - ).toThrowError('Unsupported sopsFileFormat notsupported'); + ).toThrowError('You have to specify sopsFileFormat!'); }); test('Set format: json', () => { @@ -529,14 +530,12 @@ test('Multiple parameters from yaml file', () => { const app = new App(); const stack = new Stack(app, 'ParameterIntegration'); new MultiStringParameter(stack, 'SopsSecret1', { - simpleName: false, sopsFilePath: 'test-secrets/yaml/sopsfile-complex-parameters.enc-age.yaml', encryptionKey: Key.fromKeyArn( stack, 'Key', 'arn:aws:kms:eu-central-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab', ), - stringValue: ' ', }); const template = Template.fromStack(stack); @@ -608,7 +607,6 @@ test('Multiple parameters from yaml file with custom key structure', () => { const app = new App(); const stack = new Stack(app, 'ParameterIntegration'); new MultiStringParameter(stack, 'SopsSecret1', { - simpleName: false, sopsFilePath: 'test-secrets/yaml/sopsfile-complex-parameters.enc-age.yaml', keyPrefix: '_', keySeparator: '.', @@ -617,7 +615,6 @@ test('Multiple parameters from yaml file with custom key structure', () => { 'Key', 'arn:aws:kms:eu-central-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab', ), - stringValue: ' ', }); const template = Template.fromStack(stack); @@ -689,7 +686,6 @@ test('Large set of parameters to split in multiple policies', () => { const app = new App(); const stack = new Stack(app, 'ParameterIntegration'); new MultiStringParameter(stack, 'SopsSecret1', { - simpleName: false, sopsFilePath: 'test-secrets/yaml/sopsfile-parameters-large.yaml', keyPrefix: '_', keySeparator: '.', @@ -698,7 +694,6 @@ test('Large set of parameters to split in multiple policies', () => { 'Key', 'arn:aws:kms:eu-central-1:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab', ), - stringValue: ' ', }); const template = Template.fromStack(stack); diff --git a/yarn.lock b/yarn.lock index 5e07fc79..cb428774 100644 --- a/yarn.lock +++ b/yarn.lock @@ -851,7 +851,7 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@^27": +"@types/jest@^27.5.2": version "27.5.2" resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.5.2.tgz#ec49d29d926500ffb9fd22b84262e862049c026c" integrity sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA== @@ -886,10 +886,10 @@ dependencies: undici-types "~6.20.0" -"@types/node@^16 <= 16.18.78": - version "16.18.78" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.78.tgz#3d97264128712f2eb59f1f8456bcfc5d56d8105c" - integrity sha512-2poPMDdsGfvhcLmgJZ85QrIfN6z3PijYRMiV0FWIEUiQW/t/lzH7BEm4vN+HMhjZXbtIKssMcAxTcgu4Rm83YA== +"@types/node@^16.18.78": + version "16.18.126" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.126.tgz#27875faa2926c0f475b39a8bb1e546c0176f8d4b" + integrity sha512-OTcgaiwfGFBKacvfwuHzzn1KLxH/er8mluiy8/uM3sGXHaRe73RrSIj01jow9t4kJEW633Ov+cOexXeiApTyAw== "@types/normalize-package-data@^2.4.0": version "2.4.4" @@ -3679,7 +3679,7 @@ jest-worker@^27.5.1: merge-stream "^2.0.0" supports-color "^8.0.0" -jest@^27: +jest@^27.5.1: version "27.5.1" resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc" integrity sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ== @@ -5406,7 +5406,7 @@ ts-api-utils@^2.0.0: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.0.1.tgz#660729385b625b939aaa58054f45c058f33f10cd" integrity sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w== -ts-jest@^27: +ts-jest@^27.1.5: version "27.1.5" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.1.5.tgz#0ddf1b163fbaae3d5b7504a1e65c914a95cff297" integrity sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA== From e983bc4ac11de27bb2cc7ada0a2caec6df14f2d6 Mon Sep 17 00:00:00 2001 From: Markus Siebert Date: Mon, 10 Feb 2025 10:36:54 +0100 Subject: [PATCH 04/12] chore: fix tests --- .github/workflows/build.yml | 14 +-- .projen/tasks.json | 3 +- .projenrc.js | 26 ++-- MAINTAINERS.md | 2 +- README.md | 20 ++- .../24-SECRET_BINARY-binary.json.snap | 18 +++ .../21-SECRET_BINARY-json.json.snap | 4 +- .../22-SECRET_BINARY-yaml.json.snap | 4 +- .../23-SECRET_BINARY-dotenv.json.snap | 4 +- .../24-SECRET_BINARY-binary.json.snap | 6 + lambda/events/24-SECRET_BINARY-binary.json | 10 ++ lambda/internal/client/client.go | 2 +- lambda/main_integration_test.go | 16 ++- src/LambdaInterface.ts | 3 +- src/SopsSecret.ts | 28 ++++- src/SopsSync.ts | 1 + test-secrets/README.gz.sops.binary | 20 +++ .../PARAMETER.assets.json | 10 +- .../PARAMETER.template.json | 2 +- .../PARAMETERMULTI.assets.json | 10 +- .../PARAMETERMULTI.template.json | 2 +- test/SECRET.integ.snapshot/SECRET.assets.json | 10 +- .../SECRET.template.json | 114 ++++++++++++------ test/SECRET.integ.ts | 35 +++--- test/secret.test.ts | 3 +- 25 files changed, 247 insertions(+), 120 deletions(-) create mode 100755 lambda/__snapshots__/TestHandleRequestWithClients/24-SECRET_BINARY-binary.json/24-SECRET_BINARY-binary.json.snap create mode 100755 lambda/__snapshots__/TestIntegration_HandleRequestWithClients/24-SECRET_BINARY-binary.json.snap create mode 100644 lambda/events/24-SECRET_BINARY-binary.json create mode 100644 test-secrets/README.gz.sops.binary diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 25d36d4e..65ff8a44 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,14 +31,12 @@ jobs: node-version: lts/* - name: Install dependencies run: yarn install --check-files - - name: "Update snapshots: secret-inline" - run: yarn run projen integ:secret-inline:snapshot - - name: "Update snapshots: secret-asset" - run: yarn run projen integ:secret-asset:snapshot - - name: "Update snapshots: secret-multikms" - run: yarn run projen integ:secret-multikms:snapshot - - name: "Update snapshots: secret-manual" - run: yarn run projen integ:secret-manual:snapshot + - name: "Update snapshots: PARAMETER" + run: yarn run projen integ:PARAMETER:snapshot + - name: "Update snapshots: PARAMETER_MULTI" + run: yarn run projen integ:PARAMETER_MULTI:snapshot + - name: "Update snapshots: SECRET" + run: yarn run projen integ:SECRET:snapshot - name: build run: npx projen build - name: Upload coverage to Codecov diff --git a/.projen/tasks.json b/.projen/tasks.json index cc050eaf..bb8510dc 100644 --- a/.projen/tasks.json +++ b/.projen/tasks.json @@ -446,7 +446,8 @@ "name": "release", "description": "Prepare a release from \"main\" branch", "env": { - "RELEASE": "true" + "RELEASE": "true", + "MAJOR": "2" }, "steps": [ { diff --git a/.projenrc.js b/.projenrc.js index b7dfd20e..22dd80ce 100644 --- a/.projenrc.js +++ b/.projenrc.js @@ -3,6 +3,7 @@ const project = new awscdk.AwsCdkConstructLibrary({ author: 'Markus Siebert', authorAddress: 'markus.siebert@deutschebahn.com', cdkVersion: '2.177.0', + majorVersion: 2, stability: 'stable', homepage: 'https://constructs.dev/packages/cdk-sops-secrets', description: @@ -107,22 +108,17 @@ additionalActions = [ ]; project.buildWorkflow.preBuildSteps.unshift(...additionalActions); -project.buildWorkflow.preBuildSteps.push({ - name: 'Update snapshots: secret-inline', - run: 'yarn run projen integ:secret-inline:snapshot', -}); -project.buildWorkflow.preBuildSteps.push({ - name: 'Update snapshots: secret-asset', - run: 'yarn run projen integ:secret-asset:snapshot', -}); -project.buildWorkflow.preBuildSteps.push({ - name: 'Update snapshots: secret-multikms', - run: 'yarn run projen integ:secret-multikms:snapshot', -}); -project.buildWorkflow.preBuildSteps.push({ - name: 'Update snapshots: secret-manual', - run: 'yarn run projen integ:secret-manual:snapshot', +[ + "PARAMETER", + "PARAMETER_MULTI", + "SECRET" +].forEach((type) => { + project.buildWorkflow.preBuildSteps.push({ + name: `Update snapshots: ${type}`, + run: `yarn run projen integ:${type}:snapshot`, + }); }); + project.buildWorkflow.addPostBuildSteps({ name: 'Upload coverage to Codecov', uses: 'codecov/codecov-action@v4', diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 06b8de23..9f56d9f0 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -3,5 +3,5 @@ This page lists all active maintainers of this repository in alphabetical order. [henrysachs](https://github.com/henrysachs) [markussiebert](https://github.com/markussiebert) [thomaskrause](https://github.com/obirah) -[thomasgeese](https://github.com/zh32) [lennartrommeiss](https://github.com/lenderom) +[dariozachow](https://github.com/dariozachow) \ No newline at end of file diff --git a/README.md b/README.md index 1e84623f..5f3c9883 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ It enables secure storage of secrets in Git repositories while allowing seamless # Table Of Contents +- [Introduction](#introduction) +- [Table Of Contents](#table-of-contents) - [Available Constructs](#available-constructs) - [SopsSecret — Sops to SecretsManager](#sopssecret--sops-to-secretsmanager) - [SopsStringParameter — Sops to single SSM ParameterStore Parameter](#sopsstringparameter--sops-to-single-ssm-parameterstore-parameter) @@ -25,7 +27,17 @@ It enables secure storage of secrets in Git repositories while allowing seamless - [SopsSyncProvider](#sopssyncprovider) - [Common configuration options for SopsSecret, SopsStringParameter and MultiStringParameter](#common-configuration-options-for-sopssecret-sopsstringparameter-and-multistringparameter) - [Considerations](#considerations) + - [UploadType: INLINE / ASSET](#uploadtype-inline--asset) + - [Stability](#stability) - [FAQ](#faq) + - [It does not work, what can I do?](#it-does-not-work-what-can-i-do) + - [I get errors with `dotenv` formatted files](#i-get-errors-with-dotenv-formatted-files) + - [Error: Error getting data key: 0 successful groups required, got 0](#error-error-getting-data-key-0-successful-groups-required-got-0) + - [Error: Asset of sync lambda not found](#error-asset-of-sync-lambda-not-found) + - [Can I upload the sops file myself and provide the required information as CloudFormation Parameter?](#can-i-upload-the-sops-file-myself-and-provide-the-required-information-as-cloudformation-parameter) + - [Can I access older versions of the secret stored in the SecretsManager?](#can-i-access-older-versions-of-the-secret-stored-in-the-secretsmanager) + - [I want the `raw` content of the sops file, but I always get the content nested in json](#i-want-the-raw-content-of-the-sops-file-but-i-always-get-the-content-nested-in-json) +- [License](#license) # Available Constructs @@ -100,12 +112,12 @@ If you don't want these conversions, you can completely disable them by using th ```ts const secret = new SopsSecret(stack, 'MySopsSecret', { - rawOutput: true, + rawOutput: RawOutput.STRING, ... }); ``` - -This will turn off the conversions and just place the decrypted content in the target secret. +This will turn off the conversions and just place the decrypted content in the target secret. It's also possible to use +`RawOutput.BINARY` than the AWS SecretsManager Secret will be populted with binary, instead of string data. ## SopsStringParameter — Sops to single SSM ParameterStore Parameter @@ -399,6 +411,6 @@ This does not work for `MultiStringParameter` [^1] Even if sops can handle binary data, only the AWS SecretsManager allows to store it. -## License +# License The Apache-2.0 license. Please have a look at the [LICENSE](LICENSE) and [LICENSE-3RD-PARTY](LICENSE-3RD-PARTY). diff --git a/lambda/__snapshots__/TestHandleRequestWithClients/24-SECRET_BINARY-binary.json/24-SECRET_BINARY-binary.json.snap b/lambda/__snapshots__/TestHandleRequestWithClients/24-SECRET_BINARY-binary.json/24-SECRET_BINARY-binary.json.snap new file mode 100755 index 00000000..13b51467 --- /dev/null +++ b/lambda/__snapshots__/TestHandleRequestWithClients/24-SECRET_BINARY-binary.json/24-SECRET_BINARY-binary.json.snap @@ -0,0 +1,18 @@ + +[TestHandleRequestWithClients/24-SECRET_BINARY-binary.json - 1] +main.getObjectCalls{ + "test-secrets/README.gz.sops.binary": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/README.gz.sops.binary"}, +} +main.getObjectEtagCalls{ + "test-secrets/README.gz.sops.binary": {Bucket:"cdk-hnb659fds-assets-505755377845-eu-central-1", Key:"test-secrets/README.gz.sops.binary"}, +} +main.putParameterCalls{ +} +main.putSecretValueCalls{ + "24-SECRET_BINARY-binary": map[string]interface {}{ + "binary": bool(true), + "secretContent": "\x1f\x8b\b\b+Ʃg\x00\x03README.md\x00m\x90\xc1n\x82@\x14E\xf7|\xc5K\xbai\x93\xa2(\xa0\x84\x1d\xb1`\xa3!U\xa1\xb5\xb5i\"\x1d\x06\x18\x1d\x98qf\xc0\xe0\xd7\x17j\x93v\xd1\xe5K\xee=\xf7\xe4\xdd@\xf4\xb4\x8a #\x14KȘ\x00\x85\xa5\"U\x0e\xbc\x16\x9cI\xaciq\x81A2.\x7f2\xa4\x02U\x10\t)\x11\x18)&Z8c\x81\x01\t\x9c(\x9c\xfe\x87\x18\x80'\x01WH\xb4\\\x11VABs&\x88*JxOr\xfcq[(ť;\x1cv\x87\xfe\x1b\x1b0\x91\x0f\xef\xa0[\xaa%N\xef!\xe9\xa6Uץ\xec\xdc\xd1\x12ق,\x12\xd1ϰ\xec/\x9dT\x9dB\x99|#\xae\xf2\x19\xebK}\xf2\x88[y\xd5홮\xa6\xed\xf7\xfb6)\xa9\xc6\xebOJ\x90\v\x9d\xc2(=Pz\x1e\xf3Kͅ8!\x03Wv\xe94\xc89\xda96Uid\x93|\x8a\x0e\x062r\x9a]\xb8e5)\xb2Nԩ\xf2\xa6ָ M\xf7\x05\x17\xbc\xb9\xafG\xfel\xe3\xc7\xfa\xd2\x7f\xd3G~\xf0\xbc]\x18\xf3\xf1\xeb\"^\x04\xdb\xd8\v\xc7\x0f\xf3г^fKsc\xd8[\xdb\t\xa2\xf0q\xb72\xc3\xdd\xda\xd8\xc5\xde\xda\xf7\x82\xf5l\x12Oc\xb3WԾ\x00\x9a\x91g\xf1\xa5\x01\x00\x00", + "sopsHash": "mock-etag", + }, +} +--- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/21-SECRET_BINARY-json.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/21-SECRET_BINARY-json.json.snap index ff2f32aa..34cd51b7 100755 --- a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/21-SECRET_BINARY-json.json.snap +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/21-SECRET_BINARY-json.json.snap @@ -1,6 +1,6 @@ [TestIntegration_HandleRequestWithClients/21-SECRET_BINARY-json.json - 1] &"21-SECRET_BINARY-json" -[]uint8(nil) -&"{\n\t\"apiKey\": \"sk-1234567890abcdef\",\n\t\"database\": {\n\t\t\"host\": \"db.example.com\",\n\t\t\"password\": \"P@ssw0rd!\",\n\t\t\"user\": \"admin\"\n\t},\n\t\"someOtherKey\": \"base64:aGFsbG8gd2VsdAo=\",\n\t\"specific\": {\n\t\t\"HTLMEncodingTest3\": \"@\",\n\t\t\"HTMLEncodingTest1\": \"test \",\n\t\t\"HTMLEncodingTest2\": \"&\",\n\t\t\"SpecialCharacters\": \"\\\"ajkscbuiuXA34%%&&=\",\n\t\t\"boolean\": true,\n\t\t\"null\": null,\n\t\t\"number1\": 123,\n\t\t\"number2\": 123.456\n\t},\n\t\"tokens\": [\n\t\t{\n\t\t\t\"service\": \"service1\",\n\t\t\t\"token\": \"token1\"\n\t\t},\n\t\t{\n\t\t\t\"service\": \"service2\",\n\t\t\t\"token\": \"token2\"\n\t\t}\n\t]\n}" +[]uint8{0x7b, 0xa, 0x9, 0x22, 0x61, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x22, 0x3a, 0x20, 0x22, 0x73, 0x6b, 0x2d, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x22, 0x2c, 0xa, 0x9, 0x22, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x22, 0x3a, 0x20, 0x7b, 0xa, 0x9, 0x9, 0x22, 0x68, 0x6f, 0x73, 0x74, 0x22, 0x3a, 0x20, 0x22, 0x64, 0x62, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x22, 0x2c, 0xa, 0x9, 0x9, 0x22, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x22, 0x3a, 0x20, 0x22, 0x50, 0x40, 0x73, 0x73, 0x77, 0x30, 0x72, 0x64, 0x21, 0x22, 0x2c, 0xa, 0x9, 0x9, 0x22, 0x75, 0x73, 0x65, 0x72, 0x22, 0x3a, 0x20, 0x22, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0x22, 0xa, 0x9, 0x7d, 0x2c, 0xa, 0x9, 0x22, 0x73, 0x6f, 0x6d, 0x65, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x22, 0x3a, 0x20, 0x22, 0x62, 0x61, 0x73, 0x65, 0x36, 0x34, 0x3a, 0x61, 0x47, 0x46, 0x73, 0x62, 0x47, 0x38, 0x67, 0x64, 0x32, 0x56, 0x73, 0x64, 0x41, 0x6f, 0x3d, 0x22, 0x2c, 0xa, 0x9, 0x22, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x22, 0x3a, 0x20, 0x7b, 0xa, 0x9, 0x9, 0x22, 0x48, 0x54, 0x4c, 0x4d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x73, 0x74, 0x33, 0x22, 0x3a, 0x20, 0x22, 0x40, 0x22, 0x2c, 0xa, 0x9, 0x9, 0x22, 0x48, 0x54, 0x4d, 0x4c, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x73, 0x74, 0x31, 0x22, 0x3a, 0x20, 0x22, 0x74, 0x65, 0x73, 0x74, 0x20, 0x3c, 0x74, 0x65, 0x73, 0x74, 0x40, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x3e, 0x22, 0x2c, 0xa, 0x9, 0x9, 0x22, 0x48, 0x54, 0x4d, 0x4c, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x73, 0x74, 0x32, 0x22, 0x3a, 0x20, 0x22, 0x26, 0x22, 0x2c, 0xa, 0x9, 0x9, 0x22, 0x53, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x43, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x22, 0x3a, 0x20, 0x22, 0x5c, 0x22, 0x61, 0x6a, 0x6b, 0x73, 0x63, 0x62, 0x75, 0x69, 0x75, 0x58, 0x41, 0x33, 0x34, 0x25, 0x25, 0x26, 0x26, 0x3d, 0x22, 0x2c, 0xa, 0x9, 0x9, 0x22, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x22, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0xa, 0x9, 0x9, 0x22, 0x6e, 0x75, 0x6c, 0x6c, 0x22, 0x3a, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0x2c, 0xa, 0x9, 0x9, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x31, 0x22, 0x3a, 0x20, 0x31, 0x32, 0x33, 0x2c, 0xa, 0x9, 0x9, 0x22, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x32, 0x22, 0x3a, 0x20, 0x31, 0x32, 0x33, 0x2e, 0x34, 0x35, 0x36, 0xa, 0x9, 0x7d, 0x2c, 0xa, 0x9, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x22, 0x3a, 0x20, 0x5b, 0xa, 0x9, 0x9, 0x7b, 0xa, 0x9, 0x9, 0x9, 0x22, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x31, 0x22, 0x2c, 0xa, 0x9, 0x9, 0x9, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x31, 0x22, 0xa, 0x9, 0x9, 0x7d, 0x2c, 0xa, 0x9, 0x9, 0x7b, 0xa, 0x9, 0x9, 0x9, 0x22, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x22, 0x3a, 0x20, 0x22, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x32, 0x22, 0x2c, 0xa, 0x9, 0x9, 0x9, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3a, 0x20, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x32, 0x22, 0xa, 0x9, 0x9, 0x7d, 0xa, 0x9, 0x5d, 0xa, 0x7d} +(*string)(nil) --- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/22-SECRET_BINARY-yaml.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/22-SECRET_BINARY-yaml.json.snap index cb72aacc..26af2eaf 100755 --- a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/22-SECRET_BINARY-yaml.json.snap +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/22-SECRET_BINARY-yaml.json.snap @@ -1,6 +1,6 @@ [TestIntegration_HandleRequestWithClients/22-SECRET_BINARY-yaml.json - 1] &"22-SECRET_BINARY-yaml" -[]uint8(nil) -&"apiKey: sk-1234567890abcdef\ndatabase:\n user: admin\n password: P@ssw0rd!\n host: db.example.com\ntokens:\n - service: service1\n token: token1\n - service: service2\n token: token2\nsomeOtherKey: base64:aGFsbG8gd2VsdAo=\nspecific:\n SpecialCharacters: '\"ajkscbuiuXA34%%&&='\n HTMLEncodingTest1: test \n HTMLEncodingTest2: '&'\n HTLMEncodingTest3: '@'\n \"null\": null\n boolean: true\n number1: 123\n number2: 123.456\n" +[]uint8{0x61, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x3a, 0x20, 0x73, 0x6b, 0x2d, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xa, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x3a, 0xa, 0x20, 0x20, 0x20, 0x20, 0x75, 0x73, 0x65, 0x72, 0x3a, 0x20, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x3a, 0x20, 0x50, 0x40, 0x73, 0x73, 0x77, 0x30, 0x72, 0x64, 0x21, 0xa, 0x20, 0x20, 0x20, 0x20, 0x68, 0x6f, 0x73, 0x74, 0x3a, 0x20, 0x64, 0x62, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0xa, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x3a, 0xa, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x31, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x31, 0xa, 0x20, 0x20, 0x20, 0x20, 0x2d, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3a, 0x20, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x32, 0xa, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3a, 0x20, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x32, 0xa, 0x73, 0x6f, 0x6d, 0x65, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x3a, 0x20, 0x62, 0x61, 0x73, 0x65, 0x36, 0x34, 0x3a, 0x61, 0x47, 0x46, 0x73, 0x62, 0x47, 0x38, 0x67, 0x64, 0x32, 0x56, 0x73, 0x64, 0x41, 0x6f, 0x3d, 0xa, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x3a, 0xa, 0x20, 0x20, 0x20, 0x20, 0x53, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x43, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x3a, 0x20, 0x27, 0x22, 0x61, 0x6a, 0x6b, 0x73, 0x63, 0x62, 0x75, 0x69, 0x75, 0x58, 0x41, 0x33, 0x34, 0x25, 0x25, 0x26, 0x26, 0x3d, 0x27, 0xa, 0x20, 0x20, 0x20, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x73, 0x74, 0x31, 0x3a, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x3c, 0x74, 0x65, 0x73, 0x74, 0x40, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x3e, 0xa, 0x20, 0x20, 0x20, 0x20, 0x48, 0x54, 0x4d, 0x4c, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x73, 0x74, 0x32, 0x3a, 0x20, 0x27, 0x26, 0x27, 0xa, 0x20, 0x20, 0x20, 0x20, 0x48, 0x54, 0x4c, 0x4d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x73, 0x74, 0x33, 0x3a, 0x20, 0x27, 0x40, 0x27, 0xa, 0x20, 0x20, 0x20, 0x20, 0x22, 0x6e, 0x75, 0x6c, 0x6c, 0x22, 0x3a, 0x20, 0x6e, 0x75, 0x6c, 0x6c, 0xa, 0x20, 0x20, 0x20, 0x20, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x3a, 0x20, 0x74, 0x72, 0x75, 0x65, 0xa, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x31, 0x3a, 0x20, 0x31, 0x32, 0x33, 0xa, 0x20, 0x20, 0x20, 0x20, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x32, 0x3a, 0x20, 0x31, 0x32, 0x33, 0x2e, 0x34, 0x35, 0x36, 0xa} +(*string)(nil) --- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/23-SECRET_BINARY-dotenv.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/23-SECRET_BINARY-dotenv.json.snap index d4acab62..77074a3c 100755 --- a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/23-SECRET_BINARY-dotenv.json.snap +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/23-SECRET_BINARY-dotenv.json.snap @@ -1,6 +1,6 @@ [TestIntegration_HandleRequestWithClients/23-SECRET_BINARY-dotenv.json - 1] &"23-SECRET_BINARY-dotenv" -[]uint8(nil) -&"apiKey=sk-1234567890abcdef\ndatabase:host=db.example.com\ndatabase:password=P@ssw0rd!\ndatabase:user=admin\nsomeOtherKey=base64:aGFsbG8gd2VsdAo=\nspecific:boolean=True\nspecific:SpecialCharacters=\"ajkscbuiuXA34%%&&=\nspecific:HTLMEncodingTest3=@\nspecific:HTMLEncodingTest1=test \nspecific:HTMLEncodingTest2=&\nspecific:null=\nspecific:number1=123\nspecific:number2=123.456\ntokens:0:service=service1\ntokens:0:token=token1\ntokens:1:service=service2\ntokens:1:token=token2\n" +[]uint8{0x61, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x3d, 0x73, 0x6b, 0x2d, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xa, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x3a, 0x68, 0x6f, 0x73, 0x74, 0x3d, 0x64, 0x62, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0xa, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x3a, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x3d, 0x50, 0x40, 0x73, 0x73, 0x77, 0x30, 0x72, 0x64, 0x21, 0xa, 0x64, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x3a, 0x75, 0x73, 0x65, 0x72, 0x3d, 0x61, 0x64, 0x6d, 0x69, 0x6e, 0xa, 0x73, 0x6f, 0x6d, 0x65, 0x4f, 0x74, 0x68, 0x65, 0x72, 0x4b, 0x65, 0x79, 0x3d, 0x62, 0x61, 0x73, 0x65, 0x36, 0x34, 0x3a, 0x61, 0x47, 0x46, 0x73, 0x62, 0x47, 0x38, 0x67, 0x64, 0x32, 0x56, 0x73, 0x64, 0x41, 0x6f, 0x3d, 0xa, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x3a, 0x62, 0x6f, 0x6f, 0x6c, 0x65, 0x61, 0x6e, 0x3d, 0x54, 0x72, 0x75, 0x65, 0xa, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x3a, 0x53, 0x70, 0x65, 0x63, 0x69, 0x61, 0x6c, 0x43, 0x68, 0x61, 0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x73, 0x3d, 0x22, 0x61, 0x6a, 0x6b, 0x73, 0x63, 0x62, 0x75, 0x69, 0x75, 0x58, 0x41, 0x33, 0x34, 0x25, 0x25, 0x26, 0x26, 0x3d, 0xa, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x3a, 0x48, 0x54, 0x4c, 0x4d, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x73, 0x74, 0x33, 0x3d, 0x40, 0xa, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x3a, 0x48, 0x54, 0x4d, 0x4c, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x73, 0x74, 0x31, 0x3d, 0x74, 0x65, 0x73, 0x74, 0x20, 0x3c, 0x74, 0x65, 0x73, 0x74, 0x40, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x3e, 0xa, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x3a, 0x48, 0x54, 0x4d, 0x4c, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x54, 0x65, 0x73, 0x74, 0x32, 0x3d, 0x26, 0xa, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x3a, 0x6e, 0x75, 0x6c, 0x6c, 0x3d, 0xa, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x3a, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x31, 0x3d, 0x31, 0x32, 0x33, 0xa, 0x73, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x3a, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x32, 0x3d, 0x31, 0x32, 0x33, 0x2e, 0x34, 0x35, 0x36, 0xa, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x3a, 0x30, 0x3a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x31, 0xa, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x3a, 0x30, 0x3a, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x31, 0xa, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x3a, 0x31, 0x3a, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x3d, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x32, 0xa, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x3a, 0x31, 0x3a, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x3d, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x32, 0xa} +(*string)(nil) --- diff --git a/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/24-SECRET_BINARY-binary.json.snap b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/24-SECRET_BINARY-binary.json.snap new file mode 100755 index 00000000..267339f6 --- /dev/null +++ b/lambda/__snapshots__/TestIntegration_HandleRequestWithClients/24-SECRET_BINARY-binary.json.snap @@ -0,0 +1,6 @@ + +[TestIntegration_HandleRequestWithClients/24-SECRET_BINARY-binary.json - 1] +&"24-SECRET_BINARY-binary" +[]uint8{0x1f, 0x8b, 0x8, 0x8, 0x2b, 0xc6, 0xa9, 0x67, 0x0, 0x3, 0x52, 0x45, 0x41, 0x44, 0x4d, 0x45, 0x2e, 0x6d, 0x64, 0x0, 0x6d, 0x90, 0xc1, 0x6e, 0x82, 0x40, 0x14, 0x45, 0xf7, 0x7c, 0xc5, 0x4b, 0xba, 0x69, 0x93, 0xa2, 0x28, 0xa0, 0x84, 0x1d, 0xb1, 0x60, 0xa3, 0x21, 0x55, 0xa1, 0xb5, 0xb5, 0x69, 0x22, 0x1d, 0x6, 0x18, 0x1d, 0x98, 0x71, 0x66, 0xc0, 0xe0, 0xd7, 0x17, 0x6a, 0x93, 0x76, 0xd1, 0xe5, 0x4b, 0xee, 0x3d, 0xf7, 0xe4, 0xdd, 0x40, 0xf4, 0xb4, 0x8a, 0x20, 0x23, 0x14, 0x4b, 0xc8, 0x98, 0x0, 0x85, 0xa5, 0x22, 0x55, 0xe, 0xbc, 0x16, 0x9c, 0x49, 0xac, 0x69, 0x71, 0x81, 0x41, 0x32, 0x2e, 0x7f, 0x32, 0xa4, 0x2, 0x55, 0x10, 0x9, 0x29, 0x11, 0x18, 0x29, 0x26, 0x5a, 0x38, 0x63, 0x81, 0x1, 0x9, 0x9c, 0x28, 0x9c, 0xfe, 0x87, 0x18, 0x80, 0x27, 0x1, 0x57, 0x48, 0xb4, 0x5c, 0x11, 0x56, 0x41, 0x42, 0x73, 0x26, 0x88, 0x2a, 0x4a, 0x78, 0x4f, 0x72, 0xfc, 0x71, 0x5b, 0x28, 0xc5, 0xa5, 0x3b, 0x1c, 0x76, 0x87, 0xfe, 0x1b, 0x1b, 0x30, 0x91, 0xf, 0xef, 0xa0, 0x5b, 0xaa, 0x25, 0x4e, 0xef, 0x21, 0xe9, 0xa6, 0x55, 0xd7, 0xa5, 0xec, 0xdc, 0xd1, 0x12, 0xd9, 0x82, 0x2c, 0x12, 0xd1, 0xcf, 0xb0, 0xec, 0x2f, 0x9d, 0x54, 0x9d, 0x42, 0x99, 0x7c, 0x23, 0xae, 0xf2, 0x19, 0xeb, 0x4b, 0x7d, 0xf2, 0x88, 0x5b, 0x79, 0xd5, 0xed, 0x99, 0xae, 0xa6, 0xed, 0xf7, 0xfb, 0x36, 0x29, 0xa9, 0xc6, 0xeb, 0x4f, 0x4a, 0x90, 0xb, 0x9d, 0xc2, 0x28, 0x3d, 0x50, 0x7a, 0x1e, 0xf3, 0x4b, 0xcd, 0x85, 0x38, 0x21, 0x3, 0x57, 0x76, 0xe9, 0x34, 0xc8, 0x39, 0xda, 0x39, 0x36, 0x55, 0x69, 0x64, 0x93, 0x7c, 0x8a, 0xe, 0x6, 0x32, 0x72, 0x9a, 0x5d, 0xb8, 0x65, 0x35, 0x29, 0xb2, 0x4e, 0xd4, 0xa9, 0xf2, 0xa6, 0xd6, 0xb8, 0x20, 0x4d, 0xf7, 0x5, 0x17, 0xbc, 0xb9, 0xaf, 0x47, 0xfe, 0x6c, 0xe3, 0xc7, 0xfa, 0xd2, 0x7f, 0xd3, 0x47, 0x7e, 0xf0, 0xbc, 0x5d, 0x18, 0xf3, 0xf1, 0xeb, 0x22, 0x5e, 0x4, 0xdb, 0xd8, 0xb, 0xc7, 0xf, 0xf3, 0xd0, 0xb3, 0x5e, 0x66, 0x4b, 0x73, 0x63, 0xd8, 0x5b, 0xdb, 0x9, 0xa2, 0xf0, 0x71, 0xb7, 0x32, 0xc3, 0xdd, 0xda, 0xd8, 0xc5, 0xde, 0xda, 0xf7, 0x82, 0xf5, 0x6c, 0x12, 0x4f, 0x63, 0xb3, 0x57, 0xd4, 0xbe, 0x0, 0x9a, 0x91, 0x67, 0xf1, 0xa5, 0x1, 0x0, 0x0} +(*string)(nil) +--- diff --git a/lambda/events/24-SECRET_BINARY-binary.json b/lambda/events/24-SECRET_BINARY-binary.json new file mode 100644 index 00000000..7d08c3a4 --- /dev/null +++ b/lambda/events/24-SECRET_BINARY-binary.json @@ -0,0 +1,10 @@ +{ + "EncryptionKey": "arn:aws:kms:eu-central-1:505755377845:key/58b75958-883a-440c-842c-85af5d33a5bb", + "Format": "binary", + "ResourceType": "SECRET_BINARY", + "SopsS3File": { + "Bucket": "cdk-hnb659fds-assets-505755377845-eu-central-1", + "Key": "test-secrets/README.gz.sops.binary" + }, + "Target": "24-SECRET_BINARY-binary" +} diff --git a/lambda/internal/client/client.go b/lambda/internal/client/client.go index d75bbef3..c4b8040f 100644 --- a/lambda/internal/client/client.go +++ b/lambda/internal/client/client.go @@ -107,7 +107,7 @@ func (c *Client) S3GetObjectETAG(file SopsS3File) (*string, error) { } func (c *Client) SecretsManagerPutSecretValue(sopsHash string, secretArn string, secretStringData *[]byte, binary *bool) (data *secretsmanager.PutSecretValueOutput, err error) { - if binary != nil && binary == aws.Bool(true) { + if binary != nil && *binary { input := &secretsmanager.PutSecretValueInput{ SecretId: &secretArn, SecretBinary: *secretStringData, diff --git a/lambda/main_integration_test.go b/lambda/main_integration_test.go index 87da8907..56d63209 100644 --- a/lambda/main_integration_test.go +++ b/lambda/main_integration_test.go @@ -90,7 +90,7 @@ func cleanupSecret(t *testing.T, resourceProps map[string]interface{}) { secretName := resourceProps["Target"].(string) ResourceType := resourceProps["ResourceType"].(string) - if ResourceType != "SECRET" && ResourceType != "SECRET_BINARY" { + if ResourceType != "SECRET" && ResourceType != "SECRET_BINARY" && ResourceType != "SECRET_RAW" { return } @@ -230,9 +230,9 @@ func snapshotParameter(t *testing.T, resourceProps map[string]interface{}) { } func TestIntegration_HandleRequestWithClients(t *testing.T) { - //if os.Getenv("INTEGRATION") == "" { - // return - //} + if os.Getenv("GITHUB_REPOSITORY") != "" { + t.Skip("Skipping test in GitHub Actions environment") + } t.Logf("Running at: %s", time.Now().String()) // Forces re-run os.Setenv("AWS_REGION", "eu-central-1") os.Setenv("SOPS_AGE_KEY", "AGE-SECRET-KEY-1EFUWJ0G2XJTJFWTAM2DGMA4VCK3R05W58FSMHZP3MZQ0ZTAQEAFQC6T7T3") @@ -294,8 +294,8 @@ func TestIntegration_HandleRequestWithClients(t *testing.T) { } func TestIntegration_Cleanup(t *testing.T) { - if os.Getenv("INTEGRATION") == "" { - return + if os.Getenv("GITHUB_REPOSITORY") != "" { + t.Skip("Skipping test in GitHub Actions environment") } t.Logf("Running at: %s", time.Now().String()) // Forces re-run os.Setenv("AWS_REGION", "eu-central-1") @@ -330,9 +330,7 @@ func TestIntegration_Cleanup(t *testing.T) { } func Test_CleanUpHard(t *testing.T) { - if os.Getenv("DANGER_HARD_CLEAN") == "" { - return - } + t.Skip("Skipping cleanup") deleteAllSecrets() deleteAllParametersExcept([]string{"/cdk-bootstrap/hnb659fds/version"}) } diff --git a/src/LambdaInterface.ts b/src/LambdaInterface.ts index 655a3289..28a6d027 100644 --- a/src/LambdaInterface.ts +++ b/src/LambdaInterface.ts @@ -6,13 +6,14 @@ */ export interface SopsSyncResourcePropertys { - ResourceType: "SECRET" | "SECRET_BINARY" | "PARAMETER_MULTI" | "PARAMETER"; + ResourceType: "SECRET" | "SECRET_RAW" | "SECRET_BINARY" | "PARAMETER_MULTI" | "PARAMETER"; Format: "json" | "yaml" | "dotenv" | "binary"; Target: string; EncryptionKey?: string; SopsS3File?: SopsS3File; SopsInline?: SopsInline; FlattenSeparator?: string; + ServiceToken?: string; } export interface SopsS3File { Bucket: string; diff --git a/src/SopsSecret.ts b/src/SopsSecret.ts index a5d7b7cd..50098898 100644 --- a/src/SopsSecret.ts +++ b/src/SopsSecret.ts @@ -23,15 +23,26 @@ import { import { Construct } from 'constructs'; import { ResourceType, SopsSync, SopsSyncOptions } from './SopsSync'; +export enum RawOutput { + /** + * Parse the secret as a string + */ + STRING = 'STRING', + /** + * Parse the secret as a binary + */ + BINARY = 'BINARY', +} + /** * The configuration options of the SopsSecret */ export interface SopsSecretProps extends SopsSyncOptions { /** * Should the secret parsed and transformed to json? - * @default - true + * @default - undefined - no raw output */ - readonly rawOutput?: boolean; + readonly rawOutput?: RawOutput; /** * An optional, human-friendly description of the secret. * @@ -93,12 +104,17 @@ export class SopsSecret extends Construct implements ISecret { region: this.stack.region, }; + let resourceType = ResourceType.SECRET; + if (props.rawOutput === RawOutput.BINARY) { + resourceType = ResourceType.SECRET_BINARY; + } + if (props.rawOutput === RawOutput.STRING) { + resourceType = ResourceType.SECRET_RAW; + } + this.sync = new SopsSync(this, 'SopsSync', { target: this.secret.secretArn, - resourceType: - props.rawOutput === true - ? ResourceType.SECRET_BINARY - : ResourceType.SECRET, + resourceType, flattenSeparator: '.', secret: this.secret, ...(props as SopsSyncOptions), diff --git a/src/SopsSync.ts b/src/SopsSync.ts index 12d9a4c9..7c57d7fe 100644 --- a/src/SopsSync.ts +++ b/src/SopsSync.ts @@ -36,6 +36,7 @@ export enum UploadType { export enum ResourceType { SECRET = 'SECRET', + SECRET_RAW = 'SECRET_RAW', SECRET_BINARY = 'SECRET_BINARY', PARAMETER = 'PARAMETER', PARAMETER_MULTI = 'PARAMETER_MULTI', diff --git a/test-secrets/README.gz.sops.binary b/test-secrets/README.gz.sops.binary new file mode 100644 index 00000000..bb252627 --- /dev/null +++ b/test-secrets/README.gz.sops.binary @@ -0,0 +1,20 @@ +{ + "data": "ENC[AES256_GCM,data:EjjTw976sTEpeSvA0cMYF4VruJFLRpi4Hfk3+eEb6i545QOyHUEkknnrjsr3DN1RpvyppbAmVq33WHnB3FL9CKuXfNc9k0hhTjWFAgGjYVZqLzRZJIyjbKFkxYVdpFjbCxk6L5hII1d/SRh61/WmKktEZ18eBNf88f5E5WrznPOjJfq4Zto50kkOcnn6zL7U/LuWh6iqb9Zfnc2aQpSX5JPMhc6wVp8xOMFfBT2n0bOeUHVMZzf0/jiNTcKURy+ENyqibc8zEtAGqFHVGsK/uC3YsE0zGntr3Tn40gcAkfmewz8YEU2YrnOA+KJgHoBA6hjLdCsjAdYdQ5kQRL2iZKA1AK3TosKGwjIQfS/kOi2xY5Q43tNuEkPuTjvY4ugEeuXGXxfQRz8RyoRsKIk+xbP6Pv6SoYvM5tWGwd5pzb0NDXJx7oJpilX40YFFdFegqYa9gfOhSQ==,iv:vLpG2x1eJ+HUj/VAyEnTzQYku+Tu7E+Ea2qnYMMJy00=,tag:41WDFsgPC7AEJzy49kOwGQ==,type:str]", + "sops": { + "kms": null, + "gcp_kms": null, + "azure_kv": null, + "hc_vault": null, + "age": [ + { + "recipient": "age1djllw2pzuprrqc0en5m8vc8k5ge3tm0f6g7cj0c0glfzp44vdc4ql8ngvu", + "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBvcUpWa0IvQjc4Zk1jaXEz\nVFF1TURUSkdxdkp6QUpKSWkrL21pWGZjajJZClVaOGJTd0FOMU5yanRMOHJ5REdS\nS0RoOC9PcUEyWmZ5NERqRFl0UjhyREUKLS0tIGJrc3lINVFsZDNSUjZjS2lwdnpV\nbXFzd1gvSnVUKzZTcHJiemNRTEEwOUEKZ+L9VZbrFOw1qWjUFX9YCOawR/WqPXEp\n167H2YaedW7JfgEX6LZNwrccMQEEzKS1aogrqdM0xrq8gy9wmlRf0g==\n-----END AGE ENCRYPTED FILE-----\n" + } + ], + "lastmodified": "2025-02-10T09:56:02Z", + "mac": "ENC[AES256_GCM,data:ctF4yVtqwUoo69pqguDM51pTeD1v+oF5vjhxygIuWGlXllM+eTnhtv1KMf6bXqveEcHhbI7eNmqbOI2Ts+v+1a3Tekj32yk0YjyQ9YGxqdkJo8HW6/J4rwmobe8EFujAMs7K7vT0BOFB/KOWbk1De3VWlLC7R3FRsVFGV0hcyGw=,iv:A/sVJc4+bmWVzRT7kHgRn/zbwJfHeCsnXt9VhH4+AwE=,tag:eXWJKToJDMUYg/WLeMLfvg==,type:str]", + "pgp": null, + "encrypted_regex": "^(data|stringData)$", + "version": "3.9.1" + } +} \ No newline at end of file diff --git a/test/PARAMETER.integ.snapshot/PARAMETER.assets.json b/test/PARAMETER.integ.snapshot/PARAMETER.assets.json index 4ff7f3c0..bb4ed192 100644 --- a/test/PARAMETER.integ.snapshot/PARAMETER.assets.json +++ b/test/PARAMETER.integ.snapshot/PARAMETER.assets.json @@ -1,20 +1,20 @@ { "version": "39.0.0", "files": { - "d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4": { + "0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4": { "source": { - "path": "asset.d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4.zip", + "path": "asset.0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4.zip", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4.zip", + "objectKey": "0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "9fd7420fdde16dec1a7971d76c5395a3d449336ffbf9d03938d55a930701d259": { + "403cce8728059a0118bee399fa4dde8431a7c63198d8e1511788fe25ea4485f7": { "source": { "path": "PARAMETER.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "9fd7420fdde16dec1a7971d76c5395a3d449336ffbf9d03938d55a930701d259.json", + "objectKey": "403cce8728059a0118bee399fa4dde8431a7c63198d8e1511788fe25ea4485f7.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/test/PARAMETER.integ.snapshot/PARAMETER.template.json b/test/PARAMETER.integ.snapshot/PARAMETER.template.json index e7b0bd0e..b27937ad 100644 --- a/test/PARAMETER.integ.snapshot/PARAMETER.template.json +++ b/test/PARAMETER.integ.snapshot/PARAMETER.template.json @@ -139,7 +139,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4.zip" + "S3Key": "0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4.zip" }, "Environment": { "Variables": { diff --git a/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.assets.json b/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.assets.json index 6cd115d5..8df8831a 100644 --- a/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.assets.json +++ b/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.assets.json @@ -1,20 +1,20 @@ { "version": "39.0.0", "files": { - "d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4": { + "0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4": { "source": { - "path": "asset.d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4.zip", + "path": "asset.0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4.zip", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4.zip", + "objectKey": "0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "4721826719b9692e7b57c518a8cd8688ebd74f5c9c38eb13a8630f8c3ff07d32": { + "a0ce4cda9ec46f3872ef0376abd93e9b845ab0e0abbf33fac6b0ce69bce1fefc": { "source": { "path": "PARAMETERMULTI.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "4721826719b9692e7b57c518a8cd8688ebd74f5c9c38eb13a8630f8c3ff07d32.json", + "objectKey": "a0ce4cda9ec46f3872ef0376abd93e9b845ab0e0abbf33fac6b0ce69bce1fefc.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.template.json b/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.template.json index a46eaffe..5496671e 100644 --- a/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.template.json +++ b/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.template.json @@ -535,7 +535,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4.zip" + "S3Key": "0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4.zip" }, "Environment": { "Variables": { diff --git a/test/SECRET.integ.snapshot/SECRET.assets.json b/test/SECRET.integ.snapshot/SECRET.assets.json index 626aee1a..0d2fd4b3 100644 --- a/test/SECRET.integ.snapshot/SECRET.assets.json +++ b/test/SECRET.integ.snapshot/SECRET.assets.json @@ -1,20 +1,20 @@ { "version": "39.0.0", "files": { - "d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4": { + "0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4": { "source": { - "path": "asset.d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4.zip", + "path": "asset.0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4.zip", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4.zip", + "objectKey": "0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "d7acf0346faeebfc056b5d712c021c29e4bb77ab9db7f766d78d483539fb7fc9": { + "7f4a277181a414a4b3627b80eb422237183e8ccd700dd2192456e33f294b39b1": { "source": { "path": "SECRET.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "d7acf0346faeebfc056b5d712c021c29e4bb77ab9db7f766d78d483539fb7fc9.json", + "objectKey": "7f4a277181a414a4b3627b80eb422237183e8ccd700dd2192456e33f294b39b1.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/test/SECRET.integ.snapshot/SECRET.template.json b/test/SECRET.integ.snapshot/SECRET.template.json index 05fad039..49338f64 100644 --- a/test/SECRET.integ.snapshot/SECRET.template.json +++ b/test/SECRET.integ.snapshot/SECRET.template.json @@ -85,7 +85,7 @@ ], "Effect": "Allow", "Resource": { - "Ref": "Yaml2Json4AC73F66" + "Ref": "Json2RawString0FD9054F" } }, { @@ -95,7 +95,7 @@ ], "Effect": "Allow", "Resource": { - "Ref": "Json2Raw339EA21E" + "Ref": "Yaml2Json4AC73F66" } }, { @@ -105,7 +105,7 @@ ], "Effect": "Allow", "Resource": { - "Ref": "Yaml2RawEB5BB054" + "Ref": "Yaml2RawStringBB57E2A1" } }, { @@ -125,7 +125,17 @@ ], "Effect": "Allow", "Resource": { - "Ref": "DotEnv2RawF7654593" + "Ref": "DotEnv2RawString8AFC290F" + } + }, + { + "Action": [ + "secretsmanager:PutSecretValue", + "secretsmanager:UpdateSecret" + ], + "Effect": "Allow", + "Resource": { + "Ref": "Binary2RawString41D1BBEA" } }, { @@ -135,7 +145,7 @@ ], "Effect": "Allow", "Resource": { - "Ref": "Binary2RawA83E0B31" + "Ref": "Binary2RawBinary9379AA24" } } ], @@ -156,7 +166,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "d4fa67588efc8e80877fce3ed8397e0350420ed5859c6d2a36fefc0f1604fae4.zip" + "S3Key": "0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4.zip" }, "Environment": { "Variables": { @@ -178,16 +188,16 @@ "SingletonLambdaSopsSyncProviderServiceRoleC45BBD25" ] }, - "Yaml2Json4AC73F66": { + "Json2RawString0FD9054F": { "Type": "AWS::SecretsManager::Secret", "Properties": { "GenerateSecretString": {}, - "Name": "Yaml2Json" + "Name": "Json2RawString" }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, - "Yaml2JsonSopsSync33E502C1": { + "Json2RawStringSopsSync8C4F878C": { "Type": "Custom::SopsSync", "Properties": { "ServiceToken": { @@ -197,29 +207,29 @@ ] }, "SopsInline": { - "Content": "YXBpS2V5OiBFTkNbQUVTMjU2X0dDTSxkYXRhOnI2WWZyd0drVkZ4QkY4bUhFY3NQYXhNdFVRPT0saXY6LzhycjRLNW1CeExpM2pSMmxIZmVleVZPL3dRWTAwcGMvL093NXZxWTE3UT0sdGFnOitkZ0xhS2VTeE5OQnVPRUZJZnRPWnc9PSx0eXBlOnN0cl0KZGF0YWJhc2U6CiAgICB1c2VyOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNkc1V5dm89LGl2OklWaW9KQ1Z5Uk9laEF0RzZ4Ym1BWnpkNTJIUXZrMGVaSXRNQmpCQXZxeDg9LHRhZzowcHVtemR5SDV3aUVBck1tbXJhM1VRPT0sdHlwZTpzdHJdCiAgICBwYXNzd29yZDogRU5DW0FFUzI1Nl9HQ00sZGF0YTpDU1E4akZyeG5MUVksaXY6aFhMRU5tRzhxTEdzR2RXdjN3YnJqNUxmMnpiRjFUb05Jd1M0eTF1V0VYZz0sdGFnOjhRRENNeUE2OWRZbDU4eEl1UDFEY0E9PSx0eXBlOnN0cl0KICAgIGhvc3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6eGZVMmVDKy8rdXZDa0hZOFFIWT0saXY6VUxXZHZvYTZyOEYxZzIrWkYzeFB3YWsxRWRoRFdtbmRzTzVSVXhBVlBFOD0sdGFnOktHbEpHMUlNU1duNG5FdE1hT1NzZGc9PSx0eXBlOnN0cl0KdG9rZW5zOgogICAgLSBzZXJ2aWNlOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnRSU1VwR0tJRW1jPSxpdjpoaS8zOGlDL0dsYzRueFVrUllCVjJjeTk0NmsrYXpYRnRFZEpPTlAxZy93PSx0YWc6R1EwL1dFaHRleXFDcHNFdi9TRnJiQT09LHR5cGU6c3RyXQogICAgICB0b2tlbjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpDR25TTzRIRSxpdjpMSDB4VldOVGJCbUhQUTFPaVA1K3VSRmZHL0U3SzdPR1lxS0hYT0tqZThRPSx0YWc6c09ZaGdLS1Yxb2dPczdQSnJCcnNqdz09LHR5cGU6c3RyXQogICAgLSBzZXJ2aWNlOiBFTkNbQUVTMjU2X0dDTSxkYXRhOm9ocVh2Wi83SFd3PSxpdjpDcGpVZFRiR0w0VEdSSVd0RUp4Wjg5MjN0dy9Rb213K2tDdGlIdUZpR1FjPSx0YWc6OTVUUVVhM05TVzFxR1Q4TE5zRWdiUT09LHR5cGU6c3RyXQogICAgICB0b2tlbjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpJMEkvWGdXbCxpdjo4N0UvYzdEaUdLVDIydGRkQ0ZxQnVQT0M3MzZ5djVZRDlNLytnM1BpWlg0PSx0YWc6WjFwcklIZkgzOW0yVTZpMktlVjIyUT09LHR5cGU6c3RyXQpzb21lT3RoZXJLZXk6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6SFNNRndNWEhuaTE4dFRPUHcyREFFMGc1WFFSOW9Vdz0saXY6NHhUUk84VFloYmxhMDFnemF0aGY3VUJIaDhHdGhkOTdHSXhYLzBrQ1h3Zz0sdGFnOjRwc0VGVzNPMlJxcVlONjhVMjNQeHc9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6CiAgICBTcGVjaWFsQ2hhcmFjdGVyczogRU5DW0FFUzI1Nl9HQ00sZGF0YTpFL2pxa1B2VVNiaFpQYm0wdnJDalgxc29MQT09LGl2OlJ0bzBFeVFUMm96Rm1rMXR2azN4UkR3Vm5OcHJBNXhqcENOR1RaaWViMEE9LHRhZzpwUnZoc1huVnJiMnFHRzFvY3U1bUt3PT0sdHlwZTpzdHJdCiAgICBIVE1MRW5jb2RpbmdUZXN0MTogRU5DW0FFUzI1Nl9HQ00sZGF0YTpaZGM1dlpPQklRUjhtY2xyUHl0dm15ZzRIUWVELGl2OldHelMwK0xTUDlYYUZlcWgxYVptbWdPNTRaRG44VGYyWUlPaXdtSkhwMEk9LHRhZzpaZEEveFg3Mkp6Qll4R1ZjVjJhMlJBPT0sdHlwZTpzdHJdCiAgICBIVE1MRW5jb2RpbmdUZXN0MjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpYdz09LGl2OmJsWUpYd1Qrd0VyZ1Zzd2FDVzhvV1lubnk4OG9MMXl2Rng4ZTNKY0UwOVE9LHRhZzorWVV5MDJ4YUpocXFhdEJ0a2o5NzJBPT0sdHlwZTpzdHJdCiAgICBIVExNRW5jb2RpbmdUZXN0MzogRU5DW0FFUzI1Nl9HQ00sZGF0YTovdz09LGl2Oi80ZVNWdEZRN2NHb05JN1VPTXc4bHkwK2FpWDdXaXZVNGloTWxWS1VENWs9LHRhZzpjTFNPOENSMElNK1k1TFpmZE00M0JRPT0sdHlwZTpzdHJdCiAgICAibnVsbCI6IG51bGwKICAgIGJvb2xlYW46IEVOQ1tBRVMyNTZfR0NNLGRhdGE6RDFpYVVBPT0saXY6U3VyVUFCaHFNK1VZaUNaYUVtanlHS1phaTJqREpMM25uWko0MXRNTkhCUT0sdGFnOmdld0ZsY2NVZGIzSXlYN2tQK1NQM3c9PSx0eXBlOmJvb2xdCiAgICBudW1iZXIxOiBFTkNbQUVTMjU2X0dDTSxkYXRhOk1jQk0saXY6VmpZRXBkVmdMc2pYR20yVlJEOUx1MEJYeU9NRmprVU1RSWp2dVZvZDVjcz0sdGFnOjdFZm5LMHFjSVRSZzFPYnJpdTdFZ2c9PSx0eXBlOmludF0KICAgIG51bWJlcjI6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6d0xjdTBYanlKZz09LGl2OnRaVC9BTVlNVG9aaTVudW82alV4d0IwMUhQWDRIaEhwZHQ2djd1elo5U0U9LHRhZzpmZ0s0R2ZpNVlCQTFMdXBKQlgyc0JBPT0sdHlwZTpmbG9hdF0Kc29wczoKICAgIGttczogW10KICAgIGdjcF9rbXM6IFtdCiAgICBhenVyZV9rdjogW10KICAgIGhjX3ZhdWx0OiBbXQogICAgYWdlOgogICAgICAgIC0gcmVjaXBpZW50OiBhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dQogICAgICAgICAgZW5jOiB8CiAgICAgICAgICAgIC0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgICAgICAgICAgWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQlljM0Y2WkZZNFJGbGxiU3RwTXpFegogICAgICAgICAgICBXbXh1TnpkdU15dGpSa2gxWTI0eE1VTm9WbmRDWVVOaGFHdEpDakp3WjFBelpsQlZjVmQ2WTJORmJHUjRNbVZGCiAgICAgICAgICAgIGJXOU9XV2gyYm1SamFGUnJPRm95ZVdWV2JuSlRlV01LTFMwdElFeHlWRE5GUlhwRlRFcFJNell2V0cxUGFXTnoKICAgICAgICAgICAgVFc5NmQwdHFhakJMYzAxcGFWbEVaSEZYUjFGMmJYY0tMSUpnN3lUbTB1Q2lpUGlLc25zQXlSTS9hRFovZk52dwogICAgICAgICAgICBpaWxLVEI1d1AxcWRzN1N0Y1ZMSjE4UkdVbzl2dUFBOWlQME5aQ1A2a0tMVmdaYmNKL2FTZHc9PQogICAgICAgICAgICAtLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLQogICAgbGFzdG1vZGlmaWVkOiAiMjAyNS0wMi0wN1QxNDo0NzowOVoiCiAgICBtYWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6U3gyRDZTRitwUUhRK291eDdsTmV4c2hQb2RjZ2UzdzJnNml4TFRqSy9Oa0VneUJNbWdzVnlCR1dNbCtrU2s2UFk1OEhUNEFRcHlCdHVpVUtqM2pTSjRwWm1lcGdXSUFkeEtwQjNzbHF5MzhnZ2hZUDIvQUhTYkhZUnpoTFFJT3h4RE8waW5Vd3JvSGExM0h0dEpDekRmWEtOaUtyYk1SQVFLaytGV0Y2eDN3PSxpdjo3c0JqU2hWV3JXMTc3d1pCdityeFc2ZXFLMFZRY2pqR1dWdEh3OWRiR1RZPSx0YWc6Qm8zb1lGZ2JBVGJOVndEdFAyUkFhdz09LHR5cGU6c3RyXQogICAgcGdwOiBbXQogICAgdW5lbmNyeXB0ZWRfc3VmZml4OiBfdW5lbmNyeXB0ZWQKICAgIHZlcnNpb246IDMuOS40Cg==", - "Hash": "9912a0ccf8001b767579817f902a5d7e030019cc7b6db34c028f4a0f9079fddf" + "Content": "ewoJImFwaUtleSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOmxMYlhWRWhCUktYaUdHa0JoNUtsdGdVQm9BPT0saXY6bHVheUpuaWlYSHdBM1owclp5eGVGMDB4bEhmTXdyWU1pWWgrYWhQNkF5bz0sdGFnOmwzazNwU256UlRBS2VBSE94dytmR3c9PSx0eXBlOnN0cl0iLAoJImRhdGFiYXNlIjogewoJCSJ1c2VyIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6a1F0a1Fhcz0saXY6K3F5SjlGVVhvTXRjcGNmZFQ3WlRPTkhmM1NzR2JBZkp6bkpGdDVlL3BWRT0sdGFnOjJDaW5telZlcW42NTRNZllkaGtxeGc9PSx0eXBlOnN0cl0iLAoJCSJwYXNzd29yZCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOmpId0NFSmgwMkE4cyxpdjppbXdIVzRVN0RWMDltNU5Dek81azBBdVJaZFkvVEsyK0YyOFZiV0ZINnlnPSx0YWc6cGNRM2g0MEQ5QXZCRlFFbmlSeE1vdz09LHR5cGU6c3RyXSIsCgkJImhvc3QiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpVM0p4L0drQnlLTFBuZWJzcDVVPSxpdjpjQ3VXOTlrdHlBSTRkVlF6RHQxL2pzZ0xQNXBNZFlZQ3NpNkFocXNnVlhzPSx0YWc6djE2enlZdTVBMVRWQlA0YmFPeEIxZz09LHR5cGU6c3RyXSIKCX0sCgkidG9rZW5zIjogWwoJCXsKCQkJInNlcnZpY2UiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpNTFFXOHRvY2dDYz0saXY6Ky9mb1F5UjdxMGh2Yk9rR2l2YXVVQVdkaWhmb0hLendnU1lkdjFHcTI5Yz0sdGFnOk8yZWJtVDJ1OU5mVnFvbzBxNEo5N3c9PSx0eXBlOnN0cl0iLAoJCQkidG9rZW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpwY3JGUVFEayxpdjorcS8zaTduaVR3bi9qeU9xZUhKOGhVVkE0ak44Q3FQWHVmV3NJUmtrcEpBPSx0YWc6YnVJczhHNE9maXVKUGYxMDgvc0RoUT09LHR5cGU6c3RyXSIKCQl9LAoJCXsKCQkJInNlcnZpY2UiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpneVJuSWlnUFhoOD0saXY6b1ROclhUWktYNzd5eW52Y1F3aHpYaW8yckVKWHNJQk1VRDZET0NScjRmQT0sdGFnOjJPY2habWJxZGNIZGxqQzZDS2t1bEE9PSx0eXBlOnN0cl0iLAoJCQkidG9rZW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpFd0dDWVQzayxpdjoxSE16VURxbVhySTNiaEdheGtuTWZ0d0VaOENjMXN6eGFNVjZBMTY0bWZjPSx0YWc6MGI1ZVJ3eFpENGo5dWppeFRqZkZaZz09LHR5cGU6c3RyXSIKCQl9CgldLAoJInNvbWVPdGhlcktleSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOnZWbHAzRUUxbWdUUVA5SlNER2RQZi8raDJGU3Fhalk9LGl2OnhZR0lvVFlQRW4rNGF4MkxUS2l4bFFiNU5hb3RWdyswUVZmRlNtOVFOV289LHRhZzorVTRKUWJtLzhtRldBbWxNcnlnN0xBPT0sdHlwZTpzdHJdIiwKCSJzcGVjaWZpYyI6IHsKCQkiU3BlY2lhbENoYXJhY3RlcnMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp1UHFGT1NqVU1nVmRyb1VCSU02cWVybk9zQT09LGl2OnJTU2NOZ2wzZzY2K0lUQVlZamp5VTJIekJXWUR5OGxCY0NHR1hGdkhJZ289LHRhZzpKRXczeVlkaUxLK0YrTUN5V2N0aDZ3PT0sdHlwZTpzdHJdIiwKCQkiSFRNTEVuY29kaW5nVGVzdDEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTprc0N1M0cwckcyTmY1K2MvOXZTczBhb2wreG52LGl2OjcrUEp0M1E5MUNIbXZSSHFESWJBcFNNYVlMb1pxM0QxL0JuYUEzQ2ZzTXc9LHRhZzpTL0F0MmNsU3NHQXZIU2tqTHdldHFRPT0sdHlwZTpzdHJdIiwKCQkiSFRNTEVuY29kaW5nVGVzdDIiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpadz09LGl2OmpIM1JrUkpzTURMK2dQUHpwTHYxZ1BYL1RMeTlVMXpTUHFJcEY5N3dUYjQ9LHRhZzozWGFmN0pXWVl4SVFRUjg4ZWIrRkRnPT0sdHlwZTpzdHJdIiwKCQkiSFRMTUVuY29kaW5nVGVzdDMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpVQT09LGl2OlpZcUNoTUxCZlFvS0hjbHU5NHNiY0k5OHNWR3Z5bU0zN0Vzc2h2ejBJdXc9LHRhZzpVVjF6RmltY2dFVEQwbmNUanBnRHZnPT0sdHlwZTpzdHJdIiwKCQkibnVsbCI6IG51bGwsCgkJImJvb2xlYW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp3MnNZL0E9PSxpdjpLKzJBTDhEYTcwKzFtQlZ6dXEyZU9nemtFRndlbWJFY3lYOEhYS0lBcVI4PSx0YWc6S1lDdzNtNlBUOHJjdTFpL21HWko1Zz09LHR5cGU6Ym9vbF0iLAoJCSJudW1iZXIxIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6M1kxZixpdjpNQ0NUK0V3Tm5wVkxldS9La2lRTmxJR0dva2ltaDZVN1BORUZFeXIxdTRBPSx0YWc6alpWYU1ObjRyZ2grNWtXZ056aUlpZz09LHR5cGU6ZmxvYXRdIiwKCQkibnVtYmVyMiI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOkVQZ1REN1p4VlE9PSxpdjorWkpnZkQyVi9zM1hCalF1enEweXNTNWZZdFMyUDJoWDcyZGo5cW11SENFPSx0YWc6Zk05Zyt3dHViakFmalhQSEN2c1hWQT09LHR5cGU6ZmxvYXRdIgoJfSwKCSJzb3BzIjogewoJCSJrbXMiOiBudWxsLAoJCSJnY3Bfa21zIjogbnVsbCwKCQkiYXp1cmVfa3YiOiBudWxsLAoJCSJoY192YXVsdCI6IG51bGwsCgkJImFnZSI6IFsKCQkJewoJCQkJInJlY2lwaWVudCI6ICJhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dSIsCgkJCQkiZW5jIjogIi0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS1cbllXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JqU0N0dE1GbFlaRTlGWmpkSFMyZ3dcblFqZGplRk5tUm1sUVZuVllNSEl2VXpsTFRFSkZaVkZ4WjFFMENtRnhXblJ3ZWpOTVpYcEJObnBsYVVWRGR6WnRcblFXWkdWRUo1UXpNelVVaHVkMGhrU1c1dmRHRmlVMDBLTFMwdElEVnBSVEpITWxocVRHSlpTeXRyYW5aYVNXMWFcbmNsQTBZV0ZVTlhJclkyeDJlbWg1ZEdGVGQxVmpZekFLQTlSOUMrNDJiWjJiS0RVbjhLNlNEZlE1S2tySUNZM3JcbjBOMjdWNThaUEFvNDh0cWtoZWEvbzBEQnRrZGxsckJIT3hHZU9JSm0vd0ZPZm5FVHJaNjhWdz09XG4tLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuIgoJCQl9CgkJXSwKCQkibGFzdG1vZGlmaWVkIjogIjIwMjUtMDItMDdUMTQ6NDc6MTRaIiwKCQkibWFjIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6N0N1Q2o3c0plS0ZaRnBGcDZqaTNCZkd6RFkrWDZaNWVmY2NwVHNiRGo0Y2svUVl1K3gzaUxraXJoaHJHSDBoRXVONnhIS0Fqcnkvam1DUkpwR2grN0VHbTNmZlFvU1l1OW9DK3VqU1gzKzdhV2ZoT3Y4Uk90N1IzOFo5anpFbjFxcGhLRVg5bEszTytJcnVYSGZVRSs2dC96cXdsSVZqTUdhSTFBUmJMQktBPSxpdjpuOGNlSGI0V3dYeTRWSXgvbUpOV05Nd0diRjZJdk11T3cvWVFhN0p4UmlZPSx0YWc6aGZVM1NiWkU3Y0FKOVFUWFJHWmo3dz09LHR5cGU6c3RyXSIsCgkJInBncCI6IG51bGwsCgkJInVuZW5jcnlwdGVkX3N1ZmZpeCI6ICJfdW5lbmNyeXB0ZWQiLAoJCSJ2ZXJzaW9uIjogIjMuOS40IgoJfQp9", + "Hash": "e79149a81c3a4f62383c195070a39111284086e5c754f516b315c09943583dfb" }, "FlattenSeparator": ".", - "Format": "yaml", - "ResourceType": "SECRET", + "Format": "json", + "ResourceType": "SECRET_RAW", "Target": { - "Ref": "Yaml2Json4AC73F66" + "Ref": "Json2RawString0FD9054F" } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, - "Json2Raw339EA21E": { + "Yaml2Json4AC73F66": { "Type": "AWS::SecretsManager::Secret", "Properties": { "GenerateSecretString": {}, - "Name": "Json2Raw" + "Name": "Yaml2Json" }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, - "Json2RawSopsSyncD3A7B74E": { + "Yaml2JsonSopsSync33E502C1": { "Type": "Custom::SopsSync", "Properties": { "ServiceToken": { @@ -229,29 +239,29 @@ ] }, "SopsInline": { - "Content": "ewoJImFwaUtleSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOmxMYlhWRWhCUktYaUdHa0JoNUtsdGdVQm9BPT0saXY6bHVheUpuaWlYSHdBM1owclp5eGVGMDB4bEhmTXdyWU1pWWgrYWhQNkF5bz0sdGFnOmwzazNwU256UlRBS2VBSE94dytmR3c9PSx0eXBlOnN0cl0iLAoJImRhdGFiYXNlIjogewoJCSJ1c2VyIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6a1F0a1Fhcz0saXY6K3F5SjlGVVhvTXRjcGNmZFQ3WlRPTkhmM1NzR2JBZkp6bkpGdDVlL3BWRT0sdGFnOjJDaW5telZlcW42NTRNZllkaGtxeGc9PSx0eXBlOnN0cl0iLAoJCSJwYXNzd29yZCI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOmpId0NFSmgwMkE4cyxpdjppbXdIVzRVN0RWMDltNU5Dek81azBBdVJaZFkvVEsyK0YyOFZiV0ZINnlnPSx0YWc6cGNRM2g0MEQ5QXZCRlFFbmlSeE1vdz09LHR5cGU6c3RyXSIsCgkJImhvc3QiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpVM0p4L0drQnlLTFBuZWJzcDVVPSxpdjpjQ3VXOTlrdHlBSTRkVlF6RHQxL2pzZ0xQNXBNZFlZQ3NpNkFocXNnVlhzPSx0YWc6djE2enlZdTVBMVRWQlA0YmFPeEIxZz09LHR5cGU6c3RyXSIKCX0sCgkidG9rZW5zIjogWwoJCXsKCQkJInNlcnZpY2UiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpNTFFXOHRvY2dDYz0saXY6Ky9mb1F5UjdxMGh2Yk9rR2l2YXVVQVdkaWhmb0hLendnU1lkdjFHcTI5Yz0sdGFnOk8yZWJtVDJ1OU5mVnFvbzBxNEo5N3c9PSx0eXBlOnN0cl0iLAoJCQkidG9rZW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpwY3JGUVFEayxpdjorcS8zaTduaVR3bi9qeU9xZUhKOGhVVkE0ak44Q3FQWHVmV3NJUmtrcEpBPSx0YWc6YnVJczhHNE9maXVKUGYxMDgvc0RoUT09LHR5cGU6c3RyXSIKCQl9LAoJCXsKCQkJInNlcnZpY2UiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpneVJuSWlnUFhoOD0saXY6b1ROclhUWktYNzd5eW52Y1F3aHpYaW8yckVKWHNJQk1VRDZET0NScjRmQT0sdGFnOjJPY2habWJxZGNIZGxqQzZDS2t1bEE9PSx0eXBlOnN0cl0iLAoJCQkidG9rZW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpFd0dDWVQzayxpdjoxSE16VURxbVhySTNiaEdheGtuTWZ0d0VaOENjMXN6eGFNVjZBMTY0bWZjPSx0YWc6MGI1ZVJ3eFpENGo5dWppeFRqZkZaZz09LHR5cGU6c3RyXSIKCQl9CgldLAoJInNvbWVPdGhlcktleSI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOnZWbHAzRUUxbWdUUVA5SlNER2RQZi8raDJGU3Fhalk9LGl2OnhZR0lvVFlQRW4rNGF4MkxUS2l4bFFiNU5hb3RWdyswUVZmRlNtOVFOV289LHRhZzorVTRKUWJtLzhtRldBbWxNcnlnN0xBPT0sdHlwZTpzdHJdIiwKCSJzcGVjaWZpYyI6IHsKCQkiU3BlY2lhbENoYXJhY3RlcnMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp1UHFGT1NqVU1nVmRyb1VCSU02cWVybk9zQT09LGl2OnJTU2NOZ2wzZzY2K0lUQVlZamp5VTJIekJXWUR5OGxCY0NHR1hGdkhJZ289LHRhZzpKRXczeVlkaUxLK0YrTUN5V2N0aDZ3PT0sdHlwZTpzdHJdIiwKCQkiSFRNTEVuY29kaW5nVGVzdDEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTprc0N1M0cwckcyTmY1K2MvOXZTczBhb2wreG52LGl2OjcrUEp0M1E5MUNIbXZSSHFESWJBcFNNYVlMb1pxM0QxL0JuYUEzQ2ZzTXc9LHRhZzpTL0F0MmNsU3NHQXZIU2tqTHdldHFRPT0sdHlwZTpzdHJdIiwKCQkiSFRNTEVuY29kaW5nVGVzdDIiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpadz09LGl2OmpIM1JrUkpzTURMK2dQUHpwTHYxZ1BYL1RMeTlVMXpTUHFJcEY5N3dUYjQ9LHRhZzozWGFmN0pXWVl4SVFRUjg4ZWIrRkRnPT0sdHlwZTpzdHJdIiwKCQkiSFRMTUVuY29kaW5nVGVzdDMiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpVQT09LGl2OlpZcUNoTUxCZlFvS0hjbHU5NHNiY0k5OHNWR3Z5bU0zN0Vzc2h2ejBJdXc9LHRhZzpVVjF6RmltY2dFVEQwbmNUanBnRHZnPT0sdHlwZTpzdHJdIiwKCQkibnVsbCI6IG51bGwsCgkJImJvb2xlYW4iOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTp3MnNZL0E9PSxpdjpLKzJBTDhEYTcwKzFtQlZ6dXEyZU9nemtFRndlbWJFY3lYOEhYS0lBcVI4PSx0YWc6S1lDdzNtNlBUOHJjdTFpL21HWko1Zz09LHR5cGU6Ym9vbF0iLAoJCSJudW1iZXIxIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6M1kxZixpdjpNQ0NUK0V3Tm5wVkxldS9La2lRTmxJR0dva2ltaDZVN1BORUZFeXIxdTRBPSx0YWc6alpWYU1ObjRyZ2grNWtXZ056aUlpZz09LHR5cGU6ZmxvYXRdIiwKCQkibnVtYmVyMiI6ICJFTkNbQUVTMjU2X0dDTSxkYXRhOkVQZ1REN1p4VlE9PSxpdjorWkpnZkQyVi9zM1hCalF1enEweXNTNWZZdFMyUDJoWDcyZGo5cW11SENFPSx0YWc6Zk05Zyt3dHViakFmalhQSEN2c1hWQT09LHR5cGU6ZmxvYXRdIgoJfSwKCSJzb3BzIjogewoJCSJrbXMiOiBudWxsLAoJCSJnY3Bfa21zIjogbnVsbCwKCQkiYXp1cmVfa3YiOiBudWxsLAoJCSJoY192YXVsdCI6IG51bGwsCgkJImFnZSI6IFsKCQkJewoJCQkJInJlY2lwaWVudCI6ICJhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dSIsCgkJCQkiZW5jIjogIi0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS1cbllXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0JqU0N0dE1GbFlaRTlGWmpkSFMyZ3dcblFqZGplRk5tUm1sUVZuVllNSEl2VXpsTFRFSkZaVkZ4WjFFMENtRnhXblJ3ZWpOTVpYcEJObnBsYVVWRGR6WnRcblFXWkdWRUo1UXpNelVVaHVkMGhrU1c1dmRHRmlVMDBLTFMwdElEVnBSVEpITWxocVRHSlpTeXRyYW5aYVNXMWFcbmNsQTBZV0ZVTlhJclkyeDJlbWg1ZEdGVGQxVmpZekFLQTlSOUMrNDJiWjJiS0RVbjhLNlNEZlE1S2tySUNZM3JcbjBOMjdWNThaUEFvNDh0cWtoZWEvbzBEQnRrZGxsckJIT3hHZU9JSm0vd0ZPZm5FVHJaNjhWdz09XG4tLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuIgoJCQl9CgkJXSwKCQkibGFzdG1vZGlmaWVkIjogIjIwMjUtMDItMDdUMTQ6NDc6MTRaIiwKCQkibWFjIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6N0N1Q2o3c0plS0ZaRnBGcDZqaTNCZkd6RFkrWDZaNWVmY2NwVHNiRGo0Y2svUVl1K3gzaUxraXJoaHJHSDBoRXVONnhIS0Fqcnkvam1DUkpwR2grN0VHbTNmZlFvU1l1OW9DK3VqU1gzKzdhV2ZoT3Y4Uk90N1IzOFo5anpFbjFxcGhLRVg5bEszTytJcnVYSGZVRSs2dC96cXdsSVZqTUdhSTFBUmJMQktBPSxpdjpuOGNlSGI0V3dYeTRWSXgvbUpOV05Nd0diRjZJdk11T3cvWVFhN0p4UmlZPSx0YWc6aGZVM1NiWkU3Y0FKOVFUWFJHWmo3dz09LHR5cGU6c3RyXSIsCgkJInBncCI6IG51bGwsCgkJInVuZW5jcnlwdGVkX3N1ZmZpeCI6ICJfdW5lbmNyeXB0ZWQiLAoJCSJ2ZXJzaW9uIjogIjMuOS40IgoJfQp9", - "Hash": "e79149a81c3a4f62383c195070a39111284086e5c754f516b315c09943583dfb" + "Content": "YXBpS2V5OiBFTkNbQUVTMjU2X0dDTSxkYXRhOnI2WWZyd0drVkZ4QkY4bUhFY3NQYXhNdFVRPT0saXY6LzhycjRLNW1CeExpM2pSMmxIZmVleVZPL3dRWTAwcGMvL093NXZxWTE3UT0sdGFnOitkZ0xhS2VTeE5OQnVPRUZJZnRPWnc9PSx0eXBlOnN0cl0KZGF0YWJhc2U6CiAgICB1c2VyOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnNkc1V5dm89LGl2OklWaW9KQ1Z5Uk9laEF0RzZ4Ym1BWnpkNTJIUXZrMGVaSXRNQmpCQXZxeDg9LHRhZzowcHVtemR5SDV3aUVBck1tbXJhM1VRPT0sdHlwZTpzdHJdCiAgICBwYXNzd29yZDogRU5DW0FFUzI1Nl9HQ00sZGF0YTpDU1E4akZyeG5MUVksaXY6aFhMRU5tRzhxTEdzR2RXdjN3YnJqNUxmMnpiRjFUb05Jd1M0eTF1V0VYZz0sdGFnOjhRRENNeUE2OWRZbDU4eEl1UDFEY0E9PSx0eXBlOnN0cl0KICAgIGhvc3Q6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6eGZVMmVDKy8rdXZDa0hZOFFIWT0saXY6VUxXZHZvYTZyOEYxZzIrWkYzeFB3YWsxRWRoRFdtbmRzTzVSVXhBVlBFOD0sdGFnOktHbEpHMUlNU1duNG5FdE1hT1NzZGc9PSx0eXBlOnN0cl0KdG9rZW5zOgogICAgLSBzZXJ2aWNlOiBFTkNbQUVTMjU2X0dDTSxkYXRhOnRSU1VwR0tJRW1jPSxpdjpoaS8zOGlDL0dsYzRueFVrUllCVjJjeTk0NmsrYXpYRnRFZEpPTlAxZy93PSx0YWc6R1EwL1dFaHRleXFDcHNFdi9TRnJiQT09LHR5cGU6c3RyXQogICAgICB0b2tlbjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpDR25TTzRIRSxpdjpMSDB4VldOVGJCbUhQUTFPaVA1K3VSRmZHL0U3SzdPR1lxS0hYT0tqZThRPSx0YWc6c09ZaGdLS1Yxb2dPczdQSnJCcnNqdz09LHR5cGU6c3RyXQogICAgLSBzZXJ2aWNlOiBFTkNbQUVTMjU2X0dDTSxkYXRhOm9ocVh2Wi83SFd3PSxpdjpDcGpVZFRiR0w0VEdSSVd0RUp4Wjg5MjN0dy9Rb213K2tDdGlIdUZpR1FjPSx0YWc6OTVUUVVhM05TVzFxR1Q4TE5zRWdiUT09LHR5cGU6c3RyXQogICAgICB0b2tlbjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpJMEkvWGdXbCxpdjo4N0UvYzdEaUdLVDIydGRkQ0ZxQnVQT0M3MzZ5djVZRDlNLytnM1BpWlg0PSx0YWc6WjFwcklIZkgzOW0yVTZpMktlVjIyUT09LHR5cGU6c3RyXQpzb21lT3RoZXJLZXk6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6SFNNRndNWEhuaTE4dFRPUHcyREFFMGc1WFFSOW9Vdz0saXY6NHhUUk84VFloYmxhMDFnemF0aGY3VUJIaDhHdGhkOTdHSXhYLzBrQ1h3Zz0sdGFnOjRwc0VGVzNPMlJxcVlONjhVMjNQeHc9PSx0eXBlOnN0cl0Kc3BlY2lmaWM6CiAgICBTcGVjaWFsQ2hhcmFjdGVyczogRU5DW0FFUzI1Nl9HQ00sZGF0YTpFL2pxa1B2VVNiaFpQYm0wdnJDalgxc29MQT09LGl2OlJ0bzBFeVFUMm96Rm1rMXR2azN4UkR3Vm5OcHJBNXhqcENOR1RaaWViMEE9LHRhZzpwUnZoc1huVnJiMnFHRzFvY3U1bUt3PT0sdHlwZTpzdHJdCiAgICBIVE1MRW5jb2RpbmdUZXN0MTogRU5DW0FFUzI1Nl9HQ00sZGF0YTpaZGM1dlpPQklRUjhtY2xyUHl0dm15ZzRIUWVELGl2OldHelMwK0xTUDlYYUZlcWgxYVptbWdPNTRaRG44VGYyWUlPaXdtSkhwMEk9LHRhZzpaZEEveFg3Mkp6Qll4R1ZjVjJhMlJBPT0sdHlwZTpzdHJdCiAgICBIVE1MRW5jb2RpbmdUZXN0MjogRU5DW0FFUzI1Nl9HQ00sZGF0YTpYdz09LGl2OmJsWUpYd1Qrd0VyZ1Zzd2FDVzhvV1lubnk4OG9MMXl2Rng4ZTNKY0UwOVE9LHRhZzorWVV5MDJ4YUpocXFhdEJ0a2o5NzJBPT0sdHlwZTpzdHJdCiAgICBIVExNRW5jb2RpbmdUZXN0MzogRU5DW0FFUzI1Nl9HQ00sZGF0YTovdz09LGl2Oi80ZVNWdEZRN2NHb05JN1VPTXc4bHkwK2FpWDdXaXZVNGloTWxWS1VENWs9LHRhZzpjTFNPOENSMElNK1k1TFpmZE00M0JRPT0sdHlwZTpzdHJdCiAgICAibnVsbCI6IG51bGwKICAgIGJvb2xlYW46IEVOQ1tBRVMyNTZfR0NNLGRhdGE6RDFpYVVBPT0saXY6U3VyVUFCaHFNK1VZaUNaYUVtanlHS1phaTJqREpMM25uWko0MXRNTkhCUT0sdGFnOmdld0ZsY2NVZGIzSXlYN2tQK1NQM3c9PSx0eXBlOmJvb2xdCiAgICBudW1iZXIxOiBFTkNbQUVTMjU2X0dDTSxkYXRhOk1jQk0saXY6VmpZRXBkVmdMc2pYR20yVlJEOUx1MEJYeU9NRmprVU1RSWp2dVZvZDVjcz0sdGFnOjdFZm5LMHFjSVRSZzFPYnJpdTdFZ2c9PSx0eXBlOmludF0KICAgIG51bWJlcjI6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6d0xjdTBYanlKZz09LGl2OnRaVC9BTVlNVG9aaTVudW82alV4d0IwMUhQWDRIaEhwZHQ2djd1elo5U0U9LHRhZzpmZ0s0R2ZpNVlCQTFMdXBKQlgyc0JBPT0sdHlwZTpmbG9hdF0Kc29wczoKICAgIGttczogW10KICAgIGdjcF9rbXM6IFtdCiAgICBhenVyZV9rdjogW10KICAgIGhjX3ZhdWx0OiBbXQogICAgYWdlOgogICAgICAgIC0gcmVjaXBpZW50OiBhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dQogICAgICAgICAgZW5jOiB8CiAgICAgICAgICAgIC0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS0KICAgICAgICAgICAgWVdkbExXVnVZM0o1Y0hScGIyNHViM0puTDNZeENpMCtJRmd5TlRVeE9TQlljM0Y2WkZZNFJGbGxiU3RwTXpFegogICAgICAgICAgICBXbXh1TnpkdU15dGpSa2gxWTI0eE1VTm9WbmRDWVVOaGFHdEpDakp3WjFBelpsQlZjVmQ2WTJORmJHUjRNbVZGCiAgICAgICAgICAgIGJXOU9XV2gyYm1SamFGUnJPRm95ZVdWV2JuSlRlV01LTFMwdElFeHlWRE5GUlhwRlRFcFJNell2V0cxUGFXTnoKICAgICAgICAgICAgVFc5NmQwdHFhakJMYzAxcGFWbEVaSEZYUjFGMmJYY0tMSUpnN3lUbTB1Q2lpUGlLc25zQXlSTS9hRFovZk52dwogICAgICAgICAgICBpaWxLVEI1d1AxcWRzN1N0Y1ZMSjE4UkdVbzl2dUFBOWlQME5aQ1A2a0tMVmdaYmNKL2FTZHc9PQogICAgICAgICAgICAtLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLQogICAgbGFzdG1vZGlmaWVkOiAiMjAyNS0wMi0wN1QxNDo0NzowOVoiCiAgICBtYWM6IEVOQ1tBRVMyNTZfR0NNLGRhdGE6U3gyRDZTRitwUUhRK291eDdsTmV4c2hQb2RjZ2UzdzJnNml4TFRqSy9Oa0VneUJNbWdzVnlCR1dNbCtrU2s2UFk1OEhUNEFRcHlCdHVpVUtqM2pTSjRwWm1lcGdXSUFkeEtwQjNzbHF5MzhnZ2hZUDIvQUhTYkhZUnpoTFFJT3h4RE8waW5Vd3JvSGExM0h0dEpDekRmWEtOaUtyYk1SQVFLaytGV0Y2eDN3PSxpdjo3c0JqU2hWV3JXMTc3d1pCdityeFc2ZXFLMFZRY2pqR1dWdEh3OWRiR1RZPSx0YWc6Qm8zb1lGZ2JBVGJOVndEdFAyUkFhdz09LHR5cGU6c3RyXQogICAgcGdwOiBbXQogICAgdW5lbmNyeXB0ZWRfc3VmZml4OiBfdW5lbmNyeXB0ZWQKICAgIHZlcnNpb246IDMuOS40Cg==", + "Hash": "9912a0ccf8001b767579817f902a5d7e030019cc7b6db34c028f4a0f9079fddf" }, "FlattenSeparator": ".", - "Format": "json", - "ResourceType": "SECRET_BINARY", + "Format": "yaml", + "ResourceType": "SECRET", "Target": { - "Ref": "Json2Raw339EA21E" + "Ref": "Yaml2Json4AC73F66" } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, - "Yaml2RawEB5BB054": { + "Yaml2RawStringBB57E2A1": { "Type": "AWS::SecretsManager::Secret", "Properties": { "GenerateSecretString": {}, - "Name": "Yaml2Raw" + "Name": "Yaml2RawString" }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, - "Yaml2RawSopsSyncD824DA28": { + "Yaml2RawStringSopsSyncCD57EBFA": { "Type": "Custom::SopsSync", "Properties": { "ServiceToken": { @@ -266,9 +276,9 @@ }, "FlattenSeparator": ".", "Format": "yaml", - "ResourceType": "SECRET_BINARY", + "ResourceType": "SECRET_RAW", "Target": { - "Ref": "Yaml2RawEB5BB054" + "Ref": "Yaml2RawStringBB57E2A1" } }, "UpdateReplacePolicy": "Delete", @@ -306,16 +316,16 @@ "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, - "DotEnv2RawF7654593": { + "DotEnv2RawString8AFC290F": { "Type": "AWS::SecretsManager::Secret", "Properties": { "GenerateSecretString": {}, - "Name": "DotEnv2Raw" + "Name": "DotEnv2RawString" }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, - "DotEnv2RawSopsSync731ED9C1": { + "DotEnv2RawStringSopsSyncC5213FA3": { "Type": "Custom::SopsSync", "Properties": { "ServiceToken": { @@ -330,24 +340,24 @@ }, "FlattenSeparator": ".", "Format": "binary", - "ResourceType": "SECRET_BINARY", + "ResourceType": "SECRET_RAW", "Target": { - "Ref": "DotEnv2RawF7654593" + "Ref": "DotEnv2RawString8AFC290F" } }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, - "Binary2RawA83E0B31": { + "Binary2RawString41D1BBEA": { "Type": "AWS::SecretsManager::Secret", "Properties": { "GenerateSecretString": {}, - "Name": "Binary2Raw" + "Name": "Binary2RawString" }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" }, - "Binary2RawSopsSyncD810F28A": { + "Binary2RawStringSopsSyncB4561EC6": { "Type": "Custom::SopsSync", "Properties": { "ServiceToken": { @@ -362,9 +372,41 @@ }, "FlattenSeparator": ".", "Format": "binary", + "ResourceType": "SECRET_RAW", + "Target": { + "Ref": "Binary2RawString41D1BBEA" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Binary2RawBinary9379AA24": { + "Type": "AWS::SecretsManager::Secret", + "Properties": { + "GenerateSecretString": {}, + "Name": "Binary2RawBinary" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Binary2RawBinarySopsSyncBB670AFE": { + "Type": "Custom::SopsSync", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonLambdaSopsSyncProviderAA18D140", + "Arn" + ] + }, + "SopsInline": { + "Content": "ewoJImRhdGEiOiAiRU5DW0FFUzI1Nl9HQ00sZGF0YTpFampUdzk3NnNURXBlU3ZBMGNNWUY0VnJ1SkZMUnBpNEhmazMrZUViNmk1NDVRT3lIVUVra25ucmpzcjNETjFScHZ5cHBiQW1WcTMzV0huQjNGTDlDS3VYZk5jOWswaGhUaldGQWdHallWWnFMelJaSkl5amJLRmt4WVZkcEZqYkN4azZMNWhJSTFkL1NSaDYxL1dtS2t0RVoxOGVCTmY4OGY1RTVXcnpuUE9qSmZxNFp0bzUwa2tPY25uNnpMN1UvTHVXaDZpcWI5WmZuYzJhUXBTWDVKUE1oYzZ3VnA4eE9NRmZCVDJuMGJPZVVIVk1aemYwL2ppTlRjS1VSeStFTnlxaWJjOHpFdEFHcUZIVkdzSy91QzNZc0UwekdudHIzVG40MGdjQWtmbWV3ejhZRVUyWXJuT0ErS0pnSG9CQTZoakxkQ3NqQWRZZFE1a1FSTDJpWktBMUFLM1Rvc0tHd2pJUWZTL2tPaTJ4WTVRNDN0TnVFa1B1VGp2WTR1Z0VldVhHWHhmUVJ6OFJ5b1JzS0lrK3hiUDZQdjZTb1l2TTV0V0d3ZDVwemIwTkRYSng3b0pwaWxYNDBZRkZkRmVncVlhOWdmT2hTUT09LGl2OnZMcEcyeDFlSitIVWovVkF5RW5UelFZa3UrVHU3RStFYTJxbllNTUp5MDA9LHRhZzo0MVdERnNnUEM3QUVKenk0OWtPd0dRPT0sdHlwZTpzdHJdIiwKCSJzb3BzIjogewoJCSJrbXMiOiBudWxsLAoJCSJnY3Bfa21zIjogbnVsbCwKCQkiYXp1cmVfa3YiOiBudWxsLAoJCSJoY192YXVsdCI6IG51bGwsCgkJImFnZSI6IFsKCQkJewoJCQkJInJlY2lwaWVudCI6ICJhZ2UxZGpsbHcycHp1cHJycWMwZW41bTh2YzhrNWdlM3RtMGY2ZzdjajBjMGdsZnpwNDR2ZGM0cWw4bmd2dSIsCgkJCQkiZW5jIjogIi0tLS0tQkVHSU4gQUdFIEVOQ1JZUFRFRCBGSUxFLS0tLS1cbllXZGxMV1Z1WTNKNWNIUnBiMjR1YjNKbkwzWXhDaTArSUZneU5UVXhPU0J2Y1VwV2EwSXZRamM0WmsxamFYRXpcblZGRjFUVVJVU2tkeGRrcDZRVXBLU1drckwyMXBXR1pqYWpKWkNsVmFPR0pUZDBGT01VNXlhblJNT0hKNVJFZFNcblMwUm9PQzlQY1VFeVdtWjVORVJxUkZsMFVqaHlSRVVLTFMwdElHSnJjM2xJTlZGc1pETlNValpqUzJsd2RucFZcbmJYRnpkMWd2U25WVUt6WlRjSEppZW1OUlRFRXdPVUVLWitMOVZaYnJGT3cxcVdqVUZYOVlDT2F3Ui9XcVBYRXBcbjE2N0gyWWFlZFc3SmZnRVg2TFpOd3JjY01RRUV6S1MxYW9ncnFkTTB4cnE4Z3k5d21sUmYwZz09XG4tLS0tLUVORCBBR0UgRU5DUllQVEVEIEZJTEUtLS0tLVxuIgoJCQl9CgkJXSwKCQkibGFzdG1vZGlmaWVkIjogIjIwMjUtMDItMTBUMDk6NTY6MDJaIiwKCQkibWFjIjogIkVOQ1tBRVMyNTZfR0NNLGRhdGE6Y3RGNHlWdHF3VW9vNjlwcWd1RE01MXBUZUQxditvRjV2amh4eWdJdVdHbFhsbE0rZVRuaHR2MUtNZjZiWHF2ZUVjSGhiSTdlTm1xYk9JMlRzK3YrMWEzVGVrajMyeWswWWp5UTlZR3hxZGtKbzhIVzYvSjRyd21vYmU4RUZ1akFNczdLN3ZUMEJPRkIvS09XYmsxRGUzVldsTEM3UjNGUnNWRkdWMGhjeUd3PSxpdjpBL3NWSmM0K2JtV1Z6UlQ3a0hnUm4vemJ3SmZIZUNzblh0OVZoSDQrQXdFPSx0YWc6ZVhXSktUb0pETVVZZy9XTGVNTGZ2Zz09LHR5cGU6c3RyXSIsCgkJInBncCI6IG51bGwsCgkJImVuY3J5cHRlZF9yZWdleCI6ICJeKGRhdGF8c3RyaW5nRGF0YSkkIiwKCQkidmVyc2lvbiI6ICIzLjkuMSIKCX0KfQ==", + "Hash": "28384fe2a27b34268efc6eef99b23999a6cd1bfc84a10937fc592f39c4e93b28" + }, + "FlattenSeparator": ".", + "Format": "binary", "ResourceType": "SECRET_BINARY", "Target": { - "Ref": "Binary2RawA83E0B31" + "Ref": "Binary2RawBinary9379AA24" } }, "UpdateReplacePolicy": "Delete", diff --git a/test/SECRET.integ.ts b/test/SECRET.integ.ts index 19107e61..cf16a22c 100644 --- a/test/SECRET.integ.ts +++ b/test/SECRET.integ.ts @@ -1,5 +1,5 @@ import * as cdk from 'aws-cdk-lib'; -import { SopsSecret } from '../src/index'; +import { RawOutput, SopsSecret } from '../src/index'; const app = new cdk.App(); const stack = new cdk.Stack(app, 'SECRET'); @@ -17,22 +17,22 @@ const tc = [ additionalProperties: {}, }, { - name: 'Yaml2Json', - sopsFilePath: 'test-secrets/testsecret.sops.yaml', - additionalProperties: {}, - }, - { - name: 'Json2Raw', + name: 'Json2RawString', sopsFilePath: 'test-secrets/testsecret.sops.json', additionalProperties: { - rawOutput: true, + rawOutput: RawOutput.STRING, }, }, { - name: 'Yaml2Raw', + name: 'Yaml2Json', + sopsFilePath: 'test-secrets/testsecret.sops.yaml', + additionalProperties: {}, + }, + { + name: 'Yaml2RawString', sopsFilePath: 'test-secrets/testsecret.sops.yaml', additionalProperties: { - rawOutput: true, + rawOutput: RawOutput.STRING, }, }, { @@ -41,17 +41,24 @@ const tc = [ additionalProperties: {}, }, { - name: 'DotEnv2Raw', + name: 'DotEnv2RawString', sopsFilePath: 'test-secrets/README.sops.binary', additionalProperties: { - rawOutput: true, + rawOutput: RawOutput.STRING, }, }, { - name: 'Binary2Raw', + name: 'Binary2RawString', sopsFilePath: 'test-secrets/README.sops.binary', additionalProperties: { - rawOutput: true, + rawOutput: RawOutput.STRING, + }, + }, + { + name: 'Binary2RawBinary', + sopsFilePath: 'test-secrets/README.gz.sops.binary', + additionalProperties: { + rawOutput: RawOutput.BINARY, }, }, ] satisfies TestCase[]; diff --git a/test/secret.test.ts b/test/secret.test.ts index b2436119..f70308a0 100644 --- a/test/secret.test.ts +++ b/test/secret.test.ts @@ -14,6 +14,7 @@ import { SopsSyncProvider, UploadType, MultiStringParameter, + RawOutput, } from '../src'; const keyStatements = [ @@ -32,7 +33,7 @@ test('Upload type ASSET', () => { new SopsSecret(stack, 'SopsSecret', { sopsFilePath: 'test-secrets/yaml/sopsfile.enc-kms.yaml', uploadType: UploadType.ASSET, - rawOutput: true, + rawOutput: RawOutput.STRING, }); Template.fromStack(stack).hasResource('Custom::SopsSync', { Properties: Match.objectLike({ From 7c2442d261a79a0ebff3260f7f1993d9176bd686 Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 10 Feb 2025 10:56:45 +0000 Subject: [PATCH 05/12] chore: self mutation Signed-off-by: github-actions --- .projenrc.js | 6 +-- API.md | 54 +++++++++++++++++-- .../PARAMETER.assets.json | 10 ++-- .../PARAMETER.template.json | 2 +- .../PARAMETERMULTI.assets.json | 10 ++-- .../PARAMETERMULTI.template.json | 2 +- test/SECRET.integ.snapshot/SECRET.assets.json | 10 ++-- .../SECRET.template.json | 2 +- test/SECRET.integ.ts | 2 +- 9 files changed, 70 insertions(+), 28 deletions(-) diff --git a/.projenrc.js b/.projenrc.js index 22dd80ce..d0cc8fb9 100644 --- a/.projenrc.js +++ b/.projenrc.js @@ -108,11 +108,7 @@ additionalActions = [ ]; project.buildWorkflow.preBuildSteps.unshift(...additionalActions); -[ - "PARAMETER", - "PARAMETER_MULTI", - "SECRET" -].forEach((type) => { +['PARAMETER', 'PARAMETER_MULTI', 'SECRET'].forEach((type) => { project.buildWorkflow.preBuildSteps.push({ name: `Update snapshots: ${type}`, run: `yarn run projen integ:${type}:snapshot`, diff --git a/API.md b/API.md index d87ccb1f..37c5dc7c 100644 --- a/API.md +++ b/API.md @@ -1989,6 +1989,7 @@ const sopsCommonParameterProps: SopsCommonParameterProps = { ... } | **Name** | **Type** | **Description** | | --- | --- | --- | +| assetEncryptionKey | aws-cdk-lib.aws_kms.IKey | The encryption key used by the CDK default Asset S3 Bucket. | | autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | | sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | | sopsFileFormat | string | The format of the sops file. | @@ -2004,6 +2005,19 @@ const sopsCommonParameterProps: SopsCommonParameterProps = { ... } --- +##### `assetEncryptionKey`Optional + +```typescript +public readonly assetEncryptionKey: IKey; +``` + +- *Type:* aws-cdk-lib.aws_kms.IKey +- *Default:* Trying to get the key using the CDK Bootstrap context. + +The encryption key used by the CDK default Asset S3 Bucket. + +--- + ##### `autoGenerateIamPermissions`Optional ```typescript @@ -2178,6 +2192,7 @@ const sopsSecretProps: SopsSecretProps = { ... } | **Name** | **Type** | **Description** | | --- | --- | --- | +| assetEncryptionKey | aws-cdk-lib.aws_kms.IKey | The encryption key used by the CDK default Asset S3 Bucket. | | autoGenerateIamPermissions | boolean | Should this construct automatically create IAM permissions? | | sopsAgeKey | aws-cdk-lib.SecretValue | The age key that should be used for encryption. | | sopsFileFormat | string | The format of the sops file. | @@ -2189,7 +2204,7 @@ const sopsSecretProps: SopsSecretProps = { ... } | uploadType | UploadType | How should the secret be passed to the CustomResource? | | description | string | An optional, human-friendly description of the secret. | | encryptionKey | aws-cdk-lib.aws_kms.IKey | The customer-managed encryption key to use for encrypting the secret value. | -| rawOutput | boolean | Should the secret parsed and transformed to json? | +| rawOutput | RawOutput | Should the secret parsed and transformed to json? | | removalPolicy | aws-cdk-lib.RemovalPolicy | Policy to apply when the secret is removed from this stack. | | replicaRegions | aws-cdk-lib.aws_secretsmanager.ReplicaRegion[] | A list of regions where to replicate this secret. | | secretName | string | A name for the secret. | @@ -2357,11 +2372,11 @@ The customer-managed encryption key to use for encrypting the secret value. ##### `rawOutput`Optional ```typescript -public readonly rawOutput: boolean; +public readonly rawOutput: RawOutput; ``` -- *Type:* boolean -- *Default:* true +- *Type:* RawOutput +- *Default:* undefined - no raw output Should the secret parsed and transformed to json? @@ -3106,6 +3121,31 @@ Where to place the network interfaces within the VPC. ## Enums +### RawOutput + +#### Members + +| **Name** | **Description** | +| --- | --- | +| STRING | Parse the secret as a string. | +| BINARY | Parse the secret as a binary. | + +--- + +##### `STRING` + +Parse the secret as a string. + +--- + + +##### `BINARY` + +Parse the secret as a binary. + +--- + + ### ResourceType #### Members @@ -3113,6 +3153,7 @@ Where to place the network interfaces within the VPC. | **Name** | **Description** | | --- | --- | | SECRET | *No description.* | +| SECRET_RAW | *No description.* | | SECRET_BINARY | *No description.* | | PARAMETER | *No description.* | | PARAMETER_MULTI | *No description.* | @@ -3124,6 +3165,11 @@ Where to place the network interfaces within the VPC. --- +##### `SECRET_RAW` + +--- + + ##### `SECRET_BINARY` --- diff --git a/test/PARAMETER.integ.snapshot/PARAMETER.assets.json b/test/PARAMETER.integ.snapshot/PARAMETER.assets.json index bb4ed192..22e07088 100644 --- a/test/PARAMETER.integ.snapshot/PARAMETER.assets.json +++ b/test/PARAMETER.integ.snapshot/PARAMETER.assets.json @@ -1,20 +1,20 @@ { "version": "39.0.0", "files": { - "0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4": { + "d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b": { "source": { - "path": "asset.0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4.zip", + "path": "asset.d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b.zip", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4.zip", + "objectKey": "d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "403cce8728059a0118bee399fa4dde8431a7c63198d8e1511788fe25ea4485f7": { + "6d3ff032ea46c79e4194c7129b6a118711a3c78f26a3ae56ac8bc9d9f06dbf45": { "source": { "path": "PARAMETER.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "403cce8728059a0118bee399fa4dde8431a7c63198d8e1511788fe25ea4485f7.json", + "objectKey": "6d3ff032ea46c79e4194c7129b6a118711a3c78f26a3ae56ac8bc9d9f06dbf45.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/test/PARAMETER.integ.snapshot/PARAMETER.template.json b/test/PARAMETER.integ.snapshot/PARAMETER.template.json index b27937ad..0e6ec1e8 100644 --- a/test/PARAMETER.integ.snapshot/PARAMETER.template.json +++ b/test/PARAMETER.integ.snapshot/PARAMETER.template.json @@ -139,7 +139,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4.zip" + "S3Key": "d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b.zip" }, "Environment": { "Variables": { diff --git a/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.assets.json b/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.assets.json index 8df8831a..c85bb0b1 100644 --- a/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.assets.json +++ b/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.assets.json @@ -1,20 +1,20 @@ { "version": "39.0.0", "files": { - "0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4": { + "d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b": { "source": { - "path": "asset.0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4.zip", + "path": "asset.d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b.zip", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4.zip", + "objectKey": "d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "a0ce4cda9ec46f3872ef0376abd93e9b845ab0e0abbf33fac6b0ce69bce1fefc": { + "18475bdb75dca2e0a74ecf3f0d5eade0e56714f6fe9f2f9b7a82fc039a3d78e9": { "source": { "path": "PARAMETERMULTI.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "a0ce4cda9ec46f3872ef0376abd93e9b845ab0e0abbf33fac6b0ce69bce1fefc.json", + "objectKey": "18475bdb75dca2e0a74ecf3f0d5eade0e56714f6fe9f2f9b7a82fc039a3d78e9.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.template.json b/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.template.json index 5496671e..808a43d9 100644 --- a/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.template.json +++ b/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.template.json @@ -535,7 +535,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4.zip" + "S3Key": "d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b.zip" }, "Environment": { "Variables": { diff --git a/test/SECRET.integ.snapshot/SECRET.assets.json b/test/SECRET.integ.snapshot/SECRET.assets.json index 0d2fd4b3..9b9cbc46 100644 --- a/test/SECRET.integ.snapshot/SECRET.assets.json +++ b/test/SECRET.integ.snapshot/SECRET.assets.json @@ -1,20 +1,20 @@ { "version": "39.0.0", "files": { - "0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4": { + "d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b": { "source": { - "path": "asset.0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4.zip", + "path": "asset.d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b.zip", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4.zip", + "objectKey": "d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "7f4a277181a414a4b3627b80eb422237183e8ccd700dd2192456e33f294b39b1": { + "1cf7fc474a32e929a12b22aefdcec2d75b10693f006179d6fdc4d545b02d8638": { "source": { "path": "SECRET.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "7f4a277181a414a4b3627b80eb422237183e8ccd700dd2192456e33f294b39b1.json", + "objectKey": "1cf7fc474a32e929a12b22aefdcec2d75b10693f006179d6fdc4d545b02d8638.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/test/SECRET.integ.snapshot/SECRET.template.json b/test/SECRET.integ.snapshot/SECRET.template.json index 49338f64..732c349d 100644 --- a/test/SECRET.integ.snapshot/SECRET.template.json +++ b/test/SECRET.integ.snapshot/SECRET.template.json @@ -166,7 +166,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "0e1a1f98d5c93338441170dac2f234d1f4107d939c990da1d5faaca7e12781f4.zip" + "S3Key": "d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b.zip" }, "Environment": { "Variables": { diff --git a/test/SECRET.integ.ts b/test/SECRET.integ.ts index cf16a22c..562550df 100644 --- a/test/SECRET.integ.ts +++ b/test/SECRET.integ.ts @@ -27,7 +27,7 @@ const tc = [ name: 'Yaml2Json', sopsFilePath: 'test-secrets/testsecret.sops.yaml', additionalProperties: {}, - }, + }, { name: 'Yaml2RawString', sopsFilePath: 'test-secrets/testsecret.sops.yaml', From 186b427e7f1ab072357738f775f0137496912731 Mon Sep 17 00:00:00 2001 From: Markus Siebert Date: Mon, 10 Feb 2025 12:04:43 +0100 Subject: [PATCH 06/12] chore: README --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/README.md b/README.md index 5f3c9883..81cc2dd5 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,10 @@ It enables secure storage of secrets in Git repositories while allowing seamless - [UploadType: INLINE / ASSET](#uploadtype-inline--asset) - [Stability](#stability) - [FAQ](#faq) + - [How can I migrate to V2](#how-can-i-migrate-to-v2) + - [SecretsManager](#secretsmanager) + - [Parameter](#parameter) + - [MultiParameter](#multiparameter) - [It does not work, what can I do?](#it-does-not-work-what-can-i-do) - [I get errors with `dotenv` formatted files](#i-get-errors-with-dotenv-formatted-files) - [Error: Error getting data key: 0 successful groups required, got 0](#error-error-getting-data-key-0-successful-groups-required-got-0) @@ -300,6 +304,25 @@ Nevertheless, I would recommend pinning the exact version of this library in you # FAQ +## How can I migrate to V2 + +It was required to change some user facing configuration properties. So minor changes are required to make things work again. + +### SecretsManager +- Removed property convertToJSON, flatten, stringifiedValues +- Use property rawOutput instaed: + - `undefined / not set` => (default) convertToJSON and flatten and stringifiedValues = true + - `RawOutput.STRING` => convertToJSON and flatten and stringifiedValues = false + - `RawOutput.BINARY` => convertToJSON and flatten and stringifiedValues = false and Secret is binary + +### Parameter +- Removed property convertToJSON, flatten, stringifiedValues => all of them made no sense - now only raw output of decrypted secret + +### MultiParameter +- Removed property convertToJSON, flatten, stringifiedValues => most of this combinations made no sense +- Allways convertToJson and flatten (as we have to parse it to create multiple parameters) +- You are allowed to chose the flattenSeperator + ## It does not work, what can I do? Even if this construct has some unit and integration tests performed, there can be bugs and issues. As everything is performed by a cloudformation custom resource provider, a good starting point is the log of the corresponding lambda function. It should be located in your AWS Account under Cloudwatch -> Log groups: From 8b348cf69cae143d75ec756e07b5b2e3f96ba993 Mon Sep 17 00:00:00 2001 From: Markus Siebert Date: Mon, 10 Feb 2025 13:28:55 +0100 Subject: [PATCH 07/12] chore: README --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 81cc2dd5..7b5574d1 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,6 @@ [![npm downloads](https://img.shields.io/npm/dw/cdk-sops-secrets)](https://www.npmjs.com/package/cdk-sops-secrets) [![pypi](https://img.shields.io/pypi/v/cdk-sops-secrets.svg)](https://pypi.org/project/cdk-sops-secrets) [![pypi downloads](https://img.shields.io/pypi/dw/cdk-sops-secrets)](https://pypi.org/project/cdk-sops-secrets) -![GitHub Downloads (all assets, latest release)](https://img.shields.io/github/:variant/:user/:repo/latest/total) [![codecov](https://codecov.io/gh/dbsystel/cdk-sops-secrets/branch/main/graph/badge.svg?token=OT7P7HQHXB)](https://codecov.io/gh/dbsystel/cdk-sops-secrets) [![security-vulnerabilities](https://img.shields.io/github/issues-search/dbsystel/cdk-sops-secrets?color=%23ff0000&label=security-vulnerabilities&query=is%3Aissue%20is%3Aopen%20label%3A%22Mend%3A%20dependency%20security%20vulnerability%22)](https://github.com/dbsystel/cdk-sops-secrets/issues?q=is%3Aissue+is%3Aopen+label%3A%22security+vulnerability%22) From 2d60cfc2fa73bb3352769794eebec2cf8e0eb544 Mon Sep 17 00:00:00 2001 From: Markus Siebert Date: Mon, 10 Feb 2025 13:31:44 +0100 Subject: [PATCH 08/12] chore: fix go version --- .go-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.go-version b/.go-version index 89144dbc..ca8ec414 100644 --- a/.go-version +++ b/.go-version @@ -1 +1 @@ -1.22.3 +1.23.5 From 9c1a62f71b52bd12c2d28903e8b2d6b972f94548 Mon Sep 17 00:00:00 2001 From: lennartrommeiss Date: Mon, 10 Feb 2025 15:58:27 +0100 Subject: [PATCH 09/12] fix: add some comments, readme content and minor fixes Signed-off-by: lennartrommeiss --- .gitignore | 1 + MAINTAINERS.md | 4 +- README.md | 74 +++++++++++++++++++++------------- lambda/handle.go | 9 ++++- lambda/internal/data/data.go | 8 ++++ lambda/internal/event/event.go | 7 ++++ lambda/internal/sops/sops.go | 13 ++++++ lambda/main.go | 8 ++-- 8 files changed, 89 insertions(+), 35 deletions(-) diff --git a/.gitignore b/.gitignore index dd804af9..9314c3a8 100644 --- a/.gitignore +++ b/.gitignore @@ -81,3 +81,4 @@ test/SECRET.integ.snapshot/**/tree.json .idea /assets !/.projenrc.js +*.DS_Store diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 9f56d9f0..557c8d7a 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -1,7 +1,7 @@ This page lists all active maintainers of this repository in alphabetical order. +[dariozachow](https://github.com/dariozachow) [henrysachs](https://github.com/henrysachs) +[lennartrommeiss](https://github.com/lenderom) [markussiebert](https://github.com/markussiebert) [thomaskrause](https://github.com/obirah) -[lennartrommeiss](https://github.com/lenderom) -[dariozachow](https://github.com/dariozachow) \ No newline at end of file diff --git a/README.md b/README.md index 7b5574d1..365ea92b 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,16 @@ # Introduction -This construct library offers CDK Constructs that facilitate syncing SOPS-encrypted secrets to AWS Secrets Manager and SSM Parameter Store. -It enables secure storage of secrets in Git repositories while allowing seamless synchronization and usage within AWS. +_Create secret values in AWS with infrastructure-as-code easily_ + +This construct library offers CDK Constructs that facilitate syncing [SOPS-encrypted secrets](https://github.com/getsops/sops) to AWS Secrets Manager and SSM Parameter Store. +It enables secure storage of secrets in Git repositories while allowing seamless synchronization and usage within AWS. Even large sets of SSM Parameters can be created quickly from a single file. + +- Create AWS Secrets Manager secrets +- Create single SSM Parameter +- Create multiple SSM Parameter in a batch from a file +- Use SOPS json, yaml or dotenv as input files, as well as binary data +- No need for manual permission setups for the Custom Ressource due to automatic least-privilege generation for the SyncProvider # Table Of Contents @@ -57,8 +65,8 @@ Let's assume we want to store the following secret information in AWS: "host": "db.example.com" }, "tokens": [ - {"service": "github", "token": "ghp_abcd1234"}, - {"service": "aws", "token": "AKIAIOSFODNN7EXAMPLE"} + { "service": "github", "token": "ghp_abcd1234" }, + { "service": "aws", "token": "AKIAIOSFODNN7EXAMPLE" } ], "someOtherKey": "base64:VGhpcyBpcyBhIHNlY3JldCBrZXk=" } @@ -75,8 +83,8 @@ Minimal Example: ```ts const secret = new SopsSecret(stack, 'MySopsSecret', { - secertName: 'mySecret', // name of the secret in AWS SecretsManager - sopsFilePath: 'secrets/sopsfile-encrypted-secret.json', // filepath to the sops encrypted file + secertName: 'mySecret', // name of the secret in AWS SecretsManager + sopsFilePath: 'secrets/sopsfile-encrypted-secret.json', // filepath to the sops encrypted file }); ``` @@ -85,7 +93,7 @@ For convenience, several transformations apply: - Nested structures and arrays will be resolved and flattened to a JSONPath notation - All values will be stored as strings - + This is done also because of limitations of CDK in conjunction with [dynamic references](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references-secretsmanager.html) and limitiations of the `Key/Value` view of the AWS SecretsManager WebConsole. So the result, saved in the AWS SecretsManager will actually be: @@ -108,7 +116,7 @@ This allows you to access the values from your secret via CDK: ```ts secret.secretValueFromJson('"database.password"').toString(), -secret.secretValueFromJson('"tokens[0].token"').toString() + secret.secretValueFromJson('"tokens[0].token"').toString(); ``` If you don't want these conversions, you can completely disable them by using the `rawOutput` property. @@ -119,6 +127,7 @@ const secret = new SopsSecret(stack, 'MySopsSecret', { ... }); ``` + This will turn off the conversions and just place the decrypted content in the target secret. It's also possible to use `RawOutput.BINARY` than the AWS SecretsManager Secret will be populted with binary, instead of string data. @@ -146,8 +155,8 @@ const multi = new MultiStringParameter(stack, 'MyMultiParameter', { encryptionKey: Key.fromLookup(stack, 'DefaultKey', { aliasName: 'alias/aws/ssm', }), - sopsFilePath: 'secrets/sopsfile-encrypted-secret.json' -}) + sopsFilePath: 'secrets/sopsfile-encrypted-secret.json', +}); ``` This will create several AWS SSM ParameterStore Parameters: @@ -206,15 +215,15 @@ const provider = new SopsSyncProvider(this, 'MySopsSyncProvider', { customSubnet1, // access to any VPC resources. customSubnet2, // But if you want, ] // you can change this behaviour - }, // and set vpc, subnet and + }, // and set vpc, subnet and securityGroups: [ // securitygroups to your customSecurityGroup // needs. - ], + ], }); provider.addToRolePolicy( // You cann pass PolicyStatements new PolicyStatement({ // via the addToRolePolicy Method - actions: ['...'], // + actions: ['...'], // resources: ['...'], // }) // ); // @@ -258,19 +267,19 @@ const construct = new Sops...(this, 'My' { /** * if you don't want this constructs to take care of passing the encrypted * sops file to the sops provider, you can upload them yourself to a - * S3 bucket. + * S3 bucket. * You can pass bucket and key, and the constructs won't pass the content * as ASSET or in the CloudFormation Template. * As the construct isn't aware of the sopsfile, we can't derive the required * permissions to decrypt the sops file. The same applies to the sopsFileFormat. * You have to pass them all manually. - */ + */ sopsS3Bucket: 'my-custom-bucket', sopsS3Key: 'encoded-sops.json', sopsKmsKey: [ kmsKeyUsedForEncryption, ] - sopsFileFormat: 'json', // Allowed values are json, yaml, dotenv and binary + sopsFileFormat: 'json', // Allowed values are json, yaml, dotenv and binary }) ``` @@ -282,7 +291,7 @@ const construct = new Sops...(this, 'My' { I decided, that the default behavior should be "INLINE" because of the following consideration: - Fewer permissions - + _If we use inline content instead of a S3 asset, the SopsSyncProvider does not need permissions to access the asset bucket and its KMS key._ - Faster @@ -308,16 +317,19 @@ Nevertheless, I would recommend pinning the exact version of this library in you It was required to change some user facing configuration properties. So minor changes are required to make things work again. ### SecretsManager -- Removed property convertToJSON, flatten, stringifiedValues + +- Removed property convertToJSON, flatten, stringifiedValues - Use property rawOutput instaed: - `undefined / not set` => (default) convertToJSON and flatten and stringifiedValues = true - `RawOutput.STRING` => convertToJSON and flatten and stringifiedValues = false - `RawOutput.BINARY` => convertToJSON and flatten and stringifiedValues = false and Secret is binary ### Parameter + - Removed property convertToJSON, flatten, stringifiedValues => all of them made no sense - now only raw output of decrypted secret ### MultiParameter + - Removed property convertToJSON, flatten, stringifiedValues => most of this combinations made no sense - Allways convertToJson and flatten (as we have to parse it to create multiple parameters) - You are allowed to chose the flattenSeperator @@ -326,7 +338,7 @@ It was required to change some user facing configuration properties. So minor ch Even if this construct has some unit and integration tests performed, there can be bugs and issues. As everything is performed by a cloudformation custom resource provider, a good starting point is the log of the corresponding lambda function. It should be located in your AWS Account under Cloudwatch -> Log groups: -```/aws/lambda/-SingletonLambdaSopsSyncProvider``` +`/aws/lambda/-SingletonLambdaSopsSyncProvider` ## I get errors with `dotenv` formatted files @@ -340,15 +352,15 @@ comments must be a single line, not after value assignments. ## Error: Error getting data key: 0 successful groups required, got 0 -This error message (and failed sync) is related to the getsops/sops issues [#948](https://github.com/getsops/sops/issues/948) and [#634](https://github.com/getsops/sops/issues/634). You must not create your secret with the ```--aws-profile``` flag. This profile will be written to your sops filed and is required in every runtime environment. You have to define the profile to use via the environment variable ```AWS_PROFILE``` instead, to avoid this. +This error message (and failed sync) is related to the getsops/sops issues [#948](https://github.com/getsops/sops/issues/948) and [#634](https://github.com/getsops/sops/issues/634). You must not create your secret with the `--aws-profile` flag. This profile will be written to your sops filed and is required in every runtime environment. You have to define the profile to use via the environment variable `AWS_PROFILE` instead, to avoid this. ## Error: Asset of sync lambda not found The lambda asset code is generated relative to the path of the index.ts in this package. With tools like nx this can lead to wrong results, so that the asset could not be found. -You can override the asset path via the [cdk.json](https://docs.aws.amazon.com/cdk/v2/guide/get_context_var.html) or via the flag ```-c```of the cdk cli. +You can override the asset path via the [cdk.json](https://docs.aws.amazon.com/cdk/v2/guide/get_context_var.html) or via the flag `-c`of the cdk cli. -The context used for this override is ```sops_sync_provider_asset_path```. +The context used for this override is `sops_sync_provider_asset_path`. So for example you can use @@ -362,7 +374,7 @@ or in your cdk.json { "context": { "sops_sync_provider_asset_path": "some/path/asset.zip" - } + } } ``` @@ -393,7 +405,7 @@ new SopsSecret(stack, 'SopsSecret', { sopsKmsKey ], sopsFileFormat: 'json', - ... + ... }); ``` @@ -404,13 +416,17 @@ to generate the version information of the AWS SecretsManager secret. Therefore, it is possible to reference the entries from a specific AWS SecretsManager version. ```typescript -const versionId = cdk.FileSystem.fingerprint(`./sops/SomeSecrets.json`) -const passphrase = ecs.Secret.fromSecretsManagerVersion(secretMgmt, { versionId: versionId }, 'MY_PRIVATE_PASSPHRASE') +const versionId = cdk.FileSystem.fingerprint(`./sops/SomeSecrets.json`); +const passphrase = ecs.Secret.fromSecretsManagerVersion( + secretMgmt, + { versionId: versionId }, + 'MY_PRIVATE_PASSPHRASE', +); const container = TaskDef.addContainer('Container', { - secrets: { - MY_PRIVATE_PASSPHRASE: passphrase, - }, + secrets: { + MY_PRIVATE_PASSPHRASE: passphrase, + }, }); ``` diff --git a/lambda/handle.go b/lambda/handle.go index 5ececdb8..8ac23199 100644 --- a/lambda/handle.go +++ b/lambda/handle.go @@ -24,8 +24,11 @@ func handleSecret(props BaseProps) (physicalResourceID string, data map[string]i logger.Info("Handling secret data", "ResourceType", props.properties.ResourceType) var binary *bool + + // Prepare the data depending on the resource type switch props.properties.ResourceType { case event.SECRET: + // The secretsmanager does not support nested json objects, so we have to flatten the data seperator := "." if props.properties.FlattenSeparator != nil { seperator = *props.properties.FlattenSeparator @@ -34,10 +37,14 @@ func handleSecret(props BaseProps) (physicalResourceID string, data map[string]i if err := props.secretDecryptedData.Flatten(seperator); err != nil { return props.properties.GeneratePhysicalResourceId(), nil, err } + + // Make sure the values are strings to avoid issues while storing them in the secrets manager logger.Info("Stringifying secret data", "ResourceType", props.properties.ResourceType) if err := props.secretDecryptedData.StringifyValues(); err != nil { return props.properties.GeneratePhysicalResourceId(), nil, err } + + // Secretsmanager values have to be stored as JSON logger.Info("Converting secret data to JSON", "ResourceType", props.properties.ResourceType) outData, outDataErr = props.secretDecryptedData.ToJSON() binary = ptr.Bool(false) @@ -96,7 +103,7 @@ func handleParameterMulti(props BaseProps) (physicalResourceID string, data map[ } logger.Info("Writing secret data to parameter store") for key, value := range outData { - // Ass we flatten array to [number] path notations, we have to fix this for parameter store + // As we flatten array to [number] path notations, we have to fix this for parameter store fixedKey := strings.ReplaceAll(key, "[", seperator) fixedKey = strings.ReplaceAll(fixedKey, "]", seperator) fixedKey = strings.TrimSuffix(fixedKey, seperator) diff --git a/lambda/internal/data/data.go b/lambda/internal/data/data.go index 41face28..7fef47c0 100644 --- a/lambda/internal/data/data.go +++ b/lambda/internal/data/data.go @@ -20,6 +20,8 @@ var ( ErrorUnparsedData = fmt.Errorf("Data does not contain parsed data") ) +// FromBinary creates a Data object from a binary formatted byte slice. +// It stores the binary content in the raw field of the Data object without parsing it. func FromBinary(in []byte, hash *string) (*Data, error) { return &Data{ raw: &in, @@ -27,6 +29,7 @@ func FromBinary(in []byte, hash *string) (*Data, error) { }, nil } +// Parse from yaml formatted byte slice into a map and stores it in the parsed field of the Data object. func FromYAML(in []byte, hash *string) (*Data, error) { var content any err := yaml.Unmarshal(in, &content) @@ -40,6 +43,7 @@ func FromYAML(in []byte, hash *string) (*Data, error) { }, nil } +// Parse from json formatted byte slice into a map and stores it in the parsed field of the Data object. func FromJSON(in []byte, hash *string) (*Data, error) { var content any err := json.Unmarshal(in, &content) @@ -53,15 +57,19 @@ func FromJSON(in []byte, hash *string) (*Data, error) { }, nil } +// Parse from dotenv formatted byte slice into a map and stores it in the parsed field of the Data object. func FromDotEnv(in []byte, hash *string) (*Data, error) { var dotEnvMap any = map[string]string{} dotenvLines := strings.Split(string(in), "\n") for _, line := range dotenvLines { + // Ignore empty lines and comments if line != "" && !strings.HasPrefix(line, "#") { + // Split the line into key and value parts := strings.SplitN(line, "=", 2) if len(parts) == 2 { key := strings.TrimSpace(parts[0]) value := strings.TrimSpace(parts[1]) + // Add the key-value pair to the map dotEnvMap.(map[string]string)[key] = value } } diff --git a/lambda/internal/event/event.go b/lambda/internal/event/event.go index 0ea72830..a6d1f002 100644 --- a/lambda/internal/event/event.go +++ b/lambda/internal/event/event.go @@ -104,14 +104,17 @@ func (p *SopsSyncResourcePropertys) GeneratePhysicalResourceId() string { } func (p *SopsSyncResourcePropertys) sopsInlineToSopsEncryptedSecret() (*sops.EncryptedSopsSecret, error) { + // Read the encrypted secret content from inline content, contentErr := base64.StdEncoding.DecodeString(p.SopsInline.Content) if contentErr != nil { return nil, contentErr } + // Generate a uniform EncryptedSopsSecret object from the content for later use return sops.CreateEncryptedSopsSecret(content, p.Format, p.SopsInline.Hash) } func (p *SopsSyncResourcePropertys) sopsS3FileToSopsEncryptedSecret(clients client.AwsClient) (*sops.EncryptedSopsSecret, error) { + // Read the encrypted secret content from S3 s3File := client.SopsS3File{ Bucket: p.SopsS3File.Bucket, Key: p.SopsS3File.Key, @@ -121,15 +124,18 @@ func (p *SopsSyncResourcePropertys) sopsS3FileToSopsEncryptedSecret(clients clie return nil, s3ContentErr } + // Get the Hash of the S3 object to compare it later s3Etag, s3EtagErr := clients.S3GetObjectETAG(s3File) if s3EtagErr != nil { return nil, s3EtagErr } + // Generate a uniform EncryptedSopsSecret object from the content for later use return sops.CreateEncryptedSopsSecret(s3Content, p.Format, *s3Etag) } func (p *SopsSyncResourcePropertys) GetEncryptedSopsSecret(client client.AwsClient) (*sops.EncryptedSopsSecret, error) { + // Find out from where to get the secret content if !p.SopsInline.IsEmpty() && !p.SopsS3File.IsEmpty() { return nil, fmt.Errorf("both inline and S3 secret content found") } @@ -142,6 +148,7 @@ func (p *SopsSyncResourcePropertys) GetEncryptedSopsSecret(client client.AwsClie return nil, fmt.Errorf("no secret content found") } +// generates a JSON schema for the SopsSyncResourcePropertys struct func GenerateSchema() { schema := jsonSchemaGen.Reflect(&SopsSyncResourcePropertys{}) diff --git a/lambda/internal/sops/sops.go b/lambda/internal/sops/sops.go index 4246862c..455e2bc2 100644 --- a/lambda/internal/sops/sops.go +++ b/lambda/internal/sops/sops.go @@ -49,28 +49,40 @@ type DecryptedSopsSecret struct { } func (e EncryptedSopsSecret) Decrypt() (*DecryptedSopsSecret, error) { + // Create a logger with context information logger := slog.With("Package", "sops", "Function", "Decrypt") logger.Info("Decrypting content", "Format", e.Format) + + // Decrypt the content using the specified format cleartext, err := decrypt.Data(e.Content, string(e.Format)) if err != nil { return nil, fmt.Errorf("decryption error:\n%v", err) } logger.Info("Decryption successful") + // If the format is JSON, process the cleartext to ensure proper formatting if e.Format == JSON { var jsonObj interface{} var buf bytes.Buffer + + // Unmarshal the JSON content into an interface err := json.Unmarshal(cleartext, &jsonObj) if err != nil { return nil, fmt.Errorf("decoding error:\n%v", err) } + + // Create a JSON encoder with specific settings encoder := json.NewEncoder(&buf) encoder.SetEscapeHTML(false) encoder.SetIndent("", " ") // tab inside + + // Encode the JSON object back into bytes err = encoder.Encode(jsonObj) if err != nil { return nil, fmt.Errorf("encoding error:\n%v", err) } + + // Trim any extra whitespace from the encoded JSON cleartext = bytes.TrimSpace(buf.Bytes()) } @@ -82,6 +94,7 @@ func (e EncryptedSopsSecret) Decrypt() (*DecryptedSopsSecret, error) { } func (d DecryptedSopsSecret) ToData() (*data.Data, error) { + // Generate a data object by parsing the decrypted secret depending on the data input type switch d.format { case JSON: return data.FromJSON(d.content, &d.hash) diff --git a/lambda/main.go b/lambda/main.go index e505e1bf..27db6196 100644 --- a/lambda/main.go +++ b/lambda/main.go @@ -24,25 +24,26 @@ func HandleRequestWithClients(clients client.AwsClient, e cfn.Event) (physicalRe return "", nil, fmt.Errorf("requestType '%s' not supported", e.RequestType) } + // Get the event input from the cloudformation event props, err := event.FromCfnEvent(e) if err != nil { return "", nil, err } + // Get the encrypted secret input provided by the user secretEncrypted, secretEncryptedErr := props.GetEncryptedSopsSecret(clients) - if secretEncryptedErr != nil { return "", nil, secretEncryptedErr } + // Decrypt the secret input with sops secretDecrypted, secretDecryptedErr := secretEncrypted.Decrypt() - if secretDecryptedErr != nil { return "", nil, secretDecryptedErr } + // Generate a data object by parsing the decrypted secret depending on the data input type secretDecryptedData, secretDecryptedDataErr := secretDecrypted.ToData() - if secretDecryptedDataErr != nil { return "", nil, secretDecryptedDataErr } @@ -53,6 +54,7 @@ func HandleRequestWithClients(clients client.AwsClient, e cfn.Event) (physicalRe secretDecryptedData: secretDecryptedData, } + // Fill the secret values in the ressource depending on the ressource type switch props.ResourceType { case event.SECRET, event.SECRET_RAW, event.SECRET_BINARY: return handleSecret(baseProps) From f7411813ca626abec187343214336233597292fe Mon Sep 17 00:00:00 2001 From: Lennart Rommeiss <61516567+lenderom@users.noreply.github.com> Date: Mon, 10 Feb 2025 16:01:30 +0100 Subject: [PATCH 10/12] Delete lambda/internal/.DS_Store --- lambda/internal/.DS_Store | Bin 8196 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 lambda/internal/.DS_Store diff --git a/lambda/internal/.DS_Store b/lambda/internal/.DS_Store deleted file mode 100644 index 411da647dd882e62aa8f9a9ed9a02845a8f44911..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8196 zcmeHMU2GIp6u#edfti8Y+wxa-0&HlcSc+_s77GTpfBXbYk!@)y;5yqGV8V2!?#%9j zgxF|&QT&N7KB)NfYBc(wiA0S)!K>I9dC){ne9=Vo(U|DDb7z~j&<7J@NSK?VwsEOl$6v$1u~SR3`KmzfD9*lCict4a!N`W&JZ6y5ciDugo3DddVVHy zXUIvJ)CmF!0=FU{(kI0%X0ni(v(N9vN!JO&Z1!6yb*V**m#9nBrRvH28NZqj&9EHw znx*4H8}fa(Si3iiM;*Ib;4AukFEky`E=2*3Ws}Q^5y!LqYOi1RtRRZb%LY|bwE|yr z;X+4O_m1{VcW3rud*(v-wrqQ5`$Jt9FKX(_maV&v6wbO6p8tZJ1LF4ptDiTgOS32B z29-YfL87j)Hlgoo6Vmjh#_-V*y}+9)H0r_0(DA+Cs9g$37I;HIvpX>EdxuN5XdfB( z-SUJN6nNvf>5i9OGqihLH}5=U2cw~VE);iTfnN&yBF9mOVuh{1c{#9;*c9MY?0yOh zR?HhTv=5f8T)Sc8=4|KA-F^EG4o=tK*T5T_bbX8<@@?V2`SziM^!nzUgoka*cMPqu@w?r=% z|5&BxQ13144db|I=_}b(TX8_^CPNJv29PzFdi4(9x{V)aMJc@NY~=N`>Aa#IAfOV z!76bpw(ciuv|MBtK?9Z(`cWgHafoJdOgyf~vZ6UOuUcJiJZ9uoeqE)NalDE{e5Mtb zv{qYkZE|rUSX**gscE!7tzi$+KDeKqU^bg%=h-FpCcDhuXP>aI*j4s5yTN{7KeC_L z&+Iq$C;J;I)T03$jYy*v51xA6|%#e2Ad&+s|Ez*StwH<-rv_#HR#2mVr0$|7a4(x7mqNm;IJR9cm+(y8p0 z16OK^a%?W=ls%-+WIiQI{N+w@Z`QiyO%q3dVZXAQ>>sGa%vH!>BXLtOa|^n#1Krq(M=*fB*pCCm(jg3E1fv+k zII;8;PQyV70YX&pG^U8D&*C}a>C1Qpui|yQfy;O+X6%QEzXH#2@W5OS;>v6eR`Mm! z^}W+%t8sR&d!pT01nT7Dn#K8lVBzoocec~yX$b-e0(TVxNcHFYdud1uy>`V}J44qK zbcrJTrlgEQsEUr`B%|Xv$(cV4={`fQA|@BhDJjW9<$wPW5dY3i_Wxx6j|g~=R{sKd COcP`P From 6eecb4a3ff8055e9df96ce94795c47dcd171640a Mon Sep 17 00:00:00 2001 From: github-actions Date: Mon, 10 Feb 2025 15:05:17 +0000 Subject: [PATCH 11/12] chore: self mutation Signed-off-by: github-actions --- .gitignore | 1 - test/PARAMETER.integ.snapshot/PARAMETER.assets.json | 10 +++++----- test/PARAMETER.integ.snapshot/PARAMETER.template.json | 2 +- .../PARAMETERMULTI.assets.json | 10 +++++----- .../PARAMETERMULTI.template.json | 2 +- test/SECRET.integ.snapshot/SECRET.assets.json | 10 +++++----- test/SECRET.integ.snapshot/SECRET.template.json | 2 +- 7 files changed, 18 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index 9314c3a8..dd804af9 100644 --- a/.gitignore +++ b/.gitignore @@ -81,4 +81,3 @@ test/SECRET.integ.snapshot/**/tree.json .idea /assets !/.projenrc.js -*.DS_Store diff --git a/test/PARAMETER.integ.snapshot/PARAMETER.assets.json b/test/PARAMETER.integ.snapshot/PARAMETER.assets.json index 22e07088..ca029ee5 100644 --- a/test/PARAMETER.integ.snapshot/PARAMETER.assets.json +++ b/test/PARAMETER.integ.snapshot/PARAMETER.assets.json @@ -1,20 +1,20 @@ { "version": "39.0.0", "files": { - "d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b": { + "eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc": { "source": { - "path": "asset.d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b.zip", + "path": "asset.eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc.zip", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b.zip", + "objectKey": "eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "6d3ff032ea46c79e4194c7129b6a118711a3c78f26a3ae56ac8bc9d9f06dbf45": { + "fe230a59724068b8e22b0ddbff5b46984961c41efe347bc575998ad868551ee6": { "source": { "path": "PARAMETER.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "6d3ff032ea46c79e4194c7129b6a118711a3c78f26a3ae56ac8bc9d9f06dbf45.json", + "objectKey": "fe230a59724068b8e22b0ddbff5b46984961c41efe347bc575998ad868551ee6.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/test/PARAMETER.integ.snapshot/PARAMETER.template.json b/test/PARAMETER.integ.snapshot/PARAMETER.template.json index 0e6ec1e8..4f0d6e0b 100644 --- a/test/PARAMETER.integ.snapshot/PARAMETER.template.json +++ b/test/PARAMETER.integ.snapshot/PARAMETER.template.json @@ -139,7 +139,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b.zip" + "S3Key": "eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc.zip" }, "Environment": { "Variables": { diff --git a/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.assets.json b/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.assets.json index c85bb0b1..839f0b6a 100644 --- a/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.assets.json +++ b/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.assets.json @@ -1,20 +1,20 @@ { "version": "39.0.0", "files": { - "d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b": { + "eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc": { "source": { - "path": "asset.d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b.zip", + "path": "asset.eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc.zip", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b.zip", + "objectKey": "eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "18475bdb75dca2e0a74ecf3f0d5eade0e56714f6fe9f2f9b7a82fc039a3d78e9": { + "13ee38eb33b1b85e4b825987f0ed7035df11b30a8fa50b41ff32239fcf380a8b": { "source": { "path": "PARAMETERMULTI.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "18475bdb75dca2e0a74ecf3f0d5eade0e56714f6fe9f2f9b7a82fc039a3d78e9.json", + "objectKey": "13ee38eb33b1b85e4b825987f0ed7035df11b30a8fa50b41ff32239fcf380a8b.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.template.json b/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.template.json index 808a43d9..7ce7f25e 100644 --- a/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.template.json +++ b/test/PARAMETER_MULTI.integ.snapshot/PARAMETERMULTI.template.json @@ -535,7 +535,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b.zip" + "S3Key": "eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc.zip" }, "Environment": { "Variables": { diff --git a/test/SECRET.integ.snapshot/SECRET.assets.json b/test/SECRET.integ.snapshot/SECRET.assets.json index 9b9cbc46..004fba44 100644 --- a/test/SECRET.integ.snapshot/SECRET.assets.json +++ b/test/SECRET.integ.snapshot/SECRET.assets.json @@ -1,20 +1,20 @@ { "version": "39.0.0", "files": { - "d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b": { + "eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc": { "source": { - "path": "asset.d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b.zip", + "path": "asset.eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc.zip", "packaging": "file" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b.zip", + "objectKey": "eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "1cf7fc474a32e929a12b22aefdcec2d75b10693f006179d6fdc4d545b02d8638": { + "6242ad5b6accf4725b672e5e1b6969d282ff2e191bef99f14cabf39f4988aa1a": { "source": { "path": "SECRET.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "1cf7fc474a32e929a12b22aefdcec2d75b10693f006179d6fdc4d545b02d8638.json", + "objectKey": "6242ad5b6accf4725b672e5e1b6969d282ff2e191bef99f14cabf39f4988aa1a.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/test/SECRET.integ.snapshot/SECRET.template.json b/test/SECRET.integ.snapshot/SECRET.template.json index 732c349d..807d1458 100644 --- a/test/SECRET.integ.snapshot/SECRET.template.json +++ b/test/SECRET.integ.snapshot/SECRET.template.json @@ -166,7 +166,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "d06eef6660adc92d622d31e869ffe09fc0c1f4c7b1a9705bee86da0fa5968f0b.zip" + "S3Key": "eae5bd3f5494024286c9ac23a436ddfa3da11659eb75d6cf3b4ce697c459e4dc.zip" }, "Environment": { "Variables": { From d3378982d754d6d5020d25d339c42c84445f5cac Mon Sep 17 00:00:00 2001 From: lennartrommeiss Date: Mon, 10 Feb 2025 16:29:24 +0100 Subject: [PATCH 12/12] fix: add yarn projen package to contributing.md Signed-off-by: lennartrommeiss --- CONTRIBUTING.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8f411e66..a5c8f21f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,19 +9,30 @@ We are committed to fostering a welcoming, respectful, and harassment-free envir Install all necessary tools with `yarn install` and others manually like `go` Build the go Lambda code: + ``` ./scripts/build.sh ``` + Build the package (for CDK development only the first `js` build has to complete): + ``` yarn projen build + +// to skip the tests you can also do + +yarn projen package ``` + Link the package: + ``` yarn link ``` + Switch to the path/project where you would like to use cdk-sops-secrets. \ Link the package to your local build source: + ``` yarn link "cdk-sops-secrets" -``` \ No newline at end of file +```