@digitraffic/common 2022.10.25-1 → 2022.10.28-2
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/{aws → dist/aws}/infra/api/integration.d.ts +0 -0
- package/dist/aws/infra/api/integration.js +52 -0
- package/dist/aws/infra/api/integration.js.map +1 -0
- package/{aws → dist/aws}/infra/api/response.d.ts +0 -0
- package/dist/aws/infra/api/response.js +61 -0
- package/dist/aws/infra/api/response.js.map +1 -0
- package/{aws → dist/aws}/infra/api/responses.d.ts +3 -3
- package/dist/aws/infra/api/responses.js +82 -0
- package/dist/aws/infra/api/responses.js.map +1 -0
- package/{aws → dist/aws}/infra/api/static-integration.d.ts +0 -0
- package/dist/aws/infra/api/static-integration.js +54 -0
- package/dist/aws/infra/api/static-integration.js.map +1 -0
- package/{aws → dist/aws}/infra/canaries/canary-alarm.d.ts +0 -0
- package/dist/aws/infra/canaries/canary-alarm.js +26 -0
- package/dist/aws/infra/canaries/canary-alarm.js.map +1 -0
- package/dist/aws/infra/canaries/canary-keys.d.ts +3 -0
- package/dist/aws/infra/canaries/canary-keys.js +7 -0
- package/dist/aws/infra/canaries/canary-keys.js.map +1 -0
- package/{aws → dist/aws}/infra/canaries/canary-parameters.d.ts +0 -0
- package/dist/aws/infra/canaries/canary-parameters.js +3 -0
- package/dist/aws/infra/canaries/canary-parameters.js.map +1 -0
- package/{aws → dist/aws}/infra/canaries/canary-role.d.ts +0 -0
- package/dist/aws/infra/canaries/canary-role.js +46 -0
- package/dist/aws/infra/canaries/canary-role.js.map +1 -0
- package/{aws → dist/aws}/infra/canaries/canary.d.ts +0 -0
- package/dist/aws/infra/canaries/canary.js +32 -0
- package/dist/aws/infra/canaries/canary.js.map +1 -0
- package/{aws → dist/aws}/infra/canaries/database-canary.d.ts +0 -0
- package/dist/aws/infra/canaries/database-canary.js +70 -0
- package/dist/aws/infra/canaries/database-canary.js.map +1 -0
- package/{aws → dist/aws}/infra/canaries/database-checker.d.ts +2 -2
- package/dist/aws/infra/canaries/database-checker.js +103 -0
- package/dist/aws/infra/canaries/database-checker.js.map +1 -0
- package/{aws → dist/aws}/infra/canaries/url-canary.d.ts +0 -3
- package/dist/aws/infra/canaries/url-canary.js +47 -0
- package/dist/aws/infra/canaries/url-canary.js.map +1 -0
- package/{aws → dist/aws}/infra/canaries/url-checker.d.ts +0 -0
- package/dist/aws/infra/canaries/url-checker.js +252 -0
- package/dist/aws/infra/canaries/url-checker.js.map +1 -0
- package/{aws → dist/aws}/infra/documentation.d.ts +0 -0
- package/dist/aws/infra/documentation.js +95 -0
- package/dist/aws/infra/documentation.js.map +1 -0
- package/{aws → dist/aws}/infra/scheduler.d.ts +7 -7
- package/dist/aws/infra/scheduler.js +31 -0
- package/dist/aws/infra/scheduler.js.map +1 -0
- package/{aws → dist/aws}/infra/security-rule.d.ts +0 -0
- package/dist/aws/infra/security-rule.js +39 -0
- package/dist/aws/infra/security-rule.js.map +1 -0
- package/{aws → dist/aws}/infra/sqs-integration.d.ts +0 -0
- package/dist/aws/infra/sqs-integration.js +93 -0
- package/dist/aws/infra/sqs-integration.js.map +1 -0
- package/{aws → dist/aws}/infra/sqs-queue.d.ts +0 -0
- package/dist/aws/infra/sqs-queue.js +130 -0
- package/dist/aws/infra/sqs-queue.js.map +1 -0
- package/{aws → dist/aws}/infra/stack/lambda-configs.d.ts +5 -5
- package/dist/aws/infra/stack/lambda-configs.js +105 -0
- package/dist/aws/infra/stack/lambda-configs.js.map +1 -0
- package/{aws → dist/aws}/infra/stack/monitoredfunction.d.ts +1 -1
- package/dist/aws/infra/stack/monitoredfunction.js +143 -0
- package/dist/aws/infra/stack/monitoredfunction.js.map +1 -0
- package/{aws → dist/aws}/infra/stack/rest_apis.d.ts +0 -0
- package/dist/aws/infra/stack/rest_apis.js +185 -0
- package/dist/aws/infra/stack/rest_apis.js.map +1 -0
- package/{aws → dist/aws}/infra/stack/stack-checking-aspect.d.ts +0 -0
- package/dist/aws/infra/stack/stack-checking-aspect.js +174 -0
- package/dist/aws/infra/stack/stack-checking-aspect.js.map +1 -0
- package/{aws → dist/aws}/infra/stack/stack.d.ts +5 -4
- package/dist/aws/infra/stack/stack.js +67 -0
- package/dist/aws/infra/stack/stack.js.map +1 -0
- package/{aws → dist/aws}/infra/stack/subscription.d.ts +3 -3
- package/dist/aws/infra/stack/subscription.js +42 -0
- package/dist/aws/infra/stack/subscription.js.map +1 -0
- package/{aws → dist/aws}/infra/usage-plans.d.ts +0 -0
- package/dist/aws/infra/usage-plans.js +42 -0
- package/dist/aws/infra/usage-plans.js.map +1 -0
- package/{aws → dist/aws}/runtime/apikey.d.ts +0 -0
- package/dist/aws/runtime/apikey.js +13 -0
- package/dist/aws/runtime/apikey.js.map +1 -0
- package/{aws → dist/aws}/runtime/digitraffic-integration-response.d.ts +0 -0
- package/dist/aws/runtime/digitraffic-integration-response.js +26 -0
- package/dist/aws/runtime/digitraffic-integration-response.js.map +1 -0
- package/{aws → dist/aws}/runtime/environment.d.ts +0 -0
- package/dist/aws/runtime/environment.js +12 -0
- package/dist/aws/runtime/environment.js.map +1 -0
- package/{aws → dist/aws}/runtime/messaging.d.ts +0 -0
- package/dist/aws/runtime/messaging.js +31 -0
- package/dist/aws/runtime/messaging.js.map +1 -0
- package/{aws → dist/aws}/runtime/s3.d.ts +0 -0
- package/dist/aws/runtime/s3.js +30 -0
- package/dist/aws/runtime/s3.js.map +1 -0
- package/{aws → dist/aws}/runtime/secrets/dbsecret.d.ts +0 -0
- package/dist/aws/runtime/secrets/dbsecret.js +96 -0
- package/dist/aws/runtime/secrets/dbsecret.js.map +1 -0
- package/{aws → dist/aws}/runtime/secrets/proxy-holder.d.ts +0 -0
- package/dist/aws/runtime/secrets/proxy-holder.js +27 -0
- package/dist/aws/runtime/secrets/proxy-holder.js.map +1 -0
- package/{aws → dist/aws}/runtime/secrets/rds-holder.d.ts +0 -0
- package/dist/aws/runtime/secrets/rds-holder.js +27 -0
- package/dist/aws/runtime/secrets/rds-holder.js.map +1 -0
- package/{aws → dist/aws}/runtime/secrets/secret-holder.d.ts +0 -0
- package/dist/aws/runtime/secrets/secret-holder.js +76 -0
- package/dist/aws/runtime/secrets/secret-holder.js.map +1 -0
- package/{aws → dist/aws}/runtime/secrets/secret.d.ts +0 -0
- package/dist/aws/runtime/secrets/secret.js +43 -0
- package/dist/aws/runtime/secrets/secret.js.map +1 -0
- package/{aws → dist/aws}/types/errors.d.ts +4 -0
- package/dist/aws/types/errors.js +16 -0
- package/dist/aws/types/errors.js.map +1 -0
- package/{aws → dist/aws}/types/lambda-response.d.ts +4 -3
- package/dist/aws/types/lambda-response.js +33 -0
- package/dist/aws/types/lambda-response.js.map +1 -0
- package/{aws → dist/aws}/types/mediatypes.d.ts +1 -1
- package/dist/aws/types/mediatypes.js +16 -0
- package/dist/aws/types/mediatypes.js.map +1 -0
- package/{aws → dist/aws}/types/model-with-reference.d.ts +0 -0
- package/dist/aws/types/model-with-reference.js +3 -0
- package/dist/aws/types/model-with-reference.js.map +1 -0
- package/{aws → dist/aws}/types/proxytypes.d.ts +0 -0
- package/dist/aws/types/proxytypes.js +3 -0
- package/dist/aws/types/proxytypes.js.map +1 -0
- package/{aws → dist/aws}/types/tags.d.ts +0 -0
- package/dist/aws/types/tags.js +7 -0
- package/dist/aws/types/tags.js.map +1 -0
- package/{database → dist/database}/cached.d.ts +0 -0
- package/dist/database/cached.js +32 -0
- package/dist/database/cached.js.map +1 -0
- package/{database → dist/database}/database.d.ts +0 -0
- package/dist/database/database.js +70 -0
- package/dist/database/database.js.map +1 -0
- package/{database → dist/database}/last-updated.d.ts +0 -0
- package/dist/database/last-updated.js +54 -0
- package/dist/database/last-updated.js.map +1 -0
- package/{database → dist/database}/models.d.ts +0 -0
- package/dist/database/models.js +3 -0
- package/dist/database/models.js.map +1 -0
- package/{marine → dist/marine}/id_utils.d.ts +0 -0
- package/dist/marine/id_utils.js +33 -0
- package/dist/marine/id_utils.js.map +1 -0
- package/{marine → dist/marine}/rtz.d.ts +0 -0
- package/dist/marine/rtz.js +3 -0
- package/dist/marine/rtz.js.map +1 -0
- package/{test → dist/test}/asserter.d.ts +0 -0
- package/dist/test/asserter.js +45 -0
- package/dist/test/asserter.js.map +1 -0
- package/{test → dist/test}/db-testutils.d.ts +0 -0
- package/dist/test/db-testutils.js +31 -0
- package/dist/test/db-testutils.js.map +1 -0
- package/{test → dist/test}/httpserver.d.ts +2 -1
- package/dist/test/httpserver.js +74 -0
- package/dist/test/httpserver.js.map +1 -0
- package/{test → dist/test}/secret.d.ts +0 -0
- package/dist/test/secret.js +25 -0
- package/dist/test/secret.js.map +1 -0
- package/{test → dist/test}/secrets-manager.d.ts +0 -0
- package/dist/test/secrets-manager.js +59 -0
- package/dist/test/secrets-manager.js.map +1 -0
- package/{test → dist/test}/testutils.d.ts +0 -0
- package/dist/test/testutils.js +44 -0
- package/dist/test/testutils.js.map +1 -0
- package/dist/types/either.d.ts +9 -0
- package/dist/types/either.js +3 -0
- package/dist/types/either.js.map +1 -0
- package/{types → dist/types}/input-error.d.ts +0 -0
- package/dist/types/input-error.js +7 -0
- package/dist/types/input-error.js.map +1 -0
- package/{types → dist/types}/language.d.ts +0 -0
- package/dist/types/language.js +10 -0
- package/dist/types/language.js.map +1 -0
- package/{types → dist/types}/traffictype.d.ts +0 -0
- package/dist/types/traffictype.js +13 -0
- package/dist/types/traffictype.js.map +1 -0
- package/{types → dist/types}/validator.d.ts +0 -0
- package/dist/types/validator.js +14 -0
- package/dist/types/validator.js.map +1 -0
- package/{utils → dist/utils}/api-model.d.ts +0 -0
- package/dist/utils/api-model.js +129 -0
- package/dist/utils/api-model.js.map +1 -0
- package/{utils → dist/utils}/base64.d.ts +0 -0
- package/dist/utils/base64.js +21 -0
- package/dist/utils/base64.js.map +1 -0
- package/{utils → dist/utils}/date-utils.d.ts +0 -0
- package/dist/utils/date-utils.js +34 -0
- package/dist/utils/date-utils.js.map +1 -0
- package/{utils → dist/utils}/geojson-types.d.ts +0 -0
- package/dist/utils/geojson-types.js +18 -0
- package/dist/utils/geojson-types.js.map +1 -0
- package/{utils → dist/utils}/geometry.d.ts +0 -0
- package/dist/utils/geometry.js +164 -0
- package/dist/utils/geometry.js.map +1 -0
- package/{utils → dist/utils}/retry.d.ts +0 -0
- package/dist/utils/retry.js +50 -0
- package/dist/utils/retry.js.map +1 -0
- package/{utils → dist/utils}/slack.d.ts +0 -0
- package/dist/utils/slack.js +25 -0
- package/dist/utils/slack.js.map +1 -0
- package/{utils → dist/utils}/utils.d.ts +16 -0
- package/dist/utils/utils.js +75 -0
- package/dist/utils/utils.js.map +1 -0
- package/package.json +12 -10
- package/src/@types/geojson-validation/index.d.ts +4 -0
- package/src/aws/infra/api/integration.ts +73 -0
- package/src/aws/infra/api/response.ts +67 -0
- package/src/aws/infra/api/responses.ts +124 -0
- package/src/aws/infra/api/static-integration.ts +62 -0
- package/src/aws/infra/canaries/canary-alarm.ts +31 -0
- package/src/aws/infra/canaries/canary-keys.ts +3 -0
- package/src/aws/infra/canaries/canary-parameters.ts +19 -0
- package/src/aws/infra/canaries/canary-role.ts +47 -0
- package/src/aws/infra/canaries/canary.ts +46 -0
- package/src/aws/infra/canaries/database-canary.ts +98 -0
- package/src/aws/infra/canaries/database-checker.ts +155 -0
- package/src/aws/infra/canaries/url-canary.ts +74 -0
- package/src/aws/infra/canaries/url-checker.ts +366 -0
- package/src/aws/infra/documentation.ts +124 -0
- package/src/aws/infra/scheduler.ts +59 -0
- package/src/aws/infra/security-rule.ts +38 -0
- package/src/aws/infra/sqs-integration.ts +102 -0
- package/src/aws/infra/sqs-queue.ts +148 -0
- package/src/aws/infra/stack/lambda-configs.ts +207 -0
- package/src/aws/infra/stack/monitoredfunction.ts +342 -0
- package/src/aws/infra/stack/rest_apis.ts +223 -0
- package/src/aws/infra/stack/stack-checking-aspect.ts +279 -0
- package/src/aws/infra/stack/stack.ts +145 -0
- package/src/aws/infra/stack/subscription.ts +58 -0
- package/src/aws/infra/usage-plans.ts +41 -0
- package/src/aws/runtime/apikey.ts +9 -0
- package/src/aws/runtime/digitraffic-integration-response.ts +28 -0
- package/src/aws/runtime/environment.ts +9 -0
- package/src/aws/runtime/messaging.ts +26 -0
- package/src/aws/runtime/s3.ts +44 -0
- package/src/aws/runtime/secrets/dbsecret.ts +116 -0
- package/src/aws/runtime/secrets/proxy-holder.ts +37 -0
- package/src/aws/runtime/secrets/rds-holder.ts +33 -0
- package/src/aws/runtime/secrets/secret-holder.ts +116 -0
- package/src/aws/runtime/secrets/secret.ts +50 -0
- package/src/aws/types/errors.ts +14 -0
- package/src/aws/types/lambda-response.ts +43 -0
- package/src/aws/types/mediatypes.ts +11 -0
- package/src/aws/types/model-with-reference.ts +8 -0
- package/src/aws/types/proxytypes.ts +27 -0
- package/src/aws/types/tags.ts +3 -0
- package/src/database/cached.ts +35 -0
- package/src/database/database.ts +96 -0
- package/src/database/last-updated.ts +59 -0
- package/src/database/models.ts +7 -0
- package/src/marine/id_utils.ts +30 -0
- package/src/marine/rtz.ts +57 -0
- package/src/test/asserter.ts +48 -0
- package/src/test/db-testutils.ts +44 -0
- package/src/test/httpserver.ts +96 -0
- package/src/test/secret.ts +23 -0
- package/src/test/secrets-manager.ts +34 -0
- package/src/test/testutils.ts +39 -0
- package/src/types/either.ts +3 -0
- package/src/types/input-error.ts +2 -0
- package/src/types/language.ts +3 -0
- package/src/types/traffictype.ts +8 -0
- package/src/types/validator.ts +10 -0
- package/src/utils/api-model.ts +133 -0
- package/src/utils/base64.ts +16 -0
- package/src/utils/date-utils.ts +30 -0
- package/src/utils/geojson-types.ts +22 -0
- package/src/utils/geometry.ts +164 -0
- package/src/utils/retry.ts +49 -0
- package/src/utils/slack.ts +22 -0
- package/src/utils/utils.ts +105 -0
- package/aws/infra/api/integration.js +0 -52
- package/aws/infra/api/response.js +0 -61
- package/aws/infra/api/responses.js +0 -79
- package/aws/infra/api/static-integration.js +0 -54
- package/aws/infra/canaries/canary-alarm.js +0 -26
- package/aws/infra/canaries/canary-parameters.js +0 -3
- package/aws/infra/canaries/canary-role.js +0 -46
- package/aws/infra/canaries/canary.js +0 -32
- package/aws/infra/canaries/database-canary.js +0 -55
- package/aws/infra/canaries/database-checker.js +0 -109
- package/aws/infra/canaries/url-canary.js +0 -46
- package/aws/infra/canaries/url-checker.js +0 -238
- package/aws/infra/documentation.js +0 -95
- package/aws/infra/scheduler.js +0 -31
- package/aws/infra/security-rule.js +0 -39
- package/aws/infra/sqs-integration.js +0 -93
- package/aws/infra/sqs-queue.js +0 -130
- package/aws/infra/stack/lambda-configs.js +0 -93
- package/aws/infra/stack/monitoredfunction.js +0 -135
- package/aws/infra/stack/rest_apis.js +0 -185
- package/aws/infra/stack/stack-checking-aspect.js +0 -174
- package/aws/infra/stack/stack.js +0 -60
- package/aws/infra/stack/subscription.js +0 -41
- package/aws/infra/usage-plans.js +0 -42
- package/aws/runtime/apikey.js +0 -13
- package/aws/runtime/digitraffic-integration-response.js +0 -26
- package/aws/runtime/environment.js +0 -12
- package/aws/runtime/messaging.js +0 -31
- package/aws/runtime/s3.js +0 -30
- package/aws/runtime/secrets/dbsecret.js +0 -96
- package/aws/runtime/secrets/proxy-holder.js +0 -26
- package/aws/runtime/secrets/rds-holder.js +0 -26
- package/aws/runtime/secrets/secret-holder.js +0 -73
- package/aws/runtime/secrets/secret.js +0 -43
- package/aws/types/errors.js +0 -9
- package/aws/types/lambda-response.js +0 -28
- package/aws/types/mediatypes.js +0 -15
- package/aws/types/model-with-reference.js +0 -3
- package/aws/types/proxytypes.js +0 -3
- package/aws/types/tags.js +0 -7
- package/database/cached.js +0 -32
- package/database/database.js +0 -62
- package/database/last-updated.js +0 -54
- package/database/models.js +0 -3
- package/index.d.ts +0 -1
- package/index.js +0 -18
- package/marine/id_utils.js +0 -33
- package/marine/rtz.js +0 -3
- package/test/asserter.js +0 -45
- package/test/db-testutils.js +0 -31
- package/test/httpserver.js +0 -67
- package/test/secret.js +0 -25
- package/test/secrets-manager.js +0 -59
- package/test/testutils.js +0 -44
- package/types/input-error.js +0 -7
- package/types/language.js +0 -10
- package/types/traffictype.js +0 -13
- package/types/validator.js +0 -14
- package/utils/api-model.js +0 -129
- package/utils/base64.js +0 -21
- package/utils/date-utils.js +0 -34
- package/utils/geojson-types.js +0 -18
- package/utils/geometry.js +0 -140
- package/utils/retry.js +0 -50
- package/utils/slack.js +0 -25
- package/utils/utils.js +0 -64
@@ -0,0 +1,342 @@
|
|
1
|
+
import { Function, FunctionProps } from "aws-cdk-lib/aws-lambda";
|
2
|
+
import { Stack } from "aws-cdk-lib";
|
3
|
+
import { SnsAction } from "aws-cdk-lib/aws-cloudwatch-actions";
|
4
|
+
import { ComparisonOperator, Metric } from "aws-cdk-lib/aws-cloudwatch";
|
5
|
+
import { DigitrafficStack } from "../stack/stack";
|
6
|
+
import { ITopic } from "aws-cdk-lib/aws-sns";
|
7
|
+
import {
|
8
|
+
databaseFunctionProps,
|
9
|
+
LambdaEnvironment,
|
10
|
+
MonitoredFunctionParameters,
|
11
|
+
} from "../stack/lambda-configs";
|
12
|
+
import { pascalCase } from "change-case";
|
13
|
+
import { DigitrafficLogSubscriptions } from "../stack/subscription";
|
14
|
+
import { TrafficType } from "../../../types/traffictype";
|
15
|
+
|
16
|
+
/**
|
17
|
+
* Allows customization of CloudWatch Alarm properties
|
18
|
+
*/
|
19
|
+
export type MonitoredFunctionAlarmProps = {
|
20
|
+
/**
|
21
|
+
* Setting this to false will not create a CloudWatch alarm
|
22
|
+
*/
|
23
|
+
readonly create: boolean;
|
24
|
+
|
25
|
+
readonly threshold?: number;
|
26
|
+
|
27
|
+
readonly evaluationPeriods?: number;
|
28
|
+
|
29
|
+
readonly datapointsToAlarm?: number;
|
30
|
+
|
31
|
+
readonly comparisonOperator?: ComparisonOperator;
|
32
|
+
};
|
33
|
+
|
34
|
+
export type MonitoredFunctionProps = {
|
35
|
+
readonly durationAlarmProps?: MonitoredFunctionAlarmProps;
|
36
|
+
|
37
|
+
readonly durationWarningProps?: MonitoredFunctionAlarmProps;
|
38
|
+
|
39
|
+
readonly errorAlarmProps?: MonitoredFunctionAlarmProps;
|
40
|
+
|
41
|
+
readonly throttleAlarmProps?: MonitoredFunctionAlarmProps;
|
42
|
+
};
|
43
|
+
|
44
|
+
/**
|
45
|
+
* Creates a Lambda function that monitors default CloudWatch Lambda metrics with CloudWatch Alarms.
|
46
|
+
*/
|
47
|
+
export class MonitoredFunction extends Function {
|
48
|
+
readonly givenName: string;
|
49
|
+
|
50
|
+
/** disable all alarms */
|
51
|
+
public static readonly DISABLE_ALARMS: MonitoredFunctionProps = {
|
52
|
+
durationAlarmProps: {
|
53
|
+
create: false,
|
54
|
+
},
|
55
|
+
durationWarningProps: {
|
56
|
+
create: false,
|
57
|
+
},
|
58
|
+
errorAlarmProps: {
|
59
|
+
create: false,
|
60
|
+
},
|
61
|
+
throttleAlarmProps: {
|
62
|
+
create: false,
|
63
|
+
},
|
64
|
+
};
|
65
|
+
|
66
|
+
/**
|
67
|
+
* Create new MonitoredFunction. Use topics from given DigitrafficStack.
|
68
|
+
*
|
69
|
+
* @param stack DigitrafficStack
|
70
|
+
* @param id Lambda construct Id
|
71
|
+
* @param functionProps Lambda function properties
|
72
|
+
* @param props Monitored function properties
|
73
|
+
*/
|
74
|
+
static create(
|
75
|
+
stack: DigitrafficStack,
|
76
|
+
id: string,
|
77
|
+
functionProps: FunctionProps,
|
78
|
+
props?: MonitoredFunctionProps
|
79
|
+
): MonitoredFunction {
|
80
|
+
if (
|
81
|
+
props === MonitoredFunction.DISABLE_ALARMS &&
|
82
|
+
stack.configuration.production
|
83
|
+
) {
|
84
|
+
throw new Error(
|
85
|
+
`Function ${functionProps.functionName} has DISABLE_ALARMS. Remove before installing to production or define your own properties!`
|
86
|
+
);
|
87
|
+
}
|
88
|
+
|
89
|
+
return new MonitoredFunction(
|
90
|
+
stack,
|
91
|
+
id,
|
92
|
+
functionProps,
|
93
|
+
stack.alarmTopic,
|
94
|
+
stack.warningTopic,
|
95
|
+
stack.configuration.production,
|
96
|
+
stack.configuration.trafficType,
|
97
|
+
props
|
98
|
+
);
|
99
|
+
}
|
100
|
+
|
101
|
+
/**
|
102
|
+
* Create new MonitoredFunction. Use topics from given DigitrafficStack. Generate names from given name and configuration shortName.
|
103
|
+
*
|
104
|
+
* 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.
|
105
|
+
*
|
106
|
+
* @param stack DigitrafficStack
|
107
|
+
* @param name param-case name
|
108
|
+
* @param environment Lambda environment
|
109
|
+
* @param functionParameters Lambda function parameters
|
110
|
+
*/
|
111
|
+
static createV2(
|
112
|
+
stack: DigitrafficStack,
|
113
|
+
name: string,
|
114
|
+
environment: LambdaEnvironment,
|
115
|
+
functionParameters?: MonitoredFunctionParameters
|
116
|
+
): MonitoredFunction {
|
117
|
+
const functionName =
|
118
|
+
functionParameters?.functionName ||
|
119
|
+
`${stack.configuration.shortName}-${pascalCase(name)}`;
|
120
|
+
const functionProps = databaseFunctionProps(
|
121
|
+
stack,
|
122
|
+
environment,
|
123
|
+
functionName,
|
124
|
+
name,
|
125
|
+
functionParameters
|
126
|
+
);
|
127
|
+
|
128
|
+
return MonitoredFunction.create(
|
129
|
+
stack,
|
130
|
+
functionName,
|
131
|
+
functionProps,
|
132
|
+
functionParameters
|
133
|
+
);
|
134
|
+
}
|
135
|
+
|
136
|
+
/**
|
137
|
+
* @param scope Stack
|
138
|
+
* @param id Lambda construct Id
|
139
|
+
* @param functionProps Lambda function properties
|
140
|
+
* @param alarmSnsTopic SNS topic for alarms
|
141
|
+
* @param warningSnsTopic SNS topic for warnings
|
142
|
+
* @param production Is the stack a production stack, used for determining the alarm topic
|
143
|
+
* @param trafficType Traffic type, used for alarm names. Set to null if Lambda is not related to any traffic type.
|
144
|
+
* @param props Monitored function properties
|
145
|
+
*/
|
146
|
+
constructor(
|
147
|
+
scope: Stack,
|
148
|
+
id: string,
|
149
|
+
functionProps: FunctionProps,
|
150
|
+
alarmSnsTopic: ITopic,
|
151
|
+
warningSnsTopic: ITopic,
|
152
|
+
production: boolean,
|
153
|
+
trafficType: TrafficType | null,
|
154
|
+
props?: MonitoredFunctionProps
|
155
|
+
) {
|
156
|
+
super(scope, id, functionProps);
|
157
|
+
|
158
|
+
if (functionProps.functionName === undefined) {
|
159
|
+
throw new Error("Function name not provided");
|
160
|
+
}
|
161
|
+
this.givenName = functionProps.functionName;
|
162
|
+
|
163
|
+
const alarmSnsAction = new SnsAction(alarmSnsTopic);
|
164
|
+
const warningSnsAction = new SnsAction(warningSnsTopic);
|
165
|
+
|
166
|
+
if (props?.durationAlarmProps?.create !== false) {
|
167
|
+
if (!functionProps.timeout) {
|
168
|
+
throw new Error("Timeout needs to be explicitly set");
|
169
|
+
}
|
170
|
+
|
171
|
+
this.createAlarm(
|
172
|
+
scope,
|
173
|
+
this.metricDuration().with({ statistic: "max" }),
|
174
|
+
"Duration",
|
175
|
+
"Duration alarm",
|
176
|
+
`Duration has exceeded ${functionProps.timeout.toSeconds()} seconds`,
|
177
|
+
trafficType,
|
178
|
+
this.getAlarmActionForEnv(
|
179
|
+
alarmSnsAction,
|
180
|
+
warningSnsAction,
|
181
|
+
production
|
182
|
+
),
|
183
|
+
functionProps.timeout.toMilliseconds(),
|
184
|
+
1,
|
185
|
+
1,
|
186
|
+
ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
|
187
|
+
props?.durationAlarmProps
|
188
|
+
);
|
189
|
+
}
|
190
|
+
if (props?.durationWarningProps?.create !== false) {
|
191
|
+
if (!functionProps.timeout) {
|
192
|
+
throw new Error("Timeout needs to be explicitly set");
|
193
|
+
}
|
194
|
+
|
195
|
+
this.createAlarm(
|
196
|
+
scope,
|
197
|
+
this.metricDuration().with({ statistic: "max" }),
|
198
|
+
"Duration-Warning",
|
199
|
+
"Duration warning",
|
200
|
+
`Duration is 85 % of max ${functionProps.timeout.toSeconds()} seconds`,
|
201
|
+
trafficType,
|
202
|
+
warningSnsAction,
|
203
|
+
functionProps.timeout.toMilliseconds() * 0.85,
|
204
|
+
1,
|
205
|
+
1,
|
206
|
+
ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
|
207
|
+
props?.durationWarningProps
|
208
|
+
);
|
209
|
+
}
|
210
|
+
|
211
|
+
if (props?.errorAlarmProps?.create !== false) {
|
212
|
+
this.createAlarm(
|
213
|
+
scope,
|
214
|
+
this.metricErrors(),
|
215
|
+
"Errors",
|
216
|
+
"Errors alarm",
|
217
|
+
"Invocations did not succeed",
|
218
|
+
trafficType,
|
219
|
+
this.getAlarmActionForEnv(
|
220
|
+
alarmSnsAction,
|
221
|
+
warningSnsAction,
|
222
|
+
production
|
223
|
+
),
|
224
|
+
1,
|
225
|
+
1,
|
226
|
+
1,
|
227
|
+
ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
|
228
|
+
props?.errorAlarmProps
|
229
|
+
);
|
230
|
+
}
|
231
|
+
|
232
|
+
if (props?.throttleAlarmProps?.create !== false) {
|
233
|
+
this.createAlarm(
|
234
|
+
scope,
|
235
|
+
this.metricThrottles(),
|
236
|
+
"Throttles",
|
237
|
+
"Throttles alarm",
|
238
|
+
"Has throttled",
|
239
|
+
trafficType,
|
240
|
+
this.getAlarmActionForEnv(
|
241
|
+
alarmSnsAction,
|
242
|
+
warningSnsAction,
|
243
|
+
production
|
244
|
+
),
|
245
|
+
0,
|
246
|
+
1,
|
247
|
+
1,
|
248
|
+
ComparisonOperator.GREATER_THAN_THRESHOLD,
|
249
|
+
props?.throttleAlarmProps
|
250
|
+
);
|
251
|
+
}
|
252
|
+
}
|
253
|
+
|
254
|
+
private createAlarm(
|
255
|
+
stack: Stack,
|
256
|
+
metric: Metric,
|
257
|
+
alarmId: string,
|
258
|
+
alarmName: string,
|
259
|
+
alarmDescription: string,
|
260
|
+
trafficType: TrafficType | null,
|
261
|
+
alarmSnsAction: SnsAction,
|
262
|
+
threshold: number,
|
263
|
+
evaluationPeriods: number,
|
264
|
+
datapointsToAlarm: number,
|
265
|
+
comparisonOperator: ComparisonOperator,
|
266
|
+
alarmProps?: MonitoredFunctionAlarmProps
|
267
|
+
) {
|
268
|
+
metric
|
269
|
+
.createAlarm(stack, `${this.node.id}-${alarmId}`, {
|
270
|
+
alarmName: `${trafficType ?? ""} ${stack.stackName} ${
|
271
|
+
this.functionName
|
272
|
+
} ${alarmName}`.trim(),
|
273
|
+
alarmDescription,
|
274
|
+
threshold: alarmProps?.threshold ?? threshold,
|
275
|
+
evaluationPeriods:
|
276
|
+
alarmProps?.evaluationPeriods ?? evaluationPeriods,
|
277
|
+
datapointsToAlarm:
|
278
|
+
alarmProps?.datapointsToAlarm ?? datapointsToAlarm,
|
279
|
+
comparisonOperator:
|
280
|
+
alarmProps?.comparisonOperator ?? comparisonOperator,
|
281
|
+
})
|
282
|
+
.addAlarmAction(alarmSnsAction);
|
283
|
+
}
|
284
|
+
|
285
|
+
private getAlarmActionForEnv(
|
286
|
+
alarmAction: SnsAction,
|
287
|
+
warningAction: SnsAction,
|
288
|
+
production: boolean
|
289
|
+
): SnsAction {
|
290
|
+
return production ? alarmAction : warningAction;
|
291
|
+
}
|
292
|
+
}
|
293
|
+
|
294
|
+
export class MonitoredDBFunction {
|
295
|
+
/**
|
296
|
+
* Create new MonitoredDBFunction. Use topics from given DigitrafficStack. Generate names from given name and configuration shortName.
|
297
|
+
* Grant secret and create log subscription.
|
298
|
+
*
|
299
|
+
* 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.
|
300
|
+
*
|
301
|
+
* If you don't need to pass any extra arguments to lambda-environment, you can leave environment out and this function will create the
|
302
|
+
* default Lambda Environment with SECRET_ID and DB_APPLICATION.
|
303
|
+
*
|
304
|
+
* @param stack DigitrafficStack
|
305
|
+
* @param name param-case name
|
306
|
+
* @param environment Lambda environment
|
307
|
+
* @param functionParameters Lambda function parameters
|
308
|
+
*/
|
309
|
+
static create(
|
310
|
+
stack: DigitrafficStack,
|
311
|
+
name: string,
|
312
|
+
environment?: LambdaEnvironment,
|
313
|
+
functionParameters?: MonitoredFunctionParameters
|
314
|
+
): MonitoredFunction {
|
315
|
+
const functionName =
|
316
|
+
functionParameters?.functionName ||
|
317
|
+
`${stack.configuration.shortName}-${pascalCase(name)}`;
|
318
|
+
const env = environment ? environment : stack.createLambdaEnvironment();
|
319
|
+
const functionProps = databaseFunctionProps(
|
320
|
+
stack,
|
321
|
+
env,
|
322
|
+
functionName,
|
323
|
+
name,
|
324
|
+
functionParameters
|
325
|
+
);
|
326
|
+
|
327
|
+
const mf = MonitoredFunction.create(
|
328
|
+
stack,
|
329
|
+
functionName,
|
330
|
+
functionProps,
|
331
|
+
functionParameters
|
332
|
+
);
|
333
|
+
|
334
|
+
stack.grantSecret(mf);
|
335
|
+
|
336
|
+
if (stack.configuration.logsDestinationArn) {
|
337
|
+
new DigitrafficLogSubscriptions(stack, mf);
|
338
|
+
}
|
339
|
+
|
340
|
+
return mf;
|
341
|
+
}
|
342
|
+
}
|
@@ -0,0 +1,223 @@
|
|
1
|
+
import {
|
2
|
+
RestApi,
|
3
|
+
MethodLoggingLevel,
|
4
|
+
GatewayResponse,
|
5
|
+
ResponseType,
|
6
|
+
EndpointType,
|
7
|
+
RestApiProps, JsonSchema, Model, CfnDocumentationPart, Resource,
|
8
|
+
} from 'aws-cdk-lib/aws-apigateway';
|
9
|
+
import {PolicyDocument, PolicyStatement, Effect, AnyPrincipal} from 'aws-cdk-lib/aws-iam';
|
10
|
+
import {Construct} from "constructs";
|
11
|
+
import {DigitrafficStack} from "./stack";
|
12
|
+
import {createDefaultUsagePlan, createUsagePlan} from "../usage-plans";
|
13
|
+
import {ModelWithReference} from "../../types/model-with-reference";
|
14
|
+
import {getModelReference} from "../../../utils/api-model";
|
15
|
+
import {MediaType} from "../../types/mediatypes";
|
16
|
+
import {DocumentationPart, DocumentationProperties} from "../documentation";
|
17
|
+
|
18
|
+
import R = require('ramda');
|
19
|
+
|
20
|
+
export class DigitrafficRestApi extends RestApi {
|
21
|
+
readonly apiKeyIds: string[];
|
22
|
+
readonly enableDocumentation: boolean;
|
23
|
+
|
24
|
+
constructor(
|
25
|
+
stack: DigitrafficStack, apiId: string, apiName: string, allowFromIpAddresses?: string[] | undefined, config?: Partial<RestApiProps>,
|
26
|
+
) {
|
27
|
+
const policyDocument = allowFromIpAddresses == null ? createDefaultPolicyDocument() : createIpRestrictionPolicyDocument(allowFromIpAddresses);
|
28
|
+
|
29
|
+
// override default config with given extra config
|
30
|
+
const apiConfig = {...{
|
31
|
+
deployOptions: {
|
32
|
+
loggingLevel: MethodLoggingLevel.ERROR,
|
33
|
+
},
|
34
|
+
restApiName: apiName,
|
35
|
+
endpointTypes: [EndpointType.REGIONAL],
|
36
|
+
policy: policyDocument,
|
37
|
+
}, ...config};
|
38
|
+
|
39
|
+
super(stack, apiId, apiConfig);
|
40
|
+
|
41
|
+
this.apiKeyIds = [];
|
42
|
+
this.enableDocumentation = stack.configuration.stackFeatures?.enableDocumentation ?? true;
|
43
|
+
|
44
|
+
add404Support(this, stack);
|
45
|
+
}
|
46
|
+
|
47
|
+
hostname(): string {
|
48
|
+
return `${this.restApiId}.execute-api.${(this.stack as DigitrafficStack).region}.amazonaws.com`;
|
49
|
+
}
|
50
|
+
|
51
|
+
createUsagePlan(apiKeyId: string, apiKeyName: string): string {
|
52
|
+
const newKeyId = createUsagePlan(this, apiKeyId, apiKeyName).keyId;
|
53
|
+
|
54
|
+
this.apiKeyIds.push(newKeyId);
|
55
|
+
|
56
|
+
return newKeyId;
|
57
|
+
}
|
58
|
+
|
59
|
+
createUsagePlanV2(apiName: string): string {
|
60
|
+
const newKeyId = createDefaultUsagePlan(this, apiName).keyId;
|
61
|
+
|
62
|
+
this.apiKeyIds.push(newKeyId);
|
63
|
+
|
64
|
+
return newKeyId;
|
65
|
+
}
|
66
|
+
|
67
|
+
addJsonModel(modelName: string, schema: JsonSchema) {
|
68
|
+
return this.getModelWithReference(this.addModel(modelName, {
|
69
|
+
contentType: MediaType.APPLICATION_JSON,
|
70
|
+
modelName,
|
71
|
+
schema,
|
72
|
+
}));
|
73
|
+
}
|
74
|
+
|
75
|
+
addCSVModel(modelName: string) {
|
76
|
+
return this.getModelWithReference(this.addModel(modelName, {
|
77
|
+
contentType: MediaType.TEXT_CSV,
|
78
|
+
modelName,
|
79
|
+
schema: {},
|
80
|
+
}));
|
81
|
+
}
|
82
|
+
|
83
|
+
private getModelWithReference(model: Model): ModelWithReference {
|
84
|
+
return R.assoc('modelReference', getModelReference(model.modelId, this.restApiId), model) as ModelWithReference;
|
85
|
+
}
|
86
|
+
|
87
|
+
private addDocumentationPart(
|
88
|
+
resource: Resource, parameterName: string, resourceName: string, type: string, properties: DocumentationProperties,
|
89
|
+
) {
|
90
|
+
const location: CfnDocumentationPart.LocationProperty = {
|
91
|
+
type,
|
92
|
+
path: resource.path,
|
93
|
+
name: type !== 'METHOD' ? parameterName : undefined,
|
94
|
+
};
|
95
|
+
|
96
|
+
new CfnDocumentationPart(this.stack, resourceName, {
|
97
|
+
restApiId: resource.api.restApiId,
|
98
|
+
location,
|
99
|
+
properties: JSON.stringify(properties),
|
100
|
+
});
|
101
|
+
}
|
102
|
+
|
103
|
+
documentResource(resource: Resource, ...documentationPart: DocumentationPart[]) {
|
104
|
+
if(this.enableDocumentation) {
|
105
|
+
documentationPart.forEach(dp => this.addDocumentationPart(
|
106
|
+
resource, dp.parameterName, `${resource.path}.${dp.parameterName}.Documentation`, dp.type, dp.documentationProperties,
|
107
|
+
));
|
108
|
+
} else {
|
109
|
+
console.info("Skipping documentation for %s", resource.path);
|
110
|
+
}
|
111
|
+
}
|
112
|
+
}
|
113
|
+
|
114
|
+
/**
|
115
|
+
* Due to AWS API design API Gateway will always return 403 'Missing Authentication Token' for requests
|
116
|
+
* with a non-existent endpoint. This function translates this response to a 404.
|
117
|
+
* Requests with an invalid or missing API key are not affected (still return 403 'Forbidden').
|
118
|
+
* @param restApi RestApi
|
119
|
+
* @param stack Construct
|
120
|
+
*/
|
121
|
+
export function add404Support(restApi: RestApi, stack: Construct) {
|
122
|
+
new GatewayResponse(stack, `MissingAuthenticationTokenResponse-${restApi.restApiName}`, {
|
123
|
+
restApi,
|
124
|
+
type: ResponseType.MISSING_AUTHENTICATION_TOKEN,
|
125
|
+
statusCode: '404',
|
126
|
+
templates: {
|
127
|
+
'application/json': '{"message": "Not found"}',
|
128
|
+
},
|
129
|
+
});
|
130
|
+
}
|
131
|
+
|
132
|
+
export function add401Support(restApi: RestApi, stack: Construct) {
|
133
|
+
new GatewayResponse(stack, `AuthenticationFailedResponse-${restApi.restApiName}`, {
|
134
|
+
restApi,
|
135
|
+
type: ResponseType.UNAUTHORIZED,
|
136
|
+
statusCode: "401",
|
137
|
+
responseHeaders: {
|
138
|
+
'WWW-Authenticate': "'Basic'",
|
139
|
+
},
|
140
|
+
});
|
141
|
+
}
|
142
|
+
|
143
|
+
/**
|
144
|
+
* Due to AWS API design API Gateway will always return 403 'Missing Authentication Token' for requests
|
145
|
+
* with a non-existent endpoint. This function converts this response to a custom one.
|
146
|
+
* Requests with an invalid or missing API key are not affected (still return 403 'Forbidden').
|
147
|
+
* @param returnCode
|
148
|
+
* @param message
|
149
|
+
* @param restApi RestApi
|
150
|
+
* @param stack Construct
|
151
|
+
*/
|
152
|
+
export function setReturnCodeForMissingAuthenticationToken(returnCode: number,
|
153
|
+
message: string,
|
154
|
+
restApi: RestApi,
|
155
|
+
stack: Construct) {
|
156
|
+
|
157
|
+
new GatewayResponse(stack, `MissingAuthenticationTokenResponse-${restApi.restApiName}`, {
|
158
|
+
restApi,
|
159
|
+
type: ResponseType.MISSING_AUTHENTICATION_TOKEN,
|
160
|
+
statusCode: `${returnCode}`,
|
161
|
+
templates: {
|
162
|
+
'application/json': `{"message": ${message}}`,
|
163
|
+
},
|
164
|
+
});
|
165
|
+
}
|
166
|
+
|
167
|
+
export function createRestApi(stack: Construct, apiId: string, apiName: string, allowFromIpAddresses?: string[] | undefined): RestApi {
|
168
|
+
const policyDocument = allowFromIpAddresses == null ? createDefaultPolicyDocument() : createIpRestrictionPolicyDocument(allowFromIpAddresses);
|
169
|
+
const restApi = new RestApi(stack, apiId, {
|
170
|
+
deployOptions: {
|
171
|
+
loggingLevel: MethodLoggingLevel.ERROR,
|
172
|
+
},
|
173
|
+
restApiName: apiName,
|
174
|
+
endpointTypes: [EndpointType.REGIONAL],
|
175
|
+
policy: policyDocument,
|
176
|
+
});
|
177
|
+
add404Support(restApi, stack);
|
178
|
+
return restApi;
|
179
|
+
}
|
180
|
+
|
181
|
+
export function createDefaultPolicyDocument() {
|
182
|
+
return new PolicyDocument({
|
183
|
+
statements: [
|
184
|
+
new PolicyStatement({
|
185
|
+
effect: Effect.ALLOW,
|
186
|
+
actions: [
|
187
|
+
"execute-api:Invoke",
|
188
|
+
],
|
189
|
+
resources: [
|
190
|
+
"*",
|
191
|
+
],
|
192
|
+
principals: [
|
193
|
+
new AnyPrincipal(),
|
194
|
+
],
|
195
|
+
}),
|
196
|
+
],
|
197
|
+
});
|
198
|
+
}
|
199
|
+
|
200
|
+
|
201
|
+
export function createIpRestrictionPolicyDocument(allowFromIpAddresses: string[]): PolicyDocument {
|
202
|
+
return new PolicyDocument({
|
203
|
+
statements: [
|
204
|
+
new PolicyStatement({
|
205
|
+
effect: Effect.ALLOW,
|
206
|
+
conditions: {
|
207
|
+
"IpAddress": {
|
208
|
+
"aws:SourceIp": allowFromIpAddresses,
|
209
|
+
},
|
210
|
+
},
|
211
|
+
actions: [
|
212
|
+
"execute-api:Invoke",
|
213
|
+
],
|
214
|
+
resources: [
|
215
|
+
"*",
|
216
|
+
],
|
217
|
+
principals: [
|
218
|
+
new AnyPrincipal(),
|
219
|
+
],
|
220
|
+
}),
|
221
|
+
],
|
222
|
+
});
|
223
|
+
}
|