@digitraffic/common 2024.1.24-3 → 2024.3.11-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.
Files changed (212) hide show
  1. package/dist/__test__/api/handler-factory.test.d.mts +1 -0
  2. package/dist/__test__/api/handler-factory.test.mjs +43 -0
  3. package/dist/__test__/api/response.test.d.mts +1 -0
  4. package/dist/__test__/api/response.test.mjs +86 -0
  5. package/dist/__test__/imports.test.d.mts +1 -0
  6. package/dist/__test__/imports.test.mjs +332 -0
  7. package/dist/__test__/marine/id_utils.test.d.mts +1 -0
  8. package/dist/__test__/marine/id_utils.test.mjs +44 -0
  9. package/dist/__test__/promise/promise.test.d.mts +1 -0
  10. package/dist/__test__/promise/promise.test.mjs +130 -0
  11. package/dist/__test__/runtime/dt-logger.test.d.mts +1 -0
  12. package/dist/__test__/runtime/dt-logger.test.mjs +108 -0
  13. package/dist/__test__/secrets/secret-holder.test.d.mts +1 -0
  14. package/dist/__test__/secrets/secret-holder.test.mjs +86 -0
  15. package/dist/__test__/secrets/secret.test.d.mts +1 -0
  16. package/dist/__test__/secrets/secret.test.mjs +38 -0
  17. package/dist/__test__/test/httpserver.test.d.mts +1 -0
  18. package/dist/__test__/test/httpserver.test.mjs +154 -0
  19. package/dist/__test__/test/mock-ky.test.d.mts +1 -0
  20. package/dist/__test__/test/mock-ky.test.mjs +46 -0
  21. package/dist/__test__/types/lambda-response.test.d.mts +1 -0
  22. package/dist/__test__/types/lambda-response.test.mjs +58 -0
  23. package/dist/__test__/utils/date-utils.test.d.mts +1 -0
  24. package/dist/__test__/utils/date-utils.test.mjs +27 -0
  25. package/dist/__test__/utils/geometry.test.d.mts +1 -0
  26. package/dist/__test__/utils/geometry.test.mjs +24 -0
  27. package/dist/__test__/utils/logging.test.d.mts +1 -0
  28. package/dist/__test__/utils/logging.test.mjs +78 -0
  29. package/dist/__test__/utils/utils.test.d.mts +1 -0
  30. package/dist/__test__/utils/utils.test.mjs +43 -0
  31. package/dist/aws/infra/api/handler-factory.mjs +4 -0
  32. package/dist/aws/infra/api/integration.d.mts +2 -2
  33. package/dist/aws/infra/api/integration.mjs +4 -1
  34. package/dist/aws/infra/api/response.d.mts +1 -1
  35. package/dist/aws/infra/api/responses.d.mts +1 -1
  36. package/dist/aws/infra/api/responses.mjs +2 -0
  37. package/dist/aws/infra/api/static-integration.mjs +1 -1
  38. package/dist/aws/infra/canaries/canary-alarm.d.mts +1 -1
  39. package/dist/aws/infra/canaries/canary-alarm.mjs +2 -0
  40. package/dist/aws/infra/canaries/canary-parameters.mjs +1 -1
  41. package/dist/aws/infra/canaries/canary-role.mjs +1 -0
  42. package/dist/aws/infra/canaries/canary.d.mts +2 -2
  43. package/dist/aws/infra/canaries/canary.mjs +2 -0
  44. package/dist/aws/infra/canaries/database-canary.d.mts +2 -2
  45. package/dist/aws/infra/canaries/database-canary.mjs +2 -0
  46. package/dist/aws/infra/canaries/database-checker.d.mts +1 -1
  47. package/dist/aws/infra/canaries/database-checker.mjs +7 -1
  48. package/dist/aws/infra/canaries/url-canary.d.mts +2 -2
  49. package/dist/aws/infra/canaries/url-canary.mjs +3 -0
  50. package/dist/aws/infra/canaries/url-checker.d.mts +1 -1
  51. package/dist/aws/infra/canaries/url-checker.mjs +4 -1
  52. package/dist/aws/infra/documentation.mjs +5 -1
  53. package/dist/aws/infra/import-util.d.mts +1 -1
  54. package/dist/aws/infra/import-util.mjs +4 -3
  55. package/dist/aws/infra/scheduler.mjs +2 -0
  56. package/dist/aws/infra/security-rule.d.mts +1 -1
  57. package/dist/aws/infra/security-rule.mjs +1 -0
  58. package/dist/aws/infra/sqs-integration.d.mts +1 -1
  59. package/dist/aws/infra/sqs-integration.mjs +3 -1
  60. package/dist/aws/infra/sqs-queue.d.mts +1 -1
  61. package/dist/aws/infra/sqs-queue.mjs +2 -1
  62. package/dist/aws/infra/stack/lambda-configs.d.mts +4 -4
  63. package/dist/aws/infra/stack/lambda-configs.mjs +4 -2
  64. package/dist/aws/infra/stack/monitoredfunction.d.mts +3 -3
  65. package/dist/aws/infra/stack/monitoredfunction.mjs +23 -18
  66. package/dist/aws/infra/stack/parameters.mjs +1 -0
  67. package/dist/aws/infra/stack/rest_apis.d.mts +2 -2
  68. package/dist/aws/infra/stack/rest_apis.mjs +6 -1
  69. package/dist/aws/infra/stack/stack-checking-aspect.d.mts +2 -2
  70. package/dist/aws/infra/stack/stack-checking-aspect.mjs +6 -1
  71. package/dist/aws/infra/stack/stack.d.mts +5 -5
  72. package/dist/aws/infra/stack/stack.mjs +9 -0
  73. package/dist/aws/infra/stack/subscription.mjs +4 -0
  74. package/dist/aws/infra/stacks/db-dns-stack.d.mts +1 -1
  75. package/dist/aws/infra/stacks/db-dns-stack.mjs +1 -0
  76. package/dist/aws/infra/stacks/db-proxy-stack.d.mts +3 -3
  77. package/dist/aws/infra/stacks/db-proxy-stack.mjs +4 -2
  78. package/dist/aws/infra/stacks/db-stack.d.mts +3 -3
  79. package/dist/aws/infra/stacks/db-stack.mjs +11 -7
  80. package/dist/aws/infra/stacks/intra-stack-configuration.d.mts +1 -1
  81. package/dist/aws/infra/stacks/network-stack.d.mts +2 -2
  82. package/dist/aws/infra/stacks/network-stack.mjs +8 -0
  83. package/dist/aws/infra/usage-plans.d.mts +1 -1
  84. package/dist/aws/infra/usage-plans.mjs +1 -0
  85. package/dist/aws/runtime/apikey.d.mts +2 -2
  86. package/dist/aws/runtime/apikey.mjs +2 -2
  87. package/dist/aws/runtime/digitraffic-integration-response.d.mts +1 -1
  88. package/dist/aws/runtime/dt-logger.mjs +6 -2
  89. package/dist/aws/runtime/messaging.d.mts +2 -2
  90. package/dist/aws/runtime/messaging.mjs +5 -4
  91. package/dist/aws/runtime/s3.d.mts +4 -2
  92. package/dist/aws/runtime/s3.mjs +15 -10
  93. package/dist/aws/runtime/secrets/dbsecret.d.mts +1 -1
  94. package/dist/aws/runtime/secrets/proxy-holder.mjs +1 -0
  95. package/dist/aws/runtime/secrets/rds-holder.mjs +1 -0
  96. package/dist/aws/runtime/secrets/secret-holder.d.mts +1 -1
  97. package/dist/aws/runtime/secrets/secret-holder.mjs +6 -1
  98. package/dist/aws/runtime/secrets/secret.mjs +5 -6
  99. package/dist/aws/types/errors.mjs +1 -0
  100. package/dist/aws/types/lambda-response.mjs +5 -0
  101. package/dist/aws/types/model-with-reference.mjs +1 -1
  102. package/dist/database/cached.d.mts +1 -1
  103. package/dist/database/database.mjs +1 -0
  104. package/dist/database/last-updated.d.mts +1 -1
  105. package/dist/test/db-testutils.d.mts +1 -1
  106. package/dist/test/db-testutils.mjs +1 -1
  107. package/dist/test/httpserver.mjs +7 -3
  108. package/dist/test/mock-ky.d.mts +2 -0
  109. package/dist/test/mock-ky.mjs +15 -0
  110. package/dist/test/secrets-manager.d.mts +3 -2
  111. package/dist/test/secrets-manager.mjs +14 -16
  112. package/dist/test/testutils.mjs +1 -1
  113. package/dist/types/http-error.mjs +1 -0
  114. package/dist/types/nullable.d.mts +1 -1
  115. package/dist/utils/api-model.d.mts +2 -2
  116. package/dist/utils/api-model.mjs +1 -1
  117. package/dist/utils/geojson-types.d.mts +1 -1
  118. package/dist/utils/geojson-types.mjs +4 -2
  119. package/dist/utils/geometry.d.mts +1 -1
  120. package/dist/utils/geometry.mjs +3 -0
  121. package/dist/utils/logging.mjs +2 -2
  122. package/dist/utils/retry.d.mts +2 -2
  123. package/dist/utils/retry.mjs +2 -2
  124. package/dist/utils/slack.mjs +4 -3
  125. package/dist/utils/utils.d.mts +2 -2
  126. package/package.json +25 -15
  127. package/src/@types/geojson-validation/index.d.mts +0 -4
  128. package/src/aws/infra/api/handler-factory.mts +0 -86
  129. package/src/aws/infra/api/integration.mts +0 -147
  130. package/src/aws/infra/api/response.mts +0 -165
  131. package/src/aws/infra/api/responses.mts +0 -127
  132. package/src/aws/infra/api/static-integration.mts +0 -108
  133. package/src/aws/infra/canaries/Synthetics.d.mts +0 -21
  134. package/src/aws/infra/canaries/canary-alarm.mts +0 -33
  135. package/src/aws/infra/canaries/canary-keys.mts +0 -3
  136. package/src/aws/infra/canaries/canary-parameters.mts +0 -19
  137. package/src/aws/infra/canaries/canary-role.mts +0 -73
  138. package/src/aws/infra/canaries/canary.mts +0 -44
  139. package/src/aws/infra/canaries/database-canary.mts +0 -98
  140. package/src/aws/infra/canaries/database-checker.mts +0 -163
  141. package/src/aws/infra/canaries/url-canary.mts +0 -98
  142. package/src/aws/infra/canaries/url-checker.mts +0 -388
  143. package/src/aws/infra/documentation.mts +0 -142
  144. package/src/aws/infra/import-util.mts +0 -57
  145. package/src/aws/infra/scheduler.mts +0 -59
  146. package/src/aws/infra/security-rule.mts +0 -38
  147. package/src/aws/infra/sqs-integration.mts +0 -106
  148. package/src/aws/infra/sqs-queue.mts +0 -162
  149. package/src/aws/infra/stack/lambda-configs.mts +0 -135
  150. package/src/aws/infra/stack/monitoredfunction.mts +0 -352
  151. package/src/aws/infra/stack/parameters.mts +0 -74
  152. package/src/aws/infra/stack/rest_apis.mts +0 -322
  153. package/src/aws/infra/stack/stack-checking-aspect.mts +0 -233
  154. package/src/aws/infra/stack/stack.mts +0 -144
  155. package/src/aws/infra/stack/subscription.mts +0 -58
  156. package/src/aws/infra/stacks/db-dns-stack.mts +0 -77
  157. package/src/aws/infra/stacks/db-proxy-stack.mts +0 -134
  158. package/src/aws/infra/stacks/db-stack.mts +0 -292
  159. package/src/aws/infra/stacks/intra-stack-configuration.mts +0 -6
  160. package/src/aws/infra/stacks/network-stack.mts +0 -76
  161. package/src/aws/infra/usage-plans.mts +0 -50
  162. package/src/aws/runtime/apikey.mts +0 -9
  163. package/src/aws/runtime/digitraffic-integration-response.mts +0 -35
  164. package/src/aws/runtime/dt-logger-default.mts +0 -11
  165. package/src/aws/runtime/dt-logger.mts +0 -184
  166. package/src/aws/runtime/environment.mts +0 -22
  167. package/src/aws/runtime/messaging.mts +0 -26
  168. package/src/aws/runtime/s3.mts +0 -44
  169. package/src/aws/runtime/secrets/dbsecret.mts +0 -31
  170. package/src/aws/runtime/secrets/node-ttl.d.mts +0 -12
  171. package/src/aws/runtime/secrets/proxy-holder.mts +0 -34
  172. package/src/aws/runtime/secrets/rds-holder.mts +0 -34
  173. package/src/aws/runtime/secrets/secret-holder.mts +0 -106
  174. package/src/aws/runtime/secrets/secret.mts +0 -58
  175. package/src/aws/types/errors.mts +0 -14
  176. package/src/aws/types/lambda-response.mts +0 -100
  177. package/src/aws/types/mediatypes.mts +0 -12
  178. package/src/aws/types/model-with-reference.mts +0 -8
  179. package/src/aws/types/proxytypes.mts +0 -27
  180. package/src/aws/types/tags.mts +0 -3
  181. package/src/database/cached.mts +0 -64
  182. package/src/database/database.mts +0 -107
  183. package/src/database/last-updated.mts +0 -103
  184. package/src/database/models.mts +0 -7
  185. package/src/index.mts +0 -2
  186. package/src/marine/id_utils.mts +0 -30
  187. package/src/marine/rtz.mts +0 -57
  188. package/src/test/asserter.mts +0 -58
  189. package/src/test/db-testutils.mts +0 -52
  190. package/src/test/httpserver.mts +0 -111
  191. package/src/test/secrets-manager.mts +0 -37
  192. package/src/test/testutils.mts +0 -39
  193. package/src/types/async-timeout-error.mts +0 -5
  194. package/src/types/aws-env.mts +0 -3
  195. package/src/types/either.mts +0 -9
  196. package/src/types/http-error.mts +0 -8
  197. package/src/types/input-error.mts +0 -2
  198. package/src/types/language.mts +0 -3
  199. package/src/types/nullable.mts +0 -21
  200. package/src/types/traffictype.mts +0 -8
  201. package/src/types/urn.mts +0 -1
  202. package/src/types/util-types.mts +0 -10
  203. package/src/types/validator.mts +0 -10
  204. package/src/utils/api-model.mts +0 -133
  205. package/src/utils/base64.mts +0 -16
  206. package/src/utils/date-utils.mts +0 -53
  207. package/src/utils/geojson-types.mts +0 -22
  208. package/src/utils/geometry.mts +0 -171
  209. package/src/utils/logging.mts +0 -75
  210. package/src/utils/retry.mts +0 -200
  211. package/src/utils/slack.mts +0 -26
  212. package/src/utils/utils.mts +0 -184
