@aws-mdaa/dataops-job-l3-construct 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/.jsii +38 -28
  2. package/README.md +5 -0
  3. package/lib/dataops-job-l3-construct.d.ts +8 -1
  4. package/lib/dataops-job-l3-construct.js +40 -13
  5. package/node_modules/@aws-mdaa/config/README.md +3 -0
  6. package/node_modules/@aws-mdaa/config/lib/blueprint-value-transformer.d.ts +20 -0
  7. package/node_modules/@aws-mdaa/config/lib/blueprint-value-transformer.js +70 -0
  8. package/node_modules/@aws-mdaa/config/lib/blueprint-value-transformer.ts +88 -0
  9. package/node_modules/@aws-mdaa/config/lib/config.d.ts +87 -0
  10. package/node_modules/@aws-mdaa/config/lib/config.js +7 -0
  11. package/node_modules/@aws-mdaa/config/lib/config.ts +92 -0
  12. package/node_modules/@aws-mdaa/config/lib/index.d.ts +11 -0
  13. package/node_modules/@aws-mdaa/config/lib/index.js +28 -0
  14. package/node_modules/@aws-mdaa/config/lib/index.ts +12 -0
  15. package/node_modules/@aws-mdaa/config/lib/param-transformer.d.ts +49 -0
  16. package/node_modules/@aws-mdaa/config/lib/param-transformer.js +160 -0
  17. package/node_modules/@aws-mdaa/config/lib/param-transformer.ts +159 -0
  18. package/node_modules/@aws-mdaa/config/lib/path-value-transformer.d.ts +10 -0
  19. package/node_modules/@aws-mdaa/config/lib/path-value-transformer.js +30 -0
  20. package/node_modules/@aws-mdaa/config/lib/path-value-transformer.ts +27 -0
  21. package/node_modules/@aws-mdaa/config/lib/ref-value-transformer.d.ts +44 -0
  22. package/node_modules/@aws-mdaa/config/lib/ref-value-transformer.js +243 -0
  23. package/node_modules/@aws-mdaa/config/lib/ref-value-transformer.ts +302 -0
  24. package/node_modules/@aws-mdaa/config/lib/ssm-ref-transformer.d.ts +8 -0
  25. package/node_modules/@aws-mdaa/config/lib/ssm-ref-transformer.js +22 -0
  26. package/node_modules/@aws-mdaa/config/lib/ssm-ref-transformer.ts +21 -0
  27. package/node_modules/@aws-mdaa/config/lib/transformer.d.ts +35 -0
  28. package/node_modules/@aws-mdaa/config/lib/transformer.js +66 -0
  29. package/node_modules/@aws-mdaa/config/lib/transformer.ts +74 -0
  30. package/node_modules/@aws-mdaa/config/package.json +42 -0
  31. package/node_modules/@aws-mdaa/config/test/blueprint-value-transformer.test.js +224 -0
  32. package/node_modules/@aws-mdaa/config/test/blueprint-value-transformer.test.ts +259 -0
  33. package/node_modules/@aws-mdaa/config/test/config-nt.test.d.ts +5 -0
  34. package/node_modules/@aws-mdaa/config/test/config-nt.test.js +129 -0
  35. package/node_modules/@aws-mdaa/config/test/config-nt.test.ts +163 -0
  36. package/node_modules/@aws-mdaa/config/test/config.test.d.ts +5 -0
  37. package/node_modules/@aws-mdaa/config/test/config.test.js +409 -0
  38. package/node_modules/@aws-mdaa/config/test/config.test.ts +517 -0
  39. package/node_modules/@aws-mdaa/config/test/param-transformer.test.d.ts +5 -0
  40. package/node_modules/@aws-mdaa/config/test/param-transformer.test.js +216 -0
  41. package/node_modules/@aws-mdaa/config/test/param-transformer.test.ts +234 -0
  42. package/node_modules/@aws-mdaa/config/test/path-value-transformer.test.d.ts +5 -0
  43. package/node_modules/@aws-mdaa/config/test/path-value-transformer.test.js +59 -0
  44. package/node_modules/@aws-mdaa/config/test/path-value-transformer.test.ts +68 -0
  45. package/node_modules/@aws-mdaa/config/test/ref-value-transformer.test.d.ts +5 -0
  46. package/node_modules/@aws-mdaa/config/test/ref-value-transformer.test.js +254 -0
  47. package/node_modules/@aws-mdaa/config/test/ref-value-transformer.test.ts +304 -0
  48. package/node_modules/@aws-mdaa/config/test/ssm-ref-transformer.test.d.ts +5 -0
  49. package/node_modules/@aws-mdaa/config/test/ssm-ref-transformer.test.js +66 -0
  50. package/node_modules/@aws-mdaa/config/test/ssm-ref-transformer.test.ts +79 -0
  51. package/node_modules/@aws-mdaa/config/tsconfig.tsbuildinfo +1 -0
  52. package/node_modules/lodash/README.md +2 -2
  53. package/node_modules/lodash/_baseOrderBy.js +1 -1
  54. package/node_modules/lodash/_baseUnset.js +7 -20
  55. package/node_modules/lodash/_setCacheHas.js +1 -1
  56. package/node_modules/lodash/compact.js +1 -1
  57. package/node_modules/lodash/core.js +3 -3
  58. package/node_modules/lodash/core.min.js +26 -25
  59. package/node_modules/lodash/fromPairs.js +3 -1
  60. package/node_modules/lodash/lodash.js +38 -27
  61. package/node_modules/lodash/lodash.min.js +125 -129
  62. package/node_modules/lodash/package.json +4 -2
  63. package/node_modules/lodash/random.js +9 -0
  64. package/node_modules/lodash/template.js +16 -4
  65. package/node_modules/lodash/templateSettings.js +4 -0
  66. package/package.json +27 -32
  67. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/README.md +0 -185
  68. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/lib/index.d.ts +0 -57
  69. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/lib/index.js +0 -198
  70. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/lib/index.ts +0 -241
  71. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/package.json +0 -44
  72. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/test/bucketpolicy-helper.test.js +0 -200
  73. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/test/bucketpolicy-helper.test.ts +0 -215
  74. package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/tsconfig.tsbuildinfo +0 -1
  75. package/node_modules/@aws-mdaa/s3-inventory-helper/.npmignore +0 -34
  76. package/node_modules/@aws-mdaa/s3-inventory-helper/README.md +0 -3
  77. package/node_modules/@aws-mdaa/s3-inventory-helper/jest.config.js +0 -5
  78. package/node_modules/@aws-mdaa/s3-inventory-helper/lib/index.d.ts +0 -48
  79. package/node_modules/@aws-mdaa/s3-inventory-helper/lib/index.js +0 -213
  80. package/node_modules/@aws-mdaa/s3-inventory-helper/lib/index.ts +0 -241
  81. package/node_modules/@aws-mdaa/s3-inventory-helper/package.json +0 -44
  82. package/node_modules/@aws-mdaa/s3-inventory-helper/test/TODO +0 -0
  83. package/node_modules/@aws-mdaa/s3-inventory-helper/tsconfig.json +0 -40
  84. package/node_modules/@aws-mdaa/s3-inventory-helper/tsconfig.tsbuildinfo +0 -1
  85. package/node_modules/@aws-mdaa/s3-inventory-helper/typedoc.json +0 -7
  86. /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper → config}/.npmignore +0 -0
  87. /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper → config}/jest.config.js +0 -0
  88. /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper/test/bucketpolicy-helper.test.d.ts → config/test/blueprint-value-transformer.test.d.ts} +0 -0
  89. /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper → config}/tsconfig.json +0 -0
  90. /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper → config}/typedoc.json +0 -0
