@aws-cdk/aws-redshift-alpha 2.0.0-alpha.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/.jsii +6985 -0
- package/LICENSE +201 -0
- package/NOTICE +2 -0
- package/README.md +247 -0
- package/lib/cluster.d.ts +454 -0
- package/lib/cluster.js +231 -0
- package/lib/database-options.d.ts +30 -0
- package/lib/database-options.js +3 -0
- package/lib/database-secret.d.ts +35 -0
- package/lib/database-secret.js +32 -0
- package/lib/endpoint.d.ts +31 -0
- package/lib/endpoint.js +28 -0
- package/lib/index.d.ts +8 -0
- package/lib/index.js +22 -0
- package/lib/parameter-group.d.ts +72 -0
- package/lib/parameter-group.js +52 -0
- package/lib/private/database-query-provider/handler-name.d.ts +5 -0
- package/lib/private/database-query-provider/handler-name.js +10 -0
- package/lib/private/database-query-provider/index.d.ts +2 -0
- package/lib/private/database-query-provider/index.js +21 -0
- package/lib/private/database-query-provider/privileges.d.ts +6 -0
- package/lib/private/database-query-provider/privileges.js +57 -0
- package/lib/private/database-query-provider/table.d.ts +6 -0
- package/lib/private/database-query-provider/table.js +56 -0
- package/lib/private/database-query-provider/user.d.ts +9 -0
- package/lib/private/database-query-provider/user.js +69 -0
- package/lib/private/database-query-provider/util.d.ts +4 -0
- package/lib/private/database-query-provider/util.js +41 -0
- package/lib/private/database-query.d.ts +24 -0
- package/lib/private/database-query.js +78 -0
- package/lib/private/handler-props.d.ts +26 -0
- package/lib/private/handler-props.js +3 -0
- package/lib/private/privileges.d.ts +48 -0
- package/lib/private/privileges.js +64 -0
- package/lib/redshift-canned-metrics.generated.d.ts +192 -0
- package/lib/redshift-canned-metrics.generated.js +161 -0
- package/lib/subnet-group.d.ts +74 -0
- package/lib/subnet-group.js +49 -0
- package/lib/table.d.ts +241 -0
- package/lib/table.js +104 -0
- package/lib/user.d.ts +174 -0
- package/lib/user.js +102 -0
- package/package.json +124 -0
- package/rosetta/cluster.ts-fixture +21 -0
- package/rosetta/default.ts-fixture +12 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handler = void 0;
|
|
4
|
+
const handler_name_1 = require("./handler-name");
|
|
5
|
+
const privileges_1 = require("./privileges");
|
|
6
|
+
const table_1 = require("./table");
|
|
7
|
+
const user_1 = require("./user");
|
|
8
|
+
const HANDLERS = {
|
|
9
|
+
[handler_name_1.HandlerName.Table]: table_1.handler,
|
|
10
|
+
[handler_name_1.HandlerName.User]: user_1.handler,
|
|
11
|
+
[handler_name_1.HandlerName.UserTablePrivileges]: privileges_1.handler,
|
|
12
|
+
};
|
|
13
|
+
async function handler(event) {
|
|
14
|
+
const subHandler = HANDLERS[event.ResourceProperties.handler];
|
|
15
|
+
if (!subHandler) {
|
|
16
|
+
throw new Error(`Requested handler ${event.ResourceProperties.handler} is not in supported set: ${JSON.stringify(Object.keys(HANDLERS))}`);
|
|
17
|
+
}
|
|
18
|
+
return subHandler(event.ResourceProperties, event);
|
|
19
|
+
}
|
|
20
|
+
exports.handler = handler;
|
|
21
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFFQSxpREFBNkM7QUFDN0MsNkNBQTJEO0FBQzNELG1DQUFpRDtBQUNqRCxpQ0FBK0M7QUFFL0MsTUFBTSxRQUFRLEdBQWlIO0lBQzdILENBQUMsMEJBQVcsQ0FBQyxLQUFLLENBQUMsRUFBRSxlQUFXO0lBQ2hDLENBQUMsMEJBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxjQUFVO0lBQzlCLENBQUMsMEJBQVcsQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLG9CQUFnQjtDQUNwRCxDQUFDO0FBRUssS0FBSyxVQUFVLE9BQU8sQ0FBQyxLQUFrRDtJQUM5RSxNQUFNLFVBQVUsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE9BQXNCLENBQUMsQ0FBQztJQUM3RSxJQUFJLENBQUMsVUFBVSxFQUFFO1FBQ2YsTUFBTSxJQUFJLEtBQUssQ0FBQyxxQkFBcUIsS0FBSyxDQUFDLGtCQUFrQixDQUFDLE9BQU8sNkJBQTZCLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztLQUM1STtJQUNELE9BQU8sVUFBVSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxLQUFLLENBQUMsQ0FBQztBQUNyRCxDQUFDO0FBTkQsMEJBTUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgaW1wb3J0L25vLXVucmVzb2x2ZWQgKi9cbmltcG9ydCAqIGFzIEFXU0xhbWJkYSBmcm9tICdhd3MtbGFtYmRhJztcbmltcG9ydCB7IEhhbmRsZXJOYW1lIH0gZnJvbSAnLi9oYW5kbGVyLW5hbWUnO1xuaW1wb3J0IHsgaGFuZGxlciBhcyBtYW5hZ2VQcml2aWxlZ2VzIH0gZnJvbSAnLi9wcml2aWxlZ2VzJztcbmltcG9ydCB7IGhhbmRsZXIgYXMgbWFuYWdlVGFibGUgfSBmcm9tICcuL3RhYmxlJztcbmltcG9ydCB7IGhhbmRsZXIgYXMgbWFuYWdlVXNlciB9IGZyb20gJy4vdXNlcic7XG5cbmNvbnN0IEhBTkRMRVJTOiB7IFtrZXkgaW4gSGFuZGxlck5hbWVdOiAoKHByb3BzOiBhbnksIGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50KSA9PiBQcm9taXNlPGFueT4pIH0gPSB7XG4gIFtIYW5kbGVyTmFtZS5UYWJsZV06IG1hbmFnZVRhYmxlLFxuICBbSGFuZGxlck5hbWUuVXNlcl06IG1hbmFnZVVzZXIsXG4gIFtIYW5kbGVyTmFtZS5Vc2VyVGFibGVQcml2aWxlZ2VzXTogbWFuYWdlUHJpdmlsZWdlcyxcbn07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKGV2ZW50OiBBV1NMYW1iZGEuQ2xvdWRGb3JtYXRpb25DdXN0b21SZXNvdXJjZUV2ZW50KSB7XG4gIGNvbnN0IHN1YkhhbmRsZXIgPSBIQU5ETEVSU1tldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuaGFuZGxlciBhcyBIYW5kbGVyTmFtZV07XG4gIGlmICghc3ViSGFuZGxlcikge1xuICAgIHRocm93IG5ldyBFcnJvcihgUmVxdWVzdGVkIGhhbmRsZXIgJHtldmVudC5SZXNvdXJjZVByb3BlcnRpZXMuaGFuZGxlcn0gaXMgbm90IGluIHN1cHBvcnRlZCBzZXQ6ICR7SlNPTi5zdHJpbmdpZnkoT2JqZWN0LmtleXMoSEFORExFUlMpKX1gKTtcbiAgfVxuICByZXR1cm4gc3ViSGFuZGxlcihldmVudC5SZXNvdXJjZVByb3BlcnRpZXMsIGV2ZW50KTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as AWSLambda from 'aws-lambda';
|
|
2
|
+
import { UserTablePrivilegesHandlerProps } from '../handler-props';
|
|
3
|
+
import { ClusterProps } from './util';
|
|
4
|
+
export declare function handler(props: UserTablePrivilegesHandlerProps & ClusterProps, event: AWSLambda.CloudFormationCustomResourceEvent): Promise<{
|
|
5
|
+
PhysicalResourceId: string;
|
|
6
|
+
} | undefined>;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handler = void 0;
|
|
4
|
+
const util_1 = require("./util");
|
|
5
|
+
async function handler(props, event) {
|
|
6
|
+
const username = props.username;
|
|
7
|
+
const tablePrivileges = props.tablePrivileges;
|
|
8
|
+
const clusterProps = props;
|
|
9
|
+
if (event.RequestType === 'Create') {
|
|
10
|
+
await grantPrivileges(username, tablePrivileges, clusterProps);
|
|
11
|
+
return { PhysicalResourceId: util_1.makePhysicalId(username, clusterProps, event.RequestId) };
|
|
12
|
+
}
|
|
13
|
+
else if (event.RequestType === 'Delete') {
|
|
14
|
+
await revokePrivileges(username, tablePrivileges, clusterProps);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
else if (event.RequestType === 'Update') {
|
|
18
|
+
const { replace } = await updatePrivileges(username, tablePrivileges, clusterProps, event.OldResourceProperties);
|
|
19
|
+
const physicalId = replace ? util_1.makePhysicalId(username, clusterProps, event.RequestId) : event.PhysicalResourceId;
|
|
20
|
+
return { PhysicalResourceId: physicalId };
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
/* eslint-disable-next-line dot-notation */
|
|
24
|
+
throw new Error(`Unrecognized event type: ${event['RequestType']}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.handler = handler;
|
|
28
|
+
async function revokePrivileges(username, tablePrivileges, clusterProps) {
|
|
29
|
+
await Promise.all(tablePrivileges.map(({ tableName, actions }) => {
|
|
30
|
+
return util_1.executeStatement(`REVOKE ${actions.join(', ')} ON ${tableName} FROM ${username}`, clusterProps);
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
async function grantPrivileges(username, tablePrivileges, clusterProps) {
|
|
34
|
+
await Promise.all(tablePrivileges.map(({ tableName, actions }) => {
|
|
35
|
+
return util_1.executeStatement(`GRANT ${actions.join(', ')} ON ${tableName} TO ${username}`, clusterProps);
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
async function updatePrivileges(username, tablePrivileges, clusterProps, oldResourceProperties) {
|
|
39
|
+
const oldClusterProps = oldResourceProperties;
|
|
40
|
+
if (clusterProps.clusterName !== oldClusterProps.clusterName || clusterProps.databaseName !== oldClusterProps.databaseName) {
|
|
41
|
+
await grantPrivileges(username, tablePrivileges, clusterProps);
|
|
42
|
+
return { replace: true };
|
|
43
|
+
}
|
|
44
|
+
const oldUsername = oldResourceProperties.username;
|
|
45
|
+
if (oldUsername !== username) {
|
|
46
|
+
await grantPrivileges(username, tablePrivileges, clusterProps);
|
|
47
|
+
return { replace: true };
|
|
48
|
+
}
|
|
49
|
+
const oldTablePrivileges = oldResourceProperties.tablePrivileges;
|
|
50
|
+
if (oldTablePrivileges !== tablePrivileges) {
|
|
51
|
+
await revokePrivileges(username, oldTablePrivileges, clusterProps);
|
|
52
|
+
await grantPrivileges(username, tablePrivileges, clusterProps);
|
|
53
|
+
return { replace: false };
|
|
54
|
+
}
|
|
55
|
+
return { replace: false };
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJpdmlsZWdlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInByaXZpbGVnZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBR0EsaUNBQXdFO0FBRWpFLEtBQUssVUFBVSxPQUFPLENBQUMsS0FBcUQsRUFBRSxLQUFrRDtJQUNySSxNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO0lBQ2hDLE1BQU0sZUFBZSxHQUFHLEtBQUssQ0FBQyxlQUFlLENBQUM7SUFDOUMsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDO0lBRTNCLElBQUksS0FBSyxDQUFDLFdBQVcsS0FBSyxRQUFRLEVBQUU7UUFDbEMsTUFBTSxlQUFlLENBQUMsUUFBUSxFQUFFLGVBQWUsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUMvRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUscUJBQWMsQ0FBQyxRQUFRLEVBQUUsWUFBWSxFQUFFLEtBQUssQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO0tBQ3hGO1NBQU0sSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsRUFBRTtRQUN6QyxNQUFNLGdCQUFnQixDQUFDLFFBQVEsRUFBRSxlQUFlLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDaEUsT0FBTztLQUNSO1NBQU0sSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsRUFBRTtRQUN6QyxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsTUFBTSxnQkFBZ0IsQ0FDeEMsUUFBUSxFQUNSLGVBQWUsRUFDZixZQUFZLEVBQ1osS0FBSyxDQUFDLHFCQUF1RSxDQUM5RSxDQUFDO1FBQ0YsTUFBTSxVQUFVLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxxQkFBYyxDQUFDLFFBQVEsRUFBRSxZQUFZLEVBQUUsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsa0JBQWtCLENBQUM7UUFDaEgsT0FBTyxFQUFFLGtCQUFrQixFQUFFLFVBQVUsRUFBRSxDQUFDO0tBQzNDO1NBQU07UUFDTCwyQ0FBMkM7UUFDM0MsTUFBTSxJQUFJLEtBQUssQ0FBQyw0QkFBNEIsS0FBSyxDQUFDLGFBQWEsQ0FBQyxFQUFFLENBQUMsQ0FBQztLQUNyRTtBQUNILENBQUM7QUF4QkQsMEJBd0JDO0FBRUQsS0FBSyxVQUFVLGdCQUFnQixDQUFDLFFBQWdCLEVBQUUsZUFBaUMsRUFBRSxZQUEwQjtJQUM3RyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUU7UUFDL0QsT0FBTyx1QkFBZ0IsQ0FBQyxVQUFVLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sU0FBUyxTQUFTLFFBQVEsRUFBRSxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQ3pHLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDTixDQUFDO0FBRUQsS0FBSyxVQUFVLGVBQWUsQ0FBQyxRQUFnQixFQUFFLGVBQWlDLEVBQUUsWUFBMEI7SUFDNUcsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFO1FBQy9ELE9BQU8sdUJBQWdCLENBQUMsU0FBUyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLFNBQVMsT0FBTyxRQUFRLEVBQUUsRUFBRSxZQUFZLENBQUMsQ0FBQztJQUN0RyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ04sQ0FBQztBQUVELEtBQUssVUFBVSxnQkFBZ0IsQ0FDN0IsUUFBZ0IsRUFDaEIsZUFBaUMsRUFDakMsWUFBMEIsRUFDMUIscUJBQXFFO0lBRXJFLE1BQU0sZUFBZSxHQUFHLHFCQUFxQixDQUFDO0lBQzlDLElBQUksWUFBWSxDQUFDLFdBQVcsS0FBSyxlQUFlLENBQUMsV0FBVyxJQUFJLFlBQVksQ0FBQyxZQUFZLEtBQUssZUFBZSxDQUFDLFlBQVksRUFBRTtRQUMxSCxNQUFNLGVBQWUsQ0FBQyxRQUFRLEVBQUUsZUFBZSxFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQy9ELE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7S0FDMUI7SUFFRCxNQUFNLFdBQVcsR0FBRyxxQkFBcUIsQ0FBQyxRQUFRLENBQUM7SUFDbkQsSUFBSSxXQUFXLEtBQUssUUFBUSxFQUFFO1FBQzVCLE1BQU0sZUFBZSxDQUFDLFFBQVEsRUFBRSxlQUFlLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDL0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsQ0FBQztLQUMxQjtJQUVELE1BQU0sa0JBQWtCLEdBQUcscUJBQXFCLENBQUMsZUFBZSxDQUFDO0lBQ2pFLElBQUksa0JBQWtCLEtBQUssZUFBZSxFQUFFO1FBQzFDLE1BQU0sZ0JBQWdCLENBQUMsUUFBUSxFQUFFLGtCQUFrQixFQUFFLFlBQVksQ0FBQyxDQUFDO1FBQ25FLE1BQU0sZUFBZSxDQUFDLFFBQVEsRUFBRSxlQUFlLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDL0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQztLQUMzQjtJQUVELE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUM7QUFDNUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW5yZXNvbHZlZCAqL1xuaW1wb3J0ICogYXMgQVdTTGFtYmRhIGZyb20gJ2F3cy1sYW1iZGEnO1xuaW1wb3J0IHsgVGFibGVQcml2aWxlZ2UsIFVzZXJUYWJsZVByaXZpbGVnZXNIYW5kbGVyUHJvcHMgfSBmcm9tICcuLi9oYW5kbGVyLXByb3BzJztcbmltcG9ydCB7IENsdXN0ZXJQcm9wcywgZXhlY3V0ZVN0YXRlbWVudCwgbWFrZVBoeXNpY2FsSWQgfSBmcm9tICcuL3V0aWwnO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlcihwcm9wczogVXNlclRhYmxlUHJpdmlsZWdlc0hhbmRsZXJQcm9wcyAmIENsdXN0ZXJQcm9wcywgZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQpIHtcbiAgY29uc3QgdXNlcm5hbWUgPSBwcm9wcy51c2VybmFtZTtcbiAgY29uc3QgdGFibGVQcml2aWxlZ2VzID0gcHJvcHMudGFibGVQcml2aWxlZ2VzO1xuICBjb25zdCBjbHVzdGVyUHJvcHMgPSBwcm9wcztcblxuICBpZiAoZXZlbnQuUmVxdWVzdFR5cGUgPT09ICdDcmVhdGUnKSB7XG4gICAgYXdhaXQgZ3JhbnRQcml2aWxlZ2VzKHVzZXJuYW1lLCB0YWJsZVByaXZpbGVnZXMsIGNsdXN0ZXJQcm9wcyk7XG4gICAgcmV0dXJuIHsgUGh5c2ljYWxSZXNvdXJjZUlkOiBtYWtlUGh5c2ljYWxJZCh1c2VybmFtZSwgY2x1c3RlclByb3BzLCBldmVudC5SZXF1ZXN0SWQpIH07XG4gIH0gZWxzZSBpZiAoZXZlbnQuUmVxdWVzdFR5cGUgPT09ICdEZWxldGUnKSB7XG4gICAgYXdhaXQgcmV2b2tlUHJpdmlsZWdlcyh1c2VybmFtZSwgdGFibGVQcml2aWxlZ2VzLCBjbHVzdGVyUHJvcHMpO1xuICAgIHJldHVybjtcbiAgfSBlbHNlIGlmIChldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ1VwZGF0ZScpIHtcbiAgICBjb25zdCB7IHJlcGxhY2UgfSA9IGF3YWl0IHVwZGF0ZVByaXZpbGVnZXMoXG4gICAgICB1c2VybmFtZSxcbiAgICAgIHRhYmxlUHJpdmlsZWdlcyxcbiAgICAgIGNsdXN0ZXJQcm9wcyxcbiAgICAgIGV2ZW50Lk9sZFJlc291cmNlUHJvcGVydGllcyBhcyBVc2VyVGFibGVQcml2aWxlZ2VzSGFuZGxlclByb3BzICYgQ2x1c3RlclByb3BzLFxuICAgICk7XG4gICAgY29uc3QgcGh5c2ljYWxJZCA9IHJlcGxhY2UgPyBtYWtlUGh5c2ljYWxJZCh1c2VybmFtZSwgY2x1c3RlclByb3BzLCBldmVudC5SZXF1ZXN0SWQpIDogZXZlbnQuUGh5c2ljYWxSZXNvdXJjZUlkO1xuICAgIHJldHVybiB7IFBoeXNpY2FsUmVzb3VyY2VJZDogcGh5c2ljYWxJZCB9O1xuICB9IGVsc2Uge1xuICAgIC8qIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBkb3Qtbm90YXRpb24gKi9cbiAgICB0aHJvdyBuZXcgRXJyb3IoYFVucmVjb2duaXplZCBldmVudCB0eXBlOiAke2V2ZW50WydSZXF1ZXN0VHlwZSddfWApO1xuICB9XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHJldm9rZVByaXZpbGVnZXModXNlcm5hbWU6IHN0cmluZywgdGFibGVQcml2aWxlZ2VzOiBUYWJsZVByaXZpbGVnZVtdLCBjbHVzdGVyUHJvcHM6IENsdXN0ZXJQcm9wcykge1xuICBhd2FpdCBQcm9taXNlLmFsbCh0YWJsZVByaXZpbGVnZXMubWFwKCh7IHRhYmxlTmFtZSwgYWN0aW9ucyB9KSA9PiB7XG4gICAgcmV0dXJuIGV4ZWN1dGVTdGF0ZW1lbnQoYFJFVk9LRSAke2FjdGlvbnMuam9pbignLCAnKX0gT04gJHt0YWJsZU5hbWV9IEZST00gJHt1c2VybmFtZX1gLCBjbHVzdGVyUHJvcHMpO1xuICB9KSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdyYW50UHJpdmlsZWdlcyh1c2VybmFtZTogc3RyaW5nLCB0YWJsZVByaXZpbGVnZXM6IFRhYmxlUHJpdmlsZWdlW10sIGNsdXN0ZXJQcm9wczogQ2x1c3RlclByb3BzKSB7XG4gIGF3YWl0IFByb21pc2UuYWxsKHRhYmxlUHJpdmlsZWdlcy5tYXAoKHsgdGFibGVOYW1lLCBhY3Rpb25zIH0pID0+IHtcbiAgICByZXR1cm4gZXhlY3V0ZVN0YXRlbWVudChgR1JBTlQgJHthY3Rpb25zLmpvaW4oJywgJyl9IE9OICR7dGFibGVOYW1lfSBUTyAke3VzZXJuYW1lfWAsIGNsdXN0ZXJQcm9wcyk7XG4gIH0pKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gdXBkYXRlUHJpdmlsZWdlcyhcbiAgdXNlcm5hbWU6IHN0cmluZyxcbiAgdGFibGVQcml2aWxlZ2VzOiBUYWJsZVByaXZpbGVnZVtdLFxuICBjbHVzdGVyUHJvcHM6IENsdXN0ZXJQcm9wcyxcbiAgb2xkUmVzb3VyY2VQcm9wZXJ0aWVzOiBVc2VyVGFibGVQcml2aWxlZ2VzSGFuZGxlclByb3BzICYgQ2x1c3RlclByb3BzLFxuKTogUHJvbWlzZTx7IHJlcGxhY2U6IGJvb2xlYW4gfT4ge1xuICBjb25zdCBvbGRDbHVzdGVyUHJvcHMgPSBvbGRSZXNvdXJjZVByb3BlcnRpZXM7XG4gIGlmIChjbHVzdGVyUHJvcHMuY2x1c3Rlck5hbWUgIT09IG9sZENsdXN0ZXJQcm9wcy5jbHVzdGVyTmFtZSB8fCBjbHVzdGVyUHJvcHMuZGF0YWJhc2VOYW1lICE9PSBvbGRDbHVzdGVyUHJvcHMuZGF0YWJhc2VOYW1lKSB7XG4gICAgYXdhaXQgZ3JhbnRQcml2aWxlZ2VzKHVzZXJuYW1lLCB0YWJsZVByaXZpbGVnZXMsIGNsdXN0ZXJQcm9wcyk7XG4gICAgcmV0dXJuIHsgcmVwbGFjZTogdHJ1ZSB9O1xuICB9XG5cbiAgY29uc3Qgb2xkVXNlcm5hbWUgPSBvbGRSZXNvdXJjZVByb3BlcnRpZXMudXNlcm5hbWU7XG4gIGlmIChvbGRVc2VybmFtZSAhPT0gdXNlcm5hbWUpIHtcbiAgICBhd2FpdCBncmFudFByaXZpbGVnZXModXNlcm5hbWUsIHRhYmxlUHJpdmlsZWdlcywgY2x1c3RlclByb3BzKTtcbiAgICByZXR1cm4geyByZXBsYWNlOiB0cnVlIH07XG4gIH1cblxuICBjb25zdCBvbGRUYWJsZVByaXZpbGVnZXMgPSBvbGRSZXNvdXJjZVByb3BlcnRpZXMudGFibGVQcml2aWxlZ2VzO1xuICBpZiAob2xkVGFibGVQcml2aWxlZ2VzICE9PSB0YWJsZVByaXZpbGVnZXMpIHtcbiAgICBhd2FpdCByZXZva2VQcml2aWxlZ2VzKHVzZXJuYW1lLCBvbGRUYWJsZVByaXZpbGVnZXMsIGNsdXN0ZXJQcm9wcyk7XG4gICAgYXdhaXQgZ3JhbnRQcml2aWxlZ2VzKHVzZXJuYW1lLCB0YWJsZVByaXZpbGVnZXMsIGNsdXN0ZXJQcm9wcyk7XG4gICAgcmV0dXJuIHsgcmVwbGFjZTogZmFsc2UgfTtcbiAgfVxuXG4gIHJldHVybiB7IHJlcGxhY2U6IGZhbHNlIH07XG59XG4iXX0=
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import * as AWSLambda from 'aws-lambda';
|
|
2
|
+
import { TableHandlerProps } from '../handler-props';
|
|
3
|
+
import { ClusterProps } from './util';
|
|
4
|
+
export declare function handler(props: TableHandlerProps & ClusterProps, event: AWSLambda.CloudFormationCustomResourceEvent): Promise<{
|
|
5
|
+
PhysicalResourceId: string;
|
|
6
|
+
} | undefined>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handler = void 0;
|
|
4
|
+
const util_1 = require("./util");
|
|
5
|
+
async function handler(props, event) {
|
|
6
|
+
const tableNamePrefix = props.tableName.prefix;
|
|
7
|
+
const tableNameSuffix = props.tableName.generateSuffix ? `${event.RequestId.substring(0, 8)}` : '';
|
|
8
|
+
const tableColumns = props.tableColumns;
|
|
9
|
+
const clusterProps = props;
|
|
10
|
+
if (event.RequestType === 'Create') {
|
|
11
|
+
const tableName = await createTable(tableNamePrefix, tableNameSuffix, tableColumns, clusterProps);
|
|
12
|
+
return { PhysicalResourceId: tableName };
|
|
13
|
+
}
|
|
14
|
+
else if (event.RequestType === 'Delete') {
|
|
15
|
+
await dropTable(event.PhysicalResourceId, clusterProps);
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
else if (event.RequestType === 'Update') {
|
|
19
|
+
const tableName = await updateTable(event.PhysicalResourceId, tableNamePrefix, tableNameSuffix, tableColumns, clusterProps, event.OldResourceProperties);
|
|
20
|
+
return { PhysicalResourceId: tableName };
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
/* eslint-disable-next-line dot-notation */
|
|
24
|
+
throw new Error(`Unrecognized event type: ${event['RequestType']}`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.handler = handler;
|
|
28
|
+
async function createTable(tableNamePrefix, tableNameSuffix, tableColumns, clusterProps) {
|
|
29
|
+
const tableName = tableNamePrefix + tableNameSuffix;
|
|
30
|
+
const tableColumnsString = tableColumns.map(column => `${column.name} ${column.dataType}`).join();
|
|
31
|
+
await util_1.executeStatement(`CREATE TABLE ${tableName} (${tableColumnsString})`, clusterProps);
|
|
32
|
+
return tableName;
|
|
33
|
+
}
|
|
34
|
+
async function dropTable(tableName, clusterProps) {
|
|
35
|
+
await util_1.executeStatement(`DROP TABLE ${tableName}`, clusterProps);
|
|
36
|
+
}
|
|
37
|
+
async function updateTable(tableName, tableNamePrefix, tableNameSuffix, tableColumns, clusterProps, oldResourceProperties) {
|
|
38
|
+
const oldClusterProps = oldResourceProperties;
|
|
39
|
+
if (clusterProps.clusterName !== oldClusterProps.clusterName || clusterProps.databaseName !== oldClusterProps.databaseName) {
|
|
40
|
+
return createTable(tableNamePrefix, tableNameSuffix, tableColumns, clusterProps);
|
|
41
|
+
}
|
|
42
|
+
const oldTableNamePrefix = oldResourceProperties.tableName.prefix;
|
|
43
|
+
if (tableNamePrefix !== oldTableNamePrefix) {
|
|
44
|
+
return createTable(tableNamePrefix, tableNameSuffix, tableColumns, clusterProps);
|
|
45
|
+
}
|
|
46
|
+
const oldTableColumns = oldResourceProperties.tableColumns;
|
|
47
|
+
if (!oldTableColumns.every(oldColumn => tableColumns.some(column => column.name === oldColumn.name && column.dataType === oldColumn.dataType))) {
|
|
48
|
+
return createTable(tableNamePrefix, tableNameSuffix, tableColumns, clusterProps);
|
|
49
|
+
}
|
|
50
|
+
const additions = tableColumns.filter(column => {
|
|
51
|
+
return !oldTableColumns.some(oldColumn => column.name === oldColumn.name && column.dataType === oldColumn.dataType);
|
|
52
|
+
}).map(column => `ADD ${column.name} ${column.dataType}`);
|
|
53
|
+
await Promise.all(additions.map(addition => util_1.executeStatement(`ALTER TABLE ${tableName} ${addition}`, clusterProps)));
|
|
54
|
+
return tableName;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0YWJsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFJQSxpQ0FBd0Q7QUFFakQsS0FBSyxVQUFVLE9BQU8sQ0FBQyxLQUF1QyxFQUFFLEtBQWtEO0lBQ3ZILE1BQU0sZUFBZSxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDO0lBQy9DLE1BQU0sZUFBZSxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDbkcsTUFBTSxZQUFZLEdBQUcsS0FBSyxDQUFDLFlBQVksQ0FBQztJQUN4QyxNQUFNLFlBQVksR0FBRyxLQUFLLENBQUM7SUFFM0IsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsRUFBRTtRQUNsQyxNQUFNLFNBQVMsR0FBRyxNQUFNLFdBQVcsQ0FBQyxlQUFlLEVBQUUsZUFBZSxFQUFFLFlBQVksRUFBRSxZQUFZLENBQUMsQ0FBQztRQUNsRyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsU0FBUyxFQUFFLENBQUM7S0FDMUM7U0FBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLEtBQUssUUFBUSxFQUFFO1FBQ3pDLE1BQU0sU0FBUyxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUN4RCxPQUFPO0tBQ1I7U0FBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLEtBQUssUUFBUSxFQUFFO1FBQ3pDLE1BQU0sU0FBUyxHQUFHLE1BQU0sV0FBVyxDQUNqQyxLQUFLLENBQUMsa0JBQWtCLEVBQ3hCLGVBQWUsRUFDZixlQUFlLEVBQ2YsWUFBWSxFQUNaLFlBQVksRUFDWixLQUFLLENBQUMscUJBQXlELENBQ2hFLENBQUM7UUFDRixPQUFPLEVBQUUsa0JBQWtCLEVBQUUs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bkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBpbXBvcnQvbm8tdW5yZXNvbHZlZCAqL1xuaW1wb3J0ICogYXMgQVdTTGFtYmRhIGZyb20gJ2F3cy1sYW1iZGEnO1xuaW1wb3J0IHsgQ29sdW1uIH0gZnJvbSAnLi4vLi4vdGFibGUnO1xuaW1wb3J0IHsgVGFibGVIYW5kbGVyUHJvcHMgfSBmcm9tICcuLi9oYW5kbGVyLXByb3BzJztcbmltcG9ydCB7IENsdXN0ZXJQcm9wcywgZXhlY3V0ZVN0YXRlbWVudCB9IGZyb20gJy4vdXRpbCc7XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBoYW5kbGVyKHByb3BzOiBUYWJsZUhhbmRsZXJQcm9wcyAmIENsdXN0ZXJQcm9wcywgZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQpIHtcbiAgY29uc3QgdGFibGVOYW1lUHJlZml4ID0gcHJvcHMudGFibGVOYW1lLnByZWZpeDtcbiAgY29uc3QgdGFibGVOYW1lU3VmZml4ID0gcHJvcHMudGFibGVOYW1lLmdlbmVyYXRlU3VmZml4ID8gYCR7ZXZlbnQuUmVxdWVzdElkLnN1YnN0cmluZygwLCA4KX1gIDogJyc7XG4gIGNvbnN0IHRhYmxlQ29sdW1ucyA9IHByb3BzLnRhYmxlQ29sdW1ucztcbiAgY29uc3QgY2x1c3RlclByb3BzID0gcHJvcHM7XG5cbiAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnQ3JlYXRlJykge1xuICAgIGNvbnN0IHRhYmxlTmFtZSA9IGF3YWl0IGNyZWF0ZVRhYmxlKHRhYmxlTmFtZVByZWZpeCwgdGFibGVOYW1lU3VmZml4LCB0YWJsZUNvbHVtbnMsIGNsdXN0ZXJQcm9wcyk7XG4gICAgcmV0dXJuIHsgUGh5c2ljYWxSZXNvdXJjZUlkOiB0YWJsZU5hbWUgfTtcbiAgfSBlbHNlIGlmIChldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ0RlbGV0ZScpIHtcbiAgICBhd2FpdCBkcm9wVGFibGUoZXZlbnQuUGh5c2ljYWxSZXNvdXJjZUlkLCBjbHVzdGVyUHJvcHMpO1xuICAgIHJldHVybjtcbiAgfSBlbHNlIGlmIChldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ1VwZGF0ZScpIHtcbiAgICBjb25zdCB0YWJsZU5hbWUgPSBhd2FpdCB1cGRhdGVUYWJsZShcbiAgICAgIGV2ZW50LlBoeXNpY2FsUmVzb3VyY2VJZCxcbiAgICAgIHRhYmxlTmFtZVByZWZpeCxcbiAgICAgIHRhYmxlTmFtZVN1ZmZpeCxcbiAgICAgIHRhYmxlQ29sdW1ucyxcbiAgICAgIGNsdXN0ZXJQcm9wcyxcbiAgICAgIGV2ZW50Lk9sZFJlc291cmNlUHJvcGVydGllcyBhcyBUYWJsZUhhbmRsZXJQcm9wcyAmIENsdXN0ZXJQcm9wcyxcbiAgICApO1xuICAgIHJldHVybiB7IFBoeXNpY2FsUmVzb3VyY2VJZDogdGFibGVOYW1lIH07XG4gIH0gZWxzZSB7XG4gICAgLyogZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRvdC1ub3RhdGlvbiAqL1xuICAgIHRocm93IG5ldyBFcnJvcihgVW5yZWNvZ25pemVkIGV2ZW50IHR5cGU6ICR7ZXZlbnRbJ1JlcXVlc3RUeXBlJ119YCk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gY3JlYXRlVGFibGUodGFibGVOYW1lUHJlZml4OiBzdHJpbmcsIHRhYmxlTmFtZVN1ZmZpeDogc3RyaW5nLCB0YWJsZUNvbHVtbnM6IENvbHVtbltdLCBjbHVzdGVyUHJvcHM6IENsdXN0ZXJQcm9wcyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IHRhYmxlTmFtZSA9IHRhYmxlTmFtZVByZWZpeCArIHRhYmxlTmFtZVN1ZmZpeDtcbiAgY29uc3QgdGFibGVDb2x1bW5zU3RyaW5nID0gdGFibGVDb2x1bW5zLm1hcChjb2x1bW4gPT4gYCR7Y29sdW1uLm5hbWV9ICR7Y29sdW1uLmRhdGFUeXBlfWApLmpvaW4oKTtcbiAgYXdhaXQgZXhlY3V0ZVN0YXRlbWVudChgQ1JFQVRFIFRBQkxFICR7dGFibGVOYW1lfSAoJHt0YWJsZUNvbHVtbnNTdHJpbmd9KWAsIGNsdXN0ZXJQcm9wcyk7XG4gIHJldHVybiB0YWJsZU5hbWU7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGRyb3BUYWJsZSh0YWJsZU5hbWU6IHN0cmluZywgY2x1c3RlclByb3BzOiBDbHVzdGVyUHJvcHMpIHtcbiAgYXdhaXQgZXhlY3V0ZVN0YXRlbWVudChgRFJPUCBUQUJMRSAke3RhYmxlTmFtZX1gLCBjbHVzdGVyUHJvcHMpO1xufVxuXG5hc3luYyBmdW5jdGlvbiB1cGRhdGVUYWJsZShcbiAgdGFibGVOYW1lOiBzdHJpbmcsXG4gIHRhYmxlTmFtZVByZWZpeDogc3RyaW5nLFxuICB0YWJsZU5hbWVTdWZmaXg6IHN0cmluZyxcbiAgdGFibGVDb2x1bW5zOiBDb2x1bW5bXSxcbiAgY2x1c3RlclByb3BzOiBDbHVzdGVyUHJvcHMsXG4gIG9sZFJlc291cmNlUHJvcGVydGllczogVGFibGVIYW5kbGVyUHJvcHMgJiBDbHVzdGVyUHJvcHMsXG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCBvbGRDbHVzdGVyUHJvcHMgPSBvbGRSZXNvdXJjZVByb3BlcnRpZXM7XG4gIGlmIChjbHVzdGVyUHJvcHMuY2x1c3Rlck5hbWUgIT09IG9sZENsdXN0ZXJQcm9wcy5jbHVzdGVyTmFtZSB8fCBjbHVzdGVyUHJvcHMuZGF0YWJhc2VOYW1lICE9PSBvbGRDbHVzdGVyUHJvcHMuZGF0YWJhc2VOYW1lKSB7XG4gICAgcmV0dXJuIGNyZWF0ZVRhYmxlKHRhYmxlTmFtZVByZWZpeCwgdGFibGVOYW1lU3VmZml4LCB0YWJsZUNvbHVtbnMsIGNsdXN0ZXJQcm9wcyk7XG4gIH1cblxuICBjb25zdCBvbGRUYWJsZU5hbWVQcmVmaXggPSBvbGRSZXNvdXJjZVByb3BlcnRpZXMudGFibGVOYW1lLnByZWZpeDtcbiAgaWYgKHRhYmxlTmFtZVByZWZpeCAhPT0gb2xkVGFibGVOYW1lUHJlZml4KSB7XG4gICAgcmV0dXJuIGNyZWF0ZVRhYmxlKHRhYmxlTmFtZVByZWZpeCwgdGFibGVOYW1lU3VmZml4LCB0YWJsZUNvbHVtbnMsIGNsdXN0ZXJQcm9wcyk7XG4gIH1cblxuICBjb25zdCBvbGRUYWJsZUNvbHVtbnMgPSBvbGRSZXNvdXJjZVByb3BlcnRpZXMudGFibGVDb2x1bW5zO1xuICBpZiAoIW9sZFRhYmxlQ29sdW1ucy5ldmVyeShvbGRDb2x1bW4gPT4gdGFibGVDb2x1bW5zLnNvbWUoY29sdW1uID0+IGNvbHVtbi5uYW1lID09PSBvbGRDb2x1bW4ubmFtZSAmJiBjb2x1bW4uZGF0YVR5cGUgPT09IG9sZENvbHVtbi5kYXRhVHlwZSkpKSB7XG4gICAgcmV0dXJuIGNyZWF0ZVRhYmxlKHRhYmxlTmFtZVByZWZpeCwgdGFibGVOYW1lU3VmZml4LCB0YWJsZUNvbHVtbnMsIGNsdXN0ZXJQcm9wcyk7XG4gIH1cblxuICBjb25zdCBhZGRpdGlvbnMgPSB0YWJsZUNvbHVtbnMuZmlsdGVyKGNvbHVtbiA9PiB7XG4gICAgcmV0dXJuICFvbGRUYWJsZUNvbHVtbnMuc29tZShvbGRDb2x1bW4gPT4gY29sdW1uLm5hbWUgPT09IG9sZENvbHVtbi5uYW1lICYmIGNvbHVtbi5kYXRhVHlwZSA9PT0gb2xkQ29sdW1uLmRhdGFUeXBlKTtcbiAgfSkubWFwKGNvbHVtbiA9PiBgQUREICR7Y29sdW1uLm5hbWV9ICR7Y29sdW1uLmRhdGFUeXBlfWApO1xuICBhd2FpdCBQcm9taXNlLmFsbChhZGRpdGlvbnMubWFwKGFkZGl0aW9uID0+IGV4ZWN1dGVTdGF0ZW1lbnQoYEFMVEVSIFRBQkxFICR7dGFibGVOYW1lfSAke2FkZGl0aW9ufWAsIGNsdXN0ZXJQcm9wcykpKTtcblxuICByZXR1cm4gdGFibGVOYW1lO1xufVxuIl19
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import * as AWSLambda from 'aws-lambda';
|
|
2
|
+
import { UserHandlerProps } from '../handler-props';
|
|
3
|
+
import { ClusterProps } from './util';
|
|
4
|
+
export declare function handler(props: UserHandlerProps & ClusterProps, event: AWSLambda.CloudFormationCustomResourceEvent): Promise<{
|
|
5
|
+
PhysicalResourceId: string;
|
|
6
|
+
Data: {
|
|
7
|
+
username: string;
|
|
8
|
+
};
|
|
9
|
+
} | undefined>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.handler = void 0;
|
|
4
|
+
/* eslint-disable-next-line import/no-extraneous-dependencies */
|
|
5
|
+
const SecretsManager = require("aws-sdk/clients/secretsmanager");
|
|
6
|
+
const util_1 = require("./util");
|
|
7
|
+
const secretsManager = new SecretsManager();
|
|
8
|
+
async function handler(props, event) {
|
|
9
|
+
const username = props.username;
|
|
10
|
+
const passwordSecretArn = props.passwordSecretArn;
|
|
11
|
+
const clusterProps = props;
|
|
12
|
+
if (event.RequestType === 'Create') {
|
|
13
|
+
await createUser(username, passwordSecretArn, clusterProps);
|
|
14
|
+
return { PhysicalResourceId: util_1.makePhysicalId(username, clusterProps, event.RequestId), Data: { username: username } };
|
|
15
|
+
}
|
|
16
|
+
else if (event.RequestType === 'Delete') {
|
|
17
|
+
await dropUser(username, clusterProps);
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
else if (event.RequestType === 'Update') {
|
|
21
|
+
const { replace } = await updateUser(username, passwordSecretArn, clusterProps, event.OldResourceProperties);
|
|
22
|
+
const physicalId = replace ? util_1.makePhysicalId(username, clusterProps, event.RequestId) : event.PhysicalResourceId;
|
|
23
|
+
return { PhysicalResourceId: physicalId, Data: { username: username } };
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
/* eslint-disable-next-line dot-notation */
|
|
27
|
+
throw new Error(`Unrecognized event type: ${event['RequestType']}`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.handler = handler;
|
|
31
|
+
async function dropUser(username, clusterProps) {
|
|
32
|
+
await util_1.executeStatement(`DROP USER ${username}`, clusterProps);
|
|
33
|
+
}
|
|
34
|
+
async function createUser(username, passwordSecretArn, clusterProps) {
|
|
35
|
+
const password = await getPasswordFromSecret(passwordSecretArn);
|
|
36
|
+
await util_1.executeStatement(`CREATE USER ${username} PASSWORD '${password}'`, clusterProps);
|
|
37
|
+
}
|
|
38
|
+
async function updateUser(username, passwordSecretArn, clusterProps, oldResourceProperties) {
|
|
39
|
+
const oldClusterProps = oldResourceProperties;
|
|
40
|
+
if (clusterProps.clusterName !== oldClusterProps.clusterName || clusterProps.databaseName !== oldClusterProps.databaseName) {
|
|
41
|
+
await createUser(username, passwordSecretArn, clusterProps);
|
|
42
|
+
return { replace: true };
|
|
43
|
+
}
|
|
44
|
+
const oldUsername = oldResourceProperties.username;
|
|
45
|
+
const oldPasswordSecretArn = oldResourceProperties.passwordSecretArn;
|
|
46
|
+
const oldPassword = await getPasswordFromSecret(oldPasswordSecretArn);
|
|
47
|
+
const password = await getPasswordFromSecret(passwordSecretArn);
|
|
48
|
+
if (username !== oldUsername) {
|
|
49
|
+
await createUser(username, passwordSecretArn, clusterProps);
|
|
50
|
+
return { replace: true };
|
|
51
|
+
}
|
|
52
|
+
if (password !== oldPassword) {
|
|
53
|
+
await util_1.executeStatement(`ALTER USER ${username} PASSWORD '${password}'`, clusterProps);
|
|
54
|
+
return { replace: false };
|
|
55
|
+
}
|
|
56
|
+
return { replace: false };
|
|
57
|
+
}
|
|
58
|
+
async function getPasswordFromSecret(passwordSecretArn) {
|
|
59
|
+
const secretValue = await secretsManager.getSecretValue({
|
|
60
|
+
SecretId: passwordSecretArn,
|
|
61
|
+
}).promise();
|
|
62
|
+
const secretString = secretValue.SecretString;
|
|
63
|
+
if (!secretString) {
|
|
64
|
+
throw new Error(`Secret string for ${passwordSecretArn} was empty`);
|
|
65
|
+
}
|
|
66
|
+
const { password } = JSON.parse(secretString);
|
|
67
|
+
return password;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInVzZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBRUEsZ0VBQWdFO0FBQ2hFLGlFQUFpRTtBQUVqRSxpQ0FBd0U7QUFFeEUsTUFBTSxjQUFjLEdBQUcsSUFBSSxjQUFjLEVBQUUsQ0FBQztBQUVyQyxLQUFLLFVBQVUsT0FBTyxDQUFDLEtBQXNDLEVBQUUsS0FBa0Q7SUFDdEgsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsQ0FBQztJQUNoQyxNQUFNLGlCQUFpQixHQUFHLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQztJQUNsRCxNQUFNLFlBQVksR0FBRyxLQUFLLENBQUM7SUFFM0IsSUFBSSxLQUFLLENBQUMsV0FBVyxLQUFLLFFBQVEsRUFBRTtRQUNsQyxNQUFNLFVBQVUsQ0FBQyxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDNUQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLHFCQUFjLENBQUMsUUFBUSxFQUFFLFlBQVksRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxFQUFFLENBQUM7S0FDdEg7U0FBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLEtBQUssUUFBUSxFQUFFO1FBQ3pDLE1BQU0sUUFBUSxDQUFDLFFBQVEsRUFBRSxZQUFZLENBQUMsQ0FBQztRQUN2QyxPQUFPO0tBQ1I7U0FBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLEtBQUssUUFBUSxFQUFFO1FBQ3pDLE1BQU0sRUFBRSxPQUFPLEVBQUUsR0FBRyxNQUFNLFVBQVUsQ0FBQyxRQUFRLEVBQUUsaUJBQWlCLEVBQUUsWUFBWSxFQUFFLEtBQUssQ0FBQyxxQkFBd0QsQ0FBQyxDQUFDO1FBQ2hKLE1BQU0sVUFBVSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMscUJBQWMsQ0FBQyxRQUFRLEVBQUUsWUFBWSxFQUFFLEtBQUssQ0FBQyxTQUFT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ZCAqL1xuaW1wb3J0ICogYXMgQVdTTGFtYmRhIGZyb20gJ2F3cy1sYW1iZGEnO1xuLyogZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuaW1wb3J0ICogYXMgU2VjcmV0c01hbmFnZXIgZnJvbSAnYXdzLXNkay9jbGllbnRzL3NlY3JldHNtYW5hZ2VyJztcbmltcG9ydCB7IFVzZXJIYW5kbGVyUHJvcHMgfSBmcm9tICcuLi9oYW5kbGVyLXByb3BzJztcbmltcG9ydCB7IENsdXN0ZXJQcm9wcywgZXhlY3V0ZVN0YXRlbWVudCwgbWFrZVBoeXNpY2FsSWQgfSBmcm9tICcuL3V0aWwnO1xuXG5jb25zdCBzZWNyZXRzTWFuYWdlciA9IG5ldyBTZWNyZXRzTWFuYWdlcigpO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaGFuZGxlcihwcm9wczogVXNlckhhbmRsZXJQcm9wcyAmIENsdXN0ZXJQcm9wcywgZXZlbnQ6IEFXU0xhbWJkYS5DbG91ZEZvcm1hdGlvbkN1c3RvbVJlc291cmNlRXZlbnQpIHtcbiAgY29uc3QgdXNlcm5hbWUgPSBwcm9wcy51c2VybmFtZTtcbiAgY29uc3QgcGFzc3dvcmRTZWNyZXRBcm4gPSBwcm9wcy5wYXNzd29yZFNlY3JldEFybjtcbiAgY29uc3QgY2x1c3RlclByb3BzID0gcHJvcHM7XG5cbiAgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnQ3JlYXRlJykge1xuICAgIGF3YWl0IGNyZWF0ZVVzZXIodXNlcm5hbWUsIHBhc3N3b3JkU2VjcmV0QXJuLCBjbHVzdGVyUHJvcHMpO1xuICAgIHJldHVybiB7IFBoeXNpY2FsUmVzb3VyY2VJZDogbWFrZVBoeXNpY2FsSWQodXNlcm5hbWUsIGNsdXN0ZXJQcm9wcywgZXZlbnQuUmVxdWVzdElkKSwgRGF0YTogeyB1c2VybmFtZTogdXNlcm5hbWUgfSB9O1xuICB9IGVsc2UgaWYgKGV2ZW50LlJlcXVlc3RUeXBlID09PSAnRGVsZXRlJykge1xuICAgIGF3YWl0IGRyb3BVc2VyKHVzZXJuYW1lLCBjbHVzdGVyUHJvcHMpO1xuICAgIHJldHVybjtcbiAgfSBlbHNlIGlmIChldmVudC5SZXF1ZXN0VHlwZSA9PT0gJ1VwZGF0ZScpIHtcbiAgICBjb25zdCB7IHJlcGxhY2UgfSA9IGF3YWl0IHVwZGF0ZVVzZXIodXNlcm5hbWUsIHBhc3N3b3JkU2VjcmV0QXJuLCBjbHVzdGVyUHJvcHMsIGV2ZW50Lk9sZFJlc291cmNlUHJvcGVydGllcyBhcyBVc2VySGFuZGxlclByb3BzICYgQ2x1c3RlclByb3BzKTtcbiAgICBjb25zdCBwaHlzaWNhbElkID0gcmVwbGFjZSA/IG1ha2VQaHlzaWNhbElkKHVzZXJuYW1lLCBjbHVzdGVyUHJvcHMsIGV2ZW50LlJlcXVlc3RJZCkgOiBldmVudC5QaHlzaWNhbFJlc291cmNlSWQ7XG4gICAgcmV0dXJuIHsgUGh5c2ljYWxSZXNvdXJjZUlkOiBwaHlzaWNhbElkLCBEYXRhOiB7IHVzZXJuYW1lOiB1c2VybmFtZSB9IH07XG4gIH0gZWxzZSB7XG4gICAgLyogZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRvdC1ub3RhdGlvbiAqL1xuICAgIHRocm93IG5ldyBFcnJvcihgVW5yZWNvZ25pemVkIGV2ZW50IHR5cGU6ICR7ZXZlbnRbJ1JlcXVlc3RUeXBlJ119YCk7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gZHJvcFVzZXIodXNlcm5hbWU6IHN0cmluZywgY2x1c3RlclByb3BzOiBDbHVzdGVyUHJvcHMpIHtcbiAgYXdhaXQgZXhlY3V0ZVN0YXRlbWVudChgRFJPUCBVU0VSICR7dXNlcm5hbWV9YCwgY2x1c3RlclByb3BzKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gY3JlYXRlVXNlcih1c2VybmFtZTogc3RyaW5nLCBwYXNzd29yZFNlY3JldEFybjogc3RyaW5nLCBjbHVzdGVyUHJvcHM6IENsdXN0ZXJQcm9wcykge1xuICBjb25zdCBwYXNzd29yZCA9IGF3YWl0IGdldFBhc3N3b3JkRnJvbVNlY3JldChwYXNzd29yZFNlY3JldEFybik7XG5cbiAgYXdhaXQgZXhlY3V0ZVN0YXRlbWVudChgQ1JFQVRFIFVTRVIgJHt1c2VybmFtZX0gUEFTU1dPUkQgJyR7cGFzc3dvcmR9J2AsIGNsdXN0ZXJQcm9wcyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHVwZGF0ZVVzZXIoXG4gIHVzZXJuYW1lOiBzdHJpbmcsXG4gIHBhc3N3b3JkU2VjcmV0QXJuOiBzdHJpbmcsXG4gIGNsdXN0ZXJQcm9wczogQ2x1c3RlclByb3BzLFxuICBvbGRSZXNvdXJjZVByb3BlcnRpZXM6IFVzZXJIYW5kbGVyUHJvcHMgJiBDbHVzdGVyUHJvcHMsXG4pOiBQcm9taXNlPHsgcmVwbGFjZTogYm9vbGVhbiB9PiB7XG4gIGNvbnN0IG9sZENsdXN0ZXJQcm9wcyA9IG9sZFJlc291cmNlUHJvcGVydGllcztcbiAgaWYgKGNsdXN0ZXJQcm9wcy5jbHVzdGVyTmFtZSAhPT0gb2xkQ2x1c3RlclByb3BzLmNsdXN0ZXJOYW1lIHx8IGNsdXN0ZXJQcm9wcy5kYXRhYmFzZU5hbWUgIT09IG9sZENsdXN0ZXJQcm9wcy5kYXRhYmFzZU5hbWUpIHtcbiAgICBhd2FpdCBjcmVhdGVVc2VyKHVzZXJuYW1lLCBwYXNzd29yZFNlY3JldEFybiwgY2x1c3RlclByb3BzKTtcbiAgICByZXR1cm4geyByZXBsYWNlOiB0cnVlIH07XG4gIH1cblxuICBjb25zdCBvbGRVc2VybmFtZSA9IG9sZFJlc291cmNlUHJvcGVydGllcy51c2VybmFtZTtcbiAgY29uc3Qgb2xkUGFzc3dvcmRTZWNyZXRBcm4gPSBvbGRSZXNvdXJjZVByb3BlcnRpZXMucGFzc3dvcmRTZWNyZXRBcm47XG4gIGNvbnN0IG9sZFBhc3N3b3JkID0gYXdhaXQgZ2V0UGFzc3dvcmRGcm9tU2VjcmV0KG9sZFBhc3N3b3JkU2VjcmV0QXJuKTtcbiAgY29uc3QgcGFzc3dvcmQgPSBhd2FpdCBnZXRQYXNzd29yZEZyb21TZWNyZXQocGFzc3dvcmRTZWNyZXRBcm4pO1xuXG4gIGlmICh1c2VybmFtZSAhPT0gb2xkVXNlcm5hbWUpIHtcbiAgICBhd2FpdCBjcmVhdGVVc2VyKHVzZXJuYW1lLCBwYXNzd29yZFNlY3JldEFybiwgY2x1c3RlclByb3BzKTtcbiAgICByZXR1cm4geyByZXBsYWNlOiB0cnVlIH07XG4gIH1cblxuICBpZiAocGFzc3dvcmQgIT09IG9sZFBhc3N3b3JkKSB7XG4gICAgYXdhaXQgZXhlY3V0ZVN0YXRlbWVudChgQUxURVIgVVNFUiAke3VzZXJuYW1lfSBQQVNTV09SRCAnJHtwYXNzd29yZH0nYCwgY2x1c3RlclByb3BzKTtcbiAgICByZXR1cm4geyByZXBsYWNlOiBmYWxzZSB9O1xuICB9XG5cbiAgcmV0dXJuIHsgcmVwbGFjZTogZmFsc2UgfTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0UGFzc3dvcmRGcm9tU2VjcmV0KHBhc3N3b3JkU2VjcmV0QXJuOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCBzZWNyZXRWYWx1ZSA9IGF3YWl0IHNlY3JldHNNYW5hZ2VyLmdldFNlY3JldFZhbHVlKHtcbiAgICBTZWNyZXRJZDogcGFzc3dvcmRTZWNyZXRBcm4sXG4gIH0pLnByb21pc2UoKTtcbiAgY29uc3Qgc2VjcmV0U3RyaW5nID0gc2VjcmV0VmFsdWUuU2VjcmV0U3RyaW5nO1xuICBpZiAoIXNlY3JldFN0cmluZykge1xuICAgIHRocm93IG5ldyBFcnJvcihgU2VjcmV0IHN0cmluZyBmb3IgJHtwYXNzd29yZFNlY3JldEFybn0gd2FzIGVtcHR5YCk7XG4gIH1cbiAgY29uc3QgeyBwYXNzd29yZCB9ID0gSlNPTi5wYXJzZShzZWNyZXRTdHJpbmcpO1xuXG4gIHJldHVybiBwYXNzd29yZDtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { DatabaseQueryHandlerProps } from '../handler-props';
|
|
2
|
+
export declare type ClusterProps = Omit<DatabaseQueryHandlerProps, 'handler'>;
|
|
3
|
+
export declare function executeStatement(statement: string, clusterProps: ClusterProps): Promise<void>;
|
|
4
|
+
export declare function makePhysicalId(resourceName: string, clusterProps: ClusterProps, requestId: string): string;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.makePhysicalId = exports.executeStatement = void 0;
|
|
4
|
+
/* eslint-disable-next-line import/no-extraneous-dependencies */
|
|
5
|
+
const RedshiftData = require("aws-sdk/clients/redshiftdata");
|
|
6
|
+
const redshiftData = new RedshiftData();
|
|
7
|
+
async function executeStatement(statement, clusterProps) {
|
|
8
|
+
const executeStatementProps = {
|
|
9
|
+
ClusterIdentifier: clusterProps.clusterName,
|
|
10
|
+
Database: clusterProps.databaseName,
|
|
11
|
+
SecretArn: clusterProps.adminUserArn,
|
|
12
|
+
Sql: statement,
|
|
13
|
+
};
|
|
14
|
+
const executedStatement = await redshiftData.executeStatement(executeStatementProps).promise();
|
|
15
|
+
if (!executedStatement.Id) {
|
|
16
|
+
throw new Error('Service error: Statement execution did not return a statement ID');
|
|
17
|
+
}
|
|
18
|
+
await waitForStatementComplete(executedStatement.Id);
|
|
19
|
+
}
|
|
20
|
+
exports.executeStatement = executeStatement;
|
|
21
|
+
const waitTimeout = 100;
|
|
22
|
+
async function waitForStatementComplete(statementId) {
|
|
23
|
+
await new Promise((resolve) => {
|
|
24
|
+
setTimeout(() => resolve(), waitTimeout);
|
|
25
|
+
});
|
|
26
|
+
const statement = await redshiftData.describeStatement({ Id: statementId }).promise();
|
|
27
|
+
if (statement.Status !== 'FINISHED' && statement.Status !== 'FAILED' && statement.Status !== 'ABORTED') {
|
|
28
|
+
return waitForStatementComplete(statementId);
|
|
29
|
+
}
|
|
30
|
+
else if (statement.Status === 'FINISHED') {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
throw new Error(`Statement status was ${statement.Status}: ${statement.Error}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function makePhysicalId(resourceName, clusterProps, requestId) {
|
|
38
|
+
return `${clusterProps.clusterName}:${clusterProps.databaseName}:${resourceName}:${requestId}`;
|
|
39
|
+
}
|
|
40
|
+
exports.makePhysicalId = makePhysicalId;
|
|
41
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInV0aWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsZ0VBQWdFO0FBQ2hFLDZEQUE2RDtBQUc3RCxNQUFNLFlBQVksR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO0FBSWpDLEtBQUssVUFBVSxnQkFBZ0IsQ0FBQyxTQUFpQixFQUFFLFlBQTBCO0lBQ2xGLE1BQU0scUJBQXFCLEdBQUc7UUFDNUIsaUJBQWlCLEVBQUUsWUFBWSxDQUFDLFdBQVc7UUFDM0MsUUFBUSxFQUFFLFlBQVksQ0FBQyxZQUFZO1FBQ25DLFNBQVMsRUFBRSxZQUFZLENBQUMsWUFBWTtRQUNwQyxHQUFHLEVBQUUsU0FBUztLQUNmLENBQUM7SUFDRixNQUFNLGlCQUFpQixHQUFHLE1BQU0sWUFBWSxDQUFDLGdCQUFnQixDQUFDLHFCQUFxQixDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDL0YsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsRUFBRTtRQUN6QixNQUFNLElBQUksS0FBSyxDQUFDLGtFQUFrRSxDQUFDLENBQUM7S0FDckY7SUFDRCxNQUFNLHdCQUF3QixDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ3ZELENBQUM7QUFaRCw0Q0FZQztBQUVELE1BQU0sV0FBVyxHQUFHLEdBQUcsQ0FBQztBQUN4QixLQUFLLFVBQVUsd0JBQXdCLENBQUMsV0FBbUI7SUFDekQsTUFBTSxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQThCLEVBQUUsRUFBRTtRQUNuRCxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUUsV0FBVyxDQUFDLENBQUM7SUFDM0MsQ0FBQyxDQUFDLENBQUM7SUFDSCxNQUFNLFNBQVMsR0FBRyxNQUFNLFlBQVksQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLEVBQUUsRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ3RGLElBQUksU0FBUyxDQUFDLE1BQU0sS0FBSyxVQUFVLElBQUksU0FBUyxDQUFDLE1BQU0sS0FBSyxRQUFRLElBQUksU0FBUyxDQUFDLE1BQU0sS0FBSyxTQUFTLEVBQUU7UUFDdEcsT0FBTyx3QkFBd0IsQ0FBQyxXQUFXLENBQUMsQ0FBQztLQUM5QztTQUFNLElBQUksU0FBUyxDQUFDLE1BQU0sS0FBSyxVQUFVLEVBQUU7UUFDMUMsT0FBTztLQUNSO1NBQU07UUFDTCxNQUFNLElBQUksS0FBSyxDQUFDLHdCQUF3QixTQUFTLENBQUMsTUFBTSxLQUFLLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO0tBQ2pGO0FBQ0gsQ0FBQztBQUVELFNBQWdCLGNBQWMsQ0FBQyxZQUFvQixFQUFFLFlBQTBCLEVBQUUsU0FBaUI7SUFDaEcsT0FBTyxHQUFHLFlBQVksQ0FBQyxXQUFXLElBQUksWUFBWSxDQUFDLFlBQVksSUFBSSxZQUFZLElBQUksU0FBUyxFQUFFLENBQUM7QUFDakcsQ0FBQztBQUZELHdDQUVDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuaW1wb3J0ICogYXMgUmVkc2hpZnREYXRhIGZyb20gJ2F3cy1zZGsvY2xpZW50cy9yZWRzaGlmdGRhdGEnO1xuaW1wb3J0IHsgRGF0YWJhc2VRdWVyeUhhbmRsZXJQcm9wcyB9IGZyb20gJy4uL2hhbmRsZXItcHJvcHMnO1xuXG5jb25zdCByZWRzaGlmdERhdGEgPSBuZXcgUmVkc2hpZnREYXRhKCk7XG5cbmV4cG9ydCB0eXBlIENsdXN0ZXJQcm9wcyA9IE9taXQ8RGF0YWJhc2VRdWVyeUhhbmRsZXJQcm9wcywgJ2hhbmRsZXInPjtcblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGV4ZWN1dGVTdGF0ZW1lbnQoc3RhdGVtZW50OiBzdHJpbmcsIGNsdXN0ZXJQcm9wczogQ2x1c3RlclByb3BzKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IGV4ZWN1dGVTdGF0ZW1lbnRQcm9wcyA9IHtcbiAgICBDbHVzdGVySWRlbnRpZmllcjogY2x1c3RlclByb3BzLmNsdXN0ZXJOYW1lLFxuICAgIERhdGFiYXNlOiBjbHVzdGVyUHJvcHMuZGF0YWJhc2VOYW1lLFxuICAgIFNlY3JldEFybjogY2x1c3RlclByb3BzLmFkbWluVXNlckFybixcbiAgICBTcWw6IHN0YXRlbWVudCxcbiAgfTtcbiAgY29uc3QgZXhlY3V0ZWRTdGF0ZW1lbnQgPSBhd2FpdCByZWRzaGlmdERhdGEuZXhlY3V0ZVN0YXRlbWVudChleGVjdXRlU3RhdGVtZW50UHJvcHMpLnByb21pc2UoKTtcbiAgaWYgKCFleGVjdXRlZFN0YXRlbWVudC5JZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignU2VydmljZSBlcnJvcjogU3RhdGVtZW50IGV4ZWN1dGlvbiBkaWQgbm90IHJldHVybiBhIHN0YXRlbWVudCBJRCcpO1xuICB9XG4gIGF3YWl0IHdhaXRGb3JTdGF0ZW1lbnRDb21wbGV0ZShleGVjdXRlZFN0YXRlbWVudC5JZCk7XG59XG5cbmNvbnN0IHdhaXRUaW1lb3V0ID0gMTAwO1xuYXN5bmMgZnVuY3Rpb24gd2FpdEZvclN0YXRlbWVudENvbXBsZXRlKHN0YXRlbWVudElkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmU6ICh2YWx1ZTogdm9pZCkgPT4gdm9pZCkgPT4ge1xuICAgIHNldFRpbWVvdXQoKCkgPT4gcmVzb2x2ZSgpLCB3YWl0VGltZW91dCk7XG4gIH0pO1xuICBjb25zdCBzdGF0ZW1lbnQgPSBhd2FpdCByZWRzaGlmdERhdGEuZGVzY3JpYmVTdGF0ZW1lbnQoeyBJZDogc3RhdGVtZW50SWQgfSkucHJvbWlzZSgpO1xuICBpZiAoc3RhdGVtZW50LlN0YXR1cyAhPT0gJ0ZJTklTSEVEJyAmJiBzdGF0ZW1lbnQuU3RhdHVzICE9PSAnRkFJTEVEJyAmJiBzdGF0ZW1lbnQuU3RhdHVzICE9PSAnQUJPUlRFRCcpIHtcbiAgICByZXR1cm4gd2FpdEZvclN0YXRlbWVudENvbXBsZXRlKHN0YXRlbWVudElkKTtcbiAgfSBlbHNlIGlmIChzdGF0ZW1lbnQuU3RhdHVzID09PSAnRklOSVNIRUQnKSB7XG4gICAgcmV0dXJuO1xuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcihgU3RhdGVtZW50IHN0YXR1cyB3YXMgJHtzdGF0ZW1lbnQuU3RhdHVzfTogJHtzdGF0ZW1lbnQuRXJyb3J9YCk7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG1ha2VQaHlzaWNhbElkKHJlc291cmNlTmFtZTogc3RyaW5nLCBjbHVzdGVyUHJvcHM6IENsdXN0ZXJQcm9wcywgcmVxdWVzdElkOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYCR7Y2x1c3RlclByb3BzLmNsdXN0ZXJOYW1lfToke2NsdXN0ZXJQcm9wcy5kYXRhYmFzZU5hbWV9OiR7cmVzb3VyY2VOYW1lfToke3JlcXVlc3RJZH1gO1xufVxuIl19
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as iam from 'aws-cdk-lib/aws-iam';
|
|
2
|
+
import * as cdk from 'aws-cdk-lib';
|
|
3
|
+
import { DatabaseOptions } from '../database-options';
|
|
4
|
+
import { Construct } from 'constructs';
|
|
5
|
+
export interface DatabaseQueryProps<HandlerProps> extends DatabaseOptions {
|
|
6
|
+
readonly handler: string;
|
|
7
|
+
readonly properties: HandlerProps;
|
|
8
|
+
/**
|
|
9
|
+
* The policy to apply when this resource is removed from the application.
|
|
10
|
+
*
|
|
11
|
+
* @default cdk.RemovalPolicy.Destroy
|
|
12
|
+
*/
|
|
13
|
+
readonly removalPolicy?: cdk.RemovalPolicy;
|
|
14
|
+
}
|
|
15
|
+
export declare class DatabaseQuery<HandlerProps> extends Construct implements iam.IGrantable {
|
|
16
|
+
readonly grantPrincipal: iam.IPrincipal;
|
|
17
|
+
readonly ref: string;
|
|
18
|
+
private readonly resource;
|
|
19
|
+
constructor(scope: Construct, id: string, props: DatabaseQueryProps<HandlerProps>);
|
|
20
|
+
applyRemovalPolicy(policy: cdk.RemovalPolicy): void;
|
|
21
|
+
getAtt(attributeName: string): cdk.Reference;
|
|
22
|
+
getAttString(attributeName: string): string;
|
|
23
|
+
private getAdminUser;
|
|
24
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DatabaseQuery = void 0;
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const iam = require("aws-cdk-lib/aws-iam");
|
|
6
|
+
const lambda = require("aws-cdk-lib/aws-lambda");
|
|
7
|
+
const cdk = require("aws-cdk-lib");
|
|
8
|
+
const customresources = require("aws-cdk-lib/custom-resources");
|
|
9
|
+
const cluster_1 = require("../cluster");
|
|
10
|
+
// keep this import separate from other imports to reduce chance for merge conflicts with v2-main
|
|
11
|
+
// eslint-disable-next-line no-duplicate-imports, import/order
|
|
12
|
+
const constructs_1 = require("constructs");
|
|
13
|
+
class DatabaseQuery extends constructs_1.Construct {
|
|
14
|
+
constructor(scope, id, props) {
|
|
15
|
+
super(scope, id);
|
|
16
|
+
const adminUser = this.getAdminUser(props);
|
|
17
|
+
const handler = new lambda.SingletonFunction(this, 'Handler', {
|
|
18
|
+
code: lambda.Code.fromAsset(path.join(__dirname, 'database-query-provider')),
|
|
19
|
+
runtime: lambda.Runtime.NODEJS_12_X,
|
|
20
|
+
handler: 'index.handler',
|
|
21
|
+
timeout: cdk.Duration.minutes(1),
|
|
22
|
+
uuid: '3de5bea7-27da-4796-8662-5efb56431b5f',
|
|
23
|
+
lambdaPurpose: 'Query Redshift Database',
|
|
24
|
+
});
|
|
25
|
+
handler.addToRolePolicy(new iam.PolicyStatement({
|
|
26
|
+
actions: ['redshift-data:DescribeStatement', 'redshift-data:ExecuteStatement'],
|
|
27
|
+
resources: ['*'],
|
|
28
|
+
}));
|
|
29
|
+
adminUser.grantRead(handler);
|
|
30
|
+
const provider = new customresources.Provider(this, 'Provider', {
|
|
31
|
+
onEventHandler: handler,
|
|
32
|
+
});
|
|
33
|
+
const queryHandlerProps = {
|
|
34
|
+
handler: props.handler,
|
|
35
|
+
clusterName: props.cluster.clusterName,
|
|
36
|
+
adminUserArn: adminUser.secretArn,
|
|
37
|
+
databaseName: props.databaseName,
|
|
38
|
+
...props.properties,
|
|
39
|
+
};
|
|
40
|
+
this.resource = new cdk.CustomResource(this, 'Resource', {
|
|
41
|
+
resourceType: 'Custom::RedshiftDatabaseQuery',
|
|
42
|
+
serviceToken: provider.serviceToken,
|
|
43
|
+
removalPolicy: props.removalPolicy,
|
|
44
|
+
properties: queryHandlerProps,
|
|
45
|
+
});
|
|
46
|
+
this.grantPrincipal = handler.grantPrincipal;
|
|
47
|
+
this.ref = this.resource.ref;
|
|
48
|
+
}
|
|
49
|
+
applyRemovalPolicy(policy) {
|
|
50
|
+
this.resource.applyRemovalPolicy(policy);
|
|
51
|
+
}
|
|
52
|
+
getAtt(attributeName) {
|
|
53
|
+
return this.resource.getAtt(attributeName);
|
|
54
|
+
}
|
|
55
|
+
getAttString(attributeName) {
|
|
56
|
+
return this.resource.getAttString(attributeName);
|
|
57
|
+
}
|
|
58
|
+
getAdminUser(props) {
|
|
59
|
+
const cluster = props.cluster;
|
|
60
|
+
let adminUser = props.adminUser;
|
|
61
|
+
if (!adminUser) {
|
|
62
|
+
if (cluster instanceof cluster_1.Cluster) {
|
|
63
|
+
if (cluster.secret) {
|
|
64
|
+
adminUser = cluster.secret;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
throw new Error('Administrative access to the Redshift cluster is required but an admin user secret was not provided and the cluster did not generate admin user credentials (they were provided explicitly)');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
throw new Error('Administrative access to the Redshift cluster is required but an admin user secret was not provided and the cluster was imported');
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return adminUser;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
exports.DatabaseQuery = DatabaseQuery;
|
|
78
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YWJhc2UtcXVlcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJkYXRhYmFzZS1xdWVyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSw2QkFBNkI7QUFDN0IsMkNBQTJDO0FBQzNDLGlEQUFpRDtBQUVqRCxtQ0FBbUM7QUFDbkMsZ0VBQWdFO0FBQ2hFLHdDQUFxQztBQUlyQyxpR0FBaUc7QUFDakcsOERBQThEO0FBQzlELDJDQUF1QztBQWF2QyxNQUFhLGFBQTRCLFNBQVEsc0JBQVM7SUFNeEQsWUFBWSxLQUFnQixFQUFFLEVBQVUsRUFBRSxLQUF1QztRQUMvRSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0MsTUFBTSxPQUFPLEdBQUcsSUFBSSxNQUFNLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRTtZQUM1RCxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUseUJBQXlCLENBQUMsQ0FBQztZQUM1RSxPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxXQUFXO1lBQ25DLE9BQU8sRUFBRSxlQUFlO1lBQ3hCLE9BQU8sRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDaEMsSUFBSSxFQUFFLHNDQUFzQztZQUM1QyxhQUFhLEVBQUUseUJBQXlCO1NBQ3pDLENBQUMsQ0FBQztRQUNILE9BQU8sQ0FBQyxlQUFlLENBQUMsSUFBSSxHQUFHLENBQUMsZUFBZSxDQUFDO1lBQzlDLE9BQU8sRUFBRSxDQUFDLGlDQUFpQyxFQUFFLGdDQUFnQyxDQUFDO1lBQzlFLFNBQVMsRUFBRSxDQUFDLEdBQUcsQ0FBQztTQUNqQixDQUFDLENBQUMsQ0FBQztRQUNKLFNBQVMsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFN0IsTUFBTSxRQUFRLEdBQUcsSUFBSSxlQUFlLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUU7WUFDOUQsY0FBYyxFQUFFLE9BQU87U0FDeEIsQ0FBQyxDQUFDO1FBRUgsTUFBTSxpQkFBaUIsR0FBNkM7WUFDbEUsT0FBTyxFQUFFLEtBQUssQ0FBQyxPQUFPO1lBQ3RCLFdBQVcsRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLFdBQVc7WUFDdEMsWUFBWSxFQUFFLFNBQVMsQ0FBQyxTQUFTO1lBQ2pDLFlBQVksRUFBRSxLQUFLLENBQUMsWUFBWTtZQUNoQyxHQUFHLEtBQUssQ0FBQyxVQUFVO1NBQ3BCLENBQUM7UUFDRixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksR0FBRyxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFO1lBQ3ZELFlBQVksRUFBRSwrQkFBK0I7WUFDN0MsWUFBWSxFQUFFLFFBQVEsQ0FBQyxZQUFZO1lBQ25DLGFBQWEsRUFBRSxLQUFLLENBQUMsYUFBYTtZQUNsQyxVQUFVLEVBQUUsaUJBQWlCO1NBQzlCLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxjQUFjLEdBQUcsT0FBTyxDQUFDLGNBQWMsQ0FBQztRQUM3QyxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDO0lBQy9CLENBQUM7SUFFTSxrQkFBa0IsQ0FBQyxNQUF5QjtRQUNqRCxJQUFJLENBQUMsUUFBUSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFTSxNQUFNLENBQUMsYUFBcUI7UUFDakMsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBRU0sWUFBWSxDQUFDLGFBQXFCO1FBQ3ZDLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLENBQUM7SUFDbkQsQ0FBQztJQUVPLFlBQVksQ0FBQyxLQUFzQjtRQUN6QyxNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO1FBQzlCLElBQUksU0FBUyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUM7UUFDaEMsSUFBSSxDQUFDLFNBQVMsRUFBRTtZQUNkLElBQUksT0FBTyxZQUFZLGlCQUFPLEVBQUU7Z0JBQzlCLElBQUksT0FBTyxDQUFDLE1BQU0sRUFBRTtvQkFDbEIsU0FBUyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUM7aUJBQzVCO3FCQUFNO29CQUNMLE1BQU0sSUFBSSxLQUFLLENBQ2IsNkxBQTZMLENBQzlMLENBQUM7aUJBQ0g7YUFDRjtpQkFBTTtnQkFDTCxNQUFNLElBQUksS0FBSyxDQUNiLGtJQUFrSSxDQUNuSSxDQUFDO2FBQ0g7U0FDRjtRQUNELE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7Q0FDRjtBQTlFRCxzQ0E4RUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0ICogYXMgaWFtIGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0ICogYXMgc2VjcmV0c21hbmFnZXIgZnJvbSAnYXdzLWNkay1saWIvYXdzLXNlY3JldHNtYW5hZ2VyJztcbmltcG9ydCAqIGFzIGNkayBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgKiBhcyBjdXN0b21yZXNvdXJjZXMgZnJvbSAnYXdzLWNkay1saWIvY3VzdG9tLXJlc291cmNlcyc7XG5pbXBvcnQgeyBDbHVzdGVyIH0gZnJvbSAnLi4vY2x1c3Rlcic7XG5pbXBvcnQgeyBEYXRhYmFzZU9wdGlvbnMgfSBmcm9tICcuLi9kYXRhYmFzZS1vcHRpb25zJztcbmltcG9ydCB7IERhdGFiYXNlUXVlcnlIYW5kbGVyUHJvcHMgfSBmcm9tICcuL2hhbmRsZXItcHJvcHMnO1xuXG4vLyBrZWVwIHRoaXMgaW1wb3J0IHNlcGFyYXRlIGZyb20gb3RoZXIgaW1wb3J0cyB0byByZWR1Y2UgY2hhbmNlIGZvciBtZXJnZSBjb25mbGljdHMgd2l0aCB2Mi1tYWluXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZHVwbGljYXRlLWltcG9ydHMsIGltcG9ydC9vcmRlclxuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRGF0YWJhc2VRdWVyeVByb3BzPEhhbmRsZXJQcm9wcz4gZXh0ZW5kcyBEYXRhYmFzZU9wdGlvbnMge1xuICByZWFkb25seSBoYW5kbGVyOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHByb3BlcnRpZXM6IEhhbmRsZXJQcm9wcztcbiAgLyoqXG4gICAqIFRoZSBwb2xpY3kgdG8gYXBwbHkgd2hlbiB0aGlzIHJlc291cmNlIGlzIHJlbW92ZWQgZnJvbSB0aGUgYXBwbGljYXRpb24uXG4gICAqXG4gICAqIEBkZWZhdWx0IGNkay5SZW1vdmFsUG9saWN5LkRlc3Ryb3lcbiAgICovXG4gIHJlYWRvbmx5IHJlbW92YWxQb2xpY3k/OiBjZGsuUmVtb3ZhbFBvbGljeTtcbn1cblxuZXhwb3J0IGNsYXNzIERhdGFiYXNlUXVlcnk8SGFuZGxlclByb3BzPiBleHRlbmRzIENvbnN0cnVjdCBpbXBsZW1lbnRzIGlhbS5JR3JhbnRhYmxlIHtcbiAgcmVhZG9ubHkgZ3JhbnRQcmluY2lwYWw6IGlhbS5JUHJpbmNpcGFsO1xuICByZWFkb25seSByZWY6IHN0cmluZztcblxuICBwcml2YXRlIHJlYWRvbmx5IHJlc291cmNlOiBjZGsuQ3VzdG9tUmVzb3VyY2U7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IERhdGFiYXNlUXVlcnlQcm9wczxIYW5kbGVyUHJvcHM+KSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKTtcblxuICAgIGNvbnN0IGFkbWluVXNlciA9IHRoaXMuZ2V0QWRtaW5Vc2VyKHByb3BzKTtcbiAgICBjb25zdCBoYW5kbGVyID0gbmV3IGxhbWJkYS5TaW5nbGV0b25GdW5jdGlvbih0aGlzLCAnSGFuZGxlcicsIHtcbiAgICAgIGNvZGU6IGxhbWJkYS5Db2RlLmZyb21Bc3NldChwYXRoLmpvaW4oX19kaXJuYW1lLCAnZGF0YWJhc2UtcXVlcnktcHJvdmlkZXInKSksXG4gICAgICBydW50aW1lOiBsYW1iZGEuUnVudGltZS5OT0RFSlNfMTJfWCxcbiAgICAgIGhhbmRsZXI6ICdpbmRleC5oYW5kbGVyJyxcbiAgICAgIHRpbWVvdXQ6IGNkay5EdXJhdGlvbi5taW51dGVzKDEpLFxuICAgICAgdXVpZDogJzNkZTViZWE3LTI3ZGEtNDc5Ni04NjYyLTVlZmI1NjQzMWI1ZicsXG4gICAgICBsYW1iZGFQdXJwb3NlOiAnUXVlcnkgUmVkc2hpZnQgRGF0YWJhc2UnLFxuICAgIH0pO1xuICAgIGhhbmRsZXIuYWRkVG9Sb2xlUG9saWN5KG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgIGFjdGlvbnM6IFsncmVkc2hpZnQtZGF0YTpEZXNjcmliZVN0YXRlbWVudCcsICdyZWRzaGlmdC1kYXRhOkV4ZWN1dGVTdGF0ZW1lbnQnXSxcbiAgICAgIHJlc291cmNlczogWycqJ10sXG4gICAgfSkpO1xuICAgIGFkbWluVXNlci5ncmFudFJlYWQoaGFuZGxlcik7XG5cbiAgICBjb25zdCBwcm92aWRlciA9IG5ldyBjdXN0b21yZXNvdXJjZXMuUHJvdmlkZXIodGhpcywgJ1Byb3ZpZGVyJywge1xuICAgICAgb25FdmVudEhhbmRsZXI6IGhhbmRsZXIsXG4gICAgfSk7XG5cbiAgICBjb25zdCBxdWVyeUhhbmRsZXJQcm9wczogRGF0YWJhc2VRdWVyeUhhbmRsZXJQcm9wcyAmIEhhbmRsZXJQcm9wcyA9IHtcbiAgICAgIGhhbmRsZXI6IHByb3BzLmhhbmRsZXIsXG4gICAgICBjbHVzdGVyTmFtZTogcHJvcHMuY2x1c3Rlci5jbHVzdGVyTmFtZSxcbiAgICAgIGFkbWluVXNlckFybjogYWRtaW5Vc2VyLnNlY3JldEFybixcbiAgICAgIGRhdGFiYXNlTmFtZTogcHJvcHMuZGF0YWJhc2VOYW1lLFxuICAgICAgLi4ucHJvcHMucHJvcGVydGllcyxcbiAgICB9O1xuICAgIHRoaXMucmVzb3VyY2UgPSBuZXcgY2RrLkN1c3RvbVJlc291cmNlKHRoaXMsICdSZXNvdXJjZScsIHtcbiAgICAgIHJlc291cmNlVHlwZTogJ0N1c3RvbTo6UmVkc2hpZnREYXRhYmFzZVF1ZXJ5JyxcbiAgICAgIHNlcnZpY2VUb2tlbjogcHJvdmlkZXIuc2VydmljZVRva2VuLFxuICAgICAgcmVtb3ZhbFBvbGljeTogcHJvcHMucmVtb3ZhbFBvbGljeSxcbiAgICAgIHByb3BlcnRpZXM6IHF1ZXJ5SGFuZGxlclByb3BzLFxuICAgIH0pO1xuXG4gICAgdGhpcy5ncmFudFByaW5jaXBhbCA9IGhhbmRsZXIuZ3JhbnRQcmluY2lwYWw7XG4gICAgdGhpcy5yZWYgPSB0aGlzLnJlc291cmNlLnJlZjtcbiAgfVxuXG4gIHB1YmxpYyBhcHBseVJlbW92YWxQb2xpY3kocG9saWN5OiBjZGsuUmVtb3ZhbFBvbGljeSk6IHZvaWQge1xuICAgIHRoaXMucmVzb3VyY2UuYXBwbHlSZW1vdmFsUG9saWN5KHBvbGljeSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0QXR0KGF0dHJpYnV0ZU5hbWU6IHN0cmluZyk6IGNkay5SZWZlcmVuY2Uge1xuICAgIHJldHVybiB0aGlzLnJlc291cmNlLmdldEF0dChhdHRyaWJ1dGVOYW1lKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRBdHRTdHJpbmcoYXR0cmlidXRlTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5yZXNvdXJjZS5nZXRBdHRTdHJpbmcoYXR0cmlidXRlTmFtZSk7XG4gIH1cblxuICBwcml2YXRlIGdldEFkbWluVXNlcihwcm9wczogRGF0YWJhc2VPcHRpb25zKTogc2VjcmV0c21hbmFnZXIuSVNlY3JldCB7XG4gICAgY29uc3QgY2x1c3RlciA9IHByb3BzLmNsdXN0ZXI7XG4gICAgbGV0IGFkbWluVXNlciA9IHByb3BzLmFkbWluVXNlcjtcbiAgICBpZiAoIWFkbWluVXNlcikge1xuICAgICAgaWYgKGNsdXN0ZXIgaW5zdGFuY2VvZiBDbHVzdGVyKSB7XG4gICAgICAgIGlmIChjbHVzdGVyLnNlY3JldCkge1xuICAgICAgICAgIGFkbWluVXNlciA9IGNsdXN0ZXIuc2VjcmV0O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICdBZG1pbmlzdHJhdGl2ZSBhY2Nlc3MgdG8gdGhlIFJlZHNoaWZ0IGNsdXN0ZXIgaXMgcmVxdWlyZWQgYnV0IGFuIGFkbWluIHVzZXIgc2VjcmV0IHdhcyBub3QgcHJvdmlkZWQgYW5kIHRoZSBjbHVzdGVyIGRpZCBub3QgZ2VuZXJhdGUgYWRtaW4gdXNlciBjcmVkZW50aWFscyAodGhleSB3ZXJlIHByb3ZpZGVkIGV4cGxpY2l0bHkpJyxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgJ0FkbWluaXN0cmF0aXZlIGFjY2VzcyB0byB0aGUgUmVkc2hpZnQgY2x1c3RlciBpcyByZXF1aXJlZCBidXQgYW4gYWRtaW4gdXNlciBzZWNyZXQgd2FzIG5vdCBwcm92aWRlZCBhbmQgdGhlIGNsdXN0ZXIgd2FzIGltcG9ydGVkJyxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGFkbWluVXNlcjtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Column } from '../table';
|
|
2
|
+
export interface DatabaseQueryHandlerProps {
|
|
3
|
+
readonly handler: string;
|
|
4
|
+
readonly clusterName: string;
|
|
5
|
+
readonly adminUserArn: string;
|
|
6
|
+
readonly databaseName: string;
|
|
7
|
+
}
|
|
8
|
+
export interface UserHandlerProps {
|
|
9
|
+
readonly username: string;
|
|
10
|
+
readonly passwordSecretArn: string;
|
|
11
|
+
}
|
|
12
|
+
export interface TableHandlerProps {
|
|
13
|
+
readonly tableName: {
|
|
14
|
+
readonly prefix: string;
|
|
15
|
+
readonly generateSuffix: boolean;
|
|
16
|
+
};
|
|
17
|
+
readonly tableColumns: Column[];
|
|
18
|
+
}
|
|
19
|
+
export interface TablePrivilege {
|
|
20
|
+
readonly tableName: string;
|
|
21
|
+
readonly actions: string[];
|
|
22
|
+
}
|
|
23
|
+
export interface UserTablePrivilegesHandlerProps {
|
|
24
|
+
readonly username: string;
|
|
25
|
+
readonly tablePrivileges: TablePrivilege[];
|
|
26
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGFuZGxlci1wcm9wcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImhhbmRsZXItcHJvcHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbHVtbiB9IGZyb20gJy4uL3RhYmxlJztcblxuZXhwb3J0IGludGVyZmFjZSBEYXRhYmFzZVF1ZXJ5SGFuZGxlclByb3BzIHtcbiAgcmVhZG9ubHkgaGFuZGxlcjogc3RyaW5nO1xuICByZWFkb25seSBjbHVzdGVyTmFtZTogc3RyaW5nO1xuICByZWFkb25seSBhZG1pblVzZXJBcm46IHN0cmluZztcbiAgcmVhZG9ubHkgZGF0YWJhc2VOYW1lOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVXNlckhhbmRsZXJQcm9wcyB7XG4gIHJlYWRvbmx5IHVzZXJuYW1lOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHBhc3N3b3JkU2VjcmV0QXJuOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGFibGVIYW5kbGVyUHJvcHMge1xuICByZWFkb25seSB0YWJsZU5hbWU6IHtcbiAgICByZWFkb25seSBwcmVmaXg6IHN0cmluZztcbiAgICByZWFkb25seSBnZW5lcmF0ZVN1ZmZpeDogYm9vbGVhbjtcbiAgfTtcbiAgcmVhZG9ubHkgdGFibGVDb2x1bW5zOiBDb2x1bW5bXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBUYWJsZVByaXZpbGVnZSB7XG4gIHJlYWRvbmx5IHRhYmxlTmFtZTogc3RyaW5nO1xuICByZWFkb25seSBhY3Rpb25zOiBzdHJpbmdbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBVc2VyVGFibGVQcml2aWxlZ2VzSGFuZGxlclByb3BzIHtcbiAgcmVhZG9ubHkgdXNlcm5hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgdGFibGVQcml2aWxlZ2VzOiBUYWJsZVByaXZpbGVnZVtdO1xufVxuIl19
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { DatabaseOptions } from '../database-options';
|
|
2
|
+
import { ITable, TableAction } from '../table';
|
|
3
|
+
import { IUser } from '../user';
|
|
4
|
+
import { Construct } from 'constructs';
|
|
5
|
+
/**
|
|
6
|
+
* The Redshift table and action that make up a privilege that can be granted to a Redshift user.
|
|
7
|
+
*/
|
|
8
|
+
export interface TablePrivilege {
|
|
9
|
+
/**
|
|
10
|
+
* The table on which privileges will be granted.
|
|
11
|
+
*/
|
|
12
|
+
readonly table: ITable;
|
|
13
|
+
/**
|
|
14
|
+
* The actions that will be granted.
|
|
15
|
+
*/
|
|
16
|
+
readonly actions: TableAction[];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Properties for specifying privileges granted to a Redshift user on Redshift tables.
|
|
20
|
+
*/
|
|
21
|
+
export interface UserTablePrivilegesProps extends DatabaseOptions {
|
|
22
|
+
/**
|
|
23
|
+
* The user to which privileges will be granted.
|
|
24
|
+
*/
|
|
25
|
+
readonly user: IUser;
|
|
26
|
+
/**
|
|
27
|
+
* The privileges to be granted.
|
|
28
|
+
*
|
|
29
|
+
* @default [] - use `addPrivileges` to grant privileges after construction
|
|
30
|
+
*/
|
|
31
|
+
readonly privileges?: TablePrivilege[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Privileges granted to a Redshift user on Redshift tables.
|
|
35
|
+
*
|
|
36
|
+
* This construct is located in the `private` directory to ensure that it is not exported for direct public use. This
|
|
37
|
+
* means that user privileges must be managed through the `Table.grant` method or the `User.addTablePrivileges`
|
|
38
|
+
* method. Thus, each `User` will have at most one `UserTablePrivileges` construct to manage its privileges. For details
|
|
39
|
+
* on why this is a Good Thing, see the README, under "Granting Privileges".
|
|
40
|
+
*/
|
|
41
|
+
export declare class UserTablePrivileges extends Construct {
|
|
42
|
+
private privileges;
|
|
43
|
+
constructor(scope: Construct, id: string, props: UserTablePrivilegesProps);
|
|
44
|
+
/**
|
|
45
|
+
* Grant this user additional privileges.
|
|
46
|
+
*/
|
|
47
|
+
addPrivileges(table: ITable, ...actions: TableAction[]): void;
|
|
48
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.UserTablePrivileges = void 0;
|
|
4
|
+
const cdk = require("aws-cdk-lib");
|
|
5
|
+
const table_1 = require("../table");
|
|
6
|
+
const database_query_1 = require("./database-query");
|
|
7
|
+
const handler_name_1 = require("./database-query-provider/handler-name");
|
|
8
|
+
// keep this import separate from other imports to reduce chance for merge conflicts with v2-main
|
|
9
|
+
// eslint-disable-next-line no-duplicate-imports, import/order
|
|
10
|
+
const constructs_1 = require("constructs");
|
|
11
|
+
/**
|
|
12
|
+
* Privileges granted to a Redshift user on Redshift tables.
|
|
13
|
+
*
|
|
14
|
+
* This construct is located in the `private` directory to ensure that it is not exported for direct public use. This
|
|
15
|
+
* means that user privileges must be managed through the `Table.grant` method or the `User.addTablePrivileges`
|
|
16
|
+
* method. Thus, each `User` will have at most one `UserTablePrivileges` construct to manage its privileges. For details
|
|
17
|
+
* on why this is a Good Thing, see the README, under "Granting Privileges".
|
|
18
|
+
*/
|
|
19
|
+
class UserTablePrivileges extends constructs_1.Construct {
|
|
20
|
+
constructor(scope, id, props) {
|
|
21
|
+
var _a;
|
|
22
|
+
super(scope, id);
|
|
23
|
+
this.privileges = (_a = props.privileges) !== null && _a !== void 0 ? _a : [];
|
|
24
|
+
new database_query_1.DatabaseQuery(this, 'Resource', {
|
|
25
|
+
...props,
|
|
26
|
+
handler: handler_name_1.HandlerName.UserTablePrivileges,
|
|
27
|
+
properties: {
|
|
28
|
+
username: props.user.username,
|
|
29
|
+
tablePrivileges: cdk.Lazy.any({
|
|
30
|
+
produce: () => {
|
|
31
|
+
const reducedPrivileges = this.privileges.reduce((privileges, { table, actions }) => {
|
|
32
|
+
const tableName = table.tableName;
|
|
33
|
+
if (!(tableName in privileges)) {
|
|
34
|
+
privileges[tableName] = [];
|
|
35
|
+
}
|
|
36
|
+
actions = actions.concat(privileges[tableName]);
|
|
37
|
+
if (actions.includes(table_1.TableAction.ALL)) {
|
|
38
|
+
actions = [table_1.TableAction.ALL];
|
|
39
|
+
}
|
|
40
|
+
if (actions.includes(table_1.TableAction.UPDATE) || actions.includes(table_1.TableAction.DELETE)) {
|
|
41
|
+
actions.push(table_1.TableAction.SELECT);
|
|
42
|
+
}
|
|
43
|
+
privileges[tableName] = Array.from(new Set(actions));
|
|
44
|
+
return privileges;
|
|
45
|
+
}, {});
|
|
46
|
+
const serializedPrivileges = Object.entries(reducedPrivileges).map(([tableName, actions]) => ({
|
|
47
|
+
tableName: tableName,
|
|
48
|
+
actions: actions.map(action => table_1.TableAction[action]),
|
|
49
|
+
}));
|
|
50
|
+
return serializedPrivileges;
|
|
51
|
+
},
|
|
52
|
+
}),
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Grant this user additional privileges.
|
|
58
|
+
*/
|
|
59
|
+
addPrivileges(table, ...actions) {
|
|
60
|
+
this.privileges.push({ table, actions });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
exports.UserTablePrivileges = UserTablePrivileges;
|
|
64
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJpdmlsZWdlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInByaXZpbGVnZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsbUNBQW1DO0FBRW5DLG9DQUErQztBQUUvQyxxREFBaUQ7QUFDakQseUVBQXFFO0FBR3JFLGlHQUFpRztBQUNqRyw4REFBOEQ7QUFDOUQsMkNBQXVDO0FBa0N2Qzs7Ozs7OztHQU9HO0FBQ0gsTUFBYSxtQkFBb0IsU0FBUSxzQkFBUztJQUdoRCxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLEtBQStCOztRQUN2RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRWpCLElBQUksQ0FBQyxVQUFVLFNBQUcsS0FBSyxDQUFDLFVBQVUsbUNBQUksRUFBRSxDQUFDO1FBRXpDLElBQUksOEJBQWEsQ0FBa0MsSUFBSSxFQUFFLFVBQVUsRUFBRTtZQUNuRSxHQUFHLEtBQUs7WUFDUixPQUFPLEVBQUUsMEJBQVcsQ0FBQyxtQkFBbUI7WUFDeEMsVUFBVSxFQUFFO2dCQUNWLFFBQVEsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVE7Z0JBQzdCLGVBQWUsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztvQkFDNUIsT0FBTyxFQUFFLEdBQUcsRUFBRTt3QkFDWixNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUMsVUFBVSxFQUFFLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUU7NEJBQ2xGLE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxTQUFTLENBQUM7NEJBQ2xDLElBQUksQ0FBQyxDQUFDLFNBQVMsSUFBSSxVQUFVLENBQUMsRUFBRTtnQ0FDOUIsVUFBVSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQzs2QkFDNUI7NEJBQ0QsT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7NEJBQ2hELElBQUksT0FBTyxDQUFDLFFBQVEsQ0FBQyxtQkFBVyxDQUFDLEdBQUcsQ0FBQyxFQUFFO2dDQUNyQyxPQUFPLEdBQUcsQ0FBQyxtQkFBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDOzZCQUM3Qjs0QkFDRCxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsbUJBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLG1CQUFXLENBQUMsTUFBTSxDQUFDLEVBQUU7Z0NBQ2hGLE9BQU8sQ0FBQyxJQUFJLENBQUMsbUJBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQzs2QkFDbEM7NEJBQ0QsVUFBVSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQzs0QkFDckQsT0FBTyxVQUFVLENBQUM7d0JBQ3BCLENBQUMsRUFBRSxFQUFzQyxDQUFDLENBQUM7d0JBQzNDLE1BQU0sb0JBQW9CLEdBQStCLE1BQU0sQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQzs0QkFDeEgsU0FBUyxFQUFFLFNBQVM7NEJBQ3BCLE9BQU8sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsbUJBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQzt5QkFDcEQsQ0FBQyxDQUFDLENBQUM7d0JBQ0osT0FBTyxvQkFBb0IsQ0FBQztvQkFDOUIsQ0FBQztpQkFDRixDQUFRO2FBQ1Y7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7O09BRUc7SUFDSCxhQUFhLENBQUMsS0FBYSxFQUFFLEdBQUcsT0FBc0I7UUFDcEQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUMzQyxDQUFDO0NBQ0Y7QUEvQ0Qsa0RBK0NDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY2RrIGZyb20gJ2F3cy1jZGstbGliJztcbmltcG9ydCB7IERhdGFiYXNlT3B0aW9ucyB9IGZyb20gJy4uL2RhdGFiYXNlLW9wdGlvbnMnO1xuaW1wb3J0IHsgSVRhYmxlLCBUYWJsZUFjdGlvbiB9IGZyb20gJy4uL3RhYmxlJztcbmltcG9ydCB7IElVc2VyIH0gZnJvbSAnLi4vdXNlcic7XG5pbXBvcnQgeyBEYXRhYmFzZVF1ZXJ5IH0gZnJvbSAnLi9kYXRhYmFzZS1xdWVyeSc7XG5pbXBvcnQgeyBIYW5kbGVyTmFtZSB9IGZyb20gJy4vZGF0YWJhc2UtcXVlcnktcHJvdmlkZXIvaGFuZGxlci1uYW1lJztcbmltcG9ydCB7IFRhYmxlUHJpdmlsZWdlIGFzIFNlcmlhbGl6ZWRUYWJsZVByaXZpbGVnZSwgVXNlclRhYmxlUHJpdmlsZWdlc0hhbmRsZXJQcm9wcyB9IGZyb20gJy4vaGFuZGxlci1wcm9wcyc7XG5cbi8vIGtlZXAgdGhpcyBpbXBvcnQgc2VwYXJhdGUgZnJvbSBvdGhlciBpbXBvcnRzIHRvIHJlZHVjZSBjaGFuY2UgZm9yIG1lcmdlIGNvbmZsaWN0cyB3aXRoIHYyLW1haW5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1kdXBsaWNhdGUtaW1wb3J0cywgaW1wb3J0L29yZGVyXG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcblxuLyoqXG4gKiBUaGUgUmVkc2hpZnQgdGFibGUgYW5kIGFjdGlvbiB0aGF0IG1ha2UgdXAgYSBwcml2aWxlZ2UgdGhhdCBjYW4gYmUgZ3JhbnRlZCB0byBhIFJlZHNoaWZ0IHVzZXIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGFibGVQcml2aWxlZ2Uge1xuICAvKipcbiAgICogVGhlIHRhYmxlIG9uIHdoaWNoIHByaXZpbGVnZXMgd2lsbCBiZSBncmFudGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgdGFibGU6IElUYWJsZTtcblxuICAvKipcbiAgICogVGhlIGFjdGlvbnMgdGhhdCB3aWxsIGJlIGdyYW50ZWQuXG4gICAqL1xuICByZWFkb25seSBhY3Rpb25zOiBUYWJsZUFjdGlvbltdO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIHNwZWNpZnlpbmcgcHJpdmlsZWdlcyBncmFudGVkIHRvIGEgUmVkc2hpZnQgdXNlciBvbiBSZWRzaGlmdCB0YWJsZXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVXNlclRhYmxlUHJpdmlsZWdlc1Byb3BzIGV4dGVuZHMgRGF0YWJhc2VPcHRpb25zIHtcbiAgLyoqXG4gICAqIFRoZSB1c2VyIHRvIHdoaWNoIHByaXZpbGVnZXMgd2lsbCBiZSBncmFudGVkLlxuICAgKi9cbiAgcmVhZG9ubHkgdXNlcjogSVVzZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBwcml2aWxlZ2VzIHRvIGJlIGdyYW50ZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IFtdIC0gdXNlIGBhZGRQcml2aWxlZ2VzYCB0byBncmFudCBwcml2aWxlZ2VzIGFmdGVyIGNvbnN0cnVjdGlvblxuICAgKi9cbiAgcmVhZG9ubHkgcHJpdmlsZWdlcz86IFRhYmxlUHJpdmlsZWdlW107XG59XG5cbi8qKlxuICogUHJpdmlsZWdlcyBncmFudGVkIHRvIGEgUmVkc2hpZnQgdXNlciBvbiBSZWRzaGlmdCB0YWJsZXMuXG4gKlxuICogVGhpcyBjb25zdHJ1Y3QgaXMgbG9jYXRlZCBpbiB0aGUgYHByaXZhdGVgIGRpcmVjdG9yeSB0byBlbnN1cmUgdGhhdCBpdCBpcyBub3QgZXhwb3J0ZWQgZm9yIGRpcmVjdCBwdWJsaWMgdXNlLiBUaGlzXG4gKiBtZWFucyB0aGF0IHVzZXIgcHJpdmlsZWdlcyBtdXN0IGJlIG1hbmFnZWQgdGhyb3VnaCB0aGUgYFRhYmxlLmdyYW50YCBtZXRob2Qgb3IgdGhlIGBVc2VyLmFkZFRhYmxlUHJpdmlsZWdlc2BcbiAqIG1ldGhvZC4gVGh1cywgZWFjaCBgVXNlcmAgd2lsbCBoYXZlIGF0IG1vc3Qgb25lIGBVc2VyVGFibGVQcml2aWxlZ2VzYCBjb25zdHJ1Y3QgdG8gbWFuYWdlIGl0cyBwcml2aWxlZ2VzLiBGb3IgZGV0YWlsc1xuICogb24gd2h5IHRoaXMgaXMgYSBHb29kIFRoaW5nLCBzZWUgdGhlIFJFQURNRSwgdW5kZXIgXCJHcmFudGluZyBQcml2aWxlZ2VzXCIuXG4gKi9cbmV4cG9ydCBjbGFzcyBVc2VyVGFibGVQcml2aWxlZ2VzIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgcHJpdmF0ZSBwcml2aWxlZ2VzOiBUYWJsZVByaXZpbGVnZVtdO1xuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBVc2VyVGFibGVQcml2aWxlZ2VzUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgdGhpcy5wcml2aWxlZ2VzID0gcHJvcHMucHJpdmlsZWdlcyA/PyBbXTtcblxuICAgIG5ldyBEYXRhYmFzZVF1ZXJ5PFVzZXJUYWJsZVByaXZpbGVnZXNIYW5kbGVyUHJvcHM+KHRoaXMsICdSZXNvdXJjZScsIHtcbiAgICAgIC4uLnByb3BzLFxuICAgICAgaGFuZGxlcjogSGFuZGxlck5hbWUuVXNlclRhYmxlUHJpdmlsZWdlcyxcbiAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgdXNlcm5hbWU6IHByb3BzLnVzZXIudXNlcm5hbWUsXG4gICAgICAgIHRhYmxlUHJpdmlsZWdlczogY2RrLkxhenkuYW55KHtcbiAgICAgICAgICBwcm9kdWNlOiAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCByZWR1Y2VkUHJpdmlsZWdlcyA9IHRoaXMucHJpdmlsZWdlcy5yZWR1Y2UoKHByaXZpbGVnZXMsIHsgdGFibGUsIGFjdGlvbnMgfSkgPT4ge1xuICAgICAgICAgICAgICBjb25zdCB0YWJsZU5hbWUgPSB0YWJsZS50YWJsZU5hbWU7XG4gICAgICAgICAgICAgIGlmICghKHRhYmxlTmFtZSBpbiBwcml2aWxlZ2VzKSkge1xuICAgICAgICAgICAgICAgIHByaXZpbGVnZXNbdGFibGVOYW1lXSA9IFtdO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGFjdGlvbnMgPSBhY3Rpb25zLmNvbmNhdChwcml2aWxlZ2VzW3RhYmxlTmFtZV0pO1xuICAgICAgICAgICAgICBpZiAoYWN0aW9ucy5pbmNsdWRlcyhUYWJsZUFjdGlvbi5BTEwpKSB7XG4gICAgICAgICAgICAgICAgYWN0aW9ucyA9IFtUYWJsZUFjdGlvbi5BTExdO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmIChhY3Rpb25zLmluY2x1ZGVzKFRhYmxlQWN0aW9uLlVQREFURSkgfHwgYWN0aW9ucy5pbmNsdWRlcyhUYWJsZUFjdGlvbi5ERUxFVEUpKSB7XG4gICAgICAgICAgICAgICAgYWN0aW9ucy5wdXNoKFRhYmxlQWN0aW9uLlNFTEVDVCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcHJpdmlsZWdlc1t0YWJsZU5hbWVdID0gQXJyYXkuZnJvbShuZXcgU2V0KGFjdGlvbnMpKTtcbiAgICAgICAgICAgICAgcmV0dXJuIHByaXZpbGVnZXM7XG4gICAgICAgICAgICB9LCB7fSBhcyB7IFtrZXk6IHN0cmluZ106IFRhYmxlQWN0aW9uW10gfSk7XG4gICAgICAgICAgICBjb25zdCBzZXJpYWxpemVkUHJpdmlsZWdlczogU2VyaWFsaXplZFRhYmxlUHJpdmlsZWdlW10gPSBPYmplY3QuZW50cmllcyhyZWR1Y2VkUHJpdmlsZWdlcykubWFwKChbdGFibGVOYW1lLCBhY3Rpb25zXSkgPT4gKHtcbiAgICAgICAgICAgICAgdGFibGVOYW1lOiB0YWJsZU5hbWUsXG4gICAgICAgICAgICAgIGFjdGlvbnM6IGFjdGlvbnMubWFwKGFjdGlvbiA9PiBUYWJsZUFjdGlvblthY3Rpb25dKSxcbiAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIHJldHVybiBzZXJpYWxpemVkUHJpdmlsZWdlcztcbiAgICAgICAgICB9LFxuICAgICAgICB9KSBhcyBhbnksXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEdyYW50IHRoaXMgdXNlciBhZGRpdGlvbmFsIHByaXZpbGVnZXMuXG4gICAqL1xuICBhZGRQcml2aWxlZ2VzKHRhYmxlOiBJVGFibGUsIC4uLmFjdGlvbnM6IFRhYmxlQWN0aW9uW10pOiB2b2lkIHtcbiAgICB0aGlzLnByaXZpbGVnZXMucHVzaCh7IHRhYmxlLCBhY3Rpb25zIH0pO1xuICB9XG59XG4iXX0=
|