@digitraffic/common 2022.10.6-1 → 2022.10.10-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/README.md +54 -0
- package/aws/index.d.ts +1 -0
- package/aws/index.js +18 -0
- package/aws/infra/api/index.d.ts +1 -0
- package/aws/infra/api/index.js +18 -0
- package/aws/infra/api/responses.js +1 -1
- package/aws/infra/stack/lambda-configs.js +1 -1
- package/aws/infra/stack/rest_apis.d.ts +1 -0
- package/aws/infra/stack/rest_apis.js +8 -2
- package/aws/infra/stack/stack-checking-aspect.d.ts +4 -3
- package/aws/infra/stack/stack-checking-aspect.js +8 -7
- package/aws/infra/stack/stack.d.ts +4 -1
- package/aws/infra/stack/stack.js +1 -1
- package/aws/infra/usage-plans.js +1 -1
- package/aws/types/errors.js +1 -1
- package/aws/types/tags.js +1 -1
- package/database/last-updated.js +10 -10
- package/package.json +3 -2
- package/test/httpserver.js +1 -1
- package/types/index.d.ts +1 -0
- package/types/index.js +18 -0
- package/types/language.js +1 -1
- package/utils/geometry.js +1 -1
- package/src/aws/infra/api/integration.js +0 -52
- package/src/aws/infra/api/response.js +0 -61
- package/src/aws/infra/api/responses.js +0 -79
- package/src/aws/infra/api/static-integration.js +0 -54
- package/src/aws/infra/canaries/canary-alarm.js +0 -26
- package/src/aws/infra/canaries/canary-parameters.js +0 -3
- package/src/aws/infra/canaries/canary-role.js +0 -46
- package/src/aws/infra/canaries/canary.js +0 -29
- package/src/aws/infra/canaries/database-canary.js +0 -55
- package/src/aws/infra/canaries/database-checker.js +0 -109
- package/src/aws/infra/canaries/url-canary.js +0 -46
- package/src/aws/infra/canaries/url-checker.js +0 -238
- package/src/aws/infra/documentation.js +0 -95
- package/src/aws/infra/scheduler.js +0 -31
- package/src/aws/infra/security-rule.js +0 -39
- package/src/aws/infra/sqs-integration.js +0 -93
- package/src/aws/infra/sqs-queue.js +0 -130
- package/src/aws/infra/stack/lambda-configs.js +0 -93
- package/src/aws/infra/stack/monitoredfunction.js +0 -135
- package/src/aws/infra/stack/rest_apis.js +0 -179
- package/src/aws/infra/stack/stack-checking-aspect.js +0 -163
- package/src/aws/infra/stack/stack.js +0 -58
- package/src/aws/infra/stack/subscription.js +0 -41
- package/src/aws/infra/usage-plans.js +0 -42
- package/src/aws/runtime/apikey.js +0 -13
- package/src/aws/runtime/digitraffic-integration-response.js +0 -26
- package/src/aws/runtime/messaging.js +0 -31
- package/src/aws/runtime/s3.js +0 -30
- package/src/aws/runtime/secrets/dbsecret.js +0 -96
- package/src/aws/runtime/secrets/proxy-holder.js +0 -26
- package/src/aws/runtime/secrets/rds-holder.js +0 -26
- package/src/aws/runtime/secrets/secret-holder.js +0 -73
- package/src/aws/runtime/secrets/secret.js +0 -43
- package/src/aws/types/errors.js +0 -9
- package/src/aws/types/lambda-response.js +0 -28
- package/src/aws/types/mediatypes.js +0 -15
- package/src/aws/types/model-with-reference.js +0 -3
- package/src/aws/types/proxytypes.js +0 -3
- package/src/aws/types/tags.js +0 -7
- package/src/database/cached.js +0 -32
- package/src/database/database.js +0 -62
- package/src/database/last-updated.js +0 -54
- package/src/marine/id_utils.js +0 -33
- package/src/marine/rtz.js +0 -3
- package/src/test/asserter.js +0 -45
- package/src/test/db-testutils.js +0 -31
- package/src/test/httpserver.js +0 -67
- package/src/test/secret.js +0 -25
- package/src/test/secrets-manager.js +0 -59
- package/src/test/testutils.js +0 -44
- package/src/types/input-error.js +0 -7
- package/src/types/language.js +0 -10
- package/src/types/traffictype.js +0 -13
- package/src/types/validator.js +0 -14
- package/src/utils/api-model.js +0 -129
- package/src/utils/base64.js +0 -21
- package/src/utils/date-utils.js +0 -34
- package/src/utils/geojson-types.js +0 -18
- package/src/utils/geometry.js +0 -140
- package/src/utils/retry.js +0 -50
- package/src/utils/slack.js +0 -25
- package/src/utils/utils.js +0 -40
- package/test/marine/id_utils.test.js +0 -69
- package/test/promise/promise.test.js +0 -125
- package/test/secrets/dbsecret.test.js +0 -71
- package/test/secrets/secret-holder.test.js +0 -124
- package/test/secrets/secret.test.js +0 -66
- package/test/test/httpserver.test.js +0 -87
- package/test/utils/date-utils.test.js +0 -51
- package/test/utils/geometry.test.js +0 -49
- package/test/utils/utils.test.js +0 -49
- package/yarn.lock +0 -3200
@@ -1,135 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.MonitoredDBFunction = exports.MonitoredFunction = void 0;
|
4
|
-
const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
|
5
|
-
const aws_cloudwatch_actions_1 = require("aws-cdk-lib/aws-cloudwatch-actions");
|
6
|
-
const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
|
7
|
-
const lambda_configs_1 = require("../stack/lambda-configs");
|
8
|
-
const change_case_1 = require("change-case");
|
9
|
-
const subscription_1 = require("../stack/subscription");
|
10
|
-
/**
|
11
|
-
* Creates a Lambda function that monitors default CloudWatch Lambda metrics with CloudWatch Alarms.
|
12
|
-
*/
|
13
|
-
class MonitoredFunction extends aws_lambda_1.Function {
|
14
|
-
/**
|
15
|
-
* @param scope Stack
|
16
|
-
* @param id Lambda construct Id
|
17
|
-
* @param functionProps Lambda function properties
|
18
|
-
* @param alarmSnsTopic SNS topic for alarms
|
19
|
-
* @param warningSnsTopic SNS topic for warnings
|
20
|
-
* @param production Is the stack a production stack, used for determining the alarm topic
|
21
|
-
* @param trafficType Traffic type, used for alarm names. Set to null if Lambda is not related to any traffic type.
|
22
|
-
* @param props Monitored function properties
|
23
|
-
*/
|
24
|
-
constructor(scope, id, functionProps, alarmSnsTopic, warningSnsTopic, production, trafficType, props) {
|
25
|
-
super(scope, id, functionProps);
|
26
|
-
this.givenName = functionProps.functionName;
|
27
|
-
const alarmSnsAction = new aws_cloudwatch_actions_1.SnsAction(alarmSnsTopic);
|
28
|
-
const warningSnsAction = new aws_cloudwatch_actions_1.SnsAction(warningSnsTopic);
|
29
|
-
if (props?.durationAlarmProps?.create !== false) {
|
30
|
-
if (!functionProps.timeout) {
|
31
|
-
throw new Error('Timeout needs to be explicitly set');
|
32
|
-
}
|
33
|
-
this.createAlarm(scope, this.metricDuration().with({ statistic: 'max' }), 'Duration', 'Duration alarm', `Duration has exceeded ${functionProps.timeout.toSeconds()} seconds`, trafficType, this.getAlarmActionForEnv(alarmSnsAction, warningSnsAction, production), functionProps.timeout.toMilliseconds(), 1, 1, aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD, props?.durationAlarmProps);
|
34
|
-
}
|
35
|
-
if (props?.durationWarningProps?.create !== false) {
|
36
|
-
if (!functionProps.timeout) {
|
37
|
-
throw new Error('Timeout needs to be explicitly set');
|
38
|
-
}
|
39
|
-
this.createAlarm(scope, this.metricDuration().with({ statistic: 'max' }), 'Duration-Warning', 'Duration warning', `Duration is 85 % of max ${functionProps.timeout.toSeconds()} seconds`, trafficType, warningSnsAction, functionProps.timeout.toMilliseconds() * 0.85, 1, 1, aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD, props?.durationWarningProps);
|
40
|
-
}
|
41
|
-
if (props?.errorAlarmProps?.create !== false) {
|
42
|
-
this.createAlarm(scope, this.metricErrors(), 'Errors', 'Errors alarm', 'Invocations did not succeed', trafficType, this.getAlarmActionForEnv(alarmSnsAction, warningSnsAction, production), 1, 1, 1, aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD, props?.errorAlarmProps);
|
43
|
-
}
|
44
|
-
if (props?.throttleAlarmProps?.create !== false) {
|
45
|
-
this.createAlarm(scope, this.metricThrottles(), 'Throttles', 'Throttles alarm', 'Has throttled', trafficType, this.getAlarmActionForEnv(alarmSnsAction, warningSnsAction, production), 0, 1, 1, aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_THRESHOLD, props?.throttleAlarmProps);
|
46
|
-
}
|
47
|
-
}
|
48
|
-
/**
|
49
|
-
* Create new MonitoredFunction. Use topics from given DigitrafficStack.
|
50
|
-
*
|
51
|
-
* @param stack DigitrafficStack
|
52
|
-
* @param id Lambda construct Id
|
53
|
-
* @param functionProps Lambda function properties
|
54
|
-
* @param props Monitored function properties
|
55
|
-
*/
|
56
|
-
static create(stack, id, functionProps, props) {
|
57
|
-
if (props === MonitoredFunction.DISABLE_ALARMS && stack.configuration.production) {
|
58
|
-
throw new Error(`Function ${functionProps.functionName} has DISABLE_ALARMS. Remove before installing to production or define your own properties!`);
|
59
|
-
}
|
60
|
-
return new MonitoredFunction(stack, id, functionProps, stack.alarmTopic, stack.warningTopic, stack.configuration.production, stack.configuration.trafficType, props);
|
61
|
-
}
|
62
|
-
/**
|
63
|
-
* Create new MonitoredFunction. Use topics from given DigitrafficStack. Generate names from given name and configuration shortName.
|
64
|
-
*
|
65
|
-
* For example, shortName FOO and given name update-things will create function FOO-UpdateThings and use code from lambda/update-things/update-things.ts method handler.
|
66
|
-
*
|
67
|
-
* @param stack DigitrafficStack
|
68
|
-
* @param name param-case name
|
69
|
-
* @param environment Lambda environment
|
70
|
-
* @param functionParameters Lambda function parameters
|
71
|
-
*/
|
72
|
-
static createV2(stack, name, environment, functionParameters) {
|
73
|
-
const functionName = functionParameters?.functionName || `${stack.configuration.shortName}-${(0, change_case_1.pascalCase)(name)}`;
|
74
|
-
const functionProps = (0, lambda_configs_1.databaseFunctionProps)(stack, environment, functionName, name, functionParameters);
|
75
|
-
return MonitoredFunction.create(stack, functionName, functionProps, functionParameters);
|
76
|
-
}
|
77
|
-
createAlarm(stack, metric, alarmId, alarmName, alarmDescription, trafficType, alarmSnsAction, threshold, evaluationPeriods, datapointsToAlarm, comparisonOperator, alarmProps) {
|
78
|
-
metric.createAlarm(stack, `${this.node.id}-${alarmId}`, {
|
79
|
-
alarmName: `${trafficType ?? ''} ${stack.stackName} ${this.functionName} ${alarmName}`.trim(),
|
80
|
-
alarmDescription,
|
81
|
-
threshold: alarmProps?.threshold ?? threshold,
|
82
|
-
evaluationPeriods: alarmProps?.evaluationPeriods ?? evaluationPeriods,
|
83
|
-
datapointsToAlarm: alarmProps?.datapointsToAlarm ?? datapointsToAlarm,
|
84
|
-
comparisonOperator: alarmProps?.comparisonOperator ?? comparisonOperator,
|
85
|
-
}).addAlarmAction(alarmSnsAction);
|
86
|
-
}
|
87
|
-
getAlarmActionForEnv(alarmAction, warningAction, production) {
|
88
|
-
return production ? alarmAction : warningAction;
|
89
|
-
}
|
90
|
-
}
|
91
|
-
exports.MonitoredFunction = MonitoredFunction;
|
92
|
-
/** disable all alarms */
|
93
|
-
MonitoredFunction.DISABLE_ALARMS = {
|
94
|
-
durationAlarmProps: {
|
95
|
-
create: false,
|
96
|
-
},
|
97
|
-
durationWarningProps: {
|
98
|
-
create: false,
|
99
|
-
},
|
100
|
-
errorAlarmProps: {
|
101
|
-
create: false,
|
102
|
-
},
|
103
|
-
throttleAlarmProps: {
|
104
|
-
create: false,
|
105
|
-
},
|
106
|
-
};
|
107
|
-
class MonitoredDBFunction {
|
108
|
-
/**
|
109
|
-
* Create new MonitoredDBFunction. Use topics from given DigitrafficStack. Generate names from given name and configuration shortName.
|
110
|
-
* Grant secret and create log subscription.
|
111
|
-
*
|
112
|
-
* For example, shortName FOO and given name update-things will create function FOO-UpdateThings and use code from lambda/update-things/update-things.ts method handler.
|
113
|
-
*
|
114
|
-
* If you don't need to pass any extra arguments to lambda-environment, you can leave environment out and this function will create the
|
115
|
-
* default Lambda Environment with SECRET_ID and DB_APPLICATION.
|
116
|
-
*
|
117
|
-
* @param stack DigitrafficStack
|
118
|
-
* @param name param-case name
|
119
|
-
* @param environment Lambda environment
|
120
|
-
* @param functionParameters Lambda function parameters
|
121
|
-
*/
|
122
|
-
static create(stack, name, environment, functionParameters) {
|
123
|
-
const functionName = functionParameters?.functionName || `${stack.configuration.shortName}-${(0, change_case_1.pascalCase)(name)}`;
|
124
|
-
const env = environment ? environment : stack.createLambdaEnvironment();
|
125
|
-
const functionProps = (0, lambda_configs_1.databaseFunctionProps)(stack, env, functionName, name, functionParameters);
|
126
|
-
const mf = MonitoredFunction.create(stack, functionName, functionProps, functionParameters);
|
127
|
-
stack.grantSecret(mf);
|
128
|
-
if (stack.configuration.logsDestinationArn) {
|
129
|
-
new subscription_1.DigitrafficLogSubscriptions(stack, mf);
|
130
|
-
}
|
131
|
-
return mf;
|
132
|
-
}
|
133
|
-
}
|
134
|
-
exports.MonitoredDBFunction = MonitoredDBFunction;
|
135
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9uaXRvcmVkZnVuY3Rpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvYXdzL2luZnJhL3N0YWNrL21vbml0b3JlZGZ1bmN0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHVEQUErRDtBQUUvRCwrRUFBNkQ7QUFDN0QsK0RBQXNFO0FBR3RFLDREQUE4RztBQUM5Ryw2Q0FBdUM7QUFDdkMsd0RBQWtFO0FBK0JsRTs7R0FFRztBQUNILE1BQWEsaUJBQWtCLFNBQVEscUJBQVE7SUFzRTNDOzs7Ozs7Ozs7T0FTRztJQUNILFlBQ0ksS0FBWSxFQUNaLEVBQVUsRUFDVixhQUE0QixFQUM1QixhQUFxQixFQUNyQixlQUF1QixFQUN2QixVQUFtQixFQUNuQixXQUErQixFQUMvQixLQUE4QjtRQUU5QixLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxhQUFhLENBQUMsQ0FBQztRQUVoQyxJQUFJLENBQUMsU0FBUyxHQUFHLGFBQWEsQ0FBQyxZQUFzQixDQUFDO1FBRXRELE1BQU0sY0FBYyxHQUFHLElBQUksa0NBQVMsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUNwRCxNQUFNLGdCQUFnQixHQUFHLElBQUksa0NBQVMsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUV4RCxJQUFJLEtBQUssRUFBRSxrQkFBa0IsRUFBRSxNQUFNLEtBQUssS0FBSyxFQUFFO1lBQzdDLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxFQUFFO2dCQUN4QixNQUFNLElBQUksS0FBSyxDQUFDLG9DQUFvQyxDQUFDLENBQUM7YUFDekQ7WUFFRCxJQUFJLENBQUMsV0FBVyxDQUNaLEtBQUssRUFDTCxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUMsU0FBUyxFQUFFLEtBQUssRUFBQyxDQUFDLEVBQzlDLFVBQVUsRUFDVixnQkFBZ0IsRUFDaEIseUJBQXlCLGFBQWEsQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLFVB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QUEyQixDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztTQUM5QztRQUVELE9BQU8sRUFBRSxDQUFDO0lBQ2QsQ0FBQztDQUNKO0FBbkNELGtEQW1DQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7RnVuY3Rpb24sIEZ1bmN0aW9uUHJvcHN9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0IHtTdGFja30gZnJvbSBcImF3cy1jZGstbGliXCI7XG5pbXBvcnQge1Nuc0FjdGlvbn0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZHdhdGNoLWFjdGlvbnNcIjtcbmltcG9ydCB7Q29tcGFyaXNvbk9wZXJhdG9yLCBNZXRyaWN9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaFwiO1xuaW1wb3J0IHtEaWdpdHJhZmZpY1N0YWNrfSBmcm9tIFwiLi4vc3RhY2svc3RhY2tcIjtcbmltcG9ydCB7SVRvcGljfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXNuc1wiO1xuaW1wb3J0IHtkYXRhYmFzZUZ1bmN0aW9uUHJvcHMsIExhbWJkYUVudmlyb25tZW50LCBNb25pdG9yZWRGdW5jdGlvblBhcmFtZXRlcnN9IGZyb20gXCIuLi9zdGFjay9sYW1iZGEtY29uZmlnc1wiO1xuaW1wb3J0IHtwYXNjYWxDYXNlfSBmcm9tIFwiY2hhbmdlLWNhc2VcIjtcbmltcG9ydCB7RGlnaXRyYWZmaWNMb2dTdWJzY3JpcHRpb25zfSBmcm9tIFwiLi4vc3RhY2svc3Vic2NyaXB0aW9uXCI7XG5pbXBvcnQge1RyYWZmaWNUeXBlfSBmcm9tIFwiLi4vLi4vLi4vdHlwZXMvdHJhZmZpY3R5cGVcIjtcblxuLyoqXG4gKiBBbGxvd3MgY3VzdG9taXphdGlvbiBvZiBDbG91ZFdhdGNoIEFsYXJtIHByb3BlcnRpZXNcbiAqL1xuZXhwb3J0IHR5cGUgTW9uaXRvcmVkRnVuY3Rpb25BbGFybVByb3BzID0ge1xuICAgIC8qKlxuICAgICAqIFNldHRpbmcgdGhpcyB0byBmYWxzZSB3aWxsIG5vdCBjcmVhdGUgYSBDbG91ZFdhdGNoIGFsYXJtXG4gICAgICovXG4gICAgcmVhZG9ubHkgY3JlYXRlOiBib29sZWFuXG5cbiAgICByZWFkb25seSB0aHJlc2hvbGQ/OiBudW1iZXJcblxuICAgIHJlYWRvbmx5IGV2YWx1YXRpb25QZXJpb2RzPzogbnVtYmVyXG5cbiAgICByZWFkb25seSBkYXRhcG9pbnRzVG9BbGFybT86IG51bWJlclxuXG4gICAgcmVhZG9ubHkgY29tcGFyaXNvbk9wZXJhdG9yPzogQ29tcGFyaXNvbk9wZXJhdG9yXG59XG5cbmV4cG9ydCB0eXBlIE1vbml0b3JlZEZ1bmN0aW9uUHJvcHMgPSB7XG4gICAgcmVhZG9ubHkgZHVyYXRpb25BbGFybVByb3BzPzogTW9uaXRvcmVkRnVuY3Rpb25BbGFybVByb3BzXG5cbiAgICByZWFkb25seSBkdXJhdGlvbldhcm5pbmdQcm9wcz86IE1vbml0b3JlZEZ1bmN0aW9uQWxhcm1Qcm9wc1xuXG4gICAgcmVhZG9ubHkgZXJyb3JBbGFybVByb3BzPzogTW9uaXRvcmVkRnVuY3Rpb25BbGFybVByb3BzXG5cbiAgICByZWFkb25seSB0aHJvdHRsZUFsYXJtUHJvcHM/OiBNb25pdG9yZWRGdW5jdGlvbkFsYXJtUHJvcHNcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgTGFtYmRhIGZ1bmN0aW9uIHRoYXQgbW9uaXRvcnMgZGVmYXVsdCBDbG91ZFdhdGNoIExhbWJkYSBtZXRyaWNzIHdpdGggQ2xvdWRXYXRjaCBBbGFybXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBNb25pdG9yZWRGdW5jdGlvbiBleHRlbmRzIEZ1bmN0aW9uIHtcbiAgICByZWFkb25seSBnaXZlbk5hbWU6IHN0cmluZztcblxuICAgIC8qKiBkaXNhYmxlIGFsbCBhbGFybXMgKi9cbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERJU0FCTEVfQUxBUk1TOiBNb25pdG9yZWRGdW5jdGlvblByb3BzID0ge1xuICAgICAgICBkdXJhdGlvbkFsYXJtUHJvcHM6IHtcbiAgICAgICAgICAgIGNyZWF0ZTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIGR1cmF0aW9uV2FybmluZ1Byb3BzOiB7XG4gICAgICAgICAgICBjcmVhdGU6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICBlcnJvckFsYXJtUHJvcHM6IHtcbiAgICAgICAgICAgIGNyZWF0ZTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIHRocm90dGxlQWxhcm1Qcm9wczoge1xuICAgICAgICAgICAgY3JlYXRlOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICB9O1xuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlIG5ldyBNb25pdG9yZWRGdW5jdGlvbi4gIFVzZSB0b3BpY3MgZnJvbSBnaXZlbiBEaWdpdHJhZmZpY1N0YWNrLlxuICAgICAqXG4gICAgICogQHBhcmFtIHN0YWNrIERpZ2l0cmFmZmljU3RhY2tcbiAgICAgKiBAcGFyYW0gaWQgTGFtYmRhIGNvbnN0cnVjdCBJZFxuICAgICAqIEBwYXJhbSBmdW5jdGlvblByb3BzIExhbWJkYSBmdW5jdGlvbiBwcm9wZXJ0aWVzXG4gICAgICogQHBhcmFtIHByb3BzIE1vbml0b3JlZCBmdW5jdGlvbiBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZShzdGFjazogRGlnaXRyYWZmaWNTdGFjayxcbiAgICAgICAgaWQ6IHN0cmluZyxcbiAgICAgICAgZnVuY3Rpb25Qcm9wczogRnVuY3Rpb25Qcm9wcyxcbiAgICAgICAgcHJvcHM/OiBNb25pdG9yZWRGdW5jdGlvblByb3BzKTogTW9uaXRvcmVkRnVuY3Rpb24ge1xuXG4gICAgICAgIGlmIChwcm9wcyA9PT0gTW9uaXRvcmVkRnVuY3Rpb24uRElTQUJMRV9BTEFSTVMgJiYgc3RhY2suY29uZmlndXJhdGlvbi5wcm9kdWN0aW9uKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZ1bmN0aW9uICR7ZnVuY3Rpb25Qcm9wcy5mdW5jdGlvbk5hbWV9IGhhcyBESVNBQkxFX0FMQVJNUy4gIFJlbW92ZSBiZWZvcmUgaW5zdGFsbGluZyB0byBwcm9kdWN0aW9uIG9yIGRlZmluZSB5b3VyIG93biBwcm9wZXJ0aWVzIWApO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBNb25pdG9yZWRGdW5jdGlvbihcbiAgICAgICAgICAgIHN0YWNrLFxuICAgICAgICAgICAgaWQsXG4gICAgICAgICAgICBmdW5jdGlvblByb3BzLFxuICAgICAgICAgICAgc3RhY2suYWxhcm1Ub3BpYyxcbiAgICAgICAgICAgIHN0YWNrLndhcm5pbmdUb3BpYyxcbiAgICAgICAgICAgIHN0YWNrLmNvbmZpZ3VyYXRpb24ucHJvZHVjdGlvbixcbiAgICAgICAgICAgIHN0YWNrLmNvbmZpZ3VyYXRpb24udHJhZmZpY1R5cGUsXG4gICAgICAgICAgICBwcm9wcyxcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGUgbmV3IE1vbml0b3JlZEZ1bmN0aW9uLiAgVXNlIHRvcGljcyBmcm9tIGdpdmVuIERpZ2l0cmFmZmljU3RhY2suICBHZW5lcmF0ZSBuYW1lcyBmcm9tIGdpdmVuIG5hbWUgYW5kIGNvbmZpZ3VyYXRpb24gc2hvcnROYW1lLlxuICAgICAqXG4gICAgICogRm9yIGV4YW1wbGUsIHNob3J0TmFtZSBGT08gYW5kIGdpdmVuIG5hbWUgdXBkYXRlLXRoaW5ncyB3aWxsIGNyZWF0ZSBmdW5jdGlvbiBGT08tVXBkYXRlVGhpbmdzIGFuZCB1c2UgY29kZSBmcm9tIGxhbWJkYS91cGRhdGUtdGhpbmdzL3VwZGF0ZS10aGluZ3MudHMgbWV0aG9kIGhhbmRsZXIuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gc3RhY2sgRGlnaXRyYWZmaWNTdGFja1xuICAgICAqIEBwYXJhbSBuYW1lIHBhcmFtLWNhc2UgbmFtZVxuICAgICAqIEBwYXJhbSBlbnZpcm9ubWVudCBMYW1iZGEgZW52aXJvbm1lbnRcbiAgICAgKiBAcGFyYW0gZnVuY3Rpb25QYXJhbWV0ZXJzIExhbWJkYSBmdW5jdGlvbiBwYXJhbWV0ZXJzXG4gICAgICovXG4gICAgc3RhdGljIGNyZWF0ZVYyKHN0YWNrOiBEaWdpdHJhZmZpY1N0YWNrLFxuICAgICAgICBuYW1lOiBzdHJpbmcsXG4gICAgICAgIGVudmlyb25tZW50OiBMYW1iZGFFbnZpcm9ubWVudCxcbiAgICAgICAgZnVuY3Rpb25QYXJhbWV0ZXJzPzogTW9uaXRvcmVkRnVuY3Rpb25QYXJhbWV0ZXJzKTogTW9uaXRvcmVkRnVuY3Rpb24ge1xuICAgICAgICBjb25zdCBmdW5jdGlvbk5hbWUgPSBmdW5jdGlvblBhcmFtZXRlcnM/LmZ1bmN0aW9uTmFtZSB8fCBgJHtzdGFjay5jb25maWd1cmF0aW9uLnNob3J0TmFtZX0tJHtwYXNjYWxDYXNlKG5hbWUpfWA7XG4gICAgICAgIGNvbnN0IGZ1bmN0aW9uUHJvcHMgPSBkYXRhYmFzZUZ1bmN0aW9uUHJvcHMoXG4gICAgICAgICAgICBzdGFjaywgZW52aXJvbm1lbnQsIGZ1bmN0aW9uTmFtZSwgbmFtZSwgZnVuY3Rpb25QYXJhbWV0ZXJzLFxuICAgICAgICApO1xuXG4gICAgICAgIHJldHVybiBNb25pdG9yZWRGdW5jdGlvbi5jcmVhdGUoc3RhY2ssIGZ1bmN0aW9uTmFtZSwgZnVuY3Rpb25Qcm9wcywgZnVuY3Rpb25QYXJhbWV0ZXJzKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0gc2NvcGUgU3RhY2tcbiAgICAgKiBAcGFyYW0gaWQgTGFtYmRhIGNvbnN0cnVjdCBJZFxuICAgICAqIEBwYXJhbSBmdW5jdGlvblByb3BzIExhbWJkYSBmdW5jdGlvbiBwcm9wZXJ0aWVzXG4gICAgICogQHBhcmFtIGFsYXJtU25zVG9waWMgU05TIHRvcGljIGZvciBhbGFybXNcbiAgICAgKiBAcGFyYW0gd2FybmluZ1Nuc1RvcGljIFNOUyB0b3BpYyBmb3Igd2FybmluZ3NcbiAgICAgKiBAcGFyYW0gcHJvZHVjdGlvbiBJcyB0aGUgc3RhY2sgYSBwcm9kdWN0aW9uIHN0YWNrLCB1c2VkIGZvciBkZXRlcm1pbmluZyB0aGUgYWxhcm0gdG9waWNcbiAgICAgKiBAcGFyYW0gdHJhZmZpY1R5cGUgVHJhZmZpYyB0eXBlLCB1c2VkIGZvciBhbGFybSBuYW1lcy4gU2V0IHRvIG51bGwgaWYgTGFtYmRhIGlzIG5vdCByZWxhdGVkIHRvIGFueSB0cmFmZmljIHR5cGUuXG4gICAgICogQHBhcmFtIHByb3BzIE1vbml0b3JlZCBmdW5jdGlvbiBwcm9wZXJ0aWVzXG4gICAgICovXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHNjb3BlOiBTdGFjayxcbiAgICAgICAgaWQ6IHN0cmluZyxcbiAgICAgICAgZnVuY3Rpb25Qcm9wczogRnVuY3Rpb25Qcm9wcyxcbiAgICAgICAgYWxhcm1TbnNUb3BpYzogSVRvcGljLFxuICAgICAgICB3YXJuaW5nU25zVG9waWM6IElUb3BpYyxcbiAgICAgICAgcHJvZHVjdGlvbjogYm9vbGVhbixcbiAgICAgICAgdHJhZmZpY1R5cGU6IFRyYWZmaWNUeXBlIHwgbnVsbCxcbiAgICAgICAgcHJvcHM/OiBNb25pdG9yZWRGdW5jdGlvblByb3BzLFxuICAgICkge1xuICAgICAgICBzdXBlcihzY29wZSwgaWQsIGZ1bmN0aW9uUHJvcHMpO1xuXG4gICAgICAgIHRoaXMuZ2l2ZW5OYW1lID0gZnVuY3Rpb25Qcm9wcy5mdW5jdGlvbk5hbWUgYXMgc3RyaW5nO1xuXG4gICAgICAgIGNvbnN0IGFsYXJtU25zQWN0aW9uID0gbmV3IFNuc0FjdGlvbihhbGFybVNuc1RvcGljKTtcbiAgICAgICAgY29uc3Qgd2FybmluZ1Nuc0FjdGlvbiA9IG5ldyBTbnNBY3Rpb24od2FybmluZ1Nuc1RvcGljKTtcblxuICAgICAgICBpZiAocHJvcHM/LmR1cmF0aW9uQWxhcm1Qcm9wcz8uY3JlYXRlICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgaWYgKCFmdW5jdGlvblByb3BzLnRpbWVvdXQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RpbWVvdXQgbmVlZHMgdG8gYmUgZXhwbGljaXRseSBzZXQnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5jcmVhdGVBbGFybShcbiAgICAgICAgICAgICAgICBzY29wZSxcbiAgICAgICAgICAgICAgICB0aGlzLm1ldHJpY0R1cmF0aW9uKCkud2l0aCh7c3RhdGlzdGljOiAnbWF4J30pLFxuICAgICAgICAgICAgICAgICdEdXJhdGlvbicsXG4gICAgICAgICAgICAgICAgJ0R1cmF0aW9uIGFsYXJtJyxcbiAgICAgICAgICAgICAgICBgRHVyYXRpb24gaGFzIGV4Y2VlZGVkICR7ZnVuY3Rpb25Qcm9wcy50aW1lb3V0LnRvU2Vjb25kcygpfSBzZWNvbmRzYCxcbiAgICAgICAgICAgICAgICB0cmFmZmljVHlwZSxcbiAgICAgICAgICAgICAgICB0aGlzLmdldEFsYXJtQWN0aW9uRm9yRW52KGFsYXJtU25zQWN0aW9uLCB3YXJuaW5nU25zQWN0aW9uLCBwcm9kdWN0aW9uKSxcbiAgICAgICAgICAgICAgICBmdW5jdGlvblByb3BzLnRpbWVvdXQudG9NaWxsaXNlY29uZHMoKSxcbiAgICAgICAgICAgICAgICAxLFxuICAgICAgICAgICAgICAgIDEsXG4gICAgICAgICAgICAgICAgQ29tcGFyaXNvbk9wZXJhdG9yLkdSRUFURVJfVEhBTl9PUl9FUVVBTF9UT19USFJFU0hPTEQsXG4gICAgICAgICAgICAgICAgcHJvcHM/LmR1cmF0aW9uQWxhcm1Qcm9wcyxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3BzPy5kdXJhdGlvbldhcm5pbmdQcm9wcz8uY3JlYXRlICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgaWYgKCFmdW5jdGlvblByb3BzLnRpbWVvdXQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RpbWVvdXQgbmVlZHMgdG8gYmUgZXhwbGljaXRseSBzZXQnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5jcmVhdGVBbGFybShcbiAgICAgICAgICAgICAgICBzY29wZSxcbiAgICAgICAgICAgICAgICB0aGlzLm1ldHJpY0R1cmF0aW9uKCkud2l0aCh7c3RhdGlzdGljOiAnbWF4J30pLFxuICAgICAgICAgICAgICAgICdEdXJhdGlvbi1XYXJuaW5nJyxcbiAgICAgICAgICAgICAgICAnRHVyYXRpb24gd2FybmluZycsXG4gICAgICAgICAgICAgICAgYER1cmF0aW9uIGlzIDg1ICUgb2YgbWF4ICR7ZnVuY3Rpb25Qcm9wcy50aW1lb3V0LnRvU2Vjb25kcygpfSBzZWNvbmRzYCxcbiAgICAgICAgICAgICAgICB0cmFmZmljVHlwZSxcbiAgICAgICAgICAgICAgICB3YXJuaW5nU25zQWN0aW9uLFxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uUHJvcHMudGltZW91dC50b01pbGxpc2Vjb25kcygpICogMC44NSxcbiAgICAgICAgICAgICAgICAxLFxuICAgICAgICAgICAgICAgIDEsXG4gICAgICAgICAgICAgICAgQ29tcGFyaXNvbk9wZXJhdG9yLkdSRUFURVJfVEhBTl9PUl9FUVVBTF9UT19USFJFU0hPTEQsXG4gICAgICAgICAgICAgICAgcHJvcHM/LmR1cmF0aW9uV2FybmluZ1Byb3BzLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChwcm9wcz8uZXJyb3JBbGFybVByb3BzPy5jcmVhdGUgIT09IGZhbHNlKSB7XG4gICAgICAgICAgICB0aGlzLmNyZWF0ZUFsYXJtKFxuICAgICAgICAgICAgICAgIHNjb3BlLFxuICAgICAgICAgICAgICAgIHRoaXMubWV0cmljRXJyb3JzKCksXG4gICAgICAgICAgICAgICAgJ0Vycm9ycycsXG4gICAgICAgICAgICAgICAgJ0Vycm9ycyBhbGFybScsXG4gICAgICAgICAgICAgICAgJ0ludm9jYXRpb25zIGRpZCBub3Qgc3VjY2VlZCcsXG4gICAgICAgICAgICAgICAgdHJhZmZpY1R5cGUsXG4gICAgICAgICAgICAgICAgdGhpcy5nZXRBbGFybUFjdGlvbkZvckVudihhbGFybVNuc0FjdGlvbiwgd2FybmluZ1Nuc0FjdGlvbiwgcHJvZHVjdGlvbiksXG4gICAgICAgICAgICAgICAgMSxcbiAgICAgICAgICAgICAgICAxLFxuICAgICAgICAgICAgICAgIDEsXG4gICAgICAgICAgICAgICAgQ29tcGFyaXNvbk9wZXJhdG9yLkdSRUFURVJfVEhBTl9PUl9FUVVBTF9UT19USFJFU0hPTEQsXG4gICAgICAgICAgICAgICAgcHJvcHM/LmVycm9yQWxhcm1Qcm9wcyxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocHJvcHM/LnRocm90dGxlQWxhcm1Qcm9wcz8uY3JlYXRlICE9PSBmYWxzZSkge1xuICAgICAgICAgICAgdGhpcy5jcmVhdGVBbGFybShcbiAgICAgICAgICAgICAgICBzY29wZSxcbiAgICAgICAgICAgICAgICB0aGlzLm1ldHJpY1Rocm90dGxlcygpLFxuICAgICAgICAgICAgICAgICdUaHJvdHRsZXMnLFxuICAgICAgICAgICAgICAgICdUaHJvdHRsZXMgYWxhcm0nLFxuICAgICAgICAgICAgICAgICdIYXMgdGhyb3R0bGVkJyxcbiAgICAgICAgICAgICAgICB0cmFmZmljVHlwZSxcbiAgICAgICAgICAgICAgICB0aGlzLmdldEFsYXJtQWN0aW9uRm9yRW52KGFsYXJtU25zQWN0aW9uLCB3YXJuaW5nU25zQWN0aW9uLCBwcm9kdWN0aW9uKSxcbiAgICAgICAgICAgICAgICAwLFxuICAgICAgICAgICAgICAgIDEsXG4gICAgICAgICAgICAgICAgMSxcbiAgICAgICAgICAgICAgICBDb21wYXJpc29uT3BlcmF0b3IuR1JFQVRFUl9USEFOX1RIUkVTSE9MRCxcbiAgICAgICAgICAgICAgICBwcm9wcz8udGhyb3R0bGVBbGFybVByb3BzLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgY3JlYXRlQWxhcm0oXG4gICAgICAgIHN0YWNrOiBTdGFjayxcbiAgICAgICAgbWV0cmljOiBNZXRyaWMsXG4gICAgICAgIGFsYXJtSWQ6IHN0cmluZyxcbiAgICAgICAgYWxhcm1OYW1lOiBzdHJpbmcsXG4gICAgICAgIGFsYXJtRGVzY3JpcHRpb246IHN0cmluZyxcbiAgICAgICAgdHJhZmZpY1R5cGU6IFRyYWZmaWNUeXBlIHwgbnVsbCxcbiAgICAgICAgYWxhcm1TbnNBY3Rpb246IFNuc0FjdGlvbixcbiAgICAgICAgdGhyZXNob2xkOiBudW1iZXIsXG4gICAgICAgIGV2YWx1YXRpb25QZXJpb2RzOiBudW1iZXIsXG4gICAgICAgIGRhdGFwb2ludHNUb0FsYXJtOiBudW1iZXIsXG4gICAgICAgIGNvbXBhcmlzb25PcGVyYXRvcjogQ29tcGFyaXNvbk9wZXJhdG9yLFxuICAgICAgICBhbGFybVByb3BzPzogTW9uaXRvcmVkRnVuY3Rpb25BbGFybVByb3BzLFxuICAgICkge1xuICAgICAgICBtZXRyaWMuY3JlYXRlQWxhcm0oc3RhY2ssIGAke3RoaXMubm9kZS5pZH0tJHthbGFybUlkfWAsIHtcbiAgICAgICAgICAgIGFsYXJtTmFtZTogYCR7dHJhZmZpY1R5cGUgPz8gJyd9ICR7c3RhY2suc3RhY2tOYW1lfSAke3RoaXMuZnVuY3Rpb25OYW1lfSAke2FsYXJtTmFtZX1gLnRyaW0oKSxcbiAgICAgICAgICAgIGFsYXJtRGVzY3JpcHRpb24sXG4gICAgICAgICAgICB0aHJlc2hvbGQ6IGFsYXJtUHJvcHM/LnRocmVzaG9sZCA/PyB0aHJlc2hvbGQsXG4gICAgICAgICAgICBldmFsdWF0aW9uUGVyaW9kczogYWxhcm1Qcm9wcz8uZXZhbHVhdGlvblBlcmlvZHMgPz8gZXZhbHVhdGlvblBlcmlvZHMsXG4gICAgICAgICAgICBkYXRhcG9pbnRzVG9BbGFybTogYWxhcm1Qcm9wcz8uZGF0YXBvaW50c1RvQWxhcm0gPz8gZGF0YXBvaW50c1RvQWxhcm0sXG4gICAgICAgICAgICBjb21wYXJpc29uT3BlcmF0b3I6IGFsYXJtUHJvcHM/LmNvbXBhcmlzb25PcGVyYXRvciA/PyBjb21wYXJpc29uT3BlcmF0b3IsXG4gICAgICAgIH0pLmFkZEFsYXJtQWN0aW9uKGFsYXJtU25zQWN0aW9uKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGdldEFsYXJtQWN0aW9uRm9yRW52KGFsYXJtQWN0aW9uOiBTbnNBY3Rpb24sXG4gICAgICAgIHdhcm5pbmdBY3Rpb246IFNuc0FjdGlvbixcbiAgICAgICAgcHJvZHVjdGlvbjogYm9vbGVhbik6IFNuc0FjdGlvbiB7XG5cbiAgICAgICAgcmV0dXJuIHByb2R1Y3Rpb24gPyBhbGFybUFjdGlvbiA6IHdhcm5pbmdBY3Rpb247XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgTW9uaXRvcmVkREJGdW5jdGlvbiB7XG4gICAgLyoqXG4gICAgICogQ3JlYXRlIG5ldyBNb25pdG9yZWREQkZ1bmN0aW9uLiAgVXNlIHRvcGljcyBmcm9tIGdpdmVuIERpZ2l0cmFmZmljU3RhY2suICBHZW5lcmF0ZSBuYW1lcyBmcm9tIGdpdmVuIG5hbWUgYW5kIGNvbmZpZ3VyYXRpb24gc2hvcnROYW1lLlxuICAgICAqIEdyYW50IHNlY3JldCBhbmQgY3JlYXRlIGxvZyBzdWJzY3JpcHRpb24uXG4gICAgICpcbiAgICAgKiBGb3IgZXhhbXBsZSwgc2hvcnROYW1lIEZPTyBhbmQgZ2l2ZW4gbmFtZSB1cGRhdGUtdGhpbmdzIHdpbGwgY3JlYXRlIGZ1bmN0aW9uIEZPTy1VcGRhdGVUaGluZ3MgYW5kIHVzZSBjb2RlIGZyb20gbGFtYmRhL3VwZGF0ZS10aGluZ3MvdXBkYXRlLXRoaW5ncy50cyBtZXRob2QgaGFuZGxlci5cbiAgICAgKlxuICAgICAqIElmIHlvdSBkb24ndCBuZWVkIHRvIHBhc3MgYW55IGV4dHJhIGFyZ3VtZW50cyB0byBsYW1iZGEtZW52aXJvbm1lbnQsIHlvdSBjYW4gbGVhdmUgZW52aXJvbm1lbnQgb3V0IGFuZCB0aGlzIGZ1bmN0aW9uIHdpbGwgY3JlYXRlIHRoZVxuICAgICAqIGRlZmF1bHQgTGFtYmRhIEVudmlyb25tZW50IHdpdGggU0VDUkVUX0lEIGFuZCBEQl9BUFBMSUNBVElPTi5cbiAgICAgKlxuICAgICAqIEBwYXJhbSBzdGFjayBEaWdpdHJhZmZpY1N0YWNrXG4gICAgICogQHBhcmFtIG5hbWUgcGFyYW0tY2FzZSBuYW1lXG4gICAgICogQHBhcmFtIGVudmlyb25tZW50IExhbWJkYSBlbnZpcm9ubWVudFxuICAgICAqIEBwYXJhbSBmdW5jdGlvblBhcmFtZXRlcnMgTGFtYmRhIGZ1bmN0aW9uIHBhcmFtZXRlcnNcbiAgICAgKi9cbiAgICBzdGF0aWMgY3JlYXRlKHN0YWNrOiBEaWdpdHJhZmZpY1N0YWNrLFxuICAgICAgICBuYW1lOiBzdHJpbmcsXG4gICAgICAgIGVudmlyb25tZW50PzogTGFtYmRhRW52aXJvbm1lbnQsXG4gICAgICAgIGZ1bmN0aW9uUGFyYW1ldGVycz86IE1vbml0b3JlZEZ1bmN0aW9uUGFyYW1ldGVycyk6IE1vbml0b3JlZEZ1bmN0aW9uIHtcbiAgICAgICAgY29uc3QgZnVuY3Rpb25OYW1lID0gZnVuY3Rpb25QYXJhbWV0ZXJzPy5mdW5jdGlvbk5hbWUgfHwgYCR7c3RhY2suY29uZmlndXJhdGlvbi5zaG9ydE5hbWV9LSR7cGFzY2FsQ2FzZShuYW1lKX1gO1xuICAgICAgICBjb25zdCBlbnYgPSBlbnZpcm9ubWVudCA/IGVudmlyb25tZW50IDogc3RhY2suY3JlYXRlTGFtYmRhRW52aXJvbm1lbnQoKTtcbiAgICAgICAgY29uc3QgZnVuY3Rpb25Qcm9wcyA9IGRhdGFiYXNlRnVuY3Rpb25Qcm9wcyhcbiAgICAgICAgICAgIHN0YWNrLCBlbnYsIGZ1bmN0aW9uTmFtZSwgbmFtZSwgZnVuY3Rpb25QYXJhbWV0ZXJzLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IG1mID0gTW9uaXRvcmVkRnVuY3Rpb24uY3JlYXRlKHN0YWNrLCBmdW5jdGlvbk5hbWUsIGZ1bmN0aW9uUHJvcHMsIGZ1bmN0aW9uUGFyYW1ldGVycyk7XG5cbiAgICAgICAgc3RhY2suZ3JhbnRTZWNyZXQobWYpO1xuXG4gICAgICAgIGlmIChzdGFjay5jb25maWd1cmF0aW9uLmxvZ3NEZXN0aW5hdGlvbkFybikge1xuICAgICAgICAgICAgbmV3IERpZ2l0cmFmZmljTG9nU3Vic2NyaXB0aW9ucyhzdGFjaywgbWYpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG1mO1xuICAgIH1cbn1cbiJdfQ==
|
@@ -1,179 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.createIpRestrictionPolicyDocument = exports.createDefaultPolicyDocument = exports.createRestApi = exports.setReturnCodeForMissingAuthenticationToken = exports.add401Support = exports.add404Support = exports.DigitrafficRestApi = void 0;
|
4
|
-
const aws_apigateway_1 = require("aws-cdk-lib/aws-apigateway");
|
5
|
-
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
|
6
|
-
const usage_plans_1 = require("../usage-plans");
|
7
|
-
const api_model_1 = require("../../../utils/api-model");
|
8
|
-
const mediatypes_1 = require("../../types/mediatypes");
|
9
|
-
const R = require("ramda");
|
10
|
-
class DigitrafficRestApi extends aws_apigateway_1.RestApi {
|
11
|
-
constructor(stack, apiId, apiName, allowFromIpAddresses, config) {
|
12
|
-
const policyDocument = allowFromIpAddresses == null ? createDefaultPolicyDocument() : createIpRestrictionPolicyDocument(allowFromIpAddresses);
|
13
|
-
// override default config with given extra config
|
14
|
-
const apiConfig = { ...{
|
15
|
-
deployOptions: {
|
16
|
-
loggingLevel: aws_apigateway_1.MethodLoggingLevel.ERROR,
|
17
|
-
},
|
18
|
-
restApiName: apiName,
|
19
|
-
endpointTypes: [aws_apigateway_1.EndpointType.REGIONAL],
|
20
|
-
policy: policyDocument,
|
21
|
-
}, ...config };
|
22
|
-
super(stack, apiId, apiConfig);
|
23
|
-
this.apiKeyIds = [];
|
24
|
-
add404Support(this, stack);
|
25
|
-
}
|
26
|
-
hostname() {
|
27
|
-
return `${this.restApiId}.execute-api.${this.stack.region}.amazonaws.com`;
|
28
|
-
}
|
29
|
-
createUsagePlan(apiKeyId, apiKeyName) {
|
30
|
-
const newKeyId = (0, usage_plans_1.createUsagePlan)(this, apiKeyId, apiKeyName).keyId;
|
31
|
-
this.apiKeyIds.push(newKeyId);
|
32
|
-
return newKeyId;
|
33
|
-
}
|
34
|
-
createUsagePlanV2(apiName) {
|
35
|
-
const newKeyId = (0, usage_plans_1.createDefaultUsagePlan)(this, apiName).keyId;
|
36
|
-
this.apiKeyIds.push(newKeyId);
|
37
|
-
return newKeyId;
|
38
|
-
}
|
39
|
-
addJsonModel(modelName, schema) {
|
40
|
-
return this.getModelWithReference(this.addModel(modelName, {
|
41
|
-
contentType: mediatypes_1.MediaType.APPLICATION_JSON,
|
42
|
-
modelName,
|
43
|
-
schema,
|
44
|
-
}));
|
45
|
-
}
|
46
|
-
addCSVModel(modelName) {
|
47
|
-
return this.getModelWithReference(this.addModel(modelName, {
|
48
|
-
contentType: mediatypes_1.MediaType.TEXT_CSV,
|
49
|
-
modelName,
|
50
|
-
schema: {},
|
51
|
-
}));
|
52
|
-
}
|
53
|
-
getModelWithReference(model) {
|
54
|
-
return R.assoc('modelReference', (0, api_model_1.getModelReference)(model.modelId, this.restApiId), model);
|
55
|
-
}
|
56
|
-
addDocumentationPart(resource, parameterName, resourceName, type, properties) {
|
57
|
-
const location = {
|
58
|
-
type,
|
59
|
-
path: resource.path,
|
60
|
-
name: type !== 'METHOD' ? parameterName : undefined,
|
61
|
-
};
|
62
|
-
new aws_apigateway_1.CfnDocumentationPart(this.stack, resourceName, {
|
63
|
-
restApiId: resource.api.restApiId,
|
64
|
-
location,
|
65
|
-
properties: JSON.stringify(properties),
|
66
|
-
});
|
67
|
-
}
|
68
|
-
documentResource(resource, ...documentationPart) {
|
69
|
-
documentationPart.forEach(dp => this.addDocumentationPart(resource, dp.parameterName, `${resource.path}.${dp.parameterName}.Documentation`, dp.type, dp.documentationProperties));
|
70
|
-
}
|
71
|
-
}
|
72
|
-
exports.DigitrafficRestApi = DigitrafficRestApi;
|
73
|
-
/**
|
74
|
-
* Due to AWS API design API Gateway will always return 403 'Missing Authentication Token' for requests
|
75
|
-
* with a non-existent endpoint. This function translates this response to a 404.
|
76
|
-
* Requests with an invalid or missing API key are not affected (still return 403 'Forbidden').
|
77
|
-
* @param restApi RestApi
|
78
|
-
* @param stack Construct
|
79
|
-
*/
|
80
|
-
function add404Support(restApi, stack) {
|
81
|
-
new aws_apigateway_1.GatewayResponse(stack, `MissingAuthenticationTokenResponse-${restApi.restApiName}`, {
|
82
|
-
restApi,
|
83
|
-
type: aws_apigateway_1.ResponseType.MISSING_AUTHENTICATION_TOKEN,
|
84
|
-
statusCode: '404',
|
85
|
-
templates: {
|
86
|
-
'application/json': '{"message": "Not found"}',
|
87
|
-
},
|
88
|
-
});
|
89
|
-
}
|
90
|
-
exports.add404Support = add404Support;
|
91
|
-
function add401Support(restApi, stack) {
|
92
|
-
new aws_apigateway_1.GatewayResponse(stack, `AuthenticationFailedResponse-${restApi.restApiName}`, {
|
93
|
-
restApi,
|
94
|
-
type: aws_apigateway_1.ResponseType.UNAUTHORIZED,
|
95
|
-
statusCode: "401",
|
96
|
-
responseHeaders: {
|
97
|
-
'WWW-Authenticate': "'Basic'",
|
98
|
-
},
|
99
|
-
});
|
100
|
-
}
|
101
|
-
exports.add401Support = add401Support;
|
102
|
-
/**
|
103
|
-
* Due to AWS API design API Gateway will always return 403 'Missing Authentication Token' for requests
|
104
|
-
* with a non-existent endpoint. This function converts this response to a custom one.
|
105
|
-
* Requests with an invalid or missing API key are not affected (still return 403 'Forbidden').
|
106
|
-
* @param returnCode
|
107
|
-
* @param message
|
108
|
-
* @param restApi RestApi
|
109
|
-
* @param stack Construct
|
110
|
-
*/
|
111
|
-
function setReturnCodeForMissingAuthenticationToken(returnCode, message, restApi, stack) {
|
112
|
-
new aws_apigateway_1.GatewayResponse(stack, `MissingAuthenticationTokenResponse-${restApi.restApiName}`, {
|
113
|
-
restApi,
|
114
|
-
type: aws_apigateway_1.ResponseType.MISSING_AUTHENTICATION_TOKEN,
|
115
|
-
statusCode: `${returnCode}`,
|
116
|
-
templates: {
|
117
|
-
'application/json': `{"message": ${message}}`,
|
118
|
-
},
|
119
|
-
});
|
120
|
-
}
|
121
|
-
exports.setReturnCodeForMissingAuthenticationToken = setReturnCodeForMissingAuthenticationToken;
|
122
|
-
function createRestApi(stack, apiId, apiName, allowFromIpAddresses) {
|
123
|
-
const policyDocument = allowFromIpAddresses == null ? createDefaultPolicyDocument() : createIpRestrictionPolicyDocument(allowFromIpAddresses);
|
124
|
-
const restApi = new aws_apigateway_1.RestApi(stack, apiId, {
|
125
|
-
deployOptions: {
|
126
|
-
loggingLevel: aws_apigateway_1.MethodLoggingLevel.ERROR,
|
127
|
-
},
|
128
|
-
restApiName: apiName,
|
129
|
-
endpointTypes: [aws_apigateway_1.EndpointType.REGIONAL],
|
130
|
-
policy: policyDocument,
|
131
|
-
});
|
132
|
-
add404Support(restApi, stack);
|
133
|
-
return restApi;
|
134
|
-
}
|
135
|
-
exports.createRestApi = createRestApi;
|
136
|
-
function createDefaultPolicyDocument() {
|
137
|
-
return new aws_iam_1.PolicyDocument({
|
138
|
-
statements: [
|
139
|
-
new aws_iam_1.PolicyStatement({
|
140
|
-
effect: aws_iam_1.Effect.ALLOW,
|
141
|
-
actions: [
|
142
|
-
"execute-api:Invoke",
|
143
|
-
],
|
144
|
-
resources: [
|
145
|
-
"*",
|
146
|
-
],
|
147
|
-
principals: [
|
148
|
-
new aws_iam_1.AnyPrincipal(),
|
149
|
-
],
|
150
|
-
}),
|
151
|
-
],
|
152
|
-
});
|
153
|
-
}
|
154
|
-
exports.createDefaultPolicyDocument = createDefaultPolicyDocument;
|
155
|
-
function createIpRestrictionPolicyDocument(allowFromIpAddresses) {
|
156
|
-
return new aws_iam_1.PolicyDocument({
|
157
|
-
statements: [
|
158
|
-
new aws_iam_1.PolicyStatement({
|
159
|
-
effect: aws_iam_1.Effect.ALLOW,
|
160
|
-
conditions: {
|
161
|
-
"IpAddress": {
|
162
|
-
"aws:SourceIp": allowFromIpAddresses,
|
163
|
-
},
|
164
|
-
},
|
165
|
-
actions: [
|
166
|
-
"execute-api:Invoke",
|
167
|
-
],
|
168
|
-
resources: [
|
169
|
-
"*",
|
170
|
-
],
|
171
|
-
principals: [
|
172
|
-
new aws_iam_1.AnyPrincipal(),
|
173
|
-
],
|
174
|
-
}),
|
175
|
-
],
|
176
|
-
});
|
177
|
-
}
|
178
|
-
exports.createIpRestrictionPolicyDocument = createIpRestrictionPolicyDocument;
|
179
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzdF9hcGlzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2F3cy9pbmZyYS9zdGFjay9yZXN0X2FwaXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsK0RBT29DO0FBQ3BDLGlEQUEwRjtBQUcxRixnREFBdUU7QUFFdkUsd0RBQTJEO0FBQzNELHVEQUFpRDtBQUdqRCwyQkFBNEI7QUFFNUIsTUFBYSxrQkFBbUIsU0FBUSx3QkFBTztJQUczQyxZQUNJLEtBQXVCLEVBQUUsS0FBYSxFQUFFLE9BQWUsRUFBRSxvQkFBMkMsRUFBRSxNQUE4QjtRQUVwSSxNQUFNLGNBQWMsR0FBRyxvQkFBb0IsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLDJCQUEyQixFQUFFLENBQUMsQ0FBQyxDQUFDLGlDQUFpQyxDQUFDLG9CQUFvQixDQUFDLENBQUM7UUFFOUksa0RBQWtEO1FBQ2xELE1BQU0sU0FBUyxHQUFHLEVBQUMsR0FBRztnQkFDbEIsYUFBYSxFQUFFO29CQUNYLFlBQVksRUFBRSxtQ0FBa0IsQ0FBQyxLQUFLO2lCQUN6QztnQkFDRCxXQUFXLEVBQUUsT0FBTztnQkFDcEIsYUFBYSxFQUFFLENBQUMsNkJBQVksQ0FBQyxRQUFRLENBQUM7Z0JBQ3RDLE1BQU0sRUFBRSxjQUFjO2FBQ3pCLEVBQUUsR0FBRyxNQUFNLEVBQUMsQ0FBQztRQUVkLEtBQUssQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBRS9CLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDO1FBRXBCLGFBQWEsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVELFFBQVE7UUFDSixPQUFPLEdBQUcsSUFBSSxDQUFDLFNBQVMsZ0JBQWlCLElBQUksQ0FBQyxLQUEwQixDQUFDLE1BQU0sZ0JBQWdCLENBQUM7SUFDcEcsQ0FBQztJQUVELGVBQWUsQ0FBQyxRQUFnQixFQUFFLFVBQWtCO1FB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QUFDLENBQUM7SUFDSCxhQUFhLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzlCLE9BQU8sT0FBTyxDQUFDO0FBQ25CLENBQUM7QUFaRCxzQ0FZQztBQUVELFNBQWdCLDJCQUEyQjtJQUN2QyxPQUFPLElBQUksd0JBQWMsQ0FBQztRQUN0QixVQUFVLEVBQUU7WUFDUixJQUFJLHlCQUFlLENBQUM7Z0JBQ2hCLE1BQU0sRUFBRSxnQkFBTSxDQUFDLEtBQUs7Z0JBQ3BCLE9BQU8sRUFBRTtvQkFDTCxvQkFBb0I7aUJBQ3ZCO2dCQUNELFNBQVMsRUFBRTtvQkFDUCxHQUFHO2lCQUNOO2dCQUNELFVBQVUsRUFBRTtvQkFDUixJQUFJLHNCQUFZLEVBQUU7aUJBQ3JCO2FBQ0osQ0FBQztTQUNMO0tBQ0osQ0FBQyxDQUFDO0FBQ1AsQ0FBQztBQWpCRCxrRUFpQkM7QUFHRCxTQUFnQixpQ0FBaUMsQ0FBQyxvQkFBOEI7SUFDNUUsT0FBTyxJQUFJLHdCQUFjLENBQUM7UUFDdEIsVUFBVSxFQUFFO1lBQ1IsSUFBSSx5QkFBZSxDQUFDO2dCQUNoQixNQUFNLEVBQUUsZ0JBQU0sQ0FBQyxLQUFLO2dCQUNwQixVQUFVLEVBQUU7b0JBQ1IsV0FBVyxFQUFFO3dCQUNULGNBQWMsRUFBRSxvQkFBb0I7cUJBQ3ZDO2lCQUNKO2dCQUNELE9BQU8sRUFBRTtvQkFDTCxvQkFBb0I7aUJBQ3ZCO2dCQUNELFNBQVMsRUFBRTtvQkFDUCxHQUFHO2lCQUNOO2dCQUNELFVBQVUsRUFBRTtvQkFDUixJQUFJLHNCQUFZLEVBQUU7aUJBQ3JCO2FBQ0osQ0FBQztTQUNMO0tBQ0osQ0FBQyxDQUFDO0FBQ1AsQ0FBQztBQXRCRCw4RUFzQkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gICAgUmVzdEFwaSxcclxuICAgIE1ldGhvZExvZ2dpbmdMZXZlbCxcclxuICAgIEdhdGV3YXlSZXNwb25zZSxcclxuICAgIFJlc3BvbnNlVHlwZSxcclxuICAgIEVuZHBvaW50VHlwZSxcclxuICAgIFJlc3RBcGlQcm9wcywgSnNvblNjaGVtYSwgTW9kZWwsIENmbkRvY3VtZW50YXRpb25QYXJ0LCBSZXNvdXJjZSxcclxufSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtYXBpZ2F0ZXdheSc7XHJcbmltcG9ydCB7UG9saWN5RG9jdW1lbnQsIFBvbGljeVN0YXRlbWVudCwgRWZmZWN0LCBBbnlQcmluY2lwYWx9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1pYW0nO1xyXG5pbXBvcnQge0NvbnN0cnVjdH0gZnJvbSBcImNvbnN0cnVjdHNcIjtcclxuaW1wb3J0IHtEaWdpdHJhZmZpY1N0YWNrfSBmcm9tIFwiLi9zdGFja1wiO1xyXG5pbXBvcnQge2NyZWF0ZURlZmF1bHRVc2FnZVBsYW4sIGNyZWF0ZVVzYWdlUGxhbn0gZnJvbSBcIi4uL3VzYWdlLXBsYW5zXCI7XHJcbmltcG9ydCB7TW9kZWxXaXRoUmVmZXJlbmNlfSBmcm9tIFwiLi4vLi4vdHlwZXMvbW9kZWwtd2l0aC1yZWZlcmVuY2VcIjtcclxuaW1wb3J0IHtnZXRNb2RlbFJlZmVyZW5jZX0gZnJvbSBcIi4uLy4uLy4uL3V0aWxzL2FwaS1tb2RlbFwiO1xyXG5pbXBvcnQge01lZGlhVHlwZX0gZnJvbSBcIi4uLy4uL3R5cGVzL21lZGlhdHlwZXNcIjtcclxuaW1wb3J0IHtEb2N1bWVudGF0aW9uUGFydCwgRG9jdW1lbnRhdGlvblByb3BlcnRpZXN9IGZyb20gXCIuLi9kb2N1bWVudGF0aW9uXCI7XHJcblxyXG5pbXBvcnQgUiA9IHJlcXVpcmUoJ3JhbWRhJyk7XHJcblxyXG5leHBvcnQgY2xhc3MgRGlnaXRyYWZmaWNSZXN0QXBpIGV4dGVuZHMgUmVzdEFwaSB7XHJcbiAgICByZWFkb25seSBhcGlLZXlJZHM6IHN0cmluZ1tdO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIHN0YWNrOiBEaWdpdHJhZmZpY1N0YWNrLCBhcGlJZDogc3RyaW5nLCBhcGlOYW1lOiBzdHJpbmcsIGFsbG93RnJvbUlwQWRkcmVzc2VzPzogc3RyaW5nW10gfCB1bmRlZmluZWQsIGNvbmZpZz86IFBhcnRpYWw8UmVzdEFwaVByb3BzPixcclxuICAgICkge1xyXG4gICAgICAgIGNvbnN0IHBvbGljeURvY3VtZW50ID0gYWxsb3dGcm9tSXBBZGRyZXNzZXMgPT0gbnVsbCA/IGNyZWF0ZURlZmF1bHRQb2xpY3lEb2N1bWVudCgpIDogY3JlYXRlSXBSZXN0cmljdGlvblBvbGljeURvY3VtZW50KGFsbG93RnJvbUlwQWRkcmVzc2VzKTtcclxuXHJcbiAgICAgICAgLy8gb3ZlcnJpZGUgZGVmYXVsdCBjb25maWcgd2l0aCBnaXZlbiBleHRyYSBjb25maWdcclxuICAgICAgICBjb25zdCBhcGlDb25maWcgPSB7Li4ue1xyXG4gICAgICAgICAgICBkZXBsb3lPcHRpb25zOiB7XHJcbiAgICAgICAgICAgICAgICBsb2dnaW5nTGV2ZWw6IE1ldGhvZExvZ2dpbmdMZXZlbC5FUlJPUixcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgcmVzdEFwaU5hbWU6IGFwaU5hbWUsXHJcbiAgICAgICAgICAgIGVuZHBvaW50VHlwZXM6IFtFbmRwb2ludFR5cGUuUkVHSU9OQUxdLFxyXG4gICAgICAgICAgICBwb2xpY3k6IHBvbGljeURvY3VtZW50LFxyXG4gICAgICAgIH0sIC4uLmNvbmZpZ307XHJcblxyXG4gICAgICAgIHN1cGVyKHN0YWNrLCBhcGlJZCwgYXBpQ29uZmlnKTtcclxuXHJcbiAgICAgICAgdGhpcy5hcGlLZXlJZHMgPSBbXTtcclxuXHJcbiAgICAgICAgYWRkNDA0U3VwcG9ydCh0aGlzLCBzdGFjayk7XHJcbiAgICB9XHJcblxyXG4gICAgaG9zdG5hbWUoKTogc3RyaW5nIHtcclxuICAgICAgICByZXR1cm4gYCR7dGhpcy5yZXN0QXBpSWR9LmV4ZWN1dGUtYXBpLiR7KHRoaXMuc3RhY2sgYXMgRGlnaXRyYWZmaWNTdGFjaykucmVnaW9ufS5hbWF6b25hd3MuY29tYDtcclxuICAgIH1cclxuXHJcbiAgICBjcmVhdGVVc2FnZVBsYW4oYXBpS2V5SWQ6IHN0cmluZywgYXBpS2V5TmFtZTogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgICBjb25zdCBuZXdLZXlJZCA9IGNyZWF0ZVVzYWdlUGxhbih0aGlzLCBhcGlLZXlJZCwgYXBpS2V5TmFtZSkua2V5SWQ7XHJcblxyXG4gICAgICAgIHRoaXMuYXBpS2V5SWRzLnB1c2gobmV3S2V5SWQpO1xyXG5cclxuICAgICAgICByZXR1cm4gbmV3S2V5SWQ7XHJcbiAgICB9XHJcblxyXG4gICAgY3JlYXRlVXNhZ2VQbGFuVjIoYXBpTmFtZTogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgICBjb25zdCBuZXdLZXlJZCA9IGNyZWF0ZURlZmF1bHRVc2FnZVBsYW4odGhpcywgYXBpTmFtZSkua2V5SWQ7XHJcblxyXG4gICAgICAgIHRoaXMuYXBpS2V5SWRzLnB1c2gobmV3S2V5SWQpO1xyXG5cclxuICAgICAgICByZXR1cm4gbmV3S2V5SWQ7XHJcbiAgICB9XHJcblxyXG4gICAgYWRkSnNvbk1vZGVsKG1vZGVsTmFtZTogc3RyaW5nLCBzY2hlbWE6IEpzb25TY2hlbWEpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5nZXRNb2RlbFdpdGhSZWZlcmVuY2UodGhpcy5hZGRNb2RlbChtb2RlbE5hbWUsIHtcclxuICAgICAgICAgICAgY29udGVudFR5cGU6IE1lZGlhVHlwZS5BUFBMSUNBVElPTl9KU09OLFxyXG4gICAgICAgICAgICBtb2RlbE5hbWUsXHJcbiAgICAgICAgICAgIHNjaGVtYSxcclxuICAgICAgICB9KSk7XHJcbiAgICB9XHJcblxyXG4gICAgYWRkQ1NWTW9kZWwobW9kZWxOYW1lOiBzdHJpbmcpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5nZXRNb2RlbFdpdGhSZWZlcmVuY2UodGhpcy5hZGRNb2RlbChtb2RlbE5hbWUsIHtcclxuICAgICAgICAgICAgY29udGVudFR5cGU6IE1lZGlhVHlwZS5URVhUX0NTVixcclxuICAgICAgICAgICAgbW9kZWxOYW1lLFxyXG4gICAgICAgICAgICBzY2hlbWE6IHt9LFxyXG4gICAgICAgIH0pKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGdldE1vZGVsV2l0aFJlZmVyZW5jZShtb2RlbDogTW9kZWwpOiBNb2RlbFdpdGhSZWZlcmVuY2Uge1xyXG4gICAgICAgIHJldHVybiBSLmFzc29jKCdtb2RlbFJlZmVyZW5jZScsIGdldE1vZGVsUmVmZXJlbmNlKG1vZGVsLm1vZGVsSWQsIHRoaXMucmVzdEFwaUlkKSwgbW9kZWwpIGFzIE1vZGVsV2l0aFJlZmVyZW5jZTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFkZERvY3VtZW50YXRpb25QYXJ0KFxyXG4gICAgICAgIHJlc291cmNlOiBSZXNvdXJjZSwgcGFyYW1ldGVyTmFtZTogc3RyaW5nLCByZXNvdXJjZU5hbWU6IHN0cmluZywgdHlwZTogc3RyaW5nLCBwcm9wZXJ0aWVzOiBEb2N1bWVudGF0aW9uUHJvcGVydGllcyxcclxuICAgICkge1xyXG4gICAgICAgIGNvbnN0IGxvY2F0aW9uOiBDZm5Eb2N1bWVudGF0aW9uUGFydC5Mb2NhdGlvblByb3BlcnR5ID0ge1xyXG4gICAgICAgICAgICB0eXBlLFxyXG4gICAgICAgICAgICBwYXRoOiByZXNvdXJjZS5wYXRoLFxyXG4gICAgICAgICAgICBuYW1lOiB0eXBlICE9PSAnTUVUSE9EJyA/IHBhcmFtZXRlck5hbWUgOiB1bmRlZmluZWQsXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgbmV3IENmbkRvY3VtZW50YXRpb25QYXJ0KHRoaXMuc3RhY2ssIHJlc291cmNlTmFtZSwge1xyXG4gICAgICAgICAgICByZXN0QXBpSWQ6IHJlc291cmNlLmFwaS5yZXN0QXBpSWQsXHJcbiAgICAgICAgICAgIGxvY2F0aW9uLFxyXG4gICAgICAgICAgICBwcm9wZXJ0aWVzOiBKU09OLnN0cmluZ2lmeShwcm9wZXJ0aWVzKSxcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBkb2N1bWVudFJlc291cmNlKHJlc291cmNlOiBSZXNvdXJjZSwgLi4uZG9jdW1lbnRhdGlvblBhcnQ6IERvY3VtZW50YXRpb25QYXJ0W10pIHtcclxuICAgICAgICBkb2N1bWVudGF0aW9uUGFydC5mb3JFYWNoKGRwID0+IHRoaXMuYWRkRG9jdW1lbnRhdGlvblBhcnQoXHJcbiAgICAgICAgICAgIHJlc291cmNlLCBkcC5wYXJhbWV0ZXJOYW1lLCBgJHtyZXNvdXJjZS5wYXRofS4ke2RwLnBhcmFtZXRlck5hbWV9LkRvY3VtZW50YXRpb25gLCBkcC50eXBlLCBkcC5kb2N1bWVudGF0aW9uUHJvcGVydGllcyxcclxuICAgICAgICApKTtcclxuICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIER1ZSB0byBBV1MgQVBJIGRlc2lnbiBBUEkgR2F0ZXdheSB3aWxsIGFsd2F5cyByZXR1cm4gNDAzICdNaXNzaW5nIEF1dGhlbnRpY2F0aW9uIFRva2VuJyBmb3IgcmVxdWVzdHNcclxuICogd2l0aCBhIG5vbi1leGlzdGVudCBlbmRwb2ludC4gVGhpcyBmdW5jdGlvbiB0cmFuc2xhdGVzIHRoaXMgcmVzcG9uc2UgdG8gYSA0MDQuXHJcbiAqIFJlcXVlc3RzIHdpdGggYW4gaW52YWxpZCBvciBtaXNzaW5nIEFQSSBrZXkgYXJlIG5vdCBhZmZlY3RlZCAoc3RpbGwgcmV0dXJuIDQwMyAnRm9yYmlkZGVuJykuXHJcbiAqIEBwYXJhbSByZXN0QXBpIFJlc3RBcGlcclxuICogQHBhcmFtIHN0YWNrIENvbnN0cnVjdFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGFkZDQwNFN1cHBvcnQocmVzdEFwaTogUmVzdEFwaSwgc3RhY2s6IENvbnN0cnVjdCkge1xyXG4gICAgbmV3IEdhdGV3YXlSZXNwb25zZShzdGFjaywgYE1pc3NpbmdBdXRoZW50aWNhdGlvblRva2VuUmVzcG9uc2UtJHtyZXN0QXBpLnJlc3RBcGlOYW1lfWAsIHtcclxuICAgICAgICByZXN0QXBpLFxyXG4gICAgICAgIHR5cGU6IFJlc3BvbnNlVHlwZS5NSVNTSU5HX0FVVEhFTlRJQ0FUSU9OX1RPS0VOLFxyXG4gICAgICAgIHN0YXR1c0NvZGU6ICc0MDQnLFxyXG4gICAgICAgIHRlbXBsYXRlczoge1xyXG4gICAgICAgICAgICAnYXBwbGljYXRpb24vanNvbic6ICd7XCJtZXNzYWdlXCI6IFwiTm90IGZvdW5kXCJ9JyxcclxuICAgICAgICB9LFxyXG4gICAgfSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBhZGQ0MDFTdXBwb3J0KHJlc3RBcGk6IFJlc3RBcGksIHN0YWNrOiBDb25zdHJ1Y3QpIHtcclxuICAgIG5ldyBHYXRld2F5UmVzcG9uc2Uoc3RhY2ssIGBBdXRoZW50aWNhdGlvbkZhaWxlZFJlc3BvbnNlLSR7cmVzdEFwaS5yZXN0QXBpTmFtZX1gLCB7XHJcbiAgICAgICAgcmVzdEFwaSxcclxuICAgICAgICB0eXBlOiBSZXNwb25zZVR5cGUuVU5BVVRIT1JJWkVELFxyXG4gICAgICAgIHN0YXR1c0NvZGU6IFwiNDAxXCIsXHJcbiAgICAgICAgcmVzcG9uc2VIZWFkZXJzOiB7XHJcbiAgICAgICAgICAgICdXV1ctQXV0aGVudGljYXRlJzogXCInQmFzaWMnXCIsXHJcbiAgICAgICAgfSxcclxuICAgIH0pO1xyXG59XHJcblxyXG4vKipcclxuICogRHVlIHRvIEFXUyBBUEkgZGVzaWduIEFQSSBHYXRld2F5IHdpbGwgYWx3YXlzIHJldHVybiA0MDMgJ01pc3NpbmcgQXV0aGVudGljYXRpb24gVG9rZW4nIGZvciByZXF1ZXN0c1xyXG4gKiB3aXRoIGEgbm9uLWV4aXN0ZW50IGVuZHBvaW50LiBUaGlzIGZ1bmN0aW9uIGNvbnZlcnRzIHRoaXMgcmVzcG9uc2UgdG8gYSBjdXN0b20gb25lLlxyXG4gKiBSZXF1ZXN0cyB3aXRoIGFuIGludmFsaWQgb3IgbWlzc2luZyBBUEkga2V5IGFyZSBub3QgYWZmZWN0ZWQgKHN0aWxsIHJldHVybiA0MDMgJ0ZvcmJpZGRlbicpLlxyXG4gKiBAcGFyYW0gcmV0dXJuQ29kZVxyXG4gKiBAcGFyYW0gbWVzc2FnZVxyXG4gKiBAcGFyYW0gcmVzdEFwaSBSZXN0QXBpXHJcbiAqIEBwYXJhbSBzdGFjayBDb25zdHJ1Y3RcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBzZXRSZXR1cm5Db2RlRm9yTWlzc2luZ0F1dGhlbnRpY2F0aW9uVG9rZW4ocmV0dXJuQ29kZTogbnVtYmVyLFxyXG4gICAgbWVzc2FnZTogc3RyaW5nLFxyXG4gICAgcmVzdEFwaTogUmVzdEFwaSxcclxuICAgIHN0YWNrOiBDb25zdHJ1Y3QpIHtcclxuXHJcbiAgICBuZXcgR2F0ZXdheVJlc3BvbnNlKHN0YWNrLCBgTWlzc2luZ0F1dGhlbnRpY2F0aW9uVG9rZW5SZXNwb25zZS0ke3Jlc3RBcGkucmVzdEFwaU5hbWV9YCwge1xyXG4gICAgICAgIHJlc3RBcGksXHJcbiAgICAgICAgdHlwZTogUmVzcG9uc2VUeXBlLk1JU1NJTkdfQVVUSEVOVElDQVRJT05fVE9LRU4sXHJcbiAgICAgICAgc3RhdHVzQ29kZTogYCR7cmV0dXJuQ29kZX1gLFxyXG4gICAgICAgIHRlbXBsYXRlczoge1xyXG4gICAgICAgICAgICAnYXBwbGljYXRpb24vanNvbic6IGB7XCJtZXNzYWdlXCI6ICR7bWVzc2FnZX19YCxcclxuICAgICAgICB9LFxyXG4gICAgfSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVSZXN0QXBpKHN0YWNrOiBDb25zdHJ1Y3QsIGFwaUlkOiBzdHJpbmcsIGFwaU5hbWU6IHN0cmluZywgYWxsb3dGcm9tSXBBZGRyZXNzZXM/OiBzdHJpbmdbXSB8IHVuZGVmaW5lZCk6IFJlc3RBcGkge1xyXG4gICAgY29uc3QgcG9saWN5RG9jdW1lbnQgPSBhbGxvd0Zyb21JcEFkZHJlc3NlcyA9PSBudWxsID8gY3JlYXRlRGVmYXVsdFBvbGljeURvY3VtZW50KCkgOiBjcmVhdGVJcFJlc3RyaWN0aW9uUG9saWN5RG9jdW1lbnQoYWxsb3dGcm9tSXBBZGRyZXNzZXMpO1xyXG4gICAgY29uc3QgcmVzdEFwaSA9IG5ldyBSZXN0QXBpKHN0YWNrLCBhcGlJZCwge1xyXG4gICAgICAgIGRlcGxveU9wdGlvbnM6IHtcclxuICAgICAgICAgICAgbG9nZ2luZ0xldmVsOiBNZXRob2RMb2dnaW5nTGV2ZWwuRVJST1IsXHJcbiAgICAgICAgfSxcclxuICAgICAgICByZXN0QXBpTmFtZTogYXBpTmFtZSxcclxuICAgICAgICBlbmRwb2ludFR5cGVzOiBbRW5kcG9pbnRUeXBlLlJFR0lPTkFMXSxcclxuICAgICAgICBwb2xpY3k6IHBvbGljeURvY3VtZW50LFxyXG4gICAgfSk7XHJcbiAgICBhZGQ0MDRTdXBwb3J0KHJlc3RBcGksIHN0YWNrKTtcclxuICAgIHJldHVybiByZXN0QXBpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlRGVmYXVsdFBvbGljeURvY3VtZW50KCkge1xyXG4gICAgcmV0dXJuIG5ldyBQb2xpY3lEb2N1bWVudCh7XHJcbiAgICAgICAgc3RhdGVtZW50czogW1xyXG4gICAgICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcclxuICAgICAgICAgICAgICAgIGVmZmVjdDogRWZmZWN0LkFMTE9XLFxyXG4gICAgICAgICAgICAgICAgYWN0aW9uczogW1xyXG4gICAgICAgICAgICAgICAgICAgIFwiZXhlY3V0ZS1hcGk6SW52b2tlXCIsXHJcbiAgICAgICAgICAgICAgICBdLFxyXG4gICAgICAgICAgICAgICAgcmVzb3VyY2VzOiBbXHJcbiAgICAgICAgICAgICAgICAgICAgXCIqXCIsXHJcbiAgICAgICAgICAgICAgICBdLFxyXG4gICAgICAgICAgICAgICAgcHJpbmNpcGFsczogW1xyXG4gICAgICAgICAgICAgICAgICAgIG5ldyBBbnlQcmluY2lwYWwoKSxcclxuICAgICAgICAgICAgICAgIF0sXHJcbiAgICAgICAgICAgIH0pLFxyXG4gICAgICAgIF0sXHJcbiAgICB9KTtcclxufVxyXG5cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVJcFJlc3RyaWN0aW9uUG9saWN5RG9jdW1lbnQoYWxsb3dGcm9tSXBBZGRyZXNzZXM6IHN0cmluZ1tdKTogUG9saWN5RG9jdW1lbnQge1xyXG4gICAgcmV0dXJuIG5ldyBQb2xpY3lEb2N1bWVudCh7XHJcbiAgICAgICAgc3RhdGVtZW50czogW1xyXG4gICAgICAgICAgICBuZXcgUG9saWN5U3RhdGVtZW50KHtcclxuICAgICAgICAgICAgICAgIGVmZmVjdDogRWZmZWN0LkFMTE9XLFxyXG4gICAgICAgICAgICAgICAgY29uZGl0aW9uczoge1xyXG4gICAgICAgICAgICAgICAgICAgIFwiSXBBZGRyZXNzXCI6IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgXCJhd3M6U291cmNlSXBcIjogYWxsb3dGcm9tSXBBZGRyZXNzZXMsXHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBhY3Rpb25zOiBbXHJcbiAgICAgICAgICAgICAgICAgICAgXCJleGVjdXRlLWFwaTpJbnZva2VcIixcclxuICAgICAgICAgICAgICAgIF0sXHJcbiAgICAgICAgICAgICAgICByZXNvdXJjZXM6IFtcclxuICAgICAgICAgICAgICAgICAgICBcIipcIixcclxuICAgICAgICAgICAgICAgIF0sXHJcbiAgICAgICAgICAgICAgICBwcmluY2lwYWxzOiBbXHJcbiAgICAgICAgICAgICAgICAgICAgbmV3IEFueVByaW5jaXBhbCgpLFxyXG4gICAgICAgICAgICAgICAgXSxcclxuICAgICAgICAgICAgfSksXHJcbiAgICAgICAgXSxcclxuICAgIH0pO1xyXG59XHJcbiJdfQ==
|
@@ -1,163 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.StackCheckingAspect = void 0;
|
4
|
-
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
5
|
-
const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
|
6
|
-
const aws_s3_1 = require("aws-cdk-lib/aws-s3");
|
7
|
-
const stack_1 = require("./stack");
|
8
|
-
const aws_apigateway_1 = require("aws-cdk-lib/aws-apigateway");
|
9
|
-
const change_case_1 = require("change-case");
|
10
|
-
const aws_sqs_1 = require("aws-cdk-lib/aws-sqs");
|
11
|
-
const aws_logs_1 = require("aws-cdk-lib/aws-logs");
|
12
|
-
const MAX_CONCURRENCY_LIMIT = 100;
|
13
|
-
const NODE_RUNTIME = aws_lambda_1.Runtime.NODEJS_14_X.name;
|
14
|
-
var ResourceType;
|
15
|
-
(function (ResourceType) {
|
16
|
-
ResourceType["stackName"] = "STACK_NAME";
|
17
|
-
ResourceType["reservedConcurrentConcurrency"] = "RESERVED_CONCURRENT_CONCURRENCY";
|
18
|
-
ResourceType["functionTimeout"] = "FUNCTION_TIMEOUT";
|
19
|
-
ResourceType["functionMemorySize"] = "FUNCTION_MEMORY_SIZE";
|
20
|
-
ResourceType["functionRuntime"] = "FUNCTION_RUNTIME";
|
21
|
-
ResourceType["functionName"] = "FUNCTION_NAME";
|
22
|
-
ResourceType["tagSolution"] = "TAG_SOLUTION";
|
23
|
-
ResourceType["bucketPublicity"] = "BUCKET_PUBLICITY";
|
24
|
-
ResourceType["resourcePath"] = "RESOURCE_PATH";
|
25
|
-
ResourceType["queueEncryption"] = "QUEUE_ENCRYPTION";
|
26
|
-
ResourceType["logGroupRetention"] = "LOG_GROUP_RETENTION";
|
27
|
-
})(ResourceType || (ResourceType = {}));
|
28
|
-
class StackCheckingAspect {
|
29
|
-
constructor(configuration) {
|
30
|
-
this.configuration = configuration;
|
31
|
-
}
|
32
|
-
static create(stack) {
|
33
|
-
return new StackCheckingAspect(stack.configuration);
|
34
|
-
}
|
35
|
-
visit(node) {
|
36
|
-
//console.info("visiting class " + node.constructor.name);
|
37
|
-
this.checkStack(node);
|
38
|
-
this.checkFunction(node);
|
39
|
-
this.checkTags(node);
|
40
|
-
this.checkBucket(node);
|
41
|
-
this.checkResourceCasing(node);
|
42
|
-
this.checkQueueEncryption(node);
|
43
|
-
this.checkLogGroupRetention(node);
|
44
|
-
}
|
45
|
-
isWhitelisted(key) {
|
46
|
-
return this?.configuration?.whitelistedResources?.some(wl => {
|
47
|
-
return key.matchAll(new RegExp(wl, 'g'));
|
48
|
-
});
|
49
|
-
}
|
50
|
-
addAnnotation(node, key, message, isError = true) {
|
51
|
-
const resourceKey = `${node.node.path}/${key}`;
|
52
|
-
const isWhiteListed = this.isWhitelisted(resourceKey);
|
53
|
-
const annotationMessage = `${resourceKey}:${message}`;
|
54
|
-
// error && whitelisted -> warning
|
55
|
-
// warning && whitelisted -> nothing
|
56
|
-
if (isError && !isWhiteListed) {
|
57
|
-
aws_cdk_lib_1.Annotations.of(node).addError(annotationMessage);
|
58
|
-
}
|
59
|
-
else if ((!isError && !isWhiteListed) || (isError && isWhiteListed)) {
|
60
|
-
aws_cdk_lib_1.Annotations.of(node).addWarning(annotationMessage);
|
61
|
-
}
|
62
|
-
}
|
63
|
-
checkStack(node) {
|
64
|
-
if (node instanceof stack_1.DigitrafficStack) {
|
65
|
-
if ((node.stackName.includes('Test') || node.stackName.includes('Tst')) && node.configuration?.production) {
|
66
|
-
this.addAnnotation(node, ResourceType.stackName, 'Production is set for Test-stack');
|
67
|
-
}
|
68
|
-
if ((node.stackName.includes('Prod') || node.stackName.includes('Prd')) && !node.configuration?.production) {
|
69
|
-
this.addAnnotation(node, ResourceType.stackName, 'Production is not set for Production-stack');
|
70
|
-
}
|
71
|
-
}
|
72
|
-
}
|
73
|
-
checkFunction(node) {
|
74
|
-
if (node instanceof aws_lambda_1.CfnFunction) {
|
75
|
-
if (!node.reservedConcurrentExecutions) {
|
76
|
-
this.addAnnotation(node, ResourceType.reservedConcurrentConcurrency, 'Function must have reservedConcurrentConcurrency');
|
77
|
-
}
|
78
|
-
else if (node.reservedConcurrentExecutions > MAX_CONCURRENCY_LIMIT) {
|
79
|
-
this.addAnnotation(node, ResourceType.reservedConcurrentConcurrency, 'Function reservedConcurrentConcurrency too high!');
|
80
|
-
}
|
81
|
-
if (!node.timeout) {
|
82
|
-
this.addAnnotation(node, ResourceType.functionTimeout, 'Function must have timeout');
|
83
|
-
}
|
84
|
-
if (!node.memorySize) {
|
85
|
-
this.addAnnotation(node, ResourceType.functionMemorySize, 'Function must have memorySize');
|
86
|
-
}
|
87
|
-
if (node.runtime !== NODE_RUNTIME) {
|
88
|
-
this.addAnnotation(node, ResourceType.functionRuntime, 'wrong runtime ' + node.runtime);
|
89
|
-
}
|
90
|
-
if (this.configuration?.shortName && node.functionName && node.functionName.indexOf(this.configuration.shortName) !== 0) {
|
91
|
-
this.addAnnotation(node, ResourceType.functionName, 'Function name does not begin with ' + this.configuration.shortName);
|
92
|
-
}
|
93
|
-
}
|
94
|
-
}
|
95
|
-
checkTags(node) {
|
96
|
-
if (node instanceof aws_cdk_lib_1.Stack) {
|
97
|
-
if (!node.tags.tagValues()[stack_1.SOLUTION_KEY]) {
|
98
|
-
this.addAnnotation(node, ResourceType.tagSolution, 'Solution tag is missing');
|
99
|
-
}
|
100
|
-
}
|
101
|
-
}
|
102
|
-
checkBucket(node) {
|
103
|
-
if (node instanceof aws_s3_1.CfnBucket) {
|
104
|
-
const c = node.publicAccessBlockConfiguration;
|
105
|
-
if (c) {
|
106
|
-
if (!c.blockPublicAcls || !c.blockPublicPolicy || !c.ignorePublicAcls || !c.restrictPublicBuckets) {
|
107
|
-
this.addAnnotation(node, ResourceType.bucketPublicity, 'Check bucket publicity');
|
108
|
-
}
|
109
|
-
}
|
110
|
-
}
|
111
|
-
}
|
112
|
-
static isValidPath(path) {
|
113
|
-
// if path includes . or { check only the trailing part of path
|
114
|
-
if (path.includes('.')) {
|
115
|
-
return this.isValidPath(path.split('.')[0]);
|
116
|
-
}
|
117
|
-
if (path.includes('{')) {
|
118
|
-
return this.isValidPath(path.split('{')[0]);
|
119
|
-
}
|
120
|
-
return (0, change_case_1.paramCase)(path) === path;
|
121
|
-
}
|
122
|
-
static isValidQueryString(name) {
|
123
|
-
return (0, change_case_1.snakeCase)(name) === name;
|
124
|
-
}
|
125
|
-
checkResourceCasing(node) {
|
126
|
-
if (node instanceof aws_apigateway_1.CfnResource) {
|
127
|
-
if (!StackCheckingAspect.isValidPath(node.pathPart)) {
|
128
|
-
this.addAnnotation(node, ResourceType.resourcePath, 'Path part should be in kebab-case');
|
129
|
-
}
|
130
|
-
}
|
131
|
-
else if (node instanceof aws_apigateway_1.CfnMethod) {
|
132
|
-
const integration = node.integration;
|
133
|
-
if (integration && integration.requestParameters) {
|
134
|
-
Object.keys(integration.requestParameters).forEach(key => {
|
135
|
-
const split = key.split('.');
|
136
|
-
const type = split[2];
|
137
|
-
const name = split[3];
|
138
|
-
if (type === 'querystring' && !StackCheckingAspect.isValidQueryString(name)) {
|
139
|
-
this.addAnnotation(node, name, 'Querystring should be in snake_case');
|
140
|
-
}
|
141
|
-
});
|
142
|
-
}
|
143
|
-
}
|
144
|
-
}
|
145
|
-
checkQueueEncryption(node) {
|
146
|
-
if (node instanceof aws_sqs_1.CfnQueue) {
|
147
|
-
if (!node.kmsMasterKeyId) {
|
148
|
-
this.addAnnotation(node, ResourceType.queueEncryption, 'Queue must have encryption enabled');
|
149
|
-
}
|
150
|
-
}
|
151
|
-
}
|
152
|
-
checkLogGroupRetention(node) {
|
153
|
-
if (node instanceof aws_logs_1.LogRetention) {
|
154
|
-
const child = node.node.defaultChild;
|
155
|
-
const retention = child._cfnProperties.RetentionInDays;
|
156
|
-
if (!retention) {
|
157
|
-
this.addAnnotation(node, ResourceType.logGroupRetention, 'Log group must define log group retention');
|
158
|
-
}
|
159
|
-
}
|
160
|
-
}
|
161
|
-
}
|
162
|
-
exports.StackCheckingAspect = StackCheckingAspect;
|
163
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhY2stY2hlY2tpbmctYXNwZWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2F3cy9pbmZyYS9zdGFjay9zdGFjay1jaGVja2luZy1hc3BlY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkNBQXdEO0FBQ3hELHVEQUE0RDtBQUM1RCwrQ0FBNkM7QUFDN0MsbUNBQTJFO0FBRTNFLCtEQUFrRTtBQUNsRSw2Q0FBaUQ7QUFDakQsaURBQTZDO0FBQzdDLG1EQUFrRDtBQUdsRCxNQUFNLHFCQUFxQixHQUFHLEdBQUcsQ0FBQztBQUNsQyxNQUFNLFlBQVksR0FBRyxvQkFBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUM7QUFFOUMsSUFBSyxZQVlKO0FBWkQsV0FBSyxZQUFZO0lBQ2Isd0NBQXdCLENBQUE7SUFDeEIsaUZBQWlFLENBQUE7SUFDakUsb0RBQW9DLENBQUE7SUFDcEMsMkRBQTJDLENBQUE7SUFDM0Msb0RBQW9DLENBQUE7SUFDcEMsOENBQThCLENBQUE7SUFDOUIsNENBQTRCLENBQUE7SUFDNUIsb0RBQW9DLENBQUE7SUFDcEMsOENBQThCLENBQUE7SUFDOUIsb0RBQW9DLENBQUE7SUFDcEMseURBQXlDLENBQUE7QUFDN0MsQ0FBQyxFQVpJLFlBQVksS0FBWixZQUFZLFFBWWhCO0FBRUQsTUFBYSxtQkFBbUI7SUFHNUIsWUFBWSxhQUFrQztRQUMxQyxJQUFJLENBQUMsYUFBYSxHQUFHLGFBQWEsQ0FBQztJQUN2QyxDQUFDO0lBRUQsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUF1QjtRQUNqQyxPQUFPLElBQUksbUJBQW1CLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ3hELENBQUM7SUFFTSxLQUFLLENBQUMsSUFBZ0I7UUFDekIsMERBQTBEO1FBRTFELElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENB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LGNBQWMsQ0FBQyxlQUFlLENBQUM7WUFFdkQsSUFBSSxDQUFDLFNBQVMsRUFBRTtnQkFDWixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksRUFBRSxZQUFZLENBQUMsaUJBQWlCLEVBQUUsMkNBQTJDLENBQUMsQ0FBQzthQUN6RztTQUNKO0lBQ0wsQ0FBQztDQUNKO0FBOUpELGtEQThKQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7QW5ub3RhdGlvbnMsIElBc3BlY3QsIFN0YWNrfSBmcm9tIFwiYXdzLWNkay1saWJcIjtcbmltcG9ydCB7Q2ZuRnVuY3Rpb24sIFJ1bnRpbWV9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1sYW1iZGEnO1xuaW1wb3J0IHtDZm5CdWNrZXR9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtczNcIjtcbmltcG9ydCB7RGlnaXRyYWZmaWNTdGFjaywgU09MVVRJT05fS0VZLCBTdGFja0NvbmZpZ3VyYXRpb259IGZyb20gXCIuL3N0YWNrXCI7XG5pbXBvcnQge0lDb25zdHJ1Y3R9IGZyb20gXCJjb25zdHJ1Y3RzXCI7XG5pbXBvcnQge0Nmbk1ldGhvZCwgQ2ZuUmVzb3VyY2V9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtYXBpZ2F0ZXdheVwiO1xuaW1wb3J0IHtwYXJhbUNhc2UsIHNuYWtlQ2FzZX0gZnJvbSBcImNoYW5nZS1jYXNlXCI7XG5pbXBvcnQge0NmblF1ZXVlfSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXNxc1wiO1xuaW1wb3J0IHtMb2dSZXRlbnRpb259IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbG9nc1wiO1xuaW1wb3J0IEludGVncmF0aW9uUHJvcGVydHkgPSBDZm5NZXRob2QuSW50ZWdyYXRpb25Qcm9wZXJ0eTtcblxuY29uc3QgTUFYX0NPTkNVUlJFTkNZX0xJTUlUID0gMTAwO1xuY29uc3QgTk9ERV9SVU5USU1FID0gUnVudGltZS5OT0RFSlNfMTRfWC5uYW1lO1xuXG5lbnVtIFJlc291cmNlVHlwZSB7XG4gICAgc3RhY2tOYW1lID0gXCJTVEFDS19OQU1FXCIsXG4gICAgcmVzZXJ2ZWRDb25jdXJyZW50Q29uY3VycmVuY3kgPSBcIlJFU0VSVkVEX0NPTkNVUlJFTlRfQ09OQ1VSUkVOQ1lcIixcbiAgICBmdW5jdGlvblRpbWVvdXQgPSBcIkZVTkNUSU9OX1RJTUVPVVRcIixcbiAgICBmdW5jdGlvbk1lbW9yeVNpemUgPSBcIkZVTkNUSU9OX01FTU9SWV9TSVpFXCIsXG4gICAgZnVuY3Rpb25SdW50aW1lID0gXCJGVU5DVElPTl9SVU5USU1FXCIsXG4gICAgZnVuY3Rpb25OYW1lID0gXCJGVU5DVElPTl9OQU1FXCIsXG4gICAgdGFnU29sdXRpb24gPSBcIlRBR19TT0xVVElPTlwiLFxuICAgIGJ1Y2tldFB1YmxpY2l0eSA9IFwiQlVDS0VUX1BVQkxJQ0lUWVwiLFxuICAgIHJlc291cmNlUGF0aCA9IFwiUkVTT1VSQ0VfUEFUSFwiLFxuICAgIHF1ZXVlRW5jcnlwdGlvbiA9IFwiUVVFVUVfRU5DUllQVElPTlwiLFxuICAgIGxvZ0dyb3VwUmV0ZW50aW9uID0gXCJMT0dfR1JPVVBfUkVURU5USU9OXCIsXG59XG5cbmV4cG9ydCBjbGFzcyBTdGFja0NoZWNraW5nQXNwZWN0IGltcGxlbWVudHMgSUFzcGVjdCB7XG4gICAgcHJpdmF0ZSByZWFkb25seSBjb25maWd1cmF0aW9uPzogU3RhY2tDb25maWd1cmF0aW9uO1xuXG4gICAgY29uc3RydWN0b3IoY29uZmlndXJhdGlvbj86IFN0YWNrQ29uZmlndXJhdGlvbikge1xuICAgICAgICB0aGlzLmNvbmZpZ3VyYXRpb24gPSBjb25maWd1cmF0aW9uO1xuICAgIH1cblxuICAgIHN0YXRpYyBjcmVhdGUoc3RhY2s6IERpZ2l0cmFmZmljU3RhY2spIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTdGFja0NoZWNraW5nQXNwZWN0KHN0YWNrLmNvbmZpZ3VyYXRpb24pO1xuICAgIH1cblxuICAgIHB1YmxpYyB2aXNpdChub2RlOiBJQ29uc3RydWN0KTogdm9pZCB7XG4gICAgICAgIC8vY29uc29sZS5pbmZvKFwidmlzaXRpbmcgY2xhc3MgXCIgKyBub2RlLmNvbnN0cnVjdG9yLm5hbWUpO1xuXG4gICAgICAgIHRoaXMuY2hlY2tTdGFjayhub2RlKTtcbiAgICAgICAgdGhpcy5jaGVja0Z1bmN0aW9uKG5vZGUpO1xuICAgICAgICB0aGlzLmNoZWNrVGFncyhub2RlKTtcbiAgICAgICAgdGhpcy5jaGVja0J1Y2tldChub2RlKTtcbiAgICAgICAgdGhpcy5jaGVja1Jlc291cmNlQ2FzaW5nKG5vZGUpO1xuICAgICAgICB0aGlzLmNoZWNrUXVldWVFbmNyeXB0aW9uKG5vZGUpO1xuICAgICAgICB0aGlzLmNoZWNrTG9nR3JvdXBSZXRlbnRpb24obm9kZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpc1doaXRlbGlzdGVkKGtleTogc3RyaW5nKSB7XG4gICAgICAgIHJldHVybiB0aGlzPy5jb25maWd1cmF0aW9uPy53aGl0ZWxpc3RlZFJlc291cmNlcz8uc29tZSh3bCA9PiB7XG4gICAgICAgICAgICByZXR1cm4ga2V5Lm1hdGNoQWxsKG5ldyBSZWdFeHAod2wsICdnJykpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFkZEFubm90YXRpb24obm9kZTogSUNvbnN0cnVjdCwga2V5OiBSZXNvdXJjZVR5cGUgfCBzdHJpbmcsIG1lc3NhZ2U6IHN0cmluZywgaXNFcnJvciA9IHRydWUpIHtcbiAgICAgICAgY29uc3QgcmVzb3VyY2VLZXkgPSBgJHtub2RlLm5vZGUucGF0aH0vJHtrZXl9YDtcbiAgICAgICAgY29uc3QgaXNXaGl0ZUxpc3RlZCA9IHRoaXMuaXNXaGl0ZWxpc3RlZChyZXNvdXJjZUtleSk7XG4gICAgICAgIGNvbnN0IGFubm90YXRpb25NZXNzYWdlID0gYCR7cmVzb3VyY2VLZXl9OiR7bWVzc2FnZX1gO1xuXG4gICAgICAgIC8vIGVycm9yICYmIHdoaXRlbGlzdGVkIC0+IHdhcm5pbmdcbiAgICAgICAgLy8gd2FybmluZyAmJiB3aGl0ZWxpc3RlZCAtPiBub3RoaW5nXG4gICAgICAgIGlmIChpc0Vycm9yICYmICFpc1doaXRlTGlzdGVkKSB7XG4gICAgICAgICAgICBBbm5vdGF0aW9ucy5vZihub2RlKS5hZGRFcnJvcihhbm5vdGF0aW9uTWVzc2FnZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoKCFpc0Vycm9yICYmICFpc1doaXRlTGlzdGVkKSB8fCAoaXNFcnJvciAmJiBpc1doaXRlTGlzdGVkKSkge1xuICAgICAgICAgICAgQW5ub3RhdGlvbnMub2Yobm9kZSkuYWRkV2FybmluZyhhbm5vdGF0aW9uTWVzc2FnZSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGNoZWNrU3RhY2sobm9kZTogSUNvbnN0cnVjdCkge1xuICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIERpZ2l0cmFmZmljU3RhY2spIHtcbiAgICAgICAgICAgIGlmICgobm9kZS5zdGFja05hbWUuaW5jbHVkZXMoJ1Rlc3QnKSB8fCBub2RlLnN0YWNrTmFtZS5pbmNsdWRlcygnVHN0JykpICYmIG5vZGUuY29uZmlndXJhdGlvbj8ucHJvZHVjdGlvbikge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkQW5ub3RhdGlvbihub2RlLCBSZXNvdXJjZVR5cGUuc3RhY2tOYW1lLCAnUHJvZHVjdGlvbiBpcyBzZXQgZm9yIFRlc3Qtc3RhY2snKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKChub2RlLnN0YWNrTmFtZS5pbmNsdWRlcygnUHJvZCcpIHx8IG5vZGUuc3RhY2tOYW1lLmluY2x1ZGVzKCdQcmQnKSkgJiYgIW5vZGUuY29uZmlndXJhdGlvbj8ucHJvZHVjdGlvbikge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkQW5ub3RhdGlvbihub2RlLCBSZXNvdXJjZVR5cGUuc3RhY2tOYW1lLCAnUHJvZHVjdGlvbiBpcyBub3Qgc2V0IGZvciBQcm9kdWN0aW9uLXN0YWNrJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGNoZWNrRnVuY3Rpb24obm9kZTogSUNvbnN0cnVjdCkge1xuICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIENmbkZ1bmN0aW9uKSB7XG4gICAgICAgICAgICBpZiAoIW5vZGUucmVzZXJ2ZWRDb25jdXJyZW50RXhlY3V0aW9ucykge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkQW5ub3RhdGlvbihub2RlLCBSZXNvdXJjZVR5cGUucmVzZXJ2ZWRDb25jdXJyZW50Q29uY3VycmVuY3ksICdGdW5jdGlvbiBtdXN0IGhhdmUgcmVzZXJ2ZWRDb25jdXJyZW50Q29uY3VycmVuY3knKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobm9kZS5yZXNlcnZlZENvbmN1cnJlbnRFeGVjdXRpb25zID4gTUFYX0NPTkNVUlJFTkNZX0xJTUlUKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRBbm5vdGF0aW9uKG5vZGUsIFJlc291cmNlVHlwZS5yZXNlcnZlZENvbmN1cnJlbnRDb25jdXJyZW5jeSwgJ0Z1bmN0aW9uIHJlc2VydmVkQ29uY3VycmVudENvbmN1cnJlbmN5IHRvbyBoaWdoIScpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIW5vZGUudGltZW91dCkge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkQW5ub3RhdGlvbihub2RlLCBSZXNvdXJjZVR5cGUuZnVuY3Rpb25UaW1lb3V0LCAnRnVuY3Rpb24gbXVzdCBoYXZlIHRpbWVvdXQnKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFub2RlLm1lbW9yeVNpemUpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmFkZEFubm90YXRpb24obm9kZSwgUmVzb3VyY2VUeXBlLmZ1bmN0aW9uTWVtb3J5U2l6ZSwgJ0Z1bmN0aW9uIG11c3QgaGF2ZSBtZW1vcnlTaXplJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChub2RlLnJ1bnRpbWUgIT09IE5PREVfUlVOVElNRSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkQW5ub3RhdGlvbihub2RlLCBSZXNvdXJjZVR5cGUuZnVuY3Rpb25SdW50aW1lLCd3cm9uZyBydW50aW1lICcgKyBub2RlLnJ1bnRpbWUpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodGhpcy5jb25maWd1cmF0aW9uPy5zaG9ydE5hbWUgJiYgbm9kZS5mdW5jdGlvbk5hbWUgJiYgbm9kZS5mdW5jdGlvbk5hbWUuaW5kZXhPZih0aGlzLmNvbmZpZ3VyYXRpb24uc2hvcnROYW1lKSAhPT0gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkQW5ub3RhdGlvbihub2RlLCBSZXNvdXJjZVR5cGUuZnVuY3Rpb25OYW1lLCAnRnVuY3Rpb24gbmFtZSBkb2VzIG5vdCBiZWdpbiB3aXRoICcgKyB0aGlzLmNvbmZpZ3VyYXRpb24uc2hvcnROYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgY2hlY2tUYWdzKG5vZGU6IElDb25zdHJ1Y3QpIHtcbiAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBTdGFjaykge1xuICAgICAgICAgICAgaWYgKCFub2RlLnRhZ3MudGFnVmFsdWVzKClbU09MVVRJT05fS0VZXSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkQW5ub3RhdGlvbihub2RlLCBSZXNvdXJjZVR5cGUudGFnU29sdXRpb24sICdTb2x1dGlvbiB0YWcgaXMgbWlzc2luZycpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBjaGVja0J1Y2tldChub2RlOiBJQ29uc3RydWN0KSB7XG4gICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgQ2ZuQnVja2V0KSB7XG4gICAgICAgICAgICBjb25zdCBjID0gbm9kZS5wdWJsaWNBY2Nlc3NCbG9ja0NvbmZpZ3VyYXRpb24gYXMgQ2ZuQnVja2V0LlB1YmxpY0FjY2Vzc0Jsb2NrQ29uZmlndXJhdGlvblByb3BlcnR5O1xuXG4gICAgICAgICAgICBpZiAoYykge1xuICAgICAgICAgICAgICAgIGlmICghYy5ibG9ja1B1YmxpY0FjbHMgfHwgIWMuYmxvY2tQdWJsaWNQb2xpY3kgfHwgIWMuaWdub3JlUHVibGljQWNscyB8fCAhYy5yZXN0cmljdFB1YmxpY0J1Y2tldHMpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRBbm5vdGF0aW9uKG5vZGUsIFJlc291cmNlVHlwZS5idWNrZXRQdWJsaWNpdHksICdDaGVjayBidWNrZXQgcHVibGljaXR5Jyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgaXNWYWxpZFBhdGgocGF0aDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIC8vIGlmIHBhdGggaW5jbHVkZXMgLiBvciB7IGNoZWNrIG9ubHkgdGhlIHRyYWlsaW5nIHBhcnQgb2YgcGF0aFxuICAgICAgICBpZiAocGF0aC5pbmNsdWRlcygnLicpKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5pc1ZhbGlkUGF0aChwYXRoLnNwbGl0KCcuJylbMF0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHBhdGguaW5jbHVkZXMoJ3snKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuaXNWYWxpZFBhdGgocGF0aC5zcGxpdCgneycpWzBdKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBwYXJhbUNhc2UocGF0aCkgPT09IHBhdGg7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgaXNWYWxpZFF1ZXJ5U3RyaW5nKG5hbWU6IHN0cmluZykge1xuICAgICAgICByZXR1cm4gc25ha2VDYXNlKG5hbWUpID09PSBuYW1lO1xuICAgIH1cblxuICAgIHByaXZhdGUgY2hlY2tSZXNvdXJjZUNhc2luZyhub2RlOiBJQ29uc3RydWN0KSB7XG4gICAgICAgIGlmIChub2RlIGluc3RhbmNlb2YgQ2ZuUmVzb3VyY2UpIHtcbiAgICAgICAgICAgIGlmICghU3RhY2tDaGVja2luZ0FzcGVjdC5pc1ZhbGlkUGF0aChub2RlLnBhdGhQYXJ0KSkge1xuICAgICAgICAgICAgICAgIHRoaXMuYWRkQW5ub3RhdGlvbihub2RlLCBSZXNvdXJjZVR5cGUucmVzb3VyY2VQYXRoLCAnUGF0aCBwYXJ0IHNob3VsZCBiZSBpbiBrZWJhYi1jYXNlJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAobm9kZSBpbnN0YW5jZW9mIENmbk1ldGhvZCkge1xuICAgICAgICAgICAgY29uc3QgaW50ZWdyYXRpb24gPSBub2RlLmludGVncmF0aW9uIGFzIEludGVncmF0aW9uUHJvcGVydHk7XG5cbiAgICAgICAgICAgIGlmIChpbnRlZ3JhdGlvbiAmJiBpbnRlZ3JhdGlvbi5yZXF1ZXN0UGFyYW1ldGVycykge1xuICAgICAgICAgICAgICAgIE9iamVjdC5rZXlzKGludGVncmF0aW9uLnJlcXVlc3RQYXJhbWV0ZXJzKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNwbGl0ID0ga2V5LnNwbGl0KCcuJyk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHR5cGUgPSBzcGxpdFsyXTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgbmFtZSA9IHNwbGl0WzNdO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlID09PSAncXVlcnlzdHJpbmcnICYmICFTdGFja0NoZWNraW5nQXNwZWN0LmlzVmFsaWRRdWVyeVN0cmluZyhuYW1lKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hZGRBbm5vdGF0aW9uKG5vZGUsIG5hbWUsICdRdWVyeXN0cmluZyBzaG91bGQgYmUgaW4gc25ha2VfY2FzZScpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGNoZWNrUXVldWVFbmNyeXB0aW9uKG5vZGU6IElDb25zdHJ1Y3QpIHtcbiAgICAgICAgaWYgKG5vZGUgaW5zdGFuY2VvZiBDZm5RdWV1ZSkge1xuICAgICAgICAgICAgaWYgKCFub2RlLmttc01hc3RlcktleUlkKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRBbm5vdGF0aW9uKG5vZGUsIFJlc291cmNlVHlwZS5xdWV1ZUVuY3J5cHRpb24sICdRdWV1ZSBtdXN0IGhhdmUgZW5jcnlwdGlvbiBlbmFibGVkJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGNoZWNrTG9nR3JvdXBSZXRlbnRpb24obm9kZTogSUNvbnN0cnVjdCkge1xuICAgICAgICBpZiAobm9kZSBpbnN0YW5jZW9mIExvZ1JldGVudGlvbikge1xuICAgICAgICAgICAgY29uc3QgY2hpbGQgPSBub2RlLm5vZGUuZGVmYXVsdENoaWxkIGFzIHVua25vd24gYXMgUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgc3RyaW5nPj47XG4gICAgICAgICAgICBjb25zdCByZXRlbnRpb24gPSBjaGlsZC5fY2ZuUHJvcGVydGllcy5SZXRlbnRpb25JbkRheXM7XG5cbiAgICAgICAgICAgIGlmICghcmV0ZW50aW9uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5hZGRBbm5vdGF0aW9uKG5vZGUsIFJlc291cmNlVHlwZS5sb2dHcm91cFJldGVudGlvbiwgJ0xvZyBncm91cCBtdXN0IGRlZmluZSBsb2cgZ3JvdXAgcmV0ZW50aW9uJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG4iXX0=
|