@@ -1,200 +0,0 @@
1
- "use strict";
2
- /*!
3
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- const testing_1 = require("@aws-mdaa/testing");
8
- const lib_1 = require("../lib");
9
- const aws_s3_1 = require("aws-cdk-lib/aws-s3");
10
- const aws_iam_1 = require("aws-cdk-lib/aws-iam");
11
- describe('Test BucketPolicy Helper', () => {
12
- const testApp = new testing_1.MdaaTestApp();
13
- const testBucket = aws_s3_1.Bucket.fromBucketName(testApp.testStack, 'test-bucket', 'test-bucket');
14
- describe('RestrictPrefix', () => {
15
- const baseTestProps = {
16
- s3Bucket: testBucket,
17
- s3Prefix: 'test-prefix',
18
- };
19
- test('Read Role Ids', () => {
20
- const testProps = {
21
- ...baseTestProps,
22
- readRoleIds: ['test-role-id-1', 'test-role-id-2'],
23
- };
24
- const restriction = new lib_1.RestrictObjectPrefixToRoles(testProps);
25
- // console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
26
- expect(restriction.statements().length).toBe(1);
27
- expect(restriction.readStatements().length).toBe(1);
28
- expect(restriction.readWriteSuperStatements().length).toBe(0);
29
- expect(restriction.readWriteStatements().length).toBe(0);
30
- expect(restriction.readStatements()[0].actions).toStrictEqual(['s3:GetObject*']);
31
- expect(restriction.readStatements()[0].conditions).toStrictEqual({
32
- StringLike: {
33
- 'aws:userId': ['test-role-id-1:*', 'test-role-id-2:*'],
34
- },
35
- });
36
- expect(restriction.readStatements()[0].effect).toBe('Allow');
37
- expect(restriction.readStatements()[0].resources).toStrictEqual([
38
- 'arn:test-partition:s3:::test-bucket/test-prefix/*',
39
- ]);
40
- });
41
- test('ReadWrite Role Ids', () => {
42
- const testProps = {
43
- ...baseTestProps,
44
- readWriteRoleIds: ['test-role-id-1', 'test-role-id-2'],
45
- };
46
- const restriction = new lib_1.RestrictObjectPrefixToRoles(testProps);
47
- // console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
48
- expect(restriction.statements().length).toBe(1);
49
- expect(restriction.readWriteStatements().length).toBe(1);
50
- expect(restriction.readStatements().length).toBe(0);
51
- expect(restriction.readWriteSuperStatements().length).toBe(0);
52
- expect(restriction.readWriteStatements()[0].actions).toStrictEqual([
53
- 's3:GetObject*',
54
- 's3:PutObject',
55
- 's3:PutObjectTagging',
56
- 's3:DeleteObject',
57
- ]);
58
- expect(restriction.readWriteStatements()[0].conditions).toStrictEqual({
59
- StringLike: {
60
- 'aws:userId': ['test-role-id-1:*', 'test-role-id-2:*'],
61
- },
62
- });
63
- });
64
- test('ReadWriteSuper Role Ids', () => {
65
- const testProps = {
66
- ...baseTestProps,
67
- readWriteSuperRoleIds: ['test-role-id-1', 'test-role-id-2'],
68
- };
69
- const restriction = new lib_1.RestrictObjectPrefixToRoles(testProps);
70
- // console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
71
- expect(restriction.statements().length).toBe(1);
72
- expect(restriction.readWriteSuperStatements().length).toBe(1);
73
- expect(restriction.readStatements().length).toBe(0);
74
- expect(restriction.readWriteStatements().length).toBe(0);
75
- expect(restriction.readWriteSuperStatements()[0].actions).toStrictEqual([
76
- 's3:GetObject*',
77
- 's3:PutObject',
78
- 's3:PutObjectTagging',
79
- 's3:DeleteObject',
80
- 's3:DeleteObjectVersion',
81
- ]);
82
- expect(restriction.readWriteSuperStatements()[0].conditions).toStrictEqual({
83
- StringLike: {
84
- 'aws:userId': ['test-role-id-1:*', 'test-role-id-2:*'],
85
- },
86
- });
87
- });
88
- test('Read Principals', () => {
89
- const testProps = {
90
- ...baseTestProps,
91
- readPrincipals: [new aws_iam_1.ArnPrincipal('test-role-arn-1')],
92
- };
93
- const restriction = new lib_1.RestrictObjectPrefixToRoles(testProps);
94
- // console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
95
- expect(restriction.statements().length).toBe(1);
96
- expect(restriction.readStatements().length).toBe(1);
97
- expect(restriction.readWriteSuperStatements().length).toBe(0);
98
- expect(restriction.readWriteStatements().length).toBe(0);
99
- expect(restriction.readStatements()[0].actions).toStrictEqual(['s3:GetObject*']);
100
- expect(restriction.readStatements()[0].effect).toBe('Allow');
101
- expect(restriction.readStatements()[0].resources).toStrictEqual([
102
- 'arn:test-partition:s3:::test-bucket/test-prefix/*',
103
- ]);
104
- expect(restriction.readStatements()[0].principals.length).toBe(1);
105
- expect(JSON.stringify(restriction.readStatements()[0].principals[0])).toStrictEqual(JSON.stringify({ AWS: ['test-role-arn-1'] }));
106
- });
107
- test('ReadWrite Principals', () => {
108
- const testProps = {
109
- ...baseTestProps,
110
- readWritePrincipals: [new aws_iam_1.ArnPrincipal('test-role-arn-1')],
111
- };
112
- const restriction = new lib_1.RestrictObjectPrefixToRoles(testProps);
113
- // console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
114
- expect(restriction.statements().length).toBe(1);
115
- expect(restriction.readWriteStatements().length).toBe(1);
116
- expect(restriction.readStatements().length).toBe(0);
117
- expect(restriction.readWriteSuperStatements().length).toBe(0);
118
- expect(restriction.readWriteStatements()[0].actions).toStrictEqual([
119
- 's3:GetObject*',
120
- 's3:PutObject',
121
- 's3:PutObjectTagging',
122
- 's3:DeleteObject',
123
- ]);
124
- expect(restriction.readWriteStatements()[0].effect).toBe('Allow');
125
- expect(restriction.readWriteStatements()[0].resources).toStrictEqual([
126
- 'arn:test-partition:s3:::test-bucket/test-prefix/*',
127
- ]);
128
- expect(restriction.readWriteStatements()[0].principals.length).toBe(1);
129
- expect(JSON.stringify(restriction.readWriteStatements()[0].principals[0])).toStrictEqual(JSON.stringify({ AWS: ['test-role-arn-1'] }));
130
- });
131
- test('ReadWriteSuper Principals', () => {
132
- const testProps = {
133
- ...baseTestProps,
134
- readWriteSuperPrincipals: [new aws_iam_1.ArnPrincipal('test-role-arn-1')],
135
- };
136
- const restriction = new lib_1.RestrictObjectPrefixToRoles(testProps);
137
- // console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
138
- expect(restriction.statements().length).toBe(1);
139
- expect(restriction.readStatements().length).toBe(0);
140
- expect(restriction.readWriteStatements().length).toBe(0);
141
- expect(restriction.readWriteSuperStatements().length).toBe(1);
142
- expect(restriction.readWriteSuperStatements()[0].actions).toStrictEqual([
143
- 's3:GetObject*',
144
- 's3:PutObject',
145
- 's3:PutObjectTagging',
146
- 's3:DeleteObject',
147
- 's3:DeleteObjectVersion',
148
- ]);
149
- expect(restriction.readWriteSuperStatements()[0].effect).toBe('Allow');
150
- expect(restriction.readWriteSuperStatements()[0].resources).toStrictEqual([
151
- 'arn:test-partition:s3:::test-bucket/test-prefix/*',
152
- ]);
153
- expect(restriction.readWriteSuperStatements()[0].principals.length).toBe(1);
154
- expect(JSON.stringify(restriction.readWriteSuperStatements()[0].principals[0])).toStrictEqual(JSON.stringify({ AWS: ['test-role-arn-1'] }));
155
- });
156
- });
157
- describe('RestrictBucket', () => {
158
- const baseTestProps = {
159
- s3Bucket: testBucket,
160
- roleExcludeIds: ['test-role-id-1', 'test-role-id-2'],
161
- principalExcludes: ['test-arn'],
162
- prefixExcludes: ['exclude-prefix'],
163
- prefixIncludes: ['exclude-prefix'],
164
- };
165
- test('Base Allow', () => {
166
- const testProps = {
167
- ...baseTestProps,
168
- };
169
- const restriction = new lib_1.RestrictBucketToRoles(testProps);
170
- console.log(JSON.stringify(restriction.allowStatement, undefined, 2));
171
- expect(restriction.allowStatement.actions).toStrictEqual(['s3:List*', 's3:GetBucket*']);
172
- expect(restriction.allowStatement.effect).toBe('Allow');
173
- expect(restriction.allowStatement.conditions).toStrictEqual({
174
- StringLike: {
175
- 'aws:userId': ['test-role-id-1:*', 'test-role-id-2:*'],
176
- },
177
- });
178
- expect(restriction.allowStatement.resources).toStrictEqual([
179
- 'arn:test-partition:s3:::test-bucket/*',
180
- 'arn:test-partition:s3:::test-bucket',
181
- ]);
182
- });
183
- test('Base Deny', () => {
184
- const testProps = {
185
- ...baseTestProps,
186
- };
187
- const restriction = new lib_1.RestrictBucketToRoles(testProps);
188
- console.log(JSON.stringify(restriction.denyStatement, undefined, 2));
189
- expect(restriction.denyStatement.actions).toStrictEqual(['s3:PutObject*', 's3:GetObject*', 's3:DeleteObject*']);
190
- expect(restriction.denyStatement.effect).toBe('Deny');
191
- expect(restriction.denyStatement.conditions).toStrictEqual({
192
- 'ForAnyValue:StringNotLike': {
193
- 'aws:userId': ['test-role-id-1:*', 'test-role-id-2:*'],
194
- 'aws:PrincipalArn': ['test-arn'],
195
- },
196
- });
197
- });
198
- });
199
- });
200
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVja2V0cG9saWN5LWhlbHBlci50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiYnVja2V0cG9saWN5LWhlbHBlci50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O0dBR0c7O0FBRUgsK0NBQWdEO0FBQ2hELGdDQUtnQjtBQUNoQiwrQ0FBNEM7QUFDNUMsaURBQW1EO0FBRW5ELFFBQVEsQ0FBQywwQkFBMEIsRUFBRSxHQUFHLEVBQUU7SUFDeEMsTUFBTSxPQUFPLEdBQUcsSUFBSSxxQkFBVyxFQUFFLENBQUM7SUFDbEMsTUFBTSxVQUFVLEdBQUcsZUFBTSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLGFBQWEsRUFBRSxhQUFhLENBQUMsQ0FBQztJQUMxRixRQUFRLENBQUMsZ0JBQWdCLEVBQUUsR0FBRyxFQUFFO1FBQzlCLE1BQU0sYUFBYSxHQUFpQztZQUNsRCxRQUFRLEVBQUUsVUFBVTtZQUNwQixRQUFRLEVBQUUsYUFBYTtTQUN4QixDQUFDO1FBQ0YsSUFBSSxDQUFDLGVBQWUsRUFBRSxHQUFHLEVBQUU7WUFDekIsTUFBTSxTQUFTLEdBQWlDO2dCQUM5QyxHQUFHLGFBQWE7Z0JBQ2hCLFdBQVcsRUFBRSxDQUFDLGdCQUFnQixFQUFFLGdCQUFnQixDQUFDO2FBQ2xELENBQUM7WUFDRixNQUFNLFdBQVcsR0FBRyxJQUFJLGlDQUEyQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQy9ELCtFQUErRTtZQUMvRSxNQUFNLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNoRCxNQUFNLENBQUMsV0FBVyxDQUFDLGNBQWMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNwRCxNQUFNLENBQUMsV0FBVyxDQUFDLHdCQUF3QixFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFD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LEVBQUUsa0JBQWtCLENBQUMsQ0FBQyxDQUFDO1lBQ2hILE1BQU0sQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0RCxNQUFNLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxhQUFhLENBQUM7Z0JBQ3pELDJCQUEyQixFQUFFO29CQUMzQixZQUFZLEVBQUUsQ0FBQyxrQkFBa0IsRUFBRSxrQkFBa0IsQ0FBQztvQkFDdEQsa0JBQWtCLEVBQUUsQ0FBQyxVQUFVLENBQUM7aUJBQ2pDO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gKiBDb3B5cmlnaHQgQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cblxuaW1wb3J0IHsgTWRhYVRlc3RBcHAgfSBmcm9tICdAYXdzLW1kYWEvdGVzdGluZyc7XG5pbXBvcnQge1xuICBJUmVzdHJpY3RCdWNrZXRUb1JvbGVzLFxuICBJUmVzdHJpY3RPYmplY3RQcmVmaXhUb1JvbGVzLFxuICBSZXN0cmljdEJ1Y2tldFRvUm9sZXMsXG4gIFJlc3RyaWN0T2JqZWN0UHJlZml4VG9Sb2xlcyxcbn0gZnJvbSAnLi4vbGliJztcbmltcG9ydCB7IEJ1Y2tldCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zMyc7XG5pbXBvcnQgeyBBcm5QcmluY2lwYWwgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcblxuZGVzY3JpYmUoJ1Rlc3QgQnVja2V0UG9saWN5IEhlbHBlcicsICgpID0+IHtcbiAgY29uc3QgdGVzdEFwcCA9IG5ldyBNZGFhVGVzdEFwcCgpO1xuICBjb25zdCB0ZXN0QnVja2V0ID0gQnVja2V0LmZyb21CdWNrZXROYW1lKHRlc3RBcHAudGVzdFN0YWNrLCAndGVzdC1idWNrZXQnLCAndGVzdC1idWNrZXQnKTtcbiAgZGVzY3JpYmUoJ1Jlc3RyaWN0UHJlZml4JywgKCkgPT4ge1xuICAgIGNvbnN0IGJhc2VUZXN0UHJvcHM6IElSZXN0cmljdE9iamVjdFByZWZpeFRvUm9sZXMgPSB7XG4gICAgICBzM0J1Y2tldDogdGVzdEJ1Y2tldCxcbiAgICAgIHMzUHJlZml4OiAndGVzdC1wcmVmaXgnLFxuICAgIH07XG4gICAgdGVzdCgnUmVhZCBSb2xlIElkcycsICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3RQcm9wczogSVJlc3RyaWN0T2JqZWN0UHJlZml4VG9Sb2xlcyA9IHtcbiAgICAgICAgLi4uYmFzZVRlc3RQcm9wcyxcbiAgICAgICAgcmVhZFJvbGVJZHM6IFsndGVzdC1yb2xlLWlkLTEnLCAndGVzdC1yb2xlLWlkLTInXSxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXN0cmljdGlvbiA9IG5ldyBSZXN0cmljdE9iamVjdFByZWZpeFRvUm9sZXModGVzdFByb3BzKTtcbiAgICAgIC8vIGNvbnNvbGUubG9nKCBKU09OLnN0cmluZ2lmeSggcmVzdHJpY3Rpb24uc3RhdGVtZW50cygpWyAwIF0sIHVuZGVmaW5lZCwgMiApIClcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5zdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDEpO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRTdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDEpO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN1cGVyU3RhdGVtZW50cygpLmxlbmd0aCkudG9CZSgwKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5yZWFkV3JpdGVTdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDApO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRTdGF0ZW1lbnRzKClbMF0uYWN0aW9ucykudG9TdHJpY3RFcXVhbChbJ3MzOkdldE9iamVjdConXSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24ucmVhZFN0YXRlbWVudHMoKVswXS5jb25kaXRpb25zKS50b1N0cmljdEVxdWFsKHtcbiAgICAgICAgU3RyaW5nTGlrZToge1xuICAgICAgICAgICdhd3M6dXNlcklkJzogWyd0ZXN0LXJvbGUtaWQtMToqJywgJ3Rlc3Qtcm9sZS1pZC0yOionXSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRTdGF0ZW1lbnRzKClbMF0uZWZmZWN0KS50b0JlKCdBbGxvdycpO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRTdGF0ZW1lbnRzKClbMF0ucmVzb3VyY2VzKS50b1N0cmljdEVxdWFsKFtcbiAgICAgICAgJ2Fybjp0ZXN0LXBhcnRpdGlvbjpzMzo6OnRlc3QtYnVja2V0L3Rlc3QtcHJlZml4LyonLFxuICAgICAgXSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdSZWFkV3JpdGUgUm9sZSBJZHMnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0UHJvcHM6IElSZXN0cmljdE9iamVjdFByZWZpeFRvUm9sZXMgPSB7XG4gICAgICAgIC4uLmJhc2VUZXN0UHJvcHMsXG4gICAgICAgIHJlYWRXcml0ZVJvbGVJZHM6IFsndGVzdC1yb2xlLWlkLTEnLCAndGVzdC1yb2xlLWlkLTInXSxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXN0cmljdGlvbiA9IG5ldyBSZXN0cmljdE9iamVjdFByZWZpeFRvUm9sZXModGVzdFByb3BzKTtcbiAgICAgIC8vIGNvbnNvbGUubG9nKCBKU09OLnN0cmluZ2lmeSggcmVzdHJpY3Rpb24uc3RhdGVtZW50cygpWyAwIF0sIHVuZGVmaW5lZCwgMiApIClcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5zdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDEpO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN0YXRlbWVudHMoKS5sZW5ndGgpLnRvQmUoMSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24ucmVhZFN0YXRlbWVudHMoKS5sZW5ndGgpLnRvQmUoMCk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24ucmVhZFdyaXRlU3VwZXJTdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDApO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN0YXRlbWVudHMoKVswXS5hY3Rpb25zKS50b1N0cmljdEVxdWFsKFtcbiAgICAgICAgJ3MzOkdldE9iamVjdConLFxuICAgICAgICAnczM6UHV0T2JqZWN0JyxcbiAgICAgICAgJ3MzOlB1dE9iamVjdFRhZ2dpbmcnLFxuICAgICAgICAnczM6RGVsZXRlT2JqZWN0JyxcbiAgICAgIF0pO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN0YXRlbWVudHMoKVswXS5jb25kaXRpb25zKS50b1N0cmljdEVxdWFsKHtcbiAgICAgICAgU3RyaW5nTGlrZToge1xuICAgICAgICAgICdhd3M6dXNlcklkJzogWyd0ZXN0LXJvbGUtaWQtMToqJywgJ3Rlc3Qtcm9sZS1pZC0yOionXSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnUmVhZFdyaXRlU3VwZXIgUm9sZSBJZHMnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0UHJvcHM6IElSZXN0cmljdE9iamVjdFByZWZpeFRvUm9sZXMgPSB7XG4gICAgICAgIC4uLmJhc2VUZXN0UHJvcHMsXG4gICAgICAgIHJlYWRXcml0ZVN1cGVyUm9sZUlkczogWyd0ZXN0LXJvbGUtaWQtMScsICd0ZXN0LXJvbGUtaWQtMiddLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlc3RyaWN0aW9uID0gbmV3IFJlc3RyaWN0T2JqZWN0UHJlZml4VG9Sb2xlcyh0ZXN0UHJvcHMpO1xuICAgICAgLy8gY29uc29sZS5sb2coIEpTT04uc3RyaW5naWZ5KCByZXN0cmljdGlvbi5zdGF0ZW1lbnRzKClbIDAgXSwgdW5kZWZpbmVkLCAyICkgKVxuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnN0YXRlbWVudHMoKS5sZW5ndGgpLnRvQmUoMSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24ucmVhZFdyaXRlU3VwZXJTdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDEpO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRTdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDApO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN0YXRlbWVudHMoKS5sZW5ndGgpLnRvQmUoMCk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24ucmVhZFdyaXRlU3VwZXJTdGF0ZW1lbnRzKClbMF0uYWN0aW9ucykudG9TdHJpY3RFcXVhbChbXG4gICAgICAgICdzMzpHZXRPYmplY3QqJyxcbiAgICAgICAgJ3MzOlB1dE9iamVjdCcsXG4gICAgICAgICdzMzpQdXRPYmplY3RUYWdnaW5nJyxcbiAgICAgICAgJ3MzOkRlbGV0ZU9iamVjdCcsXG4gICAgICAgICdzMzpEZWxldGVPYmplY3RWZXJzaW9uJyxcbiAgICAgIF0pO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN1cGVyU3RhdGVtZW50cygpWzBdLmNvbmRpdGlvbnMpLnRvU3RyaWN0RXF1YWwoe1xuICAgICAgICBTdHJpbmdMaWtlOiB7XG4gICAgICAgICAgJ2F3czp1c2VySWQnOiBbJ3Rlc3Qtcm9sZS1pZC0xOionLCAndGVzdC1yb2xlLWlkLTI6KiddLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdSZWFkIFByaW5jaXBhbHMnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0UHJvcHM6IElSZXN0cmljdE9iamVjdFByZWZpeFRvUm9sZXMgPSB7XG4gICAgICAgIC4uLmJhc2VUZXN0UHJvcHMsXG4gICAgICAgIHJlYWRQcmluY2lwYWxzOiBbbmV3IEFyblByaW5jaXBhbCgndGVzdC1yb2xlLWFybi0xJyldLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlc3RyaWN0aW9uID0gbmV3IFJlc3RyaWN0T2JqZWN0UHJlZml4VG9Sb2xlcyh0ZXN0UHJvcHMpO1xuICAgICAgLy8gY29uc29sZS5sb2coIEpTT04uc3RyaW5naWZ5KCByZXN0cmljdGlvbi5zdGF0ZW1lbnRzKClbIDAgXSwgdW5kZWZpbmVkLCAyICkgKVxuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnN0YXRlbWVudHMoKS5sZW5ndGgpLnRvQmUoMSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24ucmVhZFN0YXRlbWVudHMoKS5sZW5ndGgpLnRvQmUoMSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24ucmVhZFdyaXRlU3VwZXJTdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDApO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN0YXRlbWVudHMoKS5sZW5ndGgpLnRvQmUoMCk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24ucmVhZFN0YXRlbWVudHMoKVswXS5hY3Rpb25zKS50b1N0cmljdEVxdWFsKFsnczM6R2V0T2JqZWN0KiddKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5yZWFkU3RhdGVtZW50cygpWzBdLmVmZmVjdCkudG9CZSgnQWxsb3cnKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5yZWFkU3RhdGVtZW50cygpWzBdLnJlc291cmNlcykudG9TdHJpY3RFcXVhbChbXG4gICAgICAgICdhcm46dGVzdC1wYXJ0aXRpb246czM6Ojp0ZXN0LWJ1Y2tldC90ZXN0LXByZWZpeC8qJyxcbiAgICAgIF0pO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRTdGF0ZW1lbnRzKClbMF0ucHJpbmNpcGFscy5sZW5ndGgpLnRvQmUoMSk7XG4gICAgICBleHBlY3QoSlNPTi5zdHJpbmdpZnkocmVzdHJpY3Rpb24ucmVhZFN0YXRlbWVudHMoKVswXS5wcmluY2lwYWxzWzBdKSkudG9TdHJpY3RFcXVhbChcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkoeyBBV1M6IFsndGVzdC1yb2xlLWFybi0xJ10gfSksXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnUmVhZFdyaXRlIFByaW5jaXBhbHMnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0UHJvcHM6IElSZXN0cmljdE9iamVjdFByZWZpeFRvUm9sZXMgPSB7XG4gICAgICAgIC4uLmJhc2VUZXN0UHJvcHMsXG4gICAgICAgIHJlYWRXcml0ZVByaW5jaXBhbHM6IFtuZXcgQXJuUHJpbmNpcGFsKCd0ZXN0LXJvbGUtYXJuLTEnKV0sXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVzdHJpY3Rpb24gPSBuZXcgUmVzdHJpY3RPYmplY3RQcmVmaXhUb1JvbGVzKHRlc3RQcm9wcyk7XG4gICAgICAvLyBjb25zb2xlLmxvZyggSlNPTi5zdHJpbmdpZnkoIHJlc3RyaWN0aW9uLnN0YXRlbWVudHMoKVsgMCBdLCB1bmRlZmluZWQsIDIgKSApXG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24uc3RhdGVtZW50cygpLmxlbmd0aCkudG9CZSgxKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5yZWFkV3JpdGVTdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDEpO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRTdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDApO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN1cGVyU3RhdGVtZW50cygpLmxlbmd0aCkudG9CZSgwKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5yZWFkV3JpdGVTdGF0ZW1lbnRzKClbMF0uYWN0aW9ucykudG9TdHJpY3RFcXVhbChbXG4gICAgICAgICdzMzpHZXRPYmplY3QqJyxcbiAgICAgICAgJ3MzOlB1dE9iamVjdCcsXG4gICAgICAgICdzMzpQdXRPYmplY3RUYWdnaW5nJyxcbiAgICAgICAgJ3MzOkRlbGV0ZU9iamVjdCcsXG4gICAgICBdKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5yZWFkV3JpdGVTdGF0ZW1lbnRzKClbMF0uZWZmZWN0KS50b0JlKCdBbGxvdycpO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN0YXRlbWVudHMoKVswXS5yZXNvdXJjZXMpLnRvU3RyaWN0RXF1YWwoW1xuICAgICAgICAnYXJuOnRlc3QtcGFydGl0aW9uOnMzOjo6dGVzdC1idWNrZXQvdGVzdC1wcmVmaXgvKicsXG4gICAgICBdKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5yZWFkV3JpdGVTdGF0ZW1lbnRzKClbMF0ucHJpbmNpcGFscy5sZW5ndGgpLnRvQmUoMSk7XG4gICAgICBleHBlY3QoSlNPTi5zdHJpbmdpZnkocmVzdHJpY3Rpb24ucmVhZFdyaXRlU3RhdGVtZW50cygpWzBdLnByaW5jaXBhbHNbMF0pKS50b1N0cmljdEVxdWFsKFxuICAgICAgICBKU09OLnN0cmluZ2lmeSh7IEFXUzogWyd0ZXN0LXJvbGUtYXJuLTEnXSB9KSxcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdSZWFkV3JpdGVTdXBlciBQcmluY2lwYWxzJywgKCkgPT4ge1xuICAgICAgY29uc3QgdGVzdFByb3BzOiBJUmVzdHJpY3RPYmplY3RQcmVmaXhUb1JvbGVzID0ge1xuICAgICAgICAuLi5iYXNlVGVzdFByb3BzLFxuICAgICAgICByZWFkV3JpdGVTdXBlclByaW5jaXBhbHM6IFtuZXcgQXJuUHJpbmNpcGFsKCd0ZXN0LXJvbGUtYXJuLTEnKV0sXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVzdHJpY3Rpb24gPSBuZXcgUmVzdHJpY3RPYmplY3RQcmVmaXhUb1JvbGVzKHRlc3RQcm9wcyk7XG4gICAgICAvLyBjb25zb2xlLmxvZyggSlNPTi5zdHJpbmdpZnkoIHJlc3RyaWN0aW9uLnN0YXRlbWVudHMoKVsgMCBdLCB1bmRlZmluZWQsIDIgKSApXG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24uc3RhdGVtZW50cygpLmxlbmd0aCkudG9CZSgxKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5yZWFkU3RhdGVtZW50cygpLmxlbmd0aCkudG9CZSgwKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5yZWFkV3JpdGVTdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDApO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN1cGVyU3RhdGVtZW50cygpLmxlbmd0aCkudG9CZSgxKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5yZWFkV3JpdGVTdXBlclN0YXRlbWVudHMoKVswXS5hY3Rpb25zKS50b1N0cmljdEVxdWFsKFtcbiAgICAgICAgJ3MzOkdldE9iamVjdConLFxuICAgICAgICAnczM6UHV0T2JqZWN0JyxcbiAgICAgICAgJ3MzOlB1dE9iamVjdFRhZ2dpbmcnLFxuICAgICAgICAnczM6RGVsZXRlT2JqZWN0JyxcbiAgICAgICAgJ3MzOkRlbGV0ZU9iamVjdFZlcnNpb24nLFxuICAgICAgXSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24ucmVhZFdyaXRlU3VwZXJTdGF0ZW1lbnRzKClbMF0uZWZmZWN0KS50b0JlKCdBbGxvdycpO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN1cGVyU3RhdGVtZW50cygpWzBdLnJlc291cmNlcykudG9TdHJpY3RFcXVhbChbXG4gICAgICAgICdhcm46dGVzdC1wYXJ0aXRpb246czM6Ojp0ZXN0LWJ1Y2tldC90ZXN0LXByZWZpeC8qJyxcbiAgICAgIF0pO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN1cGVyU3RhdGVtZW50cygpWzBdLnByaW5jaXBhbHMubGVuZ3RoKS50b0JlKDEpO1xuICAgICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN1cGVyU3RhdGVtZW50cygpWzBdLnByaW5jaXBhbHNbMF0pKS50b1N0cmljdEVxdWFsKFxuICAgICAgICBKU09OLnN0cmluZ2lmeSh7IEFXUzogWyd0ZXN0LXJvbGUtYXJuLTEnXSB9KSxcbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuICBkZXNjcmliZSgnUmVzdHJpY3RCdWNrZXQnLCAoKSA9PiB7XG4gICAgY29uc3QgYmFzZVRlc3RQcm9wczogSVJlc3RyaWN0QnVja2V0VG9Sb2xlcyA9IHtcbiAgICAgIHMzQnVja2V0OiB0ZXN0QnVja2V0LFxuICAgICAgcm9sZUV4Y2x1ZGVJZHM6IFsndGVzdC1yb2xlLWlkLTEnLCAndGVzdC1yb2xlLWlkLTInXSxcbiAgICAgIHByaW5jaXBhbEV4Y2x1ZGVzOiBbJ3Rlc3QtYXJuJ10sXG4gICAgICBwcmVmaXhFeGNsdWRlczogWydleGNsdWRlLXByZWZpeCddLFxuICAgICAgcHJlZml4SW5jbHVkZXM6IFsnZXhjbHVkZS1wcmVmaXgnXSxcbiAgICB9O1xuICAgIHRlc3QoJ0Jhc2UgQWxsb3cnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0UHJvcHM6IElSZXN0cmljdEJ1Y2tldFRvUm9sZXMgPSB7XG4gICAgICAgIC4uLmJhc2VUZXN0UHJvcHMsXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVzdHJpY3Rpb24gPSBuZXcgUmVzdHJpY3RCdWNrZXRUb1JvbGVzKHRlc3RQcm9wcyk7XG4gICAgICBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyZXN0cmljdGlvbi5hbGxvd1N0YXRlbWVudCwgdW5kZWZpbmVkLCAyKSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24uYWxsb3dTdGF0ZW1lbnQuYWN0aW9ucykudG9TdHJpY3RFcXVhbChbJ3MzOkxpc3QqJywgJ3MzOkdldEJ1Y2tldConXSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24uYWxsb3dTdGF0ZW1lbnQuZWZmZWN0KS50b0JlKCdBbGxvdycpO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLmFsbG93U3RhdGVtZW50LmNvbmRpdGlvbnMpLnRvU3RyaWN0RXF1YWwoe1xuICAgICAgICBTdHJpbmdMaWtlOiB7XG4gICAgICAgICAgJ2F3czp1c2VySWQnOiBbJ3Rlc3Qtcm9sZS1pZC0xOionLCAndGVzdC1yb2xlLWlkLTI6KiddLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24uYWxsb3dTdGF0ZW1lbnQucmVzb3VyY2VzKS50b1N0cmljdEVxdWFsKFtcbiAgICAgICAgJ2Fybjp0ZXN0LXBhcnRpdGlvbjpzMzo6OnRlc3QtYnVja2V0LyonLFxuICAgICAgICAnYXJuOnRlc3QtcGFydGl0aW9uOnMzOjo6dGVzdC1idWNrZXQnLFxuICAgICAgXSk7XG4gICAgfSk7XG4gICAgdGVzdCgnQmFzZSBEZW55JywgKCkgPT4ge1xuICAgICAgY29uc3QgdGVzdFByb3BzOiBJUmVzdHJpY3RCdWNrZXRUb1JvbGVzID0ge1xuICAgICAgICAuLi5iYXNlVGVzdFByb3BzLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlc3RyaWN0aW9uID0gbmV3IFJlc3RyaWN0QnVja2V0VG9Sb2xlcyh0ZXN0UHJvcHMpO1xuICAgICAgY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocmVzdHJpY3Rpb24uZGVueVN0YXRlbWVudCwgdW5kZWZpbmVkLCAyKSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24uZGVueVN0YXRlbWVudC5hY3Rpb25zKS50b1N0cmljdEVxdWFsKFsnczM6UHV0T2JqZWN0KicsICdzMzpHZXRPYmplY3QqJywgJ3MzOkRlbGV0ZU9iamVjdConXSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24uZGVueVN0YXRlbWVudC5lZmZlY3QpLnRvQmUoJ0RlbnknKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5kZW55U3RhdGVtZW50LmNvbmRpdGlvbnMpLnRvU3RyaWN0RXF1YWwoe1xuICAgICAgICAnRm9yQW55VmFsdWU6U3RyaW5nTm90TGlrZSc6IHtcbiAgICAgICAgICAnYXdzOnVzZXJJZCc6IFsndGVzdC1yb2xlLWlkLTE6KicsICd0ZXN0LXJvbGUtaWQtMjoqJ10sXG4gICAgICAgICAgJ2F3czpQcmluY2lwYWxBcm4nOiBbJ3Rlc3QtYXJuJ10sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
@@ -1,215 +0,0 @@
1
- /*!
2
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3
- * SPDX-License-Identifier: Apache-2.0
4
- */
5
-
6
- import { MdaaTestApp } from '@aws-mdaa/testing';
7
- import {
8
- IRestrictBucketToRoles,
9
- IRestrictObjectPrefixToRoles,
10
- RestrictBucketToRoles,
11
- RestrictObjectPrefixToRoles,
12
- } from '../lib';
13
- import { Bucket } from 'aws-cdk-lib/aws-s3';
14
- import { ArnPrincipal } from 'aws-cdk-lib/aws-iam';
15
-
16
- describe('Test BucketPolicy Helper', () => {
17
- const testApp = new MdaaTestApp();
18
- const testBucket = Bucket.fromBucketName(testApp.testStack, 'test-bucket', 'test-bucket');
19
- describe('RestrictPrefix', () => {
20
- const baseTestProps: IRestrictObjectPrefixToRoles = {
21
- s3Bucket: testBucket,
22
- s3Prefix: 'test-prefix',
23
- };
24
- test('Read Role Ids', () => {
25
- const testProps: IRestrictObjectPrefixToRoles = {
26
- ...baseTestProps,
27
- readRoleIds: ['test-role-id-1', 'test-role-id-2'],
28
- };
29
- const restriction = new RestrictObjectPrefixToRoles(testProps);
30
- // console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
31
- expect(restriction.statements().length).toBe(1);
32
- expect(restriction.readStatements().length).toBe(1);
33
- expect(restriction.readWriteSuperStatements().length).toBe(0);
34
- expect(restriction.readWriteStatements().length).toBe(0);
35
- expect(restriction.readStatements()[0].actions).toStrictEqual(['s3:GetObject*']);
36
- expect(restriction.readStatements()[0].conditions).toStrictEqual({
37
- StringLike: {
38
- 'aws:userId': ['test-role-id-1:*', 'test-role-id-2:*'],
39
- },
40
- });
41
- expect(restriction.readStatements()[0].effect).toBe('Allow');
42
- expect(restriction.readStatements()[0].resources).toStrictEqual([
43
- 'arn:test-partition:s3:::test-bucket/test-prefix/*',
44
- ]);
45
- });
46
-
47
- test('ReadWrite Role Ids', () => {
48
- const testProps: IRestrictObjectPrefixToRoles = {
49
- ...baseTestProps,
50
- readWriteRoleIds: ['test-role-id-1', 'test-role-id-2'],
51
- };
52
- const restriction = new RestrictObjectPrefixToRoles(testProps);
53
- // console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
54
- expect(restriction.statements().length).toBe(1);
55
- expect(restriction.readWriteStatements().length).toBe(1);
56
- expect(restriction.readStatements().length).toBe(0);
57
- expect(restriction.readWriteSuperStatements().length).toBe(0);
58
- expect(restriction.readWriteStatements()[0].actions).toStrictEqual([
59
- 's3:GetObject*',
60
- 's3:PutObject',
61
- 's3:PutObjectTagging',
62
- 's3:DeleteObject',
63
- ]);
64
- expect(restriction.readWriteStatements()[0].conditions).toStrictEqual({
65
- StringLike: {
66
- 'aws:userId': ['test-role-id-1:*', 'test-role-id-2:*'],
67
- },
68
- });
69
- });
70
-
71
- test('ReadWriteSuper Role Ids', () => {
72
- const testProps: IRestrictObjectPrefixToRoles = {
73
- ...baseTestProps,
74
- readWriteSuperRoleIds: ['test-role-id-1', 'test-role-id-2'],
75
- };
76
- const restriction = new RestrictObjectPrefixToRoles(testProps);
77
- // console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
78
- expect(restriction.statements().length).toBe(1);
79
- expect(restriction.readWriteSuperStatements().length).toBe(1);
80
- expect(restriction.readStatements().length).toBe(0);
81
- expect(restriction.readWriteStatements().length).toBe(0);
82
- expect(restriction.readWriteSuperStatements()[0].actions).toStrictEqual([
83
- 's3:GetObject*',
84
- 's3:PutObject',
85
- 's3:PutObjectTagging',
86
- 's3:DeleteObject',
87
- 's3:DeleteObjectVersion',
88
- ]);
89
- expect(restriction.readWriteSuperStatements()[0].conditions).toStrictEqual({
90
- StringLike: {
91
- 'aws:userId': ['test-role-id-1:*', 'test-role-id-2:*'],
92
- },
93
- });
94
- });
95
-
96
- test('Read Principals', () => {
97
- const testProps: IRestrictObjectPrefixToRoles = {
98
- ...baseTestProps,
99
- readPrincipals: [new ArnPrincipal('test-role-arn-1')],
100
- };
101
- const restriction = new RestrictObjectPrefixToRoles(testProps);
102
- // console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
103
- expect(restriction.statements().length).toBe(1);
104
- expect(restriction.readStatements().length).toBe(1);
105
- expect(restriction.readWriteSuperStatements().length).toBe(0);
106
- expect(restriction.readWriteStatements().length).toBe(0);
107
- expect(restriction.readStatements()[0].actions).toStrictEqual(['s3:GetObject*']);
108
- expect(restriction.readStatements()[0].effect).toBe('Allow');
109
- expect(restriction.readStatements()[0].resources).toStrictEqual([
110
- 'arn:test-partition:s3:::test-bucket/test-prefix/*',
111
- ]);
112
- expect(restriction.readStatements()[0].principals.length).toBe(1);
113
- expect(JSON.stringify(restriction.readStatements()[0].principals[0])).toStrictEqual(
114
- JSON.stringify({ AWS: ['test-role-arn-1'] }),
115
- );
116
- });
117
-
118
- test('ReadWrite Principals', () => {
119
- const testProps: IRestrictObjectPrefixToRoles = {
120
- ...baseTestProps,
121
- readWritePrincipals: [new ArnPrincipal('test-role-arn-1')],
122
- };
123
- const restriction = new RestrictObjectPrefixToRoles(testProps);
124
- // console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
125
- expect(restriction.statements().length).toBe(1);
126
- expect(restriction.readWriteStatements().length).toBe(1);
127
- expect(restriction.readStatements().length).toBe(0);
128
- expect(restriction.readWriteSuperStatements().length).toBe(0);
129
- expect(restriction.readWriteStatements()[0].actions).toStrictEqual([
130
- 's3:GetObject*',
131
- 's3:PutObject',
132
- 's3:PutObjectTagging',
133
- 's3:DeleteObject',
134
- ]);
135
- expect(restriction.readWriteStatements()[0].effect).toBe('Allow');
136
- expect(restriction.readWriteStatements()[0].resources).toStrictEqual([
137
- 'arn:test-partition:s3:::test-bucket/test-prefix/*',
138
- ]);
139
- expect(restriction.readWriteStatements()[0].principals.length).toBe(1);
140
- expect(JSON.stringify(restriction.readWriteStatements()[0].principals[0])).toStrictEqual(
141
- JSON.stringify({ AWS: ['test-role-arn-1'] }),
142
- );
143
- });
144
-
145
- test('ReadWriteSuper Principals', () => {
146
- const testProps: IRestrictObjectPrefixToRoles = {
147
- ...baseTestProps,
148
- readWriteSuperPrincipals: [new ArnPrincipal('test-role-arn-1')],
149
- };
150
- const restriction = new RestrictObjectPrefixToRoles(testProps);
151
- // console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
152
- expect(restriction.statements().length).toBe(1);
153
- expect(restriction.readStatements().length).toBe(0);
154
- expect(restriction.readWriteStatements().length).toBe(0);
155
- expect(restriction.readWriteSuperStatements().length).toBe(1);
156
- expect(restriction.readWriteSuperStatements()[0].actions).toStrictEqual([
157
- 's3:GetObject*',
158
- 's3:PutObject',
159
- 's3:PutObjectTagging',
160
- 's3:DeleteObject',
161
- 's3:DeleteObjectVersion',
162
- ]);
163
- expect(restriction.readWriteSuperStatements()[0].effect).toBe('Allow');
164
- expect(restriction.readWriteSuperStatements()[0].resources).toStrictEqual([
165
- 'arn:test-partition:s3:::test-bucket/test-prefix/*',
166
- ]);
167
- expect(restriction.readWriteSuperStatements()[0].principals.length).toBe(1);
168
- expect(JSON.stringify(restriction.readWriteSuperStatements()[0].principals[0])).toStrictEqual(
169
- JSON.stringify({ AWS: ['test-role-arn-1'] }),
170
- );
171
- });
172
- });
173
- describe('RestrictBucket', () => {
174
- const baseTestProps: IRestrictBucketToRoles = {
175
- s3Bucket: testBucket,
176
- roleExcludeIds: ['test-role-id-1', 'test-role-id-2'],
177
- principalExcludes: ['test-arn'],
178
- prefixExcludes: ['exclude-prefix'],
179
- prefixIncludes: ['exclude-prefix'],
180
- };
181
- test('Base Allow', () => {
182
- const testProps: IRestrictBucketToRoles = {
183
- ...baseTestProps,
184
- };
185
- const restriction = new RestrictBucketToRoles(testProps);
186
- console.log(JSON.stringify(restriction.allowStatement, undefined, 2));
187
- expect(restriction.allowStatement.actions).toStrictEqual(['s3:List*', 's3:GetBucket*']);
188
- expect(restriction.allowStatement.effect).toBe('Allow');
189
- expect(restriction.allowStatement.conditions).toStrictEqual({
190
- StringLike: {
191
- 'aws:userId': ['test-role-id-1:*', 'test-role-id-2:*'],
192
- },
193
- });
194
- expect(restriction.allowStatement.resources).toStrictEqual([
195
- 'arn:test-partition:s3:::test-bucket/*',
196
- 'arn:test-partition:s3:::test-bucket',
197
- ]);
198
- });
199
- test('Base Deny', () => {
200
- const testProps: IRestrictBucketToRoles = {
201
- ...baseTestProps,
202
- };
203
- const restriction = new RestrictBucketToRoles(testProps);
204
- console.log(JSON.stringify(restriction.denyStatement, undefined, 2));
205
- expect(restriction.denyStatement.actions).toStrictEqual(['s3:PutObject*', 's3:GetObject*', 's3:DeleteObject*']);
206
- expect(restriction.denyStatement.effect).toBe('Deny');
207
- expect(restriction.denyStatement.conditions).toStrictEqual({
208
- 'ForAnyValue:StringNotLike': {
209
- 'aws:userId': ['test-role-id-1:*', 'test-role-id-2:*'],
210
- 'aws:PrincipalArn': ['test-arn'],
211
- },
212
- });
213
- });
214
- });
215
- });