cdk-dms-replication 0.0.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.
- package/.jsii +13491 -0
- package/API.md +8606 -0
- package/LICENSE +202 -0
- package/README.md +883 -0
- package/cdk.context.json +1 -0
- package/integ/sample-app.ts +229 -0
- package/lib/dms-roles.d.ts +14 -0
- package/lib/dms-roles.js +42 -0
- package/lib/endpoint-settings.d.ts +419 -0
- package/lib/endpoint-settings.js +3 -0
- package/lib/endpoint.d.ts +143 -0
- package/lib/endpoint.js +402 -0
- package/lib/enums.d.ts +231 -0
- package/lib/enums.js +266 -0
- package/lib/index.d.ts +9 -0
- package/lib/index.js +49 -0
- package/lib/migration-pipeline.d.ts +253 -0
- package/lib/migration-pipeline.js +218 -0
- package/lib/replication-instance.d.ts +99 -0
- package/lib/replication-instance.js +93 -0
- package/lib/replication-task.d.ts +72 -0
- package/lib/replication-task.js +46 -0
- package/lib/serverless-pipeline.d.ts +196 -0
- package/lib/serverless-pipeline.js +271 -0
- package/lib/table-mappings.d.ts +178 -0
- package/lib/table-mappings.js +283 -0
- package/lib/task-settings.d.ts +228 -0
- package/lib/task-settings.js +291 -0
- package/package.json +170 -0
- package/scripts/sync-instance-classes.js +213 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Queries the DMS API for orderable replication instance classes and
|
|
3
|
+
// regenerates the ReplicationInstanceClass enum in src/enums.ts.
|
|
4
|
+
//
|
|
5
|
+
// Usage:
|
|
6
|
+
// node scripts/sync-instance-classes.js
|
|
7
|
+
// AWS_REGION=eu-west-1 node scripts/sync-instance-classes.js
|
|
8
|
+
//
|
|
9
|
+
// Requires: AWS CLI configured with dms:DescribeOrderableReplicationInstances
|
|
10
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
const { execSync } = require('child_process');
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
|
|
16
|
+
const REGION = process.env.AWS_REGION ?? 'us-east-1';
|
|
17
|
+
const ENUMS_FILE = path.resolve(__dirname, '..', 'src', 'enums.ts');
|
|
18
|
+
|
|
19
|
+
// Known family descriptions and preferred display order.
|
|
20
|
+
// Unknown families (if AWS adds a new one) appear at the end, alphabetically.
|
|
21
|
+
const FAMILY_META = {
|
|
22
|
+
't3': 'T3 — burstable general purpose',
|
|
23
|
+
'c5': 'C5 — compute optimized (previous generation)',
|
|
24
|
+
'c6i': 'C6i — compute optimized (current generation)',
|
|
25
|
+
'c7i': 'C7i — compute optimized (latest generation)',
|
|
26
|
+
'x7i': 'X7i — compute optimized (latest generation, larger sizes)',
|
|
27
|
+
'r5': 'R5 — memory optimized (previous generation)',
|
|
28
|
+
'r6i': 'R6i — memory optimized (current generation)',
|
|
29
|
+
'r7i': 'R7i — memory optimized (latest generation)',
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
const SIZE_ORDER = [
|
|
33
|
+
'micro', 'small', 'medium', 'large',
|
|
34
|
+
'xlarge', '2xlarge', '4xlarge', '8xlarge', '9xlarge',
|
|
35
|
+
'12xlarge', '16xlarge', '18xlarge', '24xlarge', '32xlarge', '48xlarge',
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
// AWS API
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
|
|
42
|
+
function fetchInstanceClasses() {
|
|
43
|
+
const all = new Set();
|
|
44
|
+
let marker;
|
|
45
|
+
|
|
46
|
+
do {
|
|
47
|
+
const markerArg = marker ? `--marker "${marker}"` : '';
|
|
48
|
+
const raw = execSync(
|
|
49
|
+
`aws dms describe-orderable-replication-instances --region ${REGION} ${markerArg} --output json`,
|
|
50
|
+
{ encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] },
|
|
51
|
+
);
|
|
52
|
+
const page = JSON.parse(raw);
|
|
53
|
+
for (const inst of page.OrderableReplicationInstances ?? []) {
|
|
54
|
+
all.add(inst.ReplicationInstanceClass);
|
|
55
|
+
}
|
|
56
|
+
marker = page.Marker || undefined;
|
|
57
|
+
} while (marker);
|
|
58
|
+
|
|
59
|
+
return [...all];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
// Enum generation
|
|
64
|
+
// ---------------------------------------------------------------------------
|
|
65
|
+
|
|
66
|
+
function getFamily(cls) {
|
|
67
|
+
return cls.replace('dms.', '').split('.')[0];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function sizeRank(cls) {
|
|
71
|
+
const size = cls.split('.').pop();
|
|
72
|
+
const idx = SIZE_ORDER.indexOf(size);
|
|
73
|
+
return idx === -1 ? 999 : idx;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function toEnumKey(cls) {
|
|
77
|
+
return cls.replace('dms.', '').replace(/\./g, '_').toUpperCase();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function buildEnumBody(classes) {
|
|
81
|
+
// Group by family
|
|
82
|
+
const grouped = {};
|
|
83
|
+
for (const cls of classes) {
|
|
84
|
+
const f = getFamily(cls);
|
|
85
|
+
(grouped[f] = grouped[f] ?? []).push(cls);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Sort within each family by size
|
|
89
|
+
for (const f of Object.keys(grouped)) {
|
|
90
|
+
grouped[f].sort((a, b) => sizeRank(a) - sizeRank(b));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Sort families: known order first, then unknowns alphabetically
|
|
94
|
+
const knownOrder = Object.keys(FAMILY_META);
|
|
95
|
+
const families = Object.keys(grouped).sort((a, b) => {
|
|
96
|
+
const ai = knownOrder.indexOf(a);
|
|
97
|
+
const bi = knownOrder.indexOf(b);
|
|
98
|
+
if (ai !== -1 && bi !== -1) return ai - bi;
|
|
99
|
+
if (ai !== -1) return -1;
|
|
100
|
+
if (bi !== -1) return 1;
|
|
101
|
+
return a.localeCompare(b);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
const lines = [];
|
|
105
|
+
for (let i = 0; i < families.length; i++) {
|
|
106
|
+
const f = families[i];
|
|
107
|
+
const comment = FAMILY_META[f] ?? `${f.toUpperCase()} instances`;
|
|
108
|
+
lines.push(` // ${comment}`);
|
|
109
|
+
for (const cls of grouped[f]) {
|
|
110
|
+
lines.push(` ${toEnumKey(cls)} = '${cls}',`);
|
|
111
|
+
}
|
|
112
|
+
if (i < families.length - 1) lines.push('');
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return lines.join('\n');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
// File update
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
|
|
122
|
+
function replaceEnum(filePath, enumBody) {
|
|
123
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
124
|
+
const lines = content.split('\n');
|
|
125
|
+
|
|
126
|
+
// Find the line with 'export enum ReplicationInstanceClass {'
|
|
127
|
+
let enumLineIdx = -1;
|
|
128
|
+
for (let i = 0; i < lines.length; i++) {
|
|
129
|
+
if (/^export enum ReplicationInstanceClass\s*\{/.test(lines[i])) {
|
|
130
|
+
enumLineIdx = i;
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (enumLineIdx === -1) throw new Error('Cannot find ReplicationInstanceClass enum');
|
|
135
|
+
|
|
136
|
+
// Walk back to include the preceding JSDoc comment block
|
|
137
|
+
let blockStart = enumLineIdx;
|
|
138
|
+
for (let i = enumLineIdx - 1; i >= 0; i--) {
|
|
139
|
+
const t = lines[i].trim();
|
|
140
|
+
if (t.startsWith('/**') || t.startsWith('*') || t === '*/') {
|
|
141
|
+
blockStart = i;
|
|
142
|
+
} else {
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Walk forward, counting braces, to find the closing '}'
|
|
148
|
+
let depth = 0;
|
|
149
|
+
let blockEnd = -1;
|
|
150
|
+
for (let i = enumLineIdx; i < lines.length; i++) {
|
|
151
|
+
for (const ch of lines[i]) {
|
|
152
|
+
if (ch === '{') depth++;
|
|
153
|
+
if (ch === '}') depth--;
|
|
154
|
+
}
|
|
155
|
+
if (depth === 0) { blockEnd = i; break; }
|
|
156
|
+
}
|
|
157
|
+
if (blockEnd === -1) throw new Error('Cannot find closing brace of ReplicationInstanceClass enum');
|
|
158
|
+
|
|
159
|
+
const newBlock = [
|
|
160
|
+
'/**',
|
|
161
|
+
' * DMS replication instance class.',
|
|
162
|
+
' *',
|
|
163
|
+
' * @see https://docs.aws.amazon.com/dms/latest/userguide/CHAP_ReplicationInstance.Types.html',
|
|
164
|
+
' */',
|
|
165
|
+
'export enum ReplicationInstanceClass {',
|
|
166
|
+
enumBody,
|
|
167
|
+
'}',
|
|
168
|
+
].join('\n');
|
|
169
|
+
|
|
170
|
+
const before = lines.slice(0, blockStart).join('\n');
|
|
171
|
+
const after = lines.slice(blockEnd + 1).join('\n');
|
|
172
|
+
return (before ? before + '\n' : '') + newBlock + (after ? '\n' + after : '');
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// ---------------------------------------------------------------------------
|
|
176
|
+
// Main
|
|
177
|
+
// ---------------------------------------------------------------------------
|
|
178
|
+
|
|
179
|
+
function main() {
|
|
180
|
+
process.stdout.write(`Querying DMS orderable instances in ${REGION}... `);
|
|
181
|
+
|
|
182
|
+
let classes;
|
|
183
|
+
try {
|
|
184
|
+
classes = fetchInstanceClasses();
|
|
185
|
+
} catch (err) {
|
|
186
|
+
console.error('\nFailed to call DMS API:', err.message);
|
|
187
|
+
console.error('Ensure AWS credentials are configured with dms:DescribeOrderableReplicationInstances.');
|
|
188
|
+
process.exit(1);
|
|
189
|
+
}
|
|
190
|
+
console.log(`${classes.length} classes found.`);
|
|
191
|
+
|
|
192
|
+
const enumBody = buildEnumBody(classes);
|
|
193
|
+
const newContent = replaceEnum(ENUMS_FILE, enumBody);
|
|
194
|
+
const oldContent = fs.readFileSync(ENUMS_FILE, 'utf-8');
|
|
195
|
+
|
|
196
|
+
if (newContent === oldContent) {
|
|
197
|
+
console.log('✓ ReplicationInstanceClass is already up to date.');
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Report the diff before writing
|
|
202
|
+
const oldClasses = new Set([...oldContent.matchAll(/'(dms\.[^']+)'/g)].map(m => m[1]));
|
|
203
|
+
const newClasses = new Set(classes);
|
|
204
|
+
const added = classes.filter(c => !oldClasses.has(c));
|
|
205
|
+
const removed = [...oldClasses].filter(c => !newClasses.has(c));
|
|
206
|
+
if (added.length) console.log(' + Added: ', added.join(', '));
|
|
207
|
+
if (removed.length) console.log(' - Removed:', removed.join(', '));
|
|
208
|
+
|
|
209
|
+
fs.writeFileSync(ENUMS_FILE, newContent);
|
|
210
|
+
console.log('✓ Updated src/enums.ts');
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
main();
|