@@ -1,127 +0,0 @@
1
- import {
2
- InternalServerErrorResponseTemplate,
3
- XmlResponseTemplate,
4
- NotFoundResponseTemplate,
5
- BadRequestResponseTemplate,
6
- } from "./response.mjs";
7
- import {
8
- LambdaIntegration,
9
- MethodResponse,
10
- IntegrationResponse,
11
- PassthroughBehavior,
12
- type IModel
13
- } from "aws-cdk-lib/aws-apigateway";
14
- import { Function as AWSFunction } from "aws-cdk-lib/aws-lambda";
15
- import {
16
- BAD_REQUEST_MESSAGE,
17
- ERROR_MESSAGE,
18
- NOT_FOUND_MESSAGE,
19
- } from "../../types/errors.mjs";
20
- import { MediaType } from "../../types/mediatypes.mjs";
21
-
22
- /// @deprecated
23
- export const RESPONSE_200_OK: IntegrationResponse = {
24
- statusCode: "200",
25
- };
26
-
27
- /// @deprecated
28
- export const RESPONSE_400_BAD_REQUEST: IntegrationResponse = {
29
- statusCode: "400",
30
- selectionPattern: BAD_REQUEST_MESSAGE,
31
- responseTemplates: BadRequestResponseTemplate,
32
- };
33
-
34
- /// @deprecated
35
- export const RESPONSE_500_SERVER_ERROR: IntegrationResponse = {
36
- statusCode: "500",
37
- selectionPattern: ERROR_MESSAGE,
38
- responseTemplates: InternalServerErrorResponseTemplate,
39
- };
40
-
41
- /// @deprecated
42
- const RESPONSE_XML = {
43
- responseTemplates: XmlResponseTemplate,
44
- };
45
-
46
- /// @deprecated
47
- export const RESPONSE_CORS_INTEGRATION = {
48
- responseParameters: {
49
- "method.response.header.Access-Control-Allow-Origin": "'*'",
50
- },
51
- };
52
-
53
- /// @deprecated
54
- export const RESPONSE_404_NOT_FOUND = {
55
- statusCode: "404",
56
- selectionPattern: NOT_FOUND_MESSAGE,
57
- responseTemplates: NotFoundResponseTemplate,
58
- };
59
-
60
- /**
61
- * @deprecated Use DigitrafficMethodResponse
62
- */
63
- export function methodResponse(
64
- status: string,
65
- contentType: MediaType,
66
- model: IModel,
67
- parameters?: Record<string, boolean>
68
- ): MethodResponse {
69
- return {
70
- statusCode: status,
71
- responseModels: {
72
- [contentType]: model,
73
- },
74
- responseParameters: parameters ?? {},
75
- };
76
- }
77
-
78
- interface IntegrationOptions {
79
- // eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style
80
- requestParameters?: { [dest: string]: string };
81
- // eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style
82
- requestTemplates?: { [contentType: string]: string };
83
- responses?: IntegrationResponse[];
84
- disableCors?: boolean;
85
- xml?: boolean;
86
- passthroughBehavior?: PassthroughBehavior;
87
- }
88
-
89
- /**
90
- * Creates a default Lambda integration for a REST API resource _root_
91
- * @param lambdaFunction The Lambda function
92
- * @param options Options
93
- *
94
- * @deprecated Use DigitrafficIntegration
95
- */
96
- export function defaultIntegration(
97
- lambdaFunction: AWSFunction,
98
- options?: IntegrationOptions
99
- ): LambdaIntegration {
100
- return new LambdaIntegration(lambdaFunction, {
101
- proxy: false,
102
- integrationResponses: options?.responses ?? [
103
- getResponse(RESPONSE_200_OK, options),
104
- getResponse(RESPONSE_400_BAD_REQUEST, options),
105
- getResponse(RESPONSE_404_NOT_FOUND, options),
106
- getResponse(RESPONSE_500_SERVER_ERROR, options),
107
- ],
108
- requestParameters: options?.requestParameters ?? {},
109
- requestTemplates: options?.requestTemplates ?? {},
110
- passthroughBehavior:
111
- options?.passthroughBehavior ?? PassthroughBehavior.WHEN_NO_MATCH,
112
- });
113
- }
114
-
115
- export function getResponse(
116
- response: IntegrationResponse,
117
- options?: IntegrationOptions
118
- ): IntegrationResponse {
119
- if (options?.xml) {
120
- response = { ...response, ...RESPONSE_XML };
121
- }
122
- if (!options?.disableCors) {
123
- response = { ...response, ...RESPONSE_CORS_INTEGRATION };
124
- }
125
-
126
- return response;
127
- }
@@ -1,108 +0,0 @@
1
- import {
2
- MethodResponse,
3
- MockIntegration,
4
- PassthroughBehavior,
5
- Resource,
6
- } from "aws-cdk-lib/aws-apigateway";
7
- import { MediaType } from "../../types/mediatypes.mjs";
8
- import { RESPONSE_CORS_INTEGRATION } from "./responses.mjs";
9
-
10
- const INTEGRATION_RESPONSE_200 = `{
11
- "statusCode": 200
12
- }`;
13
-
14
- const METHOD_RESPONSE_200 = {
15
- statusCode: "200",
16
- };
17
-
18
- /**
19
- * Static integration, that returns the given response with given mediaType from given resource.
20
- *
21
- * @param resource
22
- * @param mediaType
23
- * @param response
24
- */
25
- export class DigitrafficStaticIntegration extends MockIntegration {
26
- constructor(
27
- resource: Resource,
28
- mediaType: MediaType,
29
- response: string,
30
- enableCors = true,
31
- apiKeyRequired = true
32
- ) {
33
- const integrationResponse =
34
- DigitrafficStaticIntegration.createIntegrationResponse(
35
- response,
36
- mediaType,
37
- enableCors
38
- );
39
-
40
- super({
41
- passthroughBehavior: PassthroughBehavior.WHEN_NO_TEMPLATES,
42
- requestTemplates: {
43
- [mediaType]: INTEGRATION_RESPONSE_200,
44
- },
45
- integrationResponses: [integrationResponse],
46
- });
47
-
48
- ["GET", "HEAD"].forEach((httpMethod) => {
49
- resource.addMethod(httpMethod, this, {
50
- apiKeyRequired,
51
- methodResponses: [
52
- DigitrafficStaticIntegration.createMethodResponse(
53
- enableCors
54
- ),
55
- ],
56
- });
57
- });
58
- }
59
-
60
- static json<K>(
61
- resource: Resource,
62
- response: K,
63
- enableCors = true,
64
- apiKeyRequired = true
65
- ) {
66
- return new DigitrafficStaticIntegration(
67
- resource,
68
- MediaType.APPLICATION_JSON,
69
- JSON.stringify(response),
70
- enableCors,
71
- apiKeyRequired
72
- );
73
- }
74
-
75
- private static createIntegrationResponse(
76
- response: string,
77
- mediaType: MediaType,
78
- enableCors: boolean
79
- ) {
80
- const integrationResponse = {
81
- statusCode: "200",
82
- responseTemplates: {
83
- [mediaType]: response,
84
- },
85
- };
86
-
87
- return enableCors
88
- ? { ...integrationResponse, ...RESPONSE_CORS_INTEGRATION }
89
- : integrationResponse;
90
- }
91
-
92
- private static createMethodResponse(enableCors: boolean) {
93
- return enableCors
94
- ? corsMethod(METHOD_RESPONSE_200)
95
- : METHOD_RESPONSE_200;
96
- }
97
- }
98
-
99
- function corsMethod(response: MethodResponse): MethodResponse {
100
- return {
101
- ...response,
102
- ...{
103
- responseParameters: {
104
- "method.response.header.Access-Control-Allow-Origin": true,
105
- },
106
- },
107
- };
108
- }
@@ -1,21 +0,0 @@
1
- declare module 'Synthetics' {
2
- import {type RequestOptions} from "http";
3
-
4
- interface SyntheticsConfiguration {
5
- withIncludeRequestBody: (value: boolean) => SyntheticsConfiguration;
6
- withIncludeRequestHeaders: (value: boolean) => SyntheticsConfiguration;
7
- withIncludeResponseBody: (value: boolean) => SyntheticsConfiguration;
8
- withIncludeResponseHeaders: (value: boolean) => SyntheticsConfiguration;
9
- withFailedCanaryMetric: (value: boolean) => SyntheticsConfiguration;
10
- disableRequestMetrics: () => SyntheticsConfiguration;
11
- }
12
-
13
- export function executeHttpStep<T>(
14
- name: string,
15
- requestOptions: RequestOptions,
16
- callback: JsonCheckerFunction<T>
17
- ): Promise<void>;
18
- export function getConfiguration(): SyntheticsConfiguration;
19
-
20
- export function executeStep(s: string, f: ()=>void, c: Record<string, boolean>)
21
- };
@@ -1,33 +0,0 @@
1
- import { Construct } from "constructs";
2
- import { CanaryParameters } from "./canary-parameters.mjs";
3
- import { Alarm, ComparisonOperator } from "aws-cdk-lib/aws-cloudwatch";
4
- import { Canary } from "aws-cdk-lib/aws-synthetics";
5
- import { SnsAction } from "aws-cdk-lib/aws-cloudwatch-actions";
6
- import { Topic } from "aws-cdk-lib/aws-sns";
7
-
8
- export class CanaryAlarm {
9
- constructor(stack: Construct, canary: Canary, params: CanaryParameters) {
10
- const alarmName = params.alarm?.alarmName ?? `${params.name}-alarm`;
11
-
12
- const alarm = new Alarm(stack, alarmName, {
13
- alarmName,
14
- alarmDescription: params.alarm?.description ?? "",
15
- metric: canary.metricSuccessPercent(),
16
- evaluationPeriods: params.alarm?.evalutionPeriods ?? 1,
17
- threshold: params.alarm?.threshold ?? 100,
18
- comparisonOperator: ComparisonOperator.LESS_THAN_THRESHOLD,
19
- });
20
-
21
- if (params.alarm?.topicArn) {
22
- alarm.addAlarmAction(
23
- new SnsAction(
24
- Topic.fromTopicArn(
25
- stack,
26
- `${alarmName}-action`,
27
- params.alarm.topicArn
28
- )
29
- )
30
- );
31
- }
32
- }
33
- }
@@ -1,3 +0,0 @@
1
- export const ENV_API_KEY = "apiKeyId";
2
- export const ENV_HOSTNAME = "hostname";
3
- export const ENV_SECRET = "secret";
@@ -1,19 +0,0 @@
1
- import { Schedule } from "aws-cdk-lib/aws-synthetics";
2
-
3
- /** Optional env parameters for canary */
4
- type CanaryEnv = Record<string, string>;
5
-
6
- export interface CanaryParameters {
7
- readonly name: string;
8
- readonly schedule?: Schedule;
9
- readonly secret?: string;
10
- readonly handler: string;
11
- readonly alarm?: {
12
- readonly alarmName?: string;
13
- readonly description?: string;
14
- readonly evalutionPeriods?: number;
15
- readonly threshold?: number;
16
- readonly topicArn?: string;
17
- };
18
- readonly canaryEnv?: CanaryEnv;
19
- }
@@ -1,73 +0,0 @@
1
- import {
2
- ManagedPolicy,
3
- PolicyStatement,
4
- PolicyStatementProps,
5
- Role,
6
- ServicePrincipal,
7
- } from "aws-cdk-lib/aws-iam";
8
- import { Construct } from "constructs";
9
-
10
- const BASE_POLICY_STATEMENT_PROPS: PolicyStatementProps = {
11
- actions: [
12
- "logs:CreateLogStream",
13
- "logs:PutLogEvents",
14
- "logs:CreateLogGroup",
15
- "logs:DescribeLogGroups",
16
- "logs:DescribeLogStreams",
17
- ],
18
- resources: ["*"],
19
- };
20
-
21
- const CLOUDWATCH_STATEMENT_PROPS: PolicyStatementProps = {
22
- actions: ["cloudwatch:PutMetricData"],
23
- resources: ["*"],
24
- conditions: {
25
- StringEquals: {
26
- "cloudwatch:namespace": "CloudWatchSynthetics",
27
- },
28
- },
29
- };
30
-
31
- export class DigitrafficCanaryRole extends Role {
32
- constructor(stack: Construct, canaryName: string) {
33
- super(stack, "canary-role-" + canaryName, {
34
- assumedBy: new ServicePrincipal("lambda.amazonaws.com"),
35
- managedPolicies: [
36
- ManagedPolicy.fromAwsManagedPolicyName(
37
- "CloudWatchSyntheticsFullAccess"
38
- ),
39
- ],
40
- });
41
-
42
- this.addToPolicy(new PolicyStatement(BASE_POLICY_STATEMENT_PROPS));
43
- this.addToPolicy(new PolicyStatement(CLOUDWATCH_STATEMENT_PROPS));
44
- }
45
-
46
- /**
47
- * Provides permissions to access resources within a VPC.
48
- */
49
- withDatabaseAccess(): this {
50
- // Won't work :(
51
- // this.addToPolicy(new PolicyStatement(DB_STATEMENT_PROPS));
52
- // Works
53
- this.addManagedPolicy(
54
- ManagedPolicy.fromAwsManagedPolicyName(
55
- "service-role/AWSLambdaVPCAccessExecutionRole"
56
- )
57
- );
58
- return this;
59
- }
60
-
61
- /**
62
- * Same as withDatabaseAccess() - renamed to avoid confusion if used with UrlCanary.
63
- * A UrlCanary needs these permissions to e.g. access a private API Gateway endpoint in a VPC.
64
- */
65
- withVpcAccess(): this {
66
- this.addManagedPolicy(
67
- ManagedPolicy.fromAwsManagedPolicyName(
68
- "service-role/AWSLambdaVPCAccessExecutionRole"
69
- )
70
- );
71
- return this;
72
- }
73
- }
@@ -1,44 +0,0 @@
1
- import { Duration } from "aws-cdk-lib";
2
- import {
3
- AssetCode,
4
- Canary,
5
- Runtime,
6
- Schedule,
7
- Test,
8
- } from "aws-cdk-lib/aws-synthetics";
9
- import { Role } from "aws-cdk-lib/aws-iam";
10
- import { CanaryAlarm } from "./canary-alarm.mjs";
11
- import { CanaryParameters } from "./canary-parameters.mjs";
12
- import { Construct } from "constructs";
13
- import { LambdaEnvironment } from "../stack/lambda-configs.mjs";
14
-
15
- export class DigitrafficCanary extends Canary {
16
- constructor(
17
- scope: Construct,
18
- canaryName: string,
19
- role: Role,
20
- params: CanaryParameters,
21
- environmentVariables: LambdaEnvironment
22
- ) {
23
- super(scope, canaryName, {
24
- runtime: Runtime.SYNTHETICS_NODEJS_PUPPETEER_4_0,
25
- role,
26
- test: Test.custom({
27
- code: new AssetCode("dist", {
28
- exclude: ["lambda", "out", "canaries"],
29
- }),
30
- handler: params.handler,
31
- }),
32
- environmentVariables: {
33
- ...environmentVariables,
34
- ...params.canaryEnv,
35
- },
36
- canaryName,
37
- schedule: params.schedule ?? Schedule.rate(Duration.minutes(15)),
38
- });
39
-
40
- this.artifactsBucket.grantWrite(role);
41
-
42
- new CanaryAlarm(scope, this, params);
43
- }
44
- }
@@ -1,98 +0,0 @@
1
- import { Role } from "aws-cdk-lib/aws-iam";
2
- import { ISecret } from "aws-cdk-lib/aws-secretsmanager";
3
- import { CfnCanary } from "aws-cdk-lib/aws-synthetics";
4
- import { Schedule } from "aws-cdk-lib/aws-events";
5
- import { Duration } from "aws-cdk-lib";
6
-
7
- import { CanaryParameters } from "./canary-parameters.mjs";
8
- import { DigitrafficCanary } from "./canary.mjs";
9
- import { DigitrafficStack } from "../stack/stack.mjs";
10
-
11
- export class DatabaseCanary extends DigitrafficCanary {
12
- constructor(
13
- stack: DigitrafficStack,
14
- role: Role,
15
- secret: ISecret,
16
- params: CanaryParameters
17
- ) {
18
- const canaryName = `${params.name}-db`;
19
- const environmentVariables = stack.createDefaultLambdaEnvironment(
20
- `Synthetics-${canaryName}`
21
- );
22
-
23
- // the handler code is defined at the actual project using this
24
- super(stack, canaryName, role, params, environmentVariables);
25
-
26
- this.artifactsBucket.grantWrite(this.role);
27
- secret.grantRead(this.role);
28
-
29
- // need to override vpc and security group, can't do this with cdk
30
- if (this.node.defaultChild instanceof CfnCanary) {
31
- const subnetIds =
32
- stack.vpc === undefined
33
- ? []
34
- : stack.vpc.privateSubnets.map((subnet) => subnet.subnetId);
35
-
36
- const securityGroupIds =
37
- stack.lambdaDbSg === undefined
38
- ? []
39
- : [stack.lambdaDbSg.securityGroupId];
40
-
41
- this.node.defaultChild.vpcConfig = {
42
- vpcId: stack.vpc?.vpcId,
43
- securityGroupIds,
44
- subnetIds,
45
- };
46
- }
47
- }
48
-
49
- static create(
50
- stack: DigitrafficStack,
51
- role: Role,
52
- params: CanaryParameters
53
- ): DatabaseCanary {
54
- const secret = stack.getSecret();
55
- return new DatabaseCanary(stack, role, secret, {
56
- ...{
57
- secret: stack.configuration.secretId,
58
- schedule: Schedule.rate(Duration.hours(1)),
59
- handler: `${params.name}.handler`,
60
- },
61
- ...params,
62
- });
63
- }
64
-
65
- /**
66
- *
67
- * @param stack
68
- * @param role
69
- * @param name name of the typescipt file without -db -suffix. Max len is 10 char if @param canaryName is not given.
70
- * @param params
71
- * @param canaryName Optional name for canary if multiple canaries is made from same ${name}-db.ts canary file.
72
- */
73
- static createV2(
74
- stack: DigitrafficStack,
75
- role: Role,
76
- name: string,
77
- params: Partial<CanaryParameters> = {},
78
- canaryName = name
79
- ): DatabaseCanary {
80
- const secret = stack.getSecret();
81
- return new DatabaseCanary(stack, role, secret, {
82
- ...{
83
- secret: stack.configuration.secretId,
84
- schedule: Schedule.rate(Duration.hours(1)),
85
- handler: `${name}-db.handler`,
86
- name: canaryName,
87
- alarm: {
88
- alarmName:
89
- canaryName === name
90
- ? `${stack.configuration.shortName}-DB-Alarm`
91
- : `${canaryName}-DB-Alarm`,
92
- topicArn: stack.configuration.alarmTopicArn,
93
- },
94
- },
95
- ...params,
96
- });
97
- }
98
- }
@@ -1,163 +0,0 @@
1
- import { DTDatabase, inDatabaseReadonly } from "../../../database/database.mjs";
2
- import { ProxyHolder } from "../../runtime/secrets/proxy-holder.mjs";
3
- import { RdsHolder } from "../../runtime/secrets/rds-holder.mjs";
4
- import { getEnvVariable } from "../../../utils/utils.mjs";
5
- import { Countable } from "../../../database/models.mjs";
6
- import { logger } from "../../runtime/dt-logger-default.mjs";
7
-
8
- import synthetics from "Synthetics";
9
-
10
- abstract class DatabaseCheck<T> {
11
- readonly name: string;
12
- readonly sql: string;
13
- failed: boolean;
14
-
15
- protected constructor(name: string, sql: string) {
16
- this.name = name;
17
- this.sql = sql;
18
- this.failed = false;
19
- }
20
-
21
- abstract check(value: T): void;
22
- }
23
-
24
- class CountDatabaseCheck extends DatabaseCheck<Countable> {
25
- readonly minCount: number | null;
26
- readonly maxCount: number | null;
27
-
28
- constructor(
29
- name: string,
30
- sql: string,
31
- minCount: number | null,
32
- maxCount: number | null
33
- ) {
34
- super(name, sql);
35
-
36
- if (
37
- !sql.toLowerCase().includes("select") ||
38
- !sql.toLowerCase().includes("count")
39
- ) {
40
- throw new Error("sql must contain select count(*)");
41
- }
42
-
43
- if (minCount == null && maxCount == null) {
44
- throw new Error("no max or min given");
45
- }
46
-
47
- this.minCount = minCount;
48
- this.maxCount = maxCount;
49
- }
50
-
51
- check(value: Countable) {
52
- if ("count" in value) {
53
- if (this.minCount && value.count < this.minCount) {
54
- this.failed = true;
55
- throw new Error(
56
- `count was ${value.count}, minimum is ${this.minCount}`
57
- );
58
- }
59
- if (this.maxCount && value.count > this.maxCount) {
60
- this.failed = true;
61
- throw new Error(
62
- `count was ${value.count}, max is ${this.maxCount}`
63
- );
64
- }
65
- } else {
66
- this.failed = true;
67
-
68
- throw new Error("no count available");
69
- }
70
- }
71
- }
72
-
73
- const stepConfig = {
74
- continueOnStepFailure: true,
75
- screenshotOnStepStart: false,
76
- screenshotOnStepSuccess: false,
77
- screenshotOnStepFailure: false,
78
- };
79
-
80
- /**
81
- * Checker for sql that checks the count. Meaning that the
82
- * sql must be structured as "select count(*) from <table> where <something>".
83
- */
84
- export class DatabaseCountChecker {
85
- readonly credentialsFunction: () => Promise<void>;
86
- readonly checks: DatabaseCheck<Countable>[] = [];
87
-
88
- private constructor(credentialsFunction: () => Promise<void>) {
89
- this.credentialsFunction = credentialsFunction;
90
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
91
- synthetics.getConfiguration().disableRequestMetrics();
92
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
93
- synthetics.getConfiguration().withFailedCanaryMetric(true);
94
- }
95
-
96
- static createForProxy() {
97
- return new DatabaseCountChecker(() =>
98
- new ProxyHolder(getEnvVariable("SECRET_ID")).setCredentials()
99
- );
100
- }
101
-
102
- static createForRds() {
103
- return new DatabaseCountChecker(() =>
104
- new RdsHolder(getEnvVariable("SECRET_ID")).setCredentials()
105
- );
106
- }
107
-
108
- /**
109
- * Expect that the count is 1
110
- */
111
- expectOne(name: string, sql: string) {
112
- this.checks.push(new CountDatabaseCheck(name, sql, 1, 1));
113
-
114
- return this;
115
- }
116
-
117
- /**
118
- * Expect that the count is 0
119
- */
120
- expectZero(name: string, sql: string) {
121
- this.checks.push(new CountDatabaseCheck(name, sql, null, 0));
122
-
123
- return this;
124
- }
125
-
126
- /**
127
- * Expect that the count is 1 or more
128
- */
129
- expectOneOrMore(name: string, sql: string) {
130
- this.checks.push(new CountDatabaseCheck(name, sql, 1, null));
131
-
132
- return this;
133
- }
134
-
135
- async expect() {
136
- if (!this.checks.length) {
137
- throw new Error("No checks");
138
- }
139
-
140
- await this.credentialsFunction();
141
- await inDatabaseReadonly(async (db: DTDatabase) => {
142
- for (const check of this.checks) {
143
- logger.info({
144
- method: "DatabaseCountChecker.expect",
145
- message: "Running sql: " + check.sql,
146
- });
147
-
148
- const value = await db.one<Countable>(check.sql);
149
- const checkFunction = () => {
150
- check.check(value);
151
- };
152
-
153
- synthetics.executeStep(check.name, checkFunction, stepConfig);
154
- }
155
- });
156
-
157
- if (this.checks.some((check) => check.failed)) {
158
- throw new Error("Failed");
159
- }
160
-
161
- return "OK";
162
- }
163
- }