@mapbox/cloudfriend 9.2.0 → 9.3.1
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.
- package/.claude/settings.local.json +8 -0
- package/.idea/cloudfriend.iml +9 -0
- package/.idea/codeStyles/Project.xml +7 -0
- package/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/.idea/misc.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/.nyc_output/6686e513-03b6-415d-9b8b-0fcde7a4e430.json +1 -0
- package/.nyc_output/f58a557c-a1c0-4dcc-83c5-bbca4d01baf9.json +1 -0
- package/.nyc_output/processinfo/6686e513-03b6-415d-9b8b-0fcde7a4e430.json +1 -0
- package/.nyc_output/processinfo/f58a557c-a1c0-4dcc-83c5-bbca4d01baf9.json +1 -0
- package/.nyc_output/processinfo/index.json +1 -1
- package/cfniceberg_createtable.yaml +71 -0
- package/changelog.md +8 -0
- package/coverage/clover.xml +630 -0
- package/coverage/coverage-final.json +33 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/cloudfriend/bin/build-template.js.html +130 -0
- package/coverage/lcov-report/cloudfriend/bin/index.html +131 -0
- package/coverage/lcov-report/cloudfriend/bin/validate-template.js.html +142 -0
- package/coverage/lcov-report/cloudfriend/index.html +116 -0
- package/coverage/lcov-report/cloudfriend/index.js.html +307 -0
- package/coverage/lcov-report/cloudfriend/lib/build.js.html +217 -0
- package/coverage/lcov-report/cloudfriend/lib/conditions.js.html +430 -0
- package/coverage/lcov-report/cloudfriend/lib/index.html +206 -0
- package/coverage/lcov-report/cloudfriend/lib/intrinsic.js.html +979 -0
- package/coverage/lcov-report/cloudfriend/lib/merge.js.html +478 -0
- package/coverage/lcov-report/cloudfriend/lib/pseudo.js.html +370 -0
- package/coverage/lcov-report/cloudfriend/lib/rules.js.html +349 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/cross-account-role.js.html +244 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/event-lambda.js.html +367 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-database.js.html +286 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-iceberg-table.js.html +646 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-json-table.js.html +235 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-orc-table.js.html +226 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-parquet-table.js.html +268 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-presto-view.js.html +358 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-spark-view.js.html +241 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/glue-table.js.html +481 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/hookshot.js.html +1504 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/index.html +431 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/index.js.html +157 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/kinesis-firehose-base.js.html +418 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/lambda.js.html +832 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/log-subscription-lambda.js.html +310 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/queue-lambda.js.html +364 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/queue.js.html +619 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/role.js.html +382 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/s3-kinesis-firehose.js.html +568 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/scheduled-lambda.js.html +490 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/service-role.js.html +307 -0
- package/coverage/lcov-report/cloudfriend/lib/shortcuts/stream-lambda.js.html +493 -0
- package/coverage/lcov-report/cloudfriend/lib/validate.js.html +154 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +161 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov.info +1319 -0
- package/jest.config.js +14 -0
- package/lib/shortcuts/api.md +37 -0
- package/lib/shortcuts/glue-iceberg-table.js +187 -0
- package/lib/shortcuts/index.js +1 -0
- package/package.json +15 -13
- package/readme.md +1 -1
- package/requirements.dev.txt +2 -2
- package/test/bin.test.js +18 -14
- package/test/fixtures/shortcuts/cross-account-role-defaults.json +1 -1
- package/test/fixtures/shortcuts/cross-account-role-no-defaults.json +1 -1
- package/test/fixtures/shortcuts/event-lambda-defaults.json +1 -1
- package/test/fixtures/shortcuts/event-lambda-full.json +1 -1
- package/test/fixtures/shortcuts/firehose-defaults.json +1 -1
- package/test/fixtures/shortcuts/firehose-with-stream.json +1 -1
- package/test/fixtures/shortcuts/glue-database-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-database-no-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-iceberg-table-defaults.json +41 -0
- package/test/fixtures/shortcuts/glue-iceberg-table-no-defaults.json +39 -0
- package/test/fixtures/shortcuts/glue-iceberg-table-with-all-optimizers.json +101 -0
- package/test/fixtures/shortcuts/glue-iceberg-table-with-both-optimizers.json +80 -0
- package/test/fixtures/shortcuts/glue-iceberg-table-with-compaction-custom.json +68 -0
- package/test/fixtures/shortcuts/glue-iceberg-table-with-compaction-defaults.json +57 -0
- package/test/fixtures/shortcuts/glue-iceberg-table-with-optimizer-custom.json +75 -0
- package/test/fixtures/shortcuts/glue-iceberg-table-with-optimizer-defaults.json +64 -0
- package/test/fixtures/shortcuts/glue-iceberg-table-with-orphan-deletion-custom.json +74 -0
- package/test/fixtures/shortcuts/glue-iceberg-table-with-orphan-deletion-defaults.json +62 -0
- package/test/fixtures/shortcuts/glue-json-table-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-json-table-no-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-orc-table-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-orc-table-no-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-parquet-table-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-parquet-table-no-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-table-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-table-no-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-view-defaults.json +1 -1
- package/test/fixtures/shortcuts/glue-view-no-defaults.json +1 -1
- package/test/fixtures/shortcuts/hookshot-github-secret-ref.json +1 -1
- package/test/fixtures/shortcuts/hookshot-github-secret-string.json +1 -1
- package/test/fixtures/shortcuts/hookshot-github.json +1 -1
- package/test/fixtures/shortcuts/hookshot-passthrough-access-log-format.json +1 -1
- package/test/fixtures/shortcuts/hookshot-passthrough-alarms.json +1 -1
- package/test/fixtures/shortcuts/hookshot-passthrough-enhanced-logging.json +1 -1
- package/test/fixtures/shortcuts/hookshot-passthrough-full-blown-logging.json +1 -1
- package/test/fixtures/shortcuts/hookshot-passthrough-logging.json +1 -1
- package/test/fixtures/shortcuts/hookshot-passthrough.json +1 -1
- package/test/fixtures/shortcuts/lambda-defaults.json +1 -1
- package/test/fixtures/shortcuts/lambda-docker.json +1 -1
- package/test/fixtures/shortcuts/lambda-full.json +1 -1
- package/test/fixtures/shortcuts/lambda-provided-role.json +1 -1
- package/test/fixtures/shortcuts/lambda-zipfile.json +1 -1
- package/test/fixtures/shortcuts/log-subscription-lambda-defaults.json +1 -1
- package/test/fixtures/shortcuts/log-subscription-lambda-no-defaults.json +1 -1
- package/test/fixtures/shortcuts/queue-defaults.json +1 -1
- package/test/fixtures/shortcuts/queue-external-topic-ref.json +1 -1
- package/test/fixtures/shortcuts/queue-external-topic.json +1 -1
- package/test/fixtures/shortcuts/queue-fifo-queuename.json +1 -1
- package/test/fixtures/shortcuts/queue-fifo.json +1 -1
- package/test/fixtures/shortcuts/queue-full.json +1 -1
- package/test/fixtures/shortcuts/queue-lambda-zero.json +1 -1
- package/test/fixtures/shortcuts/queue-lambda.json +1 -1
- package/test/fixtures/shortcuts/role-defaults.json +1 -1
- package/test/fixtures/shortcuts/role-no-defaults.json +1 -1
- package/test/fixtures/shortcuts/scheduled-lambda-defaults.json +1 -1
- package/test/fixtures/shortcuts/scheduled-lambda-full.json +1 -1
- package/test/fixtures/shortcuts/service-role-defaults.json +1 -1
- package/test/fixtures/shortcuts/service-role-no-defaults.json +1 -1
- package/test/fixtures/shortcuts/service-role-no-url-suffix.json +1 -1
- package/test/fixtures/shortcuts/service-role-url-suffix-with-replacement.json +1 -1
- package/test/fixtures/shortcuts/service-role-url-suffix.json +1 -1
- package/test/fixtures/shortcuts/stream-lambda-defaults.json +1 -1
- package/test/fixtures/shortcuts/stream-lambda-no-defaults.json +1 -1
- package/test/index.test.js +383 -235
- package/test/shortcuts.test.js +1523 -1483
- package/.nyc_output/2b544c0b-2830-4ad0-97cd-8e661710b0bb.json +0 -1
- package/.nyc_output/65e58b48-bf1c-412d-8dd4-d7b564b12d76.json +0 -1
- package/.nyc_output/processinfo/2b544c0b-2830-4ad0-97cd-8e661710b0bb.json +0 -1
- package/.nyc_output/processinfo/65e58b48-bf1c-412d-8dd4-d7b564b12d76.json +0 -1
package/jest.config.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
testEnvironment: 'node',
|
|
5
|
+
testMatch: ['**/test/*.test.js'],
|
|
6
|
+
collectCoverageFrom: [
|
|
7
|
+
'index.js',
|
|
8
|
+
'lib/**/*.js',
|
|
9
|
+
'bin/**/*.js',
|
|
10
|
+
'!**/node_modules/**'
|
|
11
|
+
],
|
|
12
|
+
coverageDirectory: 'coverage',
|
|
13
|
+
verbose: true
|
|
14
|
+
};
|
package/lib/shortcuts/api.md
CHANGED
|
@@ -12,6 +12,9 @@ a Lambda permission.</p>
|
|
|
12
12
|
<dt><a href="#GlueDatabase">GlueDatabase</a></dt>
|
|
13
13
|
<dd><p>Create a Glue Database.</p>
|
|
14
14
|
</dd>
|
|
15
|
+
<dt><a href="#GlueIcebergTable">GlueIcebergTable</a></dt>
|
|
16
|
+
<dd><p>Create a Glue table backed by Apache Iceberg format on S3.</p>
|
|
17
|
+
</dd>
|
|
15
18
|
<dt><a href="#GlueJsonTable">GlueJsonTable</a></dt>
|
|
16
19
|
<dd><p>Create a Glue Table backed by line-delimited JSON files on S3.</p>
|
|
17
20
|
</dd>
|
|
@@ -202,6 +205,40 @@ const db = new cf.shortcuts.GlueDatabase({
|
|
|
202
205
|
|
|
203
206
|
module.exports = cf.merge(myTemplate, db);
|
|
204
207
|
```
|
|
208
|
+
<a name="GlueIcebergTable"></a>
|
|
209
|
+
|
|
210
|
+
## GlueIcebergTable
|
|
211
|
+
Create a Glue table backed by Apache Iceberg format on S3.
|
|
212
|
+
|
|
213
|
+
**Kind**: global class
|
|
214
|
+
<a name="new_GlueIcebergTable_new"></a>
|
|
215
|
+
|
|
216
|
+
### new GlueIcebergTable(options)
|
|
217
|
+
|
|
218
|
+
| Param | Type | Default | Description |
|
|
219
|
+
| --- | --- | --- | --- |
|
|
220
|
+
| options | <code>Object</code> | | Options for creating an Iceberg table. |
|
|
221
|
+
| options.LogicalName | <code>String</code> | | The logical name of the Glue Table within the CloudFormation template. |
|
|
222
|
+
| options.Name | <code>String</code> | | The name of the table. |
|
|
223
|
+
| options.DatabaseName | <code>String</code> | | The name of the database the table resides in. |
|
|
224
|
+
| options.Location | <code>String</code> | | The physical location of the table (S3 URI). Required. |
|
|
225
|
+
| options.Schema | <code>Object</code> | | Full Iceberg schema definition with Type: "struct" and Fields array. Each field must have Id (integer), Name (string), Type (string or object for complex types), and Required (boolean). See [AWS documentation](https://docs.aws.amazon.com/glue/latest/webapi/API_IcebergSchema.html). |
|
|
226
|
+
| [options.PartitionSpec] | <code>Object</code> | | Iceberg partition specification. See [AWS documentation](https://docs.aws.amazon.com/glue/latest/webapi/API_IcebergPartitionSpec.html). |
|
|
227
|
+
| [options.WriteOrder] | <code>Object</code> | | Iceberg write order specification. See [AWS documentation](https://docs.aws.amazon.com/glue/latest/webapi/API_IcebergSortOrder.html). |
|
|
228
|
+
| [options.CatalogId] | <code>String</code> | <code>AccountId</code> | The AWS account ID for the account in which to create the table. |
|
|
229
|
+
| [options.IcebergVersion] | <code>String</code> | <code>'2'</code> | The table version for the Iceberg table. |
|
|
230
|
+
| [options.EnableOptimizer] | <code>Boolean</code> | <code>false</code> | Whether to enable the snapshot retention optimizer. |
|
|
231
|
+
| [options.OptimizerRoleArn] | <code>String</code> | | The ARN of the IAM role for the retention optimizer. Required if EnableOptimizer is true. |
|
|
232
|
+
| [options.SnapshotRetentionPeriodInDays] | <code>Number</code> | <code>5</code> | The number of days to retain snapshots. |
|
|
233
|
+
| [options.NumberOfSnapshotsToRetain] | <code>Number</code> | <code>1</code> | The minimum number of snapshots to retain. |
|
|
234
|
+
| [options.CleanExpiredFiles] | <code>Boolean</code> | <code>true</code> | Whether to delete expired data files after expiring snapshots. |
|
|
235
|
+
| [options.EnableCompaction] | <code>Boolean</code> | <code>false</code> | Whether to enable the compaction optimizer. |
|
|
236
|
+
| [options.CompactionRoleArn] | <code>String</code> | | The ARN of the IAM role for the compaction optimizer. Required if EnableCompaction is true. |
|
|
237
|
+
| [options.EnableOrphanFileDeletion] | <code>Boolean</code> | <code>false</code> | Whether to enable the orphan file deletion optimizer. |
|
|
238
|
+
| [options.OrphanFileDeletionRoleArn] | <code>String</code> | | The ARN of the IAM role for the orphan file deletion optimizer. Required if EnableOrphanFileDeletion is true. |
|
|
239
|
+
| [options.OrphanFileRetentionPeriodInDays] | <code>Number</code> | <code>3</code> | The number of days to retain orphan files before deleting them. |
|
|
240
|
+
| [options.OrphanFileDeletionLocation] | <code>String</code> | | The S3 location to scan for orphan files. |
|
|
241
|
+
|
|
205
242
|
<a name="GlueJsonTable"></a>
|
|
206
243
|
|
|
207
244
|
## GlueJsonTable
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Create a Glue table backed by Apache Iceberg format on S3.
|
|
5
|
+
*
|
|
6
|
+
* @param {Object} options - Options for creating an Iceberg table.
|
|
7
|
+
* @param {String} options.LogicalName - The logical name of the Glue Table within the CloudFormation template.
|
|
8
|
+
* @param {String} options.Name - The name of the table.
|
|
9
|
+
* @param {String} options.DatabaseName - The name of the database the table resides in.
|
|
10
|
+
* @param {String} options.Location - The physical location of the table (S3 URI). Required.
|
|
11
|
+
* @param {Object} options.Schema - Full Iceberg schema definition with Type: "struct" and Fields array.
|
|
12
|
+
* Each field must have Id (integer), Name (string), Type (string or object for complex types), and Required (boolean).
|
|
13
|
+
* See [AWS
|
|
14
|
+
* documentation](https://docs.aws.amazon.com/glue/latest/webapi/API_IcebergSchema.html).
|
|
15
|
+
* @param {Object} [options.PartitionSpec] - Iceberg partition specification. See [AWS
|
|
16
|
+
* documentation](https://docs.aws.amazon.com/glue/latest/webapi/API_IcebergPartitionSpec.html).
|
|
17
|
+
* @param {Object} [options.WriteOrder] - Iceberg write order specification. See [AWS
|
|
18
|
+
* documentation](https://docs.aws.amazon.com/glue/latest/webapi/API_IcebergSortOrder.html).
|
|
19
|
+
* @param {String} [options.CatalogId=AccountId] - The AWS account ID for the account in which to create the table.
|
|
20
|
+
* @param {String} [options.IcebergVersion='2'] - The table version for the Iceberg table.
|
|
21
|
+
* @param {Boolean} [options.EnableOptimizer=false] - Whether to enable the snapshot retention optimizer.
|
|
22
|
+
* @param {String} [options.OptimizerRoleArn=undefined] - The ARN of the IAM role for the retention optimizer. Required if EnableOptimizer is true.
|
|
23
|
+
* @param {Number} [options.SnapshotRetentionPeriodInDays=5] - The number of days to retain snapshots.
|
|
24
|
+
* @param {Number} [options.NumberOfSnapshotsToRetain=1] - The minimum number of snapshots to retain.
|
|
25
|
+
* @param {Boolean} [options.CleanExpiredFiles=true] - Whether to delete expired data files after expiring snapshots.
|
|
26
|
+
* @param {Boolean} [options.EnableCompaction=false] - Whether to enable the compaction optimizer.
|
|
27
|
+
* @param {String} [options.CompactionRoleArn=undefined] - The ARN of the IAM role for the compaction optimizer. Required if EnableCompaction is true.
|
|
28
|
+
* @param {Boolean} [options.EnableOrphanFileDeletion=false] - Whether to enable the orphan file deletion optimizer.
|
|
29
|
+
* @param {String} [options.OrphanFileDeletionRoleArn=undefined] - The ARN of the IAM role for the orphan file deletion optimizer. Required if EnableOrphanFileDeletion is true.
|
|
30
|
+
* @param {Number} [options.OrphanFileRetentionPeriodInDays=3] - The number of days to retain orphan files before deleting them.
|
|
31
|
+
* @param {String} [options.OrphanFileDeletionLocation=undefined] - The S3 location to scan for orphan files.
|
|
32
|
+
*/
|
|
33
|
+
class GlueIcebergTable {
|
|
34
|
+
constructor(options) {
|
|
35
|
+
if (!options) throw new Error('Options required');
|
|
36
|
+
const {
|
|
37
|
+
LogicalName,
|
|
38
|
+
Name,
|
|
39
|
+
DatabaseName,
|
|
40
|
+
Location,
|
|
41
|
+
Schema,
|
|
42
|
+
PartitionSpec,
|
|
43
|
+
WriteOrder,
|
|
44
|
+
CatalogId = { Ref: 'AWS::AccountId' },
|
|
45
|
+
IcebergVersion = '2',
|
|
46
|
+
EnableOptimizer = false,
|
|
47
|
+
OptimizerRoleArn,
|
|
48
|
+
SnapshotRetentionPeriodInDays = 5,
|
|
49
|
+
NumberOfSnapshotsToRetain = 1,
|
|
50
|
+
CleanExpiredFiles = true,
|
|
51
|
+
EnableCompaction = false,
|
|
52
|
+
CompactionRoleArn,
|
|
53
|
+
EnableOrphanFileDeletion = false,
|
|
54
|
+
OrphanFileDeletionRoleArn,
|
|
55
|
+
OrphanFileRetentionPeriodInDays = 3,
|
|
56
|
+
OrphanFileDeletionLocation
|
|
57
|
+
} = options;
|
|
58
|
+
|
|
59
|
+
// Validate required fields
|
|
60
|
+
const required = [LogicalName, Name, DatabaseName, Location, Schema];
|
|
61
|
+
if (required.some((variable) => !variable))
|
|
62
|
+
throw new Error('You must provide a LogicalName, Name, DatabaseName, Location, and Schema');
|
|
63
|
+
|
|
64
|
+
if (EnableOptimizer && !OptimizerRoleArn)
|
|
65
|
+
throw new Error('You must provide an OptimizerRoleArn when EnableOptimizer is true');
|
|
66
|
+
|
|
67
|
+
if (EnableCompaction && !CompactionRoleArn)
|
|
68
|
+
throw new Error('You must provide a CompactionRoleArn when EnableCompaction is true');
|
|
69
|
+
|
|
70
|
+
if (EnableOrphanFileDeletion && !OrphanFileDeletionRoleArn)
|
|
71
|
+
throw new Error('You must provide an OrphanFileDeletionRoleArn when EnableOrphanFileDeletion is true');
|
|
72
|
+
|
|
73
|
+
// Build the Iceberg table resource (no TableInput!)
|
|
74
|
+
this.Resources = {
|
|
75
|
+
[LogicalName]: {
|
|
76
|
+
Type: 'AWS::Glue::Table',
|
|
77
|
+
Properties: {
|
|
78
|
+
CatalogId,
|
|
79
|
+
DatabaseName,
|
|
80
|
+
Name,
|
|
81
|
+
OpenTableFormatInput: {
|
|
82
|
+
IcebergInput: {
|
|
83
|
+
MetadataOperation: 'CREATE', // NOTE: this is _always_ CREATE because it's about creating a new metadata version, not creating a new table
|
|
84
|
+
Version: IcebergVersion,
|
|
85
|
+
IcebergTableInput: {
|
|
86
|
+
Location,
|
|
87
|
+
Schema
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
// Add optional PartitionSpec if provided
|
|
96
|
+
if (PartitionSpec) {
|
|
97
|
+
this.Resources[LogicalName].Properties.OpenTableFormatInput.IcebergInput.IcebergTableInput.PartitionSpec = PartitionSpec;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Add optional WriteOrder if provided
|
|
101
|
+
if (WriteOrder) {
|
|
102
|
+
this.Resources[LogicalName].Properties.OpenTableFormatInput.IcebergInput.IcebergTableInput.WriteOrder = WriteOrder;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Optionally add TableOptimizer for configuring snapshot retention
|
|
106
|
+
if (EnableOptimizer) {
|
|
107
|
+
const optimizerLogicalName = `${LogicalName}RetentionOptimizer`;
|
|
108
|
+
this.Resources[optimizerLogicalName] = {
|
|
109
|
+
Type: 'AWS::Glue::TableOptimizer',
|
|
110
|
+
DependsOn: LogicalName,
|
|
111
|
+
Properties: {
|
|
112
|
+
CatalogId,
|
|
113
|
+
DatabaseName,
|
|
114
|
+
TableName: Name,
|
|
115
|
+
Type: 'retention',
|
|
116
|
+
TableOptimizerConfiguration: {
|
|
117
|
+
RoleArn: OptimizerRoleArn,
|
|
118
|
+
Enabled: true,
|
|
119
|
+
RetentionConfiguration: {
|
|
120
|
+
IcebergConfiguration: {
|
|
121
|
+
SnapshotRetentionPeriodInDays,
|
|
122
|
+
NumberOfSnapshotsToRetain,
|
|
123
|
+
CleanExpiredFiles
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Optionally add TableOptimizer for compaction
|
|
132
|
+
// NOTE: CloudFormation does not support CompactionConfiguration properties
|
|
133
|
+
// (strategy, minInputFiles, deleteFileThreshold). These must be configured
|
|
134
|
+
// via AWS CLI/API after stack creation, or will use AWS defaults.
|
|
135
|
+
// See: https://github.com/aws-cloudformation/cloudformation-coverage-roadmap/issues/2257
|
|
136
|
+
if (EnableCompaction) {
|
|
137
|
+
const compactionLogicalName = `${LogicalName}CompactionOptimizer`;
|
|
138
|
+
this.Resources[compactionLogicalName] = {
|
|
139
|
+
Type: 'AWS::Glue::TableOptimizer',
|
|
140
|
+
DependsOn: LogicalName,
|
|
141
|
+
Properties: {
|
|
142
|
+
CatalogId,
|
|
143
|
+
DatabaseName,
|
|
144
|
+
TableName: Name,
|
|
145
|
+
Type: 'compaction',
|
|
146
|
+
TableOptimizerConfiguration: {
|
|
147
|
+
RoleArn: CompactionRoleArn,
|
|
148
|
+
Enabled: true
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
// Optionally add TableOptimizer for orphan file deletion
|
|
155
|
+
if (EnableOrphanFileDeletion) {
|
|
156
|
+
const orphanLogicalName = `${LogicalName}OrphanFileDeletionOptimizer`;
|
|
157
|
+
const icebergConfiguration = {
|
|
158
|
+
OrphanFileRetentionPeriodInDays
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
// Only add Location if specified, otherwise it defaults to table location
|
|
162
|
+
if (OrphanFileDeletionLocation) {
|
|
163
|
+
icebergConfiguration.Location = OrphanFileDeletionLocation;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
this.Resources[orphanLogicalName] = {
|
|
167
|
+
Type: 'AWS::Glue::TableOptimizer',
|
|
168
|
+
DependsOn: LogicalName,
|
|
169
|
+
Properties: {
|
|
170
|
+
CatalogId,
|
|
171
|
+
DatabaseName,
|
|
172
|
+
TableName: Name,
|
|
173
|
+
Type: 'orphan_file_deletion',
|
|
174
|
+
TableOptimizerConfiguration: {
|
|
175
|
+
RoleArn: OrphanFileDeletionRoleArn,
|
|
176
|
+
Enabled: true,
|
|
177
|
+
OrphanFileDeletionConfiguration: {
|
|
178
|
+
IcebergConfiguration: icebergConfiguration
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
module.exports = GlueIcebergTable;
|
package/lib/shortcuts/index.js
CHANGED
|
@@ -16,6 +16,7 @@ module.exports = {
|
|
|
16
16
|
GlueJsonTable: require('./glue-json-table'),
|
|
17
17
|
GlueOrcTable: require('./glue-orc-table'),
|
|
18
18
|
GlueParquetTable: require('./glue-parquet-table'),
|
|
19
|
+
GlueIcebergTable: require('./glue-iceberg-table'),
|
|
19
20
|
GluePrestoView: require('./glue-presto-view'),
|
|
20
21
|
GlueSparkView: require('./glue-spark-view'),
|
|
21
22
|
hookshot: require('./hookshot'),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mapbox/cloudfriend",
|
|
3
|
-
"version": "9.
|
|
3
|
+
"version": "9.3.1",
|
|
4
4
|
"description": "Helper functions for assembling CloudFormation templates in JavaScript",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"engines": {
|
|
@@ -8,11 +8,10 @@
|
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"pretest": "npm run lint && npm run shortcuts-api-doc",
|
|
11
|
-
"lint": "eslint index.js test lib bin
|
|
11
|
+
"lint": "eslint index.js test lib bin",
|
|
12
12
|
"lint:fix": "npm run lint -- --fix",
|
|
13
|
-
"test": "
|
|
14
|
-
"test:update": "
|
|
15
|
-
"coverage": "nyc --reporter html tape test/*.test.js && opener coverage/index.html",
|
|
13
|
+
"test": "jest --coverage",
|
|
14
|
+
"test:update": "jest --updateSnapshot",
|
|
16
15
|
"build-ci-template": "bin/build-template.js cloudformation/ci.template.js > cloudformation/ci.template.json",
|
|
17
16
|
"shortcuts-api-doc": "jsdoc2md lib/shortcuts/*.js > lib/shortcuts/api.md"
|
|
18
17
|
},
|
|
@@ -35,14 +34,11 @@
|
|
|
35
34
|
},
|
|
36
35
|
"homepage": "https://github.com/mapbox/cloudfriend#readme",
|
|
37
36
|
"devDependencies": {
|
|
38
|
-
"@mapbox/eslint-config-mapbox": "^
|
|
39
|
-
"eslint": "^
|
|
37
|
+
"@mapbox/eslint-config-mapbox": "^5.0.1",
|
|
38
|
+
"eslint": "^8.57.0",
|
|
40
39
|
"eslint-plugin-node": "^6.0.1",
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"opener": "^1.4.1",
|
|
44
|
-
"tap-spec": "^5.0.0",
|
|
45
|
-
"tape": "^4.6.0"
|
|
40
|
+
"jest": "^29.7.0",
|
|
41
|
+
"jsdoc-to-markdown": "^9.1.3"
|
|
46
42
|
},
|
|
47
43
|
"dependencies": {
|
|
48
44
|
"@aws-sdk/client-cloudformation": "^3.848.0",
|
|
@@ -50,6 +46,12 @@
|
|
|
50
46
|
"redent": "^2.0.0"
|
|
51
47
|
},
|
|
52
48
|
"eslintConfig": {
|
|
53
|
-
"extends": "@mapbox/eslint-config-mapbox"
|
|
49
|
+
"extends": "@mapbox/eslint-config-mapbox",
|
|
50
|
+
"env": {
|
|
51
|
+
"jest": true
|
|
52
|
+
},
|
|
53
|
+
"ignorePatterns": [
|
|
54
|
+
"test/fixtures/malformed.json"
|
|
55
|
+
]
|
|
54
56
|
}
|
|
55
57
|
}
|
package/readme.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# cloudfriend
|
|
2
2
|
|
|
3
|
-
[](https://github.com/mapbox/cloudfriend/actions/workflows/test.yml)
|
|
4
4
|
|
|
5
5
|
Helper functions for assembling CloudFormation templates in JavaScript.
|
|
6
6
|
|
package/requirements.dev.txt
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
aws-sam-cli==1.
|
|
2
|
-
cfn-lint==1.
|
|
1
|
+
aws-sam-cli==1.149.0
|
|
2
|
+
cfn-lint==1.41.0
|
package/test/bin.test.js
CHANGED
|
@@ -1,22 +1,26 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const path = require('path');
|
|
4
|
-
const
|
|
5
|
-
const
|
|
4
|
+
const { execFile } = require('child_process');
|
|
5
|
+
const { promisify } = require('util');
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
const execFileAsync = promisify(execFile);
|
|
8
|
+
|
|
9
|
+
describe('bin/build-template', () => {
|
|
8
10
|
const script = path.normalize(__dirname + '/../bin/build-template.js');
|
|
9
11
|
const template = path.normalize(__dirname + '/fixtures/sync-args.js');
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
|
|
13
|
+
test('outputs expected', async () => {
|
|
14
|
+
const { stdout, stderr } = await execFileAsync(script, [
|
|
15
|
+
template,
|
|
16
|
+
'--this',
|
|
17
|
+
'that',
|
|
18
|
+
'-r',
|
|
19
|
+
'cn-north-1'
|
|
20
|
+
]);
|
|
21
|
+
expect(stderr).toBeFalsy();
|
|
22
|
+
const result = JSON.parse(stdout);
|
|
23
|
+
expect(result.this).toBe('that');
|
|
24
|
+
expect(result.region).toBe('cn-north-1');
|
|
19
25
|
});
|
|
20
|
-
t.end();
|
|
21
26
|
});
|
|
22
|
-
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"AWSTemplateFormatVersion": "2010-09-09",
|
|
3
|
+
"Metadata": {},
|
|
4
|
+
"Parameters": {},
|
|
5
|
+
"Rules": {},
|
|
6
|
+
"Mappings": {},
|
|
7
|
+
"Conditions": {},
|
|
8
|
+
"Resources": {
|
|
9
|
+
"MyTable": {
|
|
10
|
+
"Type": "AWS::Glue::Table",
|
|
11
|
+
"Properties": {
|
|
12
|
+
"CatalogId": {
|
|
13
|
+
"Ref": "AWS::AccountId"
|
|
14
|
+
},
|
|
15
|
+
"DatabaseName": "my_database",
|
|
16
|
+
"Name": "my_table",
|
|
17
|
+
"OpenTableFormatInput": {
|
|
18
|
+
"IcebergInput": {
|
|
19
|
+
"MetadataOperation": "CREATE",
|
|
20
|
+
"Version": "2",
|
|
21
|
+
"IcebergTableInput": {
|
|
22
|
+
"Location": "s3://fake/location",
|
|
23
|
+
"Schema": {
|
|
24
|
+
"Type": "struct",
|
|
25
|
+
"Fields": [
|
|
26
|
+
{
|
|
27
|
+
"Name": "column",
|
|
28
|
+
"Type": "string",
|
|
29
|
+
"Id": 1,
|
|
30
|
+
"Required": true
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"Outputs": {}
|
|
41
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"AWSTemplateFormatVersion": "2010-09-09",
|
|
3
|
+
"Metadata": {},
|
|
4
|
+
"Parameters": {},
|
|
5
|
+
"Rules": {},
|
|
6
|
+
"Mappings": {},
|
|
7
|
+
"Conditions": {},
|
|
8
|
+
"Resources": {
|
|
9
|
+
"MyTable": {
|
|
10
|
+
"Type": "AWS::Glue::Table",
|
|
11
|
+
"Properties": {
|
|
12
|
+
"CatalogId": "1234",
|
|
13
|
+
"DatabaseName": "my_database",
|
|
14
|
+
"Name": "my_table",
|
|
15
|
+
"OpenTableFormatInput": {
|
|
16
|
+
"IcebergInput": {
|
|
17
|
+
"MetadataOperation": "CREATE",
|
|
18
|
+
"Version": "2",
|
|
19
|
+
"IcebergTableInput": {
|
|
20
|
+
"Location": "s3://fake/location",
|
|
21
|
+
"Schema": {
|
|
22
|
+
"Type": "struct",
|
|
23
|
+
"Fields": [
|
|
24
|
+
{
|
|
25
|
+
"Name": "column",
|
|
26
|
+
"Type": "string",
|
|
27
|
+
"Id": 1,
|
|
28
|
+
"Required": true
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
"Outputs": {}
|
|
39
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
{
|
|
2
|
+
"AWSTemplateFormatVersion": "2010-09-09",
|
|
3
|
+
"Metadata": {},
|
|
4
|
+
"Parameters": {},
|
|
5
|
+
"Rules": {},
|
|
6
|
+
"Mappings": {},
|
|
7
|
+
"Conditions": {},
|
|
8
|
+
"Resources": {
|
|
9
|
+
"MyTable": {
|
|
10
|
+
"Type": "AWS::Glue::Table",
|
|
11
|
+
"Properties": {
|
|
12
|
+
"CatalogId": {
|
|
13
|
+
"Ref": "AWS::AccountId"
|
|
14
|
+
},
|
|
15
|
+
"DatabaseName": "my_database",
|
|
16
|
+
"Name": "my_table",
|
|
17
|
+
"OpenTableFormatInput": {
|
|
18
|
+
"IcebergInput": {
|
|
19
|
+
"MetadataOperation": "CREATE",
|
|
20
|
+
"Version": "2",
|
|
21
|
+
"IcebergTableInput": {
|
|
22
|
+
"Location": "s3://fake/location",
|
|
23
|
+
"Schema": {
|
|
24
|
+
"Type": "struct",
|
|
25
|
+
"Fields": [
|
|
26
|
+
{
|
|
27
|
+
"Name": "column",
|
|
28
|
+
"Type": "string",
|
|
29
|
+
"Id": 1,
|
|
30
|
+
"Required": true
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"MyTableRetentionOptimizer": {
|
|
40
|
+
"Type": "AWS::Glue::TableOptimizer",
|
|
41
|
+
"DependsOn": "MyTable",
|
|
42
|
+
"Properties": {
|
|
43
|
+
"CatalogId": {
|
|
44
|
+
"Ref": "AWS::AccountId"
|
|
45
|
+
},
|
|
46
|
+
"DatabaseName": "my_database",
|
|
47
|
+
"TableName": "my_table",
|
|
48
|
+
"Type": "retention",
|
|
49
|
+
"TableOptimizerConfiguration": {
|
|
50
|
+
"RoleArn": "arn:aws:iam::123456789012:role/SharedRole",
|
|
51
|
+
"Enabled": true,
|
|
52
|
+
"RetentionConfiguration": {
|
|
53
|
+
"IcebergConfiguration": {
|
|
54
|
+
"SnapshotRetentionPeriodInDays": 5,
|
|
55
|
+
"NumberOfSnapshotsToRetain": 1,
|
|
56
|
+
"CleanExpiredFiles": true
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
"MyTableCompactionOptimizer": {
|
|
63
|
+
"Type": "AWS::Glue::TableOptimizer",
|
|
64
|
+
"DependsOn": "MyTable",
|
|
65
|
+
"Properties": {
|
|
66
|
+
"CatalogId": {
|
|
67
|
+
"Ref": "AWS::AccountId"
|
|
68
|
+
},
|
|
69
|
+
"DatabaseName": "my_database",
|
|
70
|
+
"TableName": "my_table",
|
|
71
|
+
"Type": "compaction",
|
|
72
|
+
"TableOptimizerConfiguration": {
|
|
73
|
+
"RoleArn": "arn:aws:iam::123456789012:role/SharedRole",
|
|
74
|
+
"Enabled": true
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"MyTableOrphanFileDeletionOptimizer": {
|
|
79
|
+
"Type": "AWS::Glue::TableOptimizer",
|
|
80
|
+
"DependsOn": "MyTable",
|
|
81
|
+
"Properties": {
|
|
82
|
+
"CatalogId": {
|
|
83
|
+
"Ref": "AWS::AccountId"
|
|
84
|
+
},
|
|
85
|
+
"DatabaseName": "my_database",
|
|
86
|
+
"TableName": "my_table",
|
|
87
|
+
"Type": "orphan_file_deletion",
|
|
88
|
+
"TableOptimizerConfiguration": {
|
|
89
|
+
"RoleArn": "arn:aws:iam::123456789012:role/SharedRole",
|
|
90
|
+
"Enabled": true,
|
|
91
|
+
"OrphanFileDeletionConfiguration": {
|
|
92
|
+
"IcebergConfiguration": {
|
|
93
|
+
"OrphanFileRetentionPeriodInDays": 3
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
"Outputs": {}
|
|
101
|
+
}
|