@digitraffic/common 2023.12.15-1 → 2024.1.19-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/dist/aws/infra/api/handler-factory.d.ts +2 -2
- package/dist/aws/infra/api/handler-factory.js +4 -9
- package/dist/aws/infra/api/integration.d.ts +1 -1
- package/dist/aws/infra/api/integration.js +9 -13
- package/dist/aws/infra/api/response.d.ts +2 -3
- package/dist/aws/infra/api/response.js +25 -30
- package/dist/aws/infra/api/responses.d.ts +2 -3
- package/dist/aws/infra/api/responses.js +25 -31
- package/dist/aws/infra/api/static-integration.d.ts +1 -1
- package/dist/aws/infra/api/static-integration.js +7 -11
- package/dist/aws/infra/canaries/canary-alarm.d.ts +1 -1
- package/dist/aws/infra/canaries/canary-alarm.js +7 -11
- package/dist/aws/infra/canaries/canary-keys.js +3 -6
- package/dist/aws/infra/canaries/canary-parameters.js +1 -2
- package/dist/aws/infra/canaries/canary-role.js +8 -12
- package/dist/aws/infra/canaries/canary.d.ts +2 -2
- package/dist/aws/infra/canaries/canary.js +9 -13
- package/dist/aws/infra/canaries/database-canary.d.ts +3 -3
- package/dist/aws/infra/canaries/database-canary.js +8 -12
- package/dist/aws/infra/canaries/database-checker.d.ts +1 -1
- package/dist/aws/infra/canaries/database-checker.js +10 -14
- package/dist/aws/infra/canaries/url-canary.d.ts +4 -4
- package/dist/aws/infra/canaries/url-canary.js +8 -12
- package/dist/aws/infra/canaries/url-checker.d.ts +2 -2
- package/dist/aws/infra/canaries/url-checker.js +33 -40
- package/dist/aws/infra/documentation.js +8 -16
- package/dist/aws/infra/import-util.js +10 -18
- package/dist/aws/infra/scheduler.js +10 -14
- package/dist/aws/infra/security-rule.js +4 -8
- package/dist/aws/infra/sqs-integration.d.ts +1 -2
- package/dist/aws/infra/sqs-integration.js +11 -15
- package/dist/aws/infra/sqs-queue.d.ts +1 -1
- package/dist/aws/infra/sqs-queue.js +51 -50
- package/dist/aws/infra/stack/lambda-configs.d.ts +2 -2
- package/dist/aws/infra/stack/lambda-configs.js +14 -20
- package/dist/aws/infra/stack/monitoredfunction.d.ts +3 -3
- package/dist/aws/infra/stack/monitoredfunction.js +19 -27
- package/dist/aws/infra/stack/parameters.d.ts +1 -1
- package/dist/aws/infra/stack/parameters.js +5 -10
- package/dist/aws/infra/stack/rest_apis.d.ts +3 -3
- package/dist/aws/infra/stack/rest_apis.js +41 -54
- package/dist/aws/infra/stack/stack-checking-aspect.d.ts +1 -1
- package/dist/aws/infra/stack/stack-checking-aspect.js +28 -39
- package/dist/aws/infra/stack/stack.d.ts +5 -6
- package/dist/aws/infra/stack/stack.js +16 -20
- package/dist/aws/infra/stack/subscription.d.ts +2 -2
- package/dist/aws/infra/stack/subscription.js +5 -10
- package/dist/aws/infra/stacks/db-dns-stack.d.ts +2 -2
- package/dist/aws/infra/stacks/db-dns-stack.js +25 -29
- package/dist/aws/infra/stacks/db-proxy-stack.d.ts +2 -2
- package/dist/aws/infra/stacks/db-proxy-stack.js +23 -27
- package/dist/aws/infra/stacks/db-stack.d.ts +3 -4
- package/dist/aws/infra/stacks/db-stack.js +30 -34
- package/dist/aws/infra/stacks/intra-stack-configuration.js +1 -2
- package/dist/aws/infra/stacks/network-stack.d.ts +2 -2
- package/dist/aws/infra/stacks/network-stack.js +15 -19
- package/dist/aws/infra/usage-plans.js +2 -7
- package/dist/aws/runtime/apikey.js +3 -7
- package/dist/aws/runtime/digitraffic-integration-response.d.ts +1 -1
- package/dist/aws/runtime/digitraffic-integration-response.js +7 -11
- package/dist/aws/runtime/dt-logger-default.d.ts +2 -2
- package/dist/aws/runtime/dt-logger-default.js +2 -5
- package/dist/aws/runtime/dt-logger.d.ts +1 -1
- package/dist/aws/runtime/dt-logger.js +3 -10
- package/dist/aws/runtime/environment.js +3 -7
- package/dist/aws/runtime/messaging.js +1 -5
- package/dist/aws/runtime/s3.js +3 -7
- package/dist/aws/runtime/secrets/dbsecret.d.ts +1 -1
- package/dist/aws/runtime/secrets/dbsecret.js +5 -9
- package/dist/aws/runtime/secrets/proxy-holder.js +12 -16
- package/dist/aws/runtime/secrets/rds-holder.js +12 -16
- package/dist/aws/runtime/secrets/secret-holder.d.ts +1 -1
- package/dist/aws/runtime/secrets/secret-holder.js +9 -13
- package/dist/aws/runtime/secrets/secret.js +7 -11
- package/dist/aws/types/errors.js +5 -9
- package/dist/aws/types/lambda-response.js +3 -10
- package/dist/aws/types/mediatypes.js +2 -5
- package/dist/aws/types/model-with-reference.js +1 -2
- package/dist/aws/types/proxytypes.js +1 -2
- package/dist/aws/types/tags.js +2 -5
- package/dist/database/cached.d.ts +1 -1
- package/dist/database/cached.js +8 -14
- package/dist/database/database.js +14 -21
- package/dist/database/last-updated.d.ts +1 -1
- package/dist/database/last-updated.js +8 -17
- package/dist/database/models.js +1 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.js +2 -0
- package/dist/marine/id_utils.js +3 -9
- package/dist/marine/rtz.js +1 -2
- package/dist/test/asserter.js +1 -5
- package/dist/test/db-testutils.d.ts +1 -1
- package/dist/test/db-testutils.js +8 -13
- package/dist/test/httpserver.d.ts +1 -1
- package/dist/test/httpserver.js +19 -18
- package/dist/test/secrets-manager.js +9 -35
- package/dist/test/testutils.js +8 -19
- package/dist/types/async-timeout-error.js +1 -5
- package/dist/types/aws-env.js +1 -2
- package/dist/types/either.js +1 -2
- package/dist/types/http-error.js +1 -5
- package/dist/types/input-error.js +1 -5
- package/dist/types/language.js +2 -5
- package/dist/types/nullable.d.ts +1 -1
- package/dist/types/nullable.js +1 -2
- package/dist/types/traffictype.js +2 -5
- package/dist/types/urn.js +1 -2
- package/dist/types/util-types.js +1 -2
- package/dist/types/validator.js +4 -9
- package/dist/utils/api-model.d.ts +1 -1
- package/dist/utils/api-model.js +17 -27
- package/dist/utils/base64.d.ts +1 -1
- package/dist/utils/base64.js +2 -7
- package/dist/utils/date-utils.js +9 -16
- package/dist/utils/geojson-types.js +2 -7
- package/dist/utils/geometry.js +15 -48
- package/dist/utils/logging.d.ts +1 -1
- package/dist/utils/logging.js +8 -13
- package/dist/utils/retry.js +21 -26
- package/dist/utils/slack.js +7 -14
- package/dist/utils/utils.d.ts +2 -2
- package/dist/utils/utils.js +14 -29
- package/package.json +127 -41
- package/src/aws/infra/api/handler-factory.ts +3 -3
- package/src/aws/infra/api/integration.ts +2 -2
- package/src/aws/infra/api/response.ts +3 -3
- package/src/aws/infra/api/responses.ts +4 -4
- package/src/aws/infra/api/static-integration.ts +2 -2
- package/src/aws/infra/canaries/canary-alarm.ts +1 -1
- package/src/aws/infra/canaries/canary.ts +3 -3
- package/src/aws/infra/canaries/database-canary.ts +3 -3
- package/src/aws/infra/canaries/database-checker.ts +6 -6
- package/src/aws/infra/canaries/url-canary.ts +6 -6
- package/src/aws/infra/canaries/url-checker.ts +8 -8
- package/src/aws/infra/sqs-integration.ts +1 -1
- package/src/aws/infra/sqs-queue.ts +29 -44
- package/src/aws/infra/stack/lambda-configs.ts +9 -9
- package/src/aws/infra/stack/monitoredfunction.ts +4 -4
- package/src/aws/infra/stack/parameters.ts +1 -1
- package/src/aws/infra/stack/rest_apis.ts +6 -6
- package/src/aws/infra/stack/stack-checking-aspect.ts +20 -72
- package/src/aws/infra/stack/stack.ts +4 -5
- package/src/aws/infra/stack/subscription.ts +2 -2
- package/src/aws/infra/stacks/db-dns-stack.ts +4 -4
- package/src/aws/infra/stacks/db-proxy-stack.ts +5 -5
- package/src/aws/infra/stacks/db-stack.ts +5 -5
- package/src/aws/infra/stacks/network-stack.ts +3 -3
- package/src/aws/runtime/digitraffic-integration-response.ts +2 -2
- package/src/aws/runtime/dt-logger-default.ts +2 -2
- package/src/aws/runtime/secrets/dbsecret.ts +1 -1
- package/src/aws/runtime/secrets/proxy-holder.ts +4 -4
- package/src/aws/runtime/secrets/rds-holder.ts +4 -4
- package/src/aws/runtime/secrets/secret-holder.ts +4 -4
- package/src/aws/runtime/secrets/secret.ts +2 -2
- package/src/database/cached.ts +1 -1
- package/src/database/database.ts +3 -3
- package/src/database/last-updated.ts +1 -1
- package/src/index.ts +2 -0
- package/src/test/db-testutils.ts +2 -2
- package/src/test/httpserver.ts +13 -7
- package/src/test/secrets-manager.ts +2 -2
- package/src/types/nullable.ts +1 -1
- package/src/utils/api-model.ts +1 -1
- package/src/utils/geometry.ts +5 -3
- package/src/utils/logging.ts +2 -2
- package/src/utils/retry.ts +3 -3
- package/src/utils/slack.ts +2 -2
- package/src/utils/utils.ts +3 -3
@@ -1,16 +1,10 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
};
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
|
9
|
-
const api_model_1 = require("../../../utils/api-model");
|
10
|
-
const mediatypes_1 = require("../../types/mediatypes");
|
11
|
-
const usage_plans_1 = require("../usage-plans");
|
12
|
-
const lodash_1 = __importDefault(require("lodash"));
|
13
|
-
class DigitrafficRestApi extends aws_apigateway_1.RestApi {
|
1
|
+
import { CfnDocumentationPart, EndpointType, GatewayResponse, MethodLoggingLevel, MockIntegration, ResponseType, RestApi, } from "aws-cdk-lib/aws-apigateway";
|
2
|
+
import { AnyPrincipal, Effect, PolicyDocument, PolicyStatement, } from "aws-cdk-lib/aws-iam";
|
3
|
+
import { getModelReference } from "../../../utils/api-model.js";
|
4
|
+
import { MediaType } from "../../types/mediatypes.js";
|
5
|
+
import { createDefaultUsagePlan, createUsagePlan } from "../usage-plans.js";
|
6
|
+
import _ from "lodash";
|
7
|
+
export class DigitrafficRestApi extends RestApi {
|
14
8
|
constructor(stack, apiId, apiName, allowFromIpAddresses, config) {
|
15
9
|
const policyDocument = allowFromIpAddresses == null
|
16
10
|
? createDefaultPolicyDocument()
|
@@ -19,10 +13,10 @@ class DigitrafficRestApi extends aws_apigateway_1.RestApi {
|
|
19
13
|
const apiConfig = {
|
20
14
|
...{
|
21
15
|
deployOptions: {
|
22
|
-
loggingLevel:
|
16
|
+
loggingLevel: MethodLoggingLevel.ERROR,
|
23
17
|
},
|
24
18
|
restApiName: apiName,
|
25
|
-
endpointTypes: [
|
19
|
+
endpointTypes: [EndpointType.REGIONAL],
|
26
20
|
policy: policyDocument,
|
27
21
|
},
|
28
22
|
...config,
|
@@ -37,31 +31,31 @@ class DigitrafficRestApi extends aws_apigateway_1.RestApi {
|
|
37
31
|
return `${this.restApiId}.execute-api.${this.stack.region}.amazonaws.com`;
|
38
32
|
}
|
39
33
|
createUsagePlan(apiKeyId, apiKeyName) {
|
40
|
-
const newKeyId =
|
34
|
+
const newKeyId = createUsagePlan(this, apiKeyId, apiKeyName).keyId;
|
41
35
|
this.apiKeyIds.push(newKeyId);
|
42
36
|
return newKeyId;
|
43
37
|
}
|
44
38
|
createUsagePlanV2(apiName, apiKey) {
|
45
|
-
const newKeyId =
|
39
|
+
const newKeyId = createDefaultUsagePlan(this, apiName, apiKey).keyId;
|
46
40
|
this.apiKeyIds.push(newKeyId);
|
47
41
|
return newKeyId;
|
48
42
|
}
|
49
43
|
addJsonModel(modelName, schema) {
|
50
44
|
return this.getModelWithReference(this.addModel(modelName, {
|
51
|
-
contentType:
|
45
|
+
contentType: MediaType.APPLICATION_JSON,
|
52
46
|
modelName,
|
53
47
|
schema,
|
54
48
|
}));
|
55
49
|
}
|
56
50
|
addCSVModel(modelName) {
|
57
51
|
return this.getModelWithReference(this.addModel(modelName, {
|
58
|
-
contentType:
|
52
|
+
contentType: MediaType.TEXT_CSV,
|
59
53
|
modelName,
|
60
54
|
schema: {},
|
61
55
|
}));
|
62
56
|
}
|
63
57
|
getModelWithReference(model) {
|
64
|
-
return
|
58
|
+
return _.set(model, "modelReference", getModelReference(model.modelId, this.restApiId));
|
65
59
|
}
|
66
60
|
addDocumentationPart(resource, parameterName, resourceName, type, properties) {
|
67
61
|
const location = {
|
@@ -69,7 +63,7 @@ class DigitrafficRestApi extends aws_apigateway_1.RestApi {
|
|
69
63
|
path: resource.path,
|
70
64
|
name: type !== "METHOD" ? parameterName : undefined,
|
71
65
|
};
|
72
|
-
new
|
66
|
+
new CfnDocumentationPart(this.stack, resourceName, {
|
73
67
|
restApiId: resource.api.restApiId,
|
74
68
|
location,
|
75
69
|
properties: JSON.stringify(properties),
|
@@ -89,7 +83,7 @@ class DigitrafficRestApi extends aws_apigateway_1.RestApi {
|
|
89
83
|
* @param apiResource
|
90
84
|
*/
|
91
85
|
addCorsOptions(apiResource) {
|
92
|
-
apiResource.addMethod("OPTIONS", new
|
86
|
+
apiResource.addMethod("OPTIONS", new MockIntegration({
|
93
87
|
integrationResponses: [
|
94
88
|
{
|
95
89
|
statusCode: "200",
|
@@ -117,7 +111,6 @@ class DigitrafficRestApi extends aws_apigateway_1.RestApi {
|
|
117
111
|
});
|
118
112
|
}
|
119
113
|
}
|
120
|
-
exports.DigitrafficRestApi = DigitrafficRestApi;
|
121
114
|
/**
|
122
115
|
* Due to AWS API design API Gateway will always return 403 'Missing Authentication Token' for requests
|
123
116
|
* with a non-existent endpoint. This function translates this response to a 404.
|
@@ -125,28 +118,26 @@ exports.DigitrafficRestApi = DigitrafficRestApi;
|
|
125
118
|
* @param restApi RestApi
|
126
119
|
* @param stack Construct
|
127
120
|
*/
|
128
|
-
function add404Support(restApi, stack) {
|
129
|
-
new
|
121
|
+
export function add404Support(restApi, stack) {
|
122
|
+
new GatewayResponse(stack, `MissingAuthenticationTokenResponse-${restApi.restApiName}`, {
|
130
123
|
restApi,
|
131
|
-
type:
|
124
|
+
type: ResponseType.MISSING_AUTHENTICATION_TOKEN,
|
132
125
|
statusCode: "404",
|
133
126
|
templates: {
|
134
|
-
[
|
127
|
+
[MediaType.APPLICATION_JSON]: '{"message": "Not found"}',
|
135
128
|
},
|
136
129
|
});
|
137
130
|
}
|
138
|
-
|
139
|
-
|
140
|
-
new aws_apigateway_1.GatewayResponse(stack, `AuthenticationFailedResponse-${restApi.restApiName}`, {
|
131
|
+
export function add401Support(restApi, stack) {
|
132
|
+
new GatewayResponse(stack, `AuthenticationFailedResponse-${restApi.restApiName}`, {
|
141
133
|
restApi,
|
142
|
-
type:
|
134
|
+
type: ResponseType.UNAUTHORIZED,
|
143
135
|
statusCode: "401",
|
144
136
|
responseHeaders: {
|
145
137
|
"WWW-Authenticate": "'Basic'",
|
146
138
|
},
|
147
139
|
});
|
148
140
|
}
|
149
|
-
exports.add401Support = add401Support;
|
150
141
|
/**
|
151
142
|
* Due to AWS API design API Gateway will always return 403 'Missing Authentication Token' for requests
|
152
143
|
* with a non-existent endpoint. This function converts this response to a custom one.
|
@@ -156,51 +147,48 @@ exports.add401Support = add401Support;
|
|
156
147
|
* @param restApi RestApi
|
157
148
|
* @param stack Construct
|
158
149
|
*/
|
159
|
-
function setReturnCodeForMissingAuthenticationToken(returnCode, message, restApi, stack) {
|
160
|
-
new
|
150
|
+
export function setReturnCodeForMissingAuthenticationToken(returnCode, message, restApi, stack) {
|
151
|
+
new GatewayResponse(stack, `MissingAuthenticationTokenResponse-${restApi.restApiName}`, {
|
161
152
|
restApi,
|
162
|
-
type:
|
153
|
+
type: ResponseType.MISSING_AUTHENTICATION_TOKEN,
|
163
154
|
statusCode: `${returnCode}`,
|
164
155
|
templates: {
|
165
|
-
[
|
156
|
+
[MediaType.APPLICATION_JSON]: `{"message": ${message}}`,
|
166
157
|
},
|
167
158
|
});
|
168
159
|
}
|
169
|
-
|
170
|
-
function createRestApi(stack, apiId, apiName, allowFromIpAddresses) {
|
160
|
+
export function createRestApi(stack, apiId, apiName, allowFromIpAddresses) {
|
171
161
|
const policyDocument = allowFromIpAddresses == null
|
172
162
|
? createDefaultPolicyDocument()
|
173
163
|
: createIpRestrictionPolicyDocument(allowFromIpAddresses);
|
174
|
-
const restApi = new
|
164
|
+
const restApi = new RestApi(stack, apiId, {
|
175
165
|
deployOptions: {
|
176
|
-
loggingLevel:
|
166
|
+
loggingLevel: MethodLoggingLevel.ERROR,
|
177
167
|
},
|
178
168
|
restApiName: apiName,
|
179
|
-
endpointTypes: [
|
169
|
+
endpointTypes: [EndpointType.REGIONAL],
|
180
170
|
policy: policyDocument,
|
181
171
|
});
|
182
172
|
add404Support(restApi, stack);
|
183
173
|
return restApi;
|
184
174
|
}
|
185
|
-
|
186
|
-
|
187
|
-
return new aws_iam_1.PolicyDocument({
|
175
|
+
export function createDefaultPolicyDocument() {
|
176
|
+
return new PolicyDocument({
|
188
177
|
statements: [
|
189
|
-
new
|
190
|
-
effect:
|
178
|
+
new PolicyStatement({
|
179
|
+
effect: Effect.ALLOW,
|
191
180
|
actions: ["execute-api:Invoke"],
|
192
181
|
resources: ["*"],
|
193
|
-
principals: [new
|
182
|
+
principals: [new AnyPrincipal()],
|
194
183
|
}),
|
195
184
|
],
|
196
185
|
});
|
197
186
|
}
|
198
|
-
|
199
|
-
|
200
|
-
return new aws_iam_1.PolicyDocument({
|
187
|
+
export function createIpRestrictionPolicyDocument(allowFromIpAddresses) {
|
188
|
+
return new PolicyDocument({
|
201
189
|
statements: [
|
202
|
-
new
|
203
|
-
effect:
|
190
|
+
new PolicyStatement({
|
191
|
+
effect: Effect.ALLOW,
|
204
192
|
conditions: {
|
205
193
|
IpAddress: {
|
206
194
|
"aws:SourceIp": allowFromIpAddresses,
|
@@ -208,10 +196,9 @@ function createIpRestrictionPolicyDocument(allowFromIpAddresses) {
|
|
208
196
|
},
|
209
197
|
actions: ["execute-api:Invoke"],
|
210
198
|
resources: ["*"],
|
211
|
-
principals: [new
|
199
|
+
principals: [new AnyPrincipal()],
|
212
200
|
}),
|
213
201
|
],
|
214
202
|
});
|
215
203
|
}
|
216
|
-
exports.createIpRestrictionPolicyDocument = createIpRestrictionPolicyDocument;
|
217
204
|
//# sourceMappingURL=rest_apis.js.map
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import { IAspect } from "aws-cdk-lib";
|
2
|
-
import { DigitrafficStack } from "./stack";
|
2
|
+
import { DigitrafficStack } from "./stack.js";
|
3
3
|
import { IConstruct } from "constructs";
|
4
4
|
export declare class StackCheckingAspect implements IAspect {
|
5
5
|
private readonly stackShortName?;
|
@@ -1,20 +1,14 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
};
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
const stack_1 = require("./stack");
|
11
|
-
const aws_apigateway_1 = require("aws-cdk-lib/aws-apigateway");
|
12
|
-
const aws_sqs_1 = require("aws-cdk-lib/aws-sqs");
|
13
|
-
const aws_logs_1 = require("aws-cdk-lib/aws-logs");
|
14
|
-
const change_case_1 = require("change-case");
|
15
|
-
const lodash_1 = __importDefault(require("lodash"));
|
1
|
+
import { Annotations, Stack } from "aws-cdk-lib";
|
2
|
+
import { CfnFunction, Runtime } from "aws-cdk-lib/aws-lambda";
|
3
|
+
import { CfnBucket } from "aws-cdk-lib/aws-s3";
|
4
|
+
import { DigitrafficStack, SOLUTION_KEY } from "./stack.js";
|
5
|
+
import { CfnMethod, CfnResource } from "aws-cdk-lib/aws-apigateway";
|
6
|
+
import { CfnQueue } from "aws-cdk-lib/aws-sqs";
|
7
|
+
import { LogRetention } from "aws-cdk-lib/aws-logs";
|
8
|
+
import { kebabCase } from "change-case";
|
9
|
+
import _ from "lodash";
|
16
10
|
const MAX_CONCURRENCY_LIMIT = 100;
|
17
|
-
const NODE_RUNTIMES = [
|
11
|
+
const NODE_RUNTIMES = [Runtime.NODEJS_20_X.name, Runtime.NODEJS_18_X.name];
|
18
12
|
var ResourceType;
|
19
13
|
(function (ResourceType) {
|
20
14
|
ResourceType["stackName"] = "STACK_NAME";
|
@@ -29,7 +23,7 @@ var ResourceType;
|
|
29
23
|
ResourceType["queueEncryption"] = "QUEUE_ENCRYPTION";
|
30
24
|
ResourceType["logGroupRetention"] = "LOG_GROUP_RETENTION";
|
31
25
|
})(ResourceType || (ResourceType = {}));
|
32
|
-
class StackCheckingAspect {
|
26
|
+
export class StackCheckingAspect {
|
33
27
|
constructor(stackShortName, whitelistedResources) {
|
34
28
|
this.stackShortName = stackShortName;
|
35
29
|
this.whitelistedResources = whitelistedResources;
|
@@ -59,28 +53,26 @@ class StackCheckingAspect {
|
|
59
53
|
// error && whitelisted -> warning
|
60
54
|
// warning && whitelisted -> nothing
|
61
55
|
if (isError && !isWhiteListed) {
|
62
|
-
|
56
|
+
Annotations.of(node).addError(annotationMessage);
|
63
57
|
}
|
64
58
|
else if ((!isError && !isWhiteListed) || (isError && isWhiteListed)) {
|
65
|
-
|
59
|
+
Annotations.of(node).addWarning(annotationMessage);
|
66
60
|
}
|
67
61
|
}
|
68
62
|
checkStack(node) {
|
69
|
-
if (node instanceof
|
70
|
-
if ((node.stackName.includes("Test") ||
|
71
|
-
node.stackName.includes("Tst")) &&
|
63
|
+
if (node instanceof DigitrafficStack) {
|
64
|
+
if ((node.stackName.includes("Test") || node.stackName.includes("Tst")) &&
|
72
65
|
node.configuration.production) {
|
73
66
|
this.addAnnotation(node, ResourceType.stackName, "Production is set for Test-stack");
|
74
67
|
}
|
75
|
-
if ((node.stackName.includes("Prod") ||
|
76
|
-
node.stackName.includes("Prd")) &&
|
68
|
+
if ((node.stackName.includes("Prod") || node.stackName.includes("Prd")) &&
|
77
69
|
!node.configuration.production) {
|
78
70
|
this.addAnnotation(node, ResourceType.stackName, "Production is not set for Production-stack");
|
79
71
|
}
|
80
72
|
}
|
81
73
|
}
|
82
74
|
checkFunction(node) {
|
83
|
-
if (node instanceof
|
75
|
+
if (node instanceof CfnFunction) {
|
84
76
|
if (!node.reservedConcurrentExecutions) {
|
85
77
|
this.addAnnotation(node, ResourceType.reservedConcurrentConcurrency, "Function must have reservedConcurrentConcurrency");
|
86
78
|
}
|
@@ -93,8 +85,7 @@ class StackCheckingAspect {
|
|
93
85
|
if (!node.memorySize) {
|
94
86
|
this.addAnnotation(node, ResourceType.functionMemorySize, "Function must have memorySize");
|
95
87
|
}
|
96
|
-
if (node.runtime !== undefined &&
|
97
|
-
!NODE_RUNTIMES.includes(node.runtime)) {
|
88
|
+
if (node.runtime !== undefined && !NODE_RUNTIMES.includes(node.runtime)) {
|
98
89
|
this.addAnnotation(node, ResourceType.functionRuntime, `Function has wrong runtime ${node.runtime}!`);
|
99
90
|
}
|
100
91
|
if (this.stackShortName &&
|
@@ -105,14 +96,14 @@ class StackCheckingAspect {
|
|
105
96
|
}
|
106
97
|
}
|
107
98
|
checkTags(node) {
|
108
|
-
if (node instanceof
|
109
|
-
if (!node.tags.tagValues()[
|
99
|
+
if (node instanceof Stack) {
|
100
|
+
if (!node.tags.tagValues()[SOLUTION_KEY]) {
|
110
101
|
this.addAnnotation(node, ResourceType.tagSolution, "Solution tag is missing");
|
111
102
|
}
|
112
103
|
}
|
113
104
|
}
|
114
105
|
checkBucket(node) {
|
115
|
-
if (node instanceof
|
106
|
+
if (node instanceof CfnBucket) {
|
116
107
|
const c = node.publicAccessBlockConfiguration;
|
117
108
|
if (c &&
|
118
109
|
(!c.blockPublicAcls ||
|
@@ -131,26 +122,25 @@ class StackCheckingAspect {
|
|
131
122
|
if (path.includes("{")) {
|
132
123
|
return this.isValidPath(path.split("{")[0]);
|
133
124
|
}
|
134
|
-
return (
|
125
|
+
return kebabCase(path) === path;
|
135
126
|
}
|
136
127
|
static isValidQueryString(name) {
|
137
|
-
return
|
128
|
+
return _.snakeCase(name) === name;
|
138
129
|
}
|
139
130
|
checkResourceCasing(node) {
|
140
|
-
if (node instanceof
|
131
|
+
if (node instanceof CfnResource) {
|
141
132
|
if (!StackCheckingAspect.isValidPath(node.pathPart)) {
|
142
133
|
this.addAnnotation(node, ResourceType.resourcePath, "Path part should be in kebab-case");
|
143
134
|
}
|
144
135
|
}
|
145
|
-
else if (node instanceof
|
136
|
+
else if (node instanceof CfnMethod) {
|
146
137
|
const integration = node.integration;
|
147
138
|
if (integration?.requestParameters) {
|
148
139
|
Object.keys(integration.requestParameters).forEach((key) => {
|
149
140
|
const split = key.split(".");
|
150
141
|
const type = split[2];
|
151
142
|
const name = split[3];
|
152
|
-
if (type === "querystring" &&
|
153
|
-
!StackCheckingAspect.isValidQueryString(name)) {
|
143
|
+
if (type === "querystring" && !StackCheckingAspect.isValidQueryString(name)) {
|
154
144
|
this.addAnnotation(node, name, "Querystring should be in snake_case");
|
155
145
|
}
|
156
146
|
});
|
@@ -158,14 +148,14 @@ class StackCheckingAspect {
|
|
158
148
|
}
|
159
149
|
}
|
160
150
|
checkQueueEncryption(node) {
|
161
|
-
if (node instanceof
|
151
|
+
if (node instanceof CfnQueue) {
|
162
152
|
if (!node.kmsMasterKeyId) {
|
163
153
|
this.addAnnotation(node, ResourceType.queueEncryption, "Queue must have encryption enabled");
|
164
154
|
}
|
165
155
|
}
|
166
156
|
}
|
167
157
|
checkLogGroupRetention(node) {
|
168
|
-
if (node instanceof
|
158
|
+
if (node instanceof LogRetention) {
|
169
159
|
const child = node.node.defaultChild;
|
170
160
|
const retention = child._cfnProperties.RetentionInDays;
|
171
161
|
if (!retention) {
|
@@ -174,5 +164,4 @@ class StackCheckingAspect {
|
|
174
164
|
}
|
175
165
|
}
|
176
166
|
}
|
177
|
-
exports.StackCheckingAspect = StackCheckingAspect;
|
178
167
|
//# sourceMappingURL=stack-checking-aspect.js.map
|
@@ -1,15 +1,14 @@
|
|
1
1
|
import { Stack, StackProps } from "aws-cdk-lib";
|
2
|
-
import { IVpc } from "aws-cdk-lib/aws-ec2";
|
3
|
-
import { ISecurityGroup } from "aws-cdk-lib/aws-ec2/lib/security-group";
|
2
|
+
import { type ISecurityGroup, IVpc } from "aws-cdk-lib/aws-ec2";
|
4
3
|
import { ITopic } from "aws-cdk-lib/aws-sns";
|
5
4
|
import { ISecret } from "aws-cdk-lib/aws-secretsmanager";
|
6
5
|
import { Function as AWSFunction } from "aws-cdk-lib/aws-lambda";
|
7
6
|
import { Construct } from "constructs";
|
8
|
-
import { TrafficType } from "../../../types/traffictype";
|
9
|
-
import { DBLambdaEnvironment } from "./lambda-configs";
|
7
|
+
import { TrafficType } from "../../../types/traffictype.js";
|
8
|
+
import { DBLambdaEnvironment } from "./lambda-configs.js";
|
10
9
|
export declare const SOLUTION_KEY = "Solution";
|
11
|
-
export declare const SSM_KEY_WARNING_TOPIC
|
12
|
-
export declare const SSM_KEY_ALARM_TOPIC
|
10
|
+
export declare const SSM_KEY_WARNING_TOPIC = "/digitraffic/monitoring/warning-topic";
|
11
|
+
export declare const SSM_KEY_ALARM_TOPIC = "/digitraffic/monitoring/alarm-topic";
|
13
12
|
export interface StackConfiguration {
|
14
13
|
readonly shortName: string;
|
15
14
|
readonly secretId?: string;
|
@@ -1,28 +1,25 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
const aws_ssm_1 = require("aws-cdk-lib/aws-ssm");
|
8
|
-
const aws_secretsmanager_1 = require("aws-cdk-lib/aws-secretsmanager");
|
9
|
-
const stack_checking_aspect_1 = require("./stack-checking-aspect");
|
1
|
+
import { Aspects, Stack } from "aws-cdk-lib";
|
2
|
+
import { SecurityGroup, Vpc } from "aws-cdk-lib/aws-ec2";
|
3
|
+
import { Topic } from "aws-cdk-lib/aws-sns";
|
4
|
+
import { StringParameter } from "aws-cdk-lib/aws-ssm";
|
5
|
+
import { Secret } from "aws-cdk-lib/aws-secretsmanager";
|
6
|
+
import { StackCheckingAspect } from "./stack-checking-aspect.js";
|
10
7
|
const SSM_ROOT = "/digitraffic";
|
11
|
-
|
8
|
+
export const SOLUTION_KEY = "Solution";
|
12
9
|
const MONITORING_ROOT = "/monitoring";
|
13
|
-
|
14
|
-
|
15
|
-
class DigitrafficStack extends
|
10
|
+
export const SSM_KEY_WARNING_TOPIC = `${SSM_ROOT}${MONITORING_ROOT}/warning-topic`;
|
11
|
+
export const SSM_KEY_ALARM_TOPIC = `${SSM_ROOT}${MONITORING_ROOT}/alarm-topic`;
|
12
|
+
export class DigitrafficStack extends Stack {
|
16
13
|
constructor(scope, id, configuration) {
|
17
14
|
super(scope, id, configuration.stackProps);
|
18
15
|
this.configuration = configuration;
|
19
16
|
if (configuration.secretId) {
|
20
|
-
this.secret =
|
17
|
+
this.secret = Secret.fromSecretNameV2(this, "Secret", configuration.secretId);
|
21
18
|
}
|
22
19
|
// VPC reference construction requires vpcId and availability zones
|
23
20
|
// private subnets are used in Lambda configuration
|
24
21
|
if (configuration.vpcId) {
|
25
|
-
this.vpc =
|
22
|
+
this.vpc = Vpc.fromVpcAttributes(this, "vpc", {
|
26
23
|
vpcId: configuration.vpcId,
|
27
24
|
privateSubnetIds: configuration.privateSubnetIds,
|
28
25
|
availabilityZones: configuration.availabilityZones ?? [],
|
@@ -30,14 +27,14 @@ class DigitrafficStack extends aws_cdk_lib_1.Stack {
|
|
30
27
|
}
|
31
28
|
// security group that allows Lambda database access
|
32
29
|
if (configuration.lambdaDbSgId) {
|
33
|
-
this.lambdaDbSg =
|
30
|
+
this.lambdaDbSg = SecurityGroup.fromSecurityGroupId(this, "LambdaDbSG", configuration.lambdaDbSgId);
|
34
31
|
}
|
35
|
-
this.alarmTopic =
|
36
|
-
this.warningTopic =
|
32
|
+
this.alarmTopic = Topic.fromTopicArn(this, "AlarmTopic", StringParameter.fromStringParameterName(this, "AlarmTopicParam", SSM_KEY_ALARM_TOPIC).stringValue);
|
33
|
+
this.warningTopic = Topic.fromTopicArn(this, "WarningTopic", StringParameter.fromStringParameterName(this, "WarningTopicParam", SSM_KEY_WARNING_TOPIC).stringValue);
|
37
34
|
this.addAspects();
|
38
35
|
}
|
39
36
|
addAspects() {
|
40
|
-
|
37
|
+
Aspects.of(this).add(StackCheckingAspect.create(this));
|
41
38
|
}
|
42
39
|
createLambdaEnvironment() {
|
43
40
|
return this.createDefaultLambdaEnvironment(this.configuration.shortName);
|
@@ -63,5 +60,4 @@ class DigitrafficStack extends aws_cdk_lib_1.Stack {
|
|
63
60
|
lambdas.forEach((l) => secret.grantRead(l));
|
64
61
|
}
|
65
62
|
}
|
66
|
-
exports.DigitrafficStack = DigitrafficStack;
|
67
63
|
//# sourceMappingURL=stack.js.map
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import { CfnSubscriptionFilter } from "aws-cdk-lib/aws-logs";
|
2
2
|
import { Function as AWSFunction } from "aws-cdk-lib/aws-lambda";
|
3
|
-
import { DigitrafficStack } from "./stack";
|
3
|
+
import { DigitrafficStack } from "./stack.js";
|
4
4
|
import { Construct } from "constructs";
|
5
|
-
import { MonitoredFunction } from "./monitoredfunction";
|
5
|
+
import { MonitoredFunction } from "./monitoredfunction.js";
|
6
6
|
/**
|
7
7
|
* Creates a subscription filter that subscribes to a Lambda Log Group and delivers the logs to another destination.
|
8
8
|
* https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-subscriptionfilter.html
|
@@ -1,7 +1,4 @@
|
|
1
|
-
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.DigitrafficLogSubscriptions = exports.createSubscription = void 0;
|
4
|
-
const aws_logs_1 = require("aws-cdk-lib/aws-logs");
|
1
|
+
import { CfnSubscriptionFilter } from "aws-cdk-lib/aws-logs";
|
5
2
|
/**
|
6
3
|
* Creates a subscription filter that subscribes to a Lambda Log Group and delivers the logs to another destination.
|
7
4
|
* https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-logs-subscriptionfilter.html
|
@@ -10,11 +7,11 @@ const aws_logs_1 = require("aws-cdk-lib/aws-logs");
|
|
10
7
|
* @param logDestinationArn Destination for streamed logs
|
11
8
|
* @param stack CloudFormation stack
|
12
9
|
*/
|
13
|
-
function createSubscription(lambda, lambdaName, logDestinationArn, stack) {
|
10
|
+
export function createSubscription(lambda, lambdaName, logDestinationArn, stack) {
|
14
11
|
if (logDestinationArn == undefined) {
|
15
12
|
return undefined;
|
16
13
|
}
|
17
|
-
const filter = new
|
14
|
+
const filter = new CfnSubscriptionFilter(stack, `${lambdaName}LogsSubscription`, {
|
18
15
|
logGroupName: `/aws/lambda/${lambdaName}`,
|
19
16
|
filterPattern: "",
|
20
17
|
destinationArn: logDestinationArn,
|
@@ -22,13 +19,12 @@ function createSubscription(lambda, lambdaName, logDestinationArn, stack) {
|
|
22
19
|
filter.node.addDependency(lambda);
|
23
20
|
return filter;
|
24
21
|
}
|
25
|
-
|
26
|
-
class DigitrafficLogSubscriptions {
|
22
|
+
export class DigitrafficLogSubscriptions {
|
27
23
|
constructor(stack, ...lambdas) {
|
28
24
|
const destinationArn = stack.configuration.logsDestinationArn;
|
29
25
|
if (destinationArn !== undefined) {
|
30
26
|
lambdas.forEach((lambda) => {
|
31
|
-
const filter = new
|
27
|
+
const filter = new CfnSubscriptionFilter(stack, `${lambda.givenName}LogsSubscription`, {
|
32
28
|
logGroupName: `/aws/lambda/${lambda.givenName}`,
|
33
29
|
filterPattern: "",
|
34
30
|
destinationArn,
|
@@ -38,5 +34,4 @@ class DigitrafficLogSubscriptions {
|
|
38
34
|
}
|
39
35
|
}
|
40
36
|
}
|
41
|
-
exports.DigitrafficLogSubscriptions = DigitrafficLogSubscriptions;
|
42
37
|
//# sourceMappingURL=subscription.js.map
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { Stack } from "aws-cdk-lib";
|
2
|
-
import { Construct } from "constructs
|
3
|
-
import { InfraStackConfiguration } from "./intra-stack-configuration";
|
2
|
+
import { type Construct } from "constructs";
|
3
|
+
import { InfraStackConfiguration } from "./intra-stack-configuration.js";
|
4
4
|
/**
|
5
5
|
* Creates a dns local zone and creates records for cluster endpoints and proxy endpoints.
|
6
6
|
*
|
@@ -1,18 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
const
|
6
|
-
const import_util_1 = require("../import-util");
|
7
|
-
const parameters_1 = require("../stack/parameters");
|
8
|
-
const DEFAULT_RECORD_TTL = aws_cdk_lib_1.Duration.seconds(30);
|
1
|
+
import { Duration, RemovalPolicy, Stack } from "aws-cdk-lib";
|
2
|
+
import { PrivateHostedZone, RecordSet, RecordTarget, RecordType, } from "aws-cdk-lib/aws-route53";
|
3
|
+
import { importVpc } from "../import-util.js";
|
4
|
+
import { getParameterValue } from "../stack/parameters.js";
|
5
|
+
const DEFAULT_RECORD_TTL = Duration.seconds(30);
|
9
6
|
/**
|
10
7
|
* Creates a dns local zone and creates records for cluster endpoints and proxy endpoints.
|
11
8
|
*
|
12
9
|
* Please note, that created PrivateHostedZone has RETAIN removalPolicy, so if you want to delete this stack,
|
13
10
|
* you must remove the zone by hand after.
|
14
11
|
*/
|
15
|
-
class DbDnsStack extends
|
12
|
+
export class DbDnsStack extends Stack {
|
16
13
|
constructor(scope, id, isc) {
|
17
14
|
super(scope, id, {
|
18
15
|
env: isc.env,
|
@@ -20,45 +17,44 @@ class DbDnsStack extends aws_cdk_lib_1.Stack {
|
|
20
17
|
this.createDnsRecords(isc);
|
21
18
|
}
|
22
19
|
createDnsRecords(isc) {
|
23
|
-
const vpc =
|
24
|
-
const zone = new
|
20
|
+
const vpc = importVpc(this, isc.environmentName);
|
21
|
+
const zone = new PrivateHostedZone(this, "DNSHostedZone", {
|
25
22
|
zoneName: isc.environmentName + ".local",
|
26
23
|
vpc,
|
27
24
|
});
|
28
|
-
zone.applyRemovalPolicy(
|
29
|
-
const clusterReaderEndpoint =
|
30
|
-
const clusterWriterEndpoint =
|
31
|
-
const proxyReaderEndpoint =
|
32
|
-
const proxyWriterEndpoint =
|
33
|
-
new
|
34
|
-
recordType:
|
25
|
+
zone.applyRemovalPolicy(RemovalPolicy.RETAIN);
|
26
|
+
const clusterReaderEndpoint = getParameterValue(this, "cluster.reader");
|
27
|
+
const clusterWriterEndpoint = getParameterValue(this, "cluster.writer");
|
28
|
+
const proxyReaderEndpoint = getParameterValue(this, "proxy.reader");
|
29
|
+
const proxyWriterEndpoint = getParameterValue(this, "proxy.writer");
|
30
|
+
new RecordSet(this, "ReaderRecord", {
|
31
|
+
recordType: RecordType.CNAME,
|
35
32
|
recordName: `db-ro.${isc.environmentName}.local`,
|
36
|
-
target:
|
33
|
+
target: RecordTarget.fromValues(clusterReaderEndpoint),
|
37
34
|
ttl: DEFAULT_RECORD_TTL,
|
38
35
|
zone,
|
39
36
|
});
|
40
|
-
new
|
41
|
-
recordType:
|
37
|
+
new RecordSet(this, "WriterRecord", {
|
38
|
+
recordType: RecordType.CNAME,
|
42
39
|
recordName: `db.${isc.environmentName}.local`,
|
43
|
-
target:
|
40
|
+
target: RecordTarget.fromValues(clusterWriterEndpoint),
|
44
41
|
ttl: DEFAULT_RECORD_TTL,
|
45
42
|
zone,
|
46
43
|
});
|
47
|
-
new
|
48
|
-
recordType:
|
44
|
+
new RecordSet(this, "ProxyReaderRecord", {
|
45
|
+
recordType: RecordType.CNAME,
|
49
46
|
recordName: `proxy-ro.${isc.environmentName}.local`,
|
50
|
-
target:
|
47
|
+
target: RecordTarget.fromValues(proxyReaderEndpoint),
|
51
48
|
ttl: DEFAULT_RECORD_TTL,
|
52
49
|
zone,
|
53
50
|
});
|
54
|
-
new
|
55
|
-
recordType:
|
51
|
+
new RecordSet(this, "ProxyWriterRecord", {
|
52
|
+
recordType: RecordType.CNAME,
|
56
53
|
recordName: `proxy.${isc.environmentName}.local`,
|
57
|
-
target:
|
54
|
+
target: RecordTarget.fromValues(proxyWriterEndpoint),
|
58
55
|
ttl: DEFAULT_RECORD_TTL,
|
59
56
|
zone,
|
60
57
|
});
|
61
58
|
}
|
62
59
|
}
|
63
|
-
exports.DbDnsStack = DbDnsStack;
|
64
60
|
//# sourceMappingURL=db-dns-stack.js.map
|
@@ -1,9 +1,9 @@
|
|
1
1
|
import { CfnDBProxyEndpoint, DatabaseProxy } from "aws-cdk-lib/aws-rds";
|
2
2
|
import { ISecret } from "aws-cdk-lib/aws-secretsmanager";
|
3
3
|
import { IVpc } from "aws-cdk-lib/aws-ec2";
|
4
|
-
import { InfraStackConfiguration } from "./intra-stack-configuration";
|
4
|
+
import { InfraStackConfiguration } from "./intra-stack-configuration.js";
|
5
5
|
import { Stack } from "aws-cdk-lib/core";
|
6
|
-
import { Construct } from "constructs/lib/construct";
|
6
|
+
import { Construct } from "constructs/lib/construct.js";
|
7
7
|
export interface ProxyConfiguration {
|
8
8
|
readonly secretArn: string;
|
9
9
|
readonly name?: string;
|