@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.
Files changed (332) hide show
  1. package/{aws → dist/aws}/infra/api/integration.d.ts +0 -0
  2. package/dist/aws/infra/api/integration.js +52 -0
  3. package/dist/aws/infra/api/integration.js.map +1 -0
  4. package/{aws → dist/aws}/infra/api/response.d.ts +0 -0
  5. package/dist/aws/infra/api/response.js +61 -0
  6. package/dist/aws/infra/api/response.js.map +1 -0
  7. package/{aws → dist/aws}/infra/api/responses.d.ts +3 -3
  8. package/dist/aws/infra/api/responses.js +82 -0
  9. package/dist/aws/infra/api/responses.js.map +1 -0
  10. package/{aws → dist/aws}/infra/api/static-integration.d.ts +0 -0
  11. package/dist/aws/infra/api/static-integration.js +54 -0
  12. package/dist/aws/infra/api/static-integration.js.map +1 -0
  13. package/{aws → dist/aws}/infra/canaries/canary-alarm.d.ts +0 -0
  14. package/dist/aws/infra/canaries/canary-alarm.js +26 -0
  15. package/dist/aws/infra/canaries/canary-alarm.js.map +1 -0
  16. package/dist/aws/infra/canaries/canary-keys.d.ts +3 -0
  17. package/dist/aws/infra/canaries/canary-keys.js +7 -0
  18. package/dist/aws/infra/canaries/canary-keys.js.map +1 -0
  19. package/{aws → dist/aws}/infra/canaries/canary-parameters.d.ts +0 -0
  20. package/dist/aws/infra/canaries/canary-parameters.js +3 -0
  21. package/dist/aws/infra/canaries/canary-parameters.js.map +1 -0
  22. package/{aws → dist/aws}/infra/canaries/canary-role.d.ts +0 -0
  23. package/dist/aws/infra/canaries/canary-role.js +46 -0
  24. package/dist/aws/infra/canaries/canary-role.js.map +1 -0
  25. package/{aws → dist/aws}/infra/canaries/canary.d.ts +0 -0
  26. package/dist/aws/infra/canaries/canary.js +32 -0
  27. package/dist/aws/infra/canaries/canary.js.map +1 -0
  28. package/{aws → dist/aws}/infra/canaries/database-canary.d.ts +0 -0
  29. package/dist/aws/infra/canaries/database-canary.js +70 -0
  30. package/dist/aws/infra/canaries/database-canary.js.map +1 -0
  31. package/{aws → dist/aws}/infra/canaries/database-checker.d.ts +2 -2
  32. package/dist/aws/infra/canaries/database-checker.js +103 -0
  33. package/dist/aws/infra/canaries/database-checker.js.map +1 -0
  34. package/{aws → dist/aws}/infra/canaries/url-canary.d.ts +0 -3
  35. package/dist/aws/infra/canaries/url-canary.js +47 -0
  36. package/dist/aws/infra/canaries/url-canary.js.map +1 -0
  37. package/{aws → dist/aws}/infra/canaries/url-checker.d.ts +0 -0
  38. package/dist/aws/infra/canaries/url-checker.js +252 -0
  39. package/dist/aws/infra/canaries/url-checker.js.map +1 -0
  40. package/{aws → dist/aws}/infra/documentation.d.ts +0 -0
  41. package/dist/aws/infra/documentation.js +95 -0
  42. package/dist/aws/infra/documentation.js.map +1 -0
  43. package/{aws → dist/aws}/infra/scheduler.d.ts +7 -7
  44. package/dist/aws/infra/scheduler.js +31 -0
  45. package/dist/aws/infra/scheduler.js.map +1 -0
  46. package/{aws → dist/aws}/infra/security-rule.d.ts +0 -0
  47. package/dist/aws/infra/security-rule.js +39 -0
  48. package/dist/aws/infra/security-rule.js.map +1 -0
  49. package/{aws → dist/aws}/infra/sqs-integration.d.ts +0 -0
  50. package/dist/aws/infra/sqs-integration.js +93 -0
  51. package/dist/aws/infra/sqs-integration.js.map +1 -0
  52. package/{aws → dist/aws}/infra/sqs-queue.d.ts +0 -0
  53. package/dist/aws/infra/sqs-queue.js +130 -0
  54. package/dist/aws/infra/sqs-queue.js.map +1 -0
  55. package/{aws → dist/aws}/infra/stack/lambda-configs.d.ts +5 -5
  56. package/dist/aws/infra/stack/lambda-configs.js +105 -0
  57. package/dist/aws/infra/stack/lambda-configs.js.map +1 -0
  58. package/{aws → dist/aws}/infra/stack/monitoredfunction.d.ts +1 -1
  59. package/dist/aws/infra/stack/monitoredfunction.js +143 -0
  60. package/dist/aws/infra/stack/monitoredfunction.js.map +1 -0
  61. package/{aws → dist/aws}/infra/stack/rest_apis.d.ts +0 -0
  62. package/dist/aws/infra/stack/rest_apis.js +185 -0
  63. package/dist/aws/infra/stack/rest_apis.js.map +1 -0
  64. package/{aws → dist/aws}/infra/stack/stack-checking-aspect.d.ts +0 -0
  65. package/dist/aws/infra/stack/stack-checking-aspect.js +174 -0
  66. package/dist/aws/infra/stack/stack-checking-aspect.js.map +1 -0
  67. package/{aws → dist/aws}/infra/stack/stack.d.ts +5 -4
  68. package/dist/aws/infra/stack/stack.js +67 -0
  69. package/dist/aws/infra/stack/stack.js.map +1 -0
  70. package/{aws → dist/aws}/infra/stack/subscription.d.ts +3 -3
  71. package/dist/aws/infra/stack/subscription.js +42 -0
  72. package/dist/aws/infra/stack/subscription.js.map +1 -0
  73. package/{aws → dist/aws}/infra/usage-plans.d.ts +0 -0
  74. package/dist/aws/infra/usage-plans.js +42 -0
  75. package/dist/aws/infra/usage-plans.js.map +1 -0
  76. package/{aws → dist/aws}/runtime/apikey.d.ts +0 -0
  77. package/dist/aws/runtime/apikey.js +13 -0
  78. package/dist/aws/runtime/apikey.js.map +1 -0
  79. package/{aws → dist/aws}/runtime/digitraffic-integration-response.d.ts +0 -0
  80. package/dist/aws/runtime/digitraffic-integration-response.js +26 -0
  81. package/dist/aws/runtime/digitraffic-integration-response.js.map +1 -0
  82. package/{aws → dist/aws}/runtime/environment.d.ts +0 -0
  83. package/dist/aws/runtime/environment.js +12 -0
  84. package/dist/aws/runtime/environment.js.map +1 -0
  85. package/{aws → dist/aws}/runtime/messaging.d.ts +0 -0
  86. package/dist/aws/runtime/messaging.js +31 -0
  87. package/dist/aws/runtime/messaging.js.map +1 -0
  88. package/{aws → dist/aws}/runtime/s3.d.ts +0 -0
  89. package/dist/aws/runtime/s3.js +30 -0
  90. package/dist/aws/runtime/s3.js.map +1 -0
  91. package/{aws → dist/aws}/runtime/secrets/dbsecret.d.ts +0 -0
  92. package/dist/aws/runtime/secrets/dbsecret.js +96 -0
  93. package/dist/aws/runtime/secrets/dbsecret.js.map +1 -0
  94. package/{aws → dist/aws}/runtime/secrets/proxy-holder.d.ts +0 -0
  95. package/dist/aws/runtime/secrets/proxy-holder.js +27 -0
  96. package/dist/aws/runtime/secrets/proxy-holder.js.map +1 -0
  97. package/{aws → dist/aws}/runtime/secrets/rds-holder.d.ts +0 -0
  98. package/dist/aws/runtime/secrets/rds-holder.js +27 -0
  99. package/dist/aws/runtime/secrets/rds-holder.js.map +1 -0
  100. package/{aws → dist/aws}/runtime/secrets/secret-holder.d.ts +0 -0
  101. package/dist/aws/runtime/secrets/secret-holder.js +76 -0
  102. package/dist/aws/runtime/secrets/secret-holder.js.map +1 -0
  103. package/{aws → dist/aws}/runtime/secrets/secret.d.ts +0 -0
  104. package/dist/aws/runtime/secrets/secret.js +43 -0
  105. package/dist/aws/runtime/secrets/secret.js.map +1 -0
  106. package/{aws → dist/aws}/types/errors.d.ts +4 -0
  107. package/dist/aws/types/errors.js +16 -0
  108. package/dist/aws/types/errors.js.map +1 -0
  109. package/{aws → dist/aws}/types/lambda-response.d.ts +4 -3
  110. package/dist/aws/types/lambda-response.js +33 -0
  111. package/dist/aws/types/lambda-response.js.map +1 -0
  112. package/{aws → dist/aws}/types/mediatypes.d.ts +1 -1
  113. package/dist/aws/types/mediatypes.js +16 -0
  114. package/dist/aws/types/mediatypes.js.map +1 -0
  115. package/{aws → dist/aws}/types/model-with-reference.d.ts +0 -0
  116. package/dist/aws/types/model-with-reference.js +3 -0
  117. package/dist/aws/types/model-with-reference.js.map +1 -0
  118. package/{aws → dist/aws}/types/proxytypes.d.ts +0 -0
  119. package/dist/aws/types/proxytypes.js +3 -0
  120. package/dist/aws/types/proxytypes.js.map +1 -0
  121. package/{aws → dist/aws}/types/tags.d.ts +0 -0
  122. package/dist/aws/types/tags.js +7 -0
  123. package/dist/aws/types/tags.js.map +1 -0
  124. package/{database → dist/database}/cached.d.ts +0 -0
  125. package/dist/database/cached.js +32 -0
  126. package/dist/database/cached.js.map +1 -0
  127. package/{database → dist/database}/database.d.ts +0 -0
  128. package/dist/database/database.js +70 -0
  129. package/dist/database/database.js.map +1 -0
  130. package/{database → dist/database}/last-updated.d.ts +0 -0
  131. package/dist/database/last-updated.js +54 -0
  132. package/dist/database/last-updated.js.map +1 -0
  133. package/{database → dist/database}/models.d.ts +0 -0
  134. package/dist/database/models.js +3 -0
  135. package/dist/database/models.js.map +1 -0
  136. package/{marine → dist/marine}/id_utils.d.ts +0 -0
  137. package/dist/marine/id_utils.js +33 -0
  138. package/dist/marine/id_utils.js.map +1 -0
  139. package/{marine → dist/marine}/rtz.d.ts +0 -0
  140. package/dist/marine/rtz.js +3 -0
  141. package/dist/marine/rtz.js.map +1 -0
  142. package/{test → dist/test}/asserter.d.ts +0 -0
  143. package/dist/test/asserter.js +45 -0
  144. package/dist/test/asserter.js.map +1 -0
  145. package/{test → dist/test}/db-testutils.d.ts +0 -0
  146. package/dist/test/db-testutils.js +31 -0
  147. package/dist/test/db-testutils.js.map +1 -0
  148. package/{test → dist/test}/httpserver.d.ts +2 -1
  149. package/dist/test/httpserver.js +74 -0
  150. package/dist/test/httpserver.js.map +1 -0
  151. package/{test → dist/test}/secret.d.ts +0 -0
  152. package/dist/test/secret.js +25 -0
  153. package/dist/test/secret.js.map +1 -0
  154. package/{test → dist/test}/secrets-manager.d.ts +0 -0
  155. package/dist/test/secrets-manager.js +59 -0
  156. package/dist/test/secrets-manager.js.map +1 -0
  157. package/{test → dist/test}/testutils.d.ts +0 -0
  158. package/dist/test/testutils.js +44 -0
  159. package/dist/test/testutils.js.map +1 -0
  160. package/dist/types/either.d.ts +9 -0
  161. package/dist/types/either.js +3 -0
  162. package/dist/types/either.js.map +1 -0
  163. package/{types → dist/types}/input-error.d.ts +0 -0
  164. package/dist/types/input-error.js +7 -0
  165. package/dist/types/input-error.js.map +1 -0
  166. package/{types → dist/types}/language.d.ts +0 -0
  167. package/dist/types/language.js +10 -0
  168. package/dist/types/language.js.map +1 -0
  169. package/{types → dist/types}/traffictype.d.ts +0 -0
  170. package/dist/types/traffictype.js +13 -0
  171. package/dist/types/traffictype.js.map +1 -0
  172. package/{types → dist/types}/validator.d.ts +0 -0
  173. package/dist/types/validator.js +14 -0
  174. package/dist/types/validator.js.map +1 -0
  175. package/{utils → dist/utils}/api-model.d.ts +0 -0
  176. package/dist/utils/api-model.js +129 -0
  177. package/dist/utils/api-model.js.map +1 -0
  178. package/{utils → dist/utils}/base64.d.ts +0 -0
  179. package/dist/utils/base64.js +21 -0
  180. package/dist/utils/base64.js.map +1 -0
  181. package/{utils → dist/utils}/date-utils.d.ts +0 -0
  182. package/dist/utils/date-utils.js +34 -0
  183. package/dist/utils/date-utils.js.map +1 -0
  184. package/{utils → dist/utils}/geojson-types.d.ts +0 -0
  185. package/dist/utils/geojson-types.js +18 -0
  186. package/dist/utils/geojson-types.js.map +1 -0
  187. package/{utils → dist/utils}/geometry.d.ts +0 -0
  188. package/dist/utils/geometry.js +164 -0
  189. package/dist/utils/geometry.js.map +1 -0
  190. package/{utils → dist/utils}/retry.d.ts +0 -0
  191. package/dist/utils/retry.js +50 -0
  192. package/dist/utils/retry.js.map +1 -0
  193. package/{utils → dist/utils}/slack.d.ts +0 -0
  194. package/dist/utils/slack.js +25 -0
  195. package/dist/utils/slack.js.map +1 -0
  196. package/{utils → dist/utils}/utils.d.ts +16 -0
  197. package/dist/utils/utils.js +75 -0
  198. package/dist/utils/utils.js.map +1 -0
  199. package/package.json +12 -10
  200. package/src/@types/geojson-validation/index.d.ts +4 -0
  201. package/src/aws/infra/api/integration.ts +73 -0
  202. package/src/aws/infra/api/response.ts +67 -0
  203. package/src/aws/infra/api/responses.ts +124 -0
  204. package/src/aws/infra/api/static-integration.ts +62 -0
  205. package/src/aws/infra/canaries/canary-alarm.ts +31 -0
  206. package/src/aws/infra/canaries/canary-keys.ts +3 -0
  207. package/src/aws/infra/canaries/canary-parameters.ts +19 -0
  208. package/src/aws/infra/canaries/canary-role.ts +47 -0
  209. package/src/aws/infra/canaries/canary.ts +46 -0
  210. package/src/aws/infra/canaries/database-canary.ts +98 -0
  211. package/src/aws/infra/canaries/database-checker.ts +155 -0
  212. package/src/aws/infra/canaries/url-canary.ts +74 -0
  213. package/src/aws/infra/canaries/url-checker.ts +366 -0
  214. package/src/aws/infra/documentation.ts +124 -0
  215. package/src/aws/infra/scheduler.ts +59 -0
  216. package/src/aws/infra/security-rule.ts +38 -0
  217. package/src/aws/infra/sqs-integration.ts +102 -0
  218. package/src/aws/infra/sqs-queue.ts +148 -0
  219. package/src/aws/infra/stack/lambda-configs.ts +207 -0
  220. package/src/aws/infra/stack/monitoredfunction.ts +342 -0
  221. package/src/aws/infra/stack/rest_apis.ts +223 -0
  222. package/src/aws/infra/stack/stack-checking-aspect.ts +279 -0
  223. package/src/aws/infra/stack/stack.ts +145 -0
  224. package/src/aws/infra/stack/subscription.ts +58 -0
  225. package/src/aws/infra/usage-plans.ts +41 -0
  226. package/src/aws/runtime/apikey.ts +9 -0
  227. package/src/aws/runtime/digitraffic-integration-response.ts +28 -0
  228. package/src/aws/runtime/environment.ts +9 -0
  229. package/src/aws/runtime/messaging.ts +26 -0
  230. package/src/aws/runtime/s3.ts +44 -0
  231. package/src/aws/runtime/secrets/dbsecret.ts +116 -0
  232. package/src/aws/runtime/secrets/proxy-holder.ts +37 -0
  233. package/src/aws/runtime/secrets/rds-holder.ts +33 -0
  234. package/src/aws/runtime/secrets/secret-holder.ts +116 -0
  235. package/src/aws/runtime/secrets/secret.ts +50 -0
  236. package/src/aws/types/errors.ts +14 -0
  237. package/src/aws/types/lambda-response.ts +43 -0
  238. package/src/aws/types/mediatypes.ts +11 -0
  239. package/src/aws/types/model-with-reference.ts +8 -0
  240. package/src/aws/types/proxytypes.ts +27 -0
  241. package/src/aws/types/tags.ts +3 -0
  242. package/src/database/cached.ts +35 -0
  243. package/src/database/database.ts +96 -0
  244. package/src/database/last-updated.ts +59 -0
  245. package/src/database/models.ts +7 -0
  246. package/src/marine/id_utils.ts +30 -0
  247. package/src/marine/rtz.ts +57 -0
  248. package/src/test/asserter.ts +48 -0
  249. package/src/test/db-testutils.ts +44 -0
  250. package/src/test/httpserver.ts +96 -0
  251. package/src/test/secret.ts +23 -0
  252. package/src/test/secrets-manager.ts +34 -0
  253. package/src/test/testutils.ts +39 -0
  254. package/src/types/either.ts +3 -0
  255. package/src/types/input-error.ts +2 -0
  256. package/src/types/language.ts +3 -0
  257. package/src/types/traffictype.ts +8 -0
  258. package/src/types/validator.ts +10 -0
  259. package/src/utils/api-model.ts +133 -0
  260. package/src/utils/base64.ts +16 -0
  261. package/src/utils/date-utils.ts +30 -0
  262. package/src/utils/geojson-types.ts +22 -0
  263. package/src/utils/geometry.ts +164 -0
  264. package/src/utils/retry.ts +49 -0
  265. package/src/utils/slack.ts +22 -0
  266. package/src/utils/utils.ts +105 -0
  267. package/aws/infra/api/integration.js +0 -52
  268. package/aws/infra/api/response.js +0 -61
  269. package/aws/infra/api/responses.js +0 -79
  270. package/aws/infra/api/static-integration.js +0 -54
  271. package/aws/infra/canaries/canary-alarm.js +0 -26
  272. package/aws/infra/canaries/canary-parameters.js +0 -3
  273. package/aws/infra/canaries/canary-role.js +0 -46
  274. package/aws/infra/canaries/canary.js +0 -32
  275. package/aws/infra/canaries/database-canary.js +0 -55
  276. package/aws/infra/canaries/database-checker.js +0 -109
  277. package/aws/infra/canaries/url-canary.js +0 -46
  278. package/aws/infra/canaries/url-checker.js +0 -238
  279. package/aws/infra/documentation.js +0 -95
  280. package/aws/infra/scheduler.js +0 -31
  281. package/aws/infra/security-rule.js +0 -39
  282. package/aws/infra/sqs-integration.js +0 -93
  283. package/aws/infra/sqs-queue.js +0 -130
  284. package/aws/infra/stack/lambda-configs.js +0 -93
  285. package/aws/infra/stack/monitoredfunction.js +0 -135
  286. package/aws/infra/stack/rest_apis.js +0 -185
  287. package/aws/infra/stack/stack-checking-aspect.js +0 -174
  288. package/aws/infra/stack/stack.js +0 -60
  289. package/aws/infra/stack/subscription.js +0 -41
  290. package/aws/infra/usage-plans.js +0 -42
  291. package/aws/runtime/apikey.js +0 -13
  292. package/aws/runtime/digitraffic-integration-response.js +0 -26
  293. package/aws/runtime/environment.js +0 -12
  294. package/aws/runtime/messaging.js +0 -31
  295. package/aws/runtime/s3.js +0 -30
  296. package/aws/runtime/secrets/dbsecret.js +0 -96
  297. package/aws/runtime/secrets/proxy-holder.js +0 -26
  298. package/aws/runtime/secrets/rds-holder.js +0 -26
  299. package/aws/runtime/secrets/secret-holder.js +0 -73
  300. package/aws/runtime/secrets/secret.js +0 -43
  301. package/aws/types/errors.js +0 -9
  302. package/aws/types/lambda-response.js +0 -28
  303. package/aws/types/mediatypes.js +0 -15
  304. package/aws/types/model-with-reference.js +0 -3
  305. package/aws/types/proxytypes.js +0 -3
  306. package/aws/types/tags.js +0 -7
  307. package/database/cached.js +0 -32
  308. package/database/database.js +0 -62
  309. package/database/last-updated.js +0 -54
  310. package/database/models.js +0 -3
  311. package/index.d.ts +0 -1
  312. package/index.js +0 -18
  313. package/marine/id_utils.js +0 -33
  314. package/marine/rtz.js +0 -3
  315. package/test/asserter.js +0 -45
  316. package/test/db-testutils.js +0 -31
  317. package/test/httpserver.js +0 -67
  318. package/test/secret.js +0 -25
  319. package/test/secrets-manager.js +0 -59
  320. package/test/testutils.js +0 -44
  321. package/types/input-error.js +0 -7
  322. package/types/language.js +0 -10
  323. package/types/traffictype.js +0 -13
  324. package/types/validator.js +0 -14
  325. package/utils/api-model.js +0 -129
  326. package/utils/base64.js +0 -21
  327. package/utils/date-utils.js +0 -34
  328. package/utils/geojson-types.js +0 -18
  329. package/utils/geometry.js +0 -140
  330. package/utils/retry.js +0 -50
  331. package/utils/slack.js +0 -25
  332. package/utils/utils.js +0 -64
@@ -0,0 +1,124 @@
1
+ import {Construct} from "constructs";
2
+ import {CfnDocumentationPart, Resource} from "aws-cdk-lib/aws-apigateway";
3
+
4
+ // Documentation parts are objects that describe an API Gateway API or parts of an API
5
+ // https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-documenting-api.html
6
+
7
+ /**
8
+ * Add description to a query parameter
9
+ * @param name query parameter name
10
+ * @param description query parameter description
11
+ * @param resource REST API resource
12
+ * @param stack CloudFormation stack
13
+ *
14
+ * @deprecated Use DigitrafficRestApi.documentResource
15
+ */
16
+ export function addQueryParameterDescription(name: string,
17
+ description: string,
18
+ resource: Resource,
19
+ stack: Construct) {
20
+ new CfnDocumentationPart(stack, `${name}Documentation`, {
21
+ restApiId: resource.api.restApiId,
22
+ location: {
23
+ type: 'QUERY_PARAMETER',
24
+ name,
25
+ path: resource.path,
26
+ },
27
+ properties: JSON.stringify({description}),
28
+ });
29
+ }
30
+
31
+ /**
32
+ * Add a documentation part to a method
33
+ * @param methodDescription
34
+ * @param documentationProperties
35
+ * @param resource REST API resource
36
+ * @param stack CloudFormation stack
37
+ */
38
+ export function addDocumentation(methodDescription: string,
39
+ documentationProperties: object,
40
+ resource: Resource,
41
+ stack: Construct) {
42
+ new CfnDocumentationPart(stack, `${methodDescription}Documentation`, {
43
+ restApiId: resource.api.restApiId,
44
+ location: {
45
+ type: 'METHOD',
46
+ path: resource.path,
47
+ },
48
+ properties: JSON.stringify(documentationProperties),
49
+ });
50
+ }
51
+
52
+ /**
53
+ * Adds OpenAPI tags to an API method
54
+ * @param methodDescription Description of API method
55
+ * @param tags OpenAPI tags
56
+ * @param resource REST API resource
57
+ * @param stack CloudFormation stack
58
+ */
59
+ export function addTags(methodDescription: string,
60
+ tags: string[],
61
+ resource: Resource,
62
+ stack: Construct) {
63
+ addDocumentation(methodDescription, {tags}, resource, stack);
64
+ }
65
+
66
+ /**
67
+ * Adds OpenAPI tags and a method summary to an API method
68
+ *
69
+ * @deprecated Use DigitrafficRestApi.documentResource
70
+ *
71
+ * @param methodDescription Description of API method
72
+ * @param tags OpenAPI tags
73
+ * @param summary OpenAPI summary
74
+ * @param resource REST API resource
75
+ * @param stack CloudFormation stack
76
+ */
77
+ export function addTagsAndSummary(
78
+ methodDescription: string,
79
+ tags: string[],
80
+ summary: string,
81
+ resource: Resource,
82
+ stack: Construct,
83
+ ) {
84
+ addDocumentation(methodDescription, {tags, summary}, resource, stack);
85
+ }
86
+
87
+ export interface DocumentationProperties {
88
+ description?: string
89
+ tags?: string[]
90
+ summary?: string
91
+ deprecated?: boolean
92
+ }
93
+
94
+ export class DocumentationPart {
95
+ readonly parameterName: string;
96
+ readonly type: string;
97
+ readonly documentationProperties: DocumentationProperties;
98
+
99
+ private constructor(parameterName: string, documentationProperties: DocumentationProperties, type: string) {
100
+ this.parameterName = parameterName;
101
+ this.documentationProperties = documentationProperties;
102
+ this.type = type;
103
+ }
104
+
105
+ deprecated(note: string): DocumentationPart {
106
+ // deprecated is not supported ATM: https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-known-issues.html
107
+ this.documentationProperties.deprecated = true;
108
+ this.documentationProperties.summary+= '. ' + note;
109
+
110
+ return this;
111
+ }
112
+
113
+ static queryParameter(parameterName: string, description: string) {
114
+ return new DocumentationPart(parameterName, {description}, "QUERY_PARAMETER");
115
+ }
116
+
117
+ static pathParameter(parameterName: string, description: string) {
118
+ return new DocumentationPart(parameterName, {description}, "PATH_PARAMETER");
119
+ }
120
+
121
+ static method(tags: string[], name: string, summary: string) {
122
+ return new DocumentationPart(name, {tags, summary}, "METHOD");
123
+ }
124
+ }
@@ -0,0 +1,59 @@
1
+ import { Rule, Schedule } from "aws-cdk-lib/aws-events";
2
+ import { Duration } from "aws-cdk-lib";
3
+ import { LambdaFunction } from "aws-cdk-lib/aws-events-targets";
4
+ import { Function as AWSFunction } from "aws-cdk-lib/aws-lambda";
5
+ import { Construct } from "constructs";
6
+
7
+ export class Scheduler extends Rule {
8
+ constructor(
9
+ stack: Construct,
10
+ ruleName: string,
11
+ schedule: Schedule,
12
+ lambda?: AWSFunction
13
+ ) {
14
+ super(stack, ruleName, { ruleName, schedule });
15
+
16
+ if (lambda) {
17
+ this.addTarget(new LambdaFunction(lambda));
18
+ }
19
+ }
20
+
21
+ static everyMinute(
22
+ stack: Construct,
23
+ ruleName: string,
24
+ lambda?: AWSFunction
25
+ ) {
26
+ return Scheduler.every(stack, ruleName, Duration.minutes(1), lambda);
27
+ }
28
+
29
+ static everyMinutes(
30
+ stack: Construct,
31
+ ruleName: string,
32
+ minutes: number,
33
+ lambda?: AWSFunction
34
+ ) {
35
+ return Scheduler.every(
36
+ stack,
37
+ ruleName,
38
+ Duration.minutes(minutes),
39
+ lambda
40
+ );
41
+ }
42
+
43
+ static everyHour(stack: Construct, ruleName: string, lambda?: AWSFunction) {
44
+ return Scheduler.every(stack, ruleName, Duration.hours(1), lambda);
45
+ }
46
+
47
+ static everyDay(stack: Construct, ruleName: string, lambda?: AWSFunction) {
48
+ return Scheduler.every(stack, ruleName, Duration.days(1), lambda);
49
+ }
50
+
51
+ static every(
52
+ stack: Construct,
53
+ ruleName: string,
54
+ duration: Duration,
55
+ lambda?: AWSFunction
56
+ ) {
57
+ return new Scheduler(stack, ruleName, Schedule.rate(duration), lambda);
58
+ }
59
+ }
@@ -0,0 +1,38 @@
1
+ import {Construct} from "constructs";
2
+ import {Rule} from "aws-cdk-lib/aws-events";
3
+ import {ITopic} from "aws-cdk-lib/aws-sns";
4
+ import {SnsTopic} from "aws-cdk-lib/aws-events-targets";
5
+
6
+ /**
7
+ * Automatic rule for Security Hub. Send notification to given topic if the following conditions apply:
8
+ * * There is a finding with a status of NEW
9
+ * * It has severity of HIGH or CRITICAL
10
+ * * It is in a FAILED state
11
+ */
12
+ export class DigitrafficSecurityRule extends Rule {
13
+ constructor(scope: Construct, topic: ITopic) {
14
+ const ruleName = 'SecurityHubRule';
15
+ super(scope, ruleName, {
16
+ ruleName,
17
+ eventPattern: {
18
+ source: ['aws.securityhub'],
19
+ detailType: ["Security Hub Findings - Imported"],
20
+ detail: {
21
+ findings: {
22
+ "Compliance": {
23
+ "Status": ["FAILED"],
24
+ },
25
+ "Workflow": {
26
+ "Status": ["NEW"],
27
+ },
28
+ "Severity": {
29
+ "Label": ["HIGH", "CRITICAL"],
30
+ },
31
+ },
32
+ },
33
+ },
34
+ });
35
+
36
+ this.addTarget(new SnsTopic(topic));
37
+ }
38
+ }
@@ -0,0 +1,102 @@
1
+ import {Aws} from "aws-cdk-lib";
2
+ import {AwsIntegration, PassthroughBehavior, RequestValidator, Resource} from "aws-cdk-lib/aws-apigateway";
3
+ import {Queue} from "aws-cdk-lib/aws-sqs";
4
+ import {PolicyStatement, Role, ServicePrincipal} from "aws-cdk-lib/aws-iam";
5
+ import {IModel} from "aws-cdk-lib/aws-apigateway/lib/model";
6
+ import {Construct} from "constructs";
7
+
8
+ export function attachQueueToApiGatewayResource(
9
+ stack: Construct,
10
+ queue: Queue,
11
+ resource: Resource,
12
+ requestValidator: RequestValidator,
13
+ resourceName: string,
14
+ apiKeyRequired: boolean,
15
+ requestModels?: {[param: string]: IModel},
16
+ ) {
17
+ // role for API Gateway
18
+ const apiGwRole = new Role(stack, `${resourceName}APIGatewayToSQSRole`, {
19
+ assumedBy: new ServicePrincipal('apigateway.amazonaws.com'),
20
+ });
21
+ // grants API Gateway the right to send SQS messages
22
+ apiGwRole.addToPolicy(new PolicyStatement({
23
+ resources: [
24
+ queue.queueArn,
25
+ ],
26
+ actions: [
27
+ 'sqs:SendMessage',
28
+ ],
29
+ }));
30
+ // grants API Gateway the right write CloudWatch Logs
31
+ apiGwRole.addToPolicy(new PolicyStatement({
32
+ resources: [
33
+ '*',
34
+ ],
35
+ actions: [
36
+ 'logs:CreateLogGroup',
37
+ 'logs:CreateLogStream',
38
+ 'logs:DescribeLogGroups',
39
+ 'logs:DescribeLogStreams',
40
+ 'logs:PutLogEvents',
41
+ 'logs:GetLogEvents',
42
+ 'logs:FilterLogEvents',
43
+ ],
44
+ }));
45
+ // create an integration between API Gateway and an SQS queue
46
+ const fifoMessageGroupId = queue.fifo ? '&MessageGroupId=AlwaysSameFifoGroup' : '';
47
+ const sqsIntegration = new AwsIntegration({
48
+ service: 'sqs',
49
+ integrationHttpMethod: 'POST',
50
+ options: {
51
+ passthroughBehavior: PassthroughBehavior.NEVER,
52
+ credentialsRole: apiGwRole,
53
+ requestParameters: {
54
+ // SQS requires the Content-Type of the HTTP request to be application/x-www-form-urlencoded
55
+ 'integration.request.header.Content-Type': "'application/x-www-form-urlencoded'",
56
+ },
57
+ requestTemplates: {
58
+ // map the JSON request to a form parameter, FIFO needs also MessageGroupId
59
+ // https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html
60
+ 'application/json': `Action=SendMessage${fifoMessageGroupId}&MessageBody=$util.urlEncode($input.body)`,
61
+ },
62
+ // these are required by SQS
63
+ integrationResponses: [
64
+ {
65
+ statusCode: '200',
66
+ responseTemplates: {
67
+ 'text/html': 'Success',
68
+ },
69
+ },
70
+ {
71
+ statusCode: '500',
72
+ responseTemplates: {
73
+ 'text/html': 'Error',
74
+ },
75
+ selectionPattern: '500',
76
+ },
77
+
78
+ ],
79
+
80
+ },
81
+ path: `${Aws.ACCOUNT_ID}/${queue.queueName}`,
82
+ });
83
+ resource.addMethod('POST', sqsIntegration, {
84
+ requestValidator,
85
+ apiKeyRequired,
86
+ requestModels: requestModels ?? {},
87
+ methodResponses: [
88
+ {
89
+ statusCode: '200',
90
+ responseParameters: {
91
+ 'method.response.header.Content-Type': true,
92
+ },
93
+ },
94
+ {
95
+ statusCode: '500',
96
+ responseParameters: {
97
+ 'method.response.header.Content-Type': true,
98
+ },
99
+ },
100
+ ],
101
+ });
102
+ }
@@ -0,0 +1,148 @@
1
+ import {Queue, QueueEncryption, QueueProps} from "aws-cdk-lib/aws-sqs";
2
+ import {Duration} from "aws-cdk-lib";
3
+ import {BlockPublicAccess, Bucket} from "aws-cdk-lib/aws-s3";
4
+ import {PolicyStatement} from "aws-cdk-lib/aws-iam";
5
+ import {InlineCode, Runtime} from "aws-cdk-lib/aws-lambda";
6
+ import {RetentionDays} from "aws-cdk-lib/aws-logs";
7
+ import {SqsEventSource} from "aws-cdk-lib/aws-lambda-event-sources";
8
+ import {ComparisonOperator, TreatMissingData} from "aws-cdk-lib/aws-cloudwatch";
9
+ import {SnsAction} from "aws-cdk-lib/aws-cloudwatch-actions";
10
+ import {ManagedUpload} from "aws-sdk/clients/s3";
11
+ import {S3} from "aws-sdk";
12
+ import {SQSEvent, SQSHandler, SQSRecord} from "aws-lambda";
13
+ import {Construct} from "constructs";
14
+ import {DigitrafficStack} from "./stack/stack";
15
+ import {MonitoredFunction} from "./stack/monitoredfunction";
16
+
17
+ /**
18
+ * Construct for creating SQS-queues.
19
+ *
20
+ * If you don't config your own deadLetterQueue, this will create a dlq for you, also a lambda function, a s3 bucket
21
+ * and an alarm for the queue. Anything that goes to the dlq will be written into the bucket and the alarm is activated.
22
+ */
23
+ export class DigitrafficSqsQueue extends Queue {
24
+ constructor(scope: Construct, name: string, props: QueueProps) {
25
+ super(scope, name, props);
26
+ }
27
+
28
+ static create(stack: DigitrafficStack, name: string, props: QueueProps): DigitrafficSqsQueue {
29
+ const queueName = `${stack.configuration.shortName}-${name}-Queue`;
30
+ const queueProps = {...props, ...{
31
+ encryption: QueueEncryption.KMS_MANAGED,
32
+ queueName,
33
+ deadLetterQueue: props.deadLetterQueue || {
34
+ maxReceiveCount: 2,
35
+ queue: DigitrafficDLQueue.create(stack, name),
36
+ },
37
+ }};
38
+
39
+ return new DigitrafficSqsQueue(stack, queueName, queueProps);
40
+ }
41
+ }
42
+
43
+ export class DigitrafficDLQueue {
44
+ static create(stack: DigitrafficStack, name: string): DigitrafficSqsQueue {
45
+ const dlqName = `${stack.configuration.shortName}-${name}-DLQ`;
46
+
47
+ const dlq = new DigitrafficSqsQueue(stack, dlqName, {
48
+ queueName: dlqName,
49
+ visibilityTimeout: Duration.seconds(60),
50
+ encryption: QueueEncryption.KMS_MANAGED,
51
+ });
52
+
53
+ const dlqBucket = new Bucket(stack, `${dlqName}-Bucket`, {
54
+ blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
55
+ });
56
+
57
+ const dlqFunctionName = `${dlqName}-Function`;
58
+ const lambda = MonitoredFunction.create(stack, dlqFunctionName, {
59
+ runtime: Runtime.NODEJS_14_X,
60
+ logRetention: RetentionDays.ONE_YEAR,
61
+ functionName: dlqFunctionName,
62
+ code: getDlqCode(dlqBucket.bucketName),
63
+ timeout: Duration.seconds(10),
64
+ handler: 'index.handler',
65
+ memorySize: 128,
66
+ reservedConcurrentExecutions: 1,
67
+ });
68
+
69
+ const statement = new PolicyStatement();
70
+ statement.addActions('s3:PutObject');
71
+ statement.addActions('s3:PutObjectAcl');
72
+ statement.addResources(dlqBucket.bucketArn + '/*');
73
+
74
+ lambda.addToRolePolicy(statement);
75
+ lambda.addEventSource(new SqsEventSource(dlq));
76
+
77
+ addDLQAlarm(stack, dlqName, dlq);
78
+
79
+ return dlq;
80
+ }
81
+ }
82
+
83
+ function addDLQAlarm(stack: DigitrafficStack, dlqName: string, dlq: Queue) {
84
+ const alarmName = `${dlqName}-Alarm`;
85
+ dlq.metricNumberOfMessagesReceived({
86
+ period: Duration.minutes(5),
87
+ }).createAlarm(stack, alarmName, {
88
+ alarmName,
89
+ threshold: 0,
90
+ evaluationPeriods: 1,
91
+ treatMissingData: TreatMissingData.NOT_BREACHING,
92
+ comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,
93
+ }).addAlarmAction(new SnsAction(stack.warningTopic));
94
+ }
95
+
96
+ function getDlqCode(bName: string): InlineCode {
97
+ const functionBody = DLQ_LAMBDA_CODE
98
+ .replace("__bucketName__", bName)
99
+ .replace("__upload__", uploadToS3.toString())
100
+ .replace("__doUpload__", doUpload.toString())
101
+ .replace("__handler__", createHandler().toString().substring(23)); // remove function handler() from signature
102
+
103
+ return new InlineCode(functionBody);
104
+ }
105
+
106
+ async function uploadToS3(s3: S3, bName: string, body: string, objectName: string): Promise<void> {
107
+ try {
108
+ console.info('writing %s to %s', objectName, bName);
109
+ await doUpload(s3, bName, body, objectName);
110
+ } catch (error) {
111
+ console.warn(error);
112
+ console.warn('method=uploadToS3 retrying upload to bucket %s', bName);
113
+ try {
114
+ await doUpload(s3, bName, body, objectName);
115
+ } catch (e2) {
116
+ console.error('method=uploadToS3 failed retrying upload to bucket %s', bName);
117
+ }
118
+ }
119
+ }
120
+
121
+ function doUpload(s3: S3, bName: string, Body: string, Key: string): Promise<ManagedUpload.SendData> {
122
+ return s3.upload({
123
+ Bucket: bName, Body, Key,
124
+ }).promise();
125
+ }
126
+
127
+ // bucketName is unused, will be overridden in the actual lambda code below
128
+ const bucketName = '';
129
+
130
+ function createHandler(): SQSHandler {
131
+ return async function handler(event: SQSEvent): Promise<void> {
132
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
133
+ const AWS = require('aws-sdk');
134
+
135
+ const millis = new Date().getTime();
136
+ await Promise.all(event.Records.map((e: SQSRecord, idx: number) =>
137
+ uploadToS3(new AWS.S3(), bucketName, e.body, `dlq-${millis}-${idx}.json`)));
138
+ };
139
+ }
140
+
141
+ const DLQ_LAMBDA_CODE = `const AWS = require('aws-sdk');
142
+ const bucketName = "__bucketName__";
143
+
144
+ __upload__
145
+ __doUpload__
146
+
147
+ exports.handler = async (event) => __handler__
148
+ `;
@@ -0,0 +1,207 @@
1
+ import {
2
+ Architecture,
3
+ AssetCode,
4
+ Code,
5
+ FunctionProps,
6
+ Runtime,
7
+ } from "aws-cdk-lib/aws-lambda";
8
+ import { Duration } from "aws-cdk-lib";
9
+ import { ISecurityGroup, IVpc, SubnetSelection } from "aws-cdk-lib/aws-ec2";
10
+ import { RetentionDays } from "aws-cdk-lib/aws-logs";
11
+ import { Role } from "aws-cdk-lib/aws-iam";
12
+ import { DigitrafficStack } from "./stack";
13
+ import { MonitoredFunctionAlarmProps } from "./monitoredfunction";
14
+
15
+ export type LambdaEnvironment = Record<string, string>;
16
+
17
+ export type DBLambdaEnvironment = LambdaEnvironment & {
18
+ SECRET_ID?: string;
19
+ DB_APPLICATION: string;
20
+ };
21
+
22
+ export interface LambdaConfiguration {
23
+ vpcId: string;
24
+ allowFromIpAddresses?: string[];
25
+ privateSubnetIds: string[];
26
+ availabilityZones: string[];
27
+ lambdaDbSgId: string;
28
+ dbProps?: DbProps;
29
+ defaultLambdaDurationSeconds?: number;
30
+ logsDestinationArn: string;
31
+ memorySize?: number;
32
+ runtime?: Runtime;
33
+ }
34
+
35
+ declare interface DbProps {
36
+ username: string;
37
+ password: string;
38
+ uri?: string;
39
+ ro_uri?: string;
40
+ }
41
+
42
+ export function databaseFunctionProps(
43
+ stack: DigitrafficStack,
44
+ environment: LambdaEnvironment,
45
+ lambdaName: string,
46
+ simpleLambdaName: string,
47
+ config?: FunctionParameters
48
+ ): FunctionProps {
49
+ const vpcSubnets = stack.vpc
50
+ ? {
51
+ subnets: stack.vpc.privateSubnets,
52
+ }
53
+ : undefined;
54
+
55
+ return {
56
+ ...lambdaFunctionProps(
57
+ stack,
58
+ environment,
59
+ lambdaName,
60
+ simpleLambdaName,
61
+ config
62
+ ),
63
+ ...{
64
+ vpc: stack.vpc || undefined,
65
+ vpcSubnets,
66
+ securityGroup: stack.lambdaDbSg || undefined,
67
+ },
68
+ };
69
+ }
70
+
71
+ export function lambdaFunctionProps(
72
+ stack: DigitrafficStack,
73
+ environment: LambdaEnvironment,
74
+ lambdaName: string,
75
+ simpleLambdaName: string,
76
+ config?: FunctionParameters
77
+ ): FunctionProps {
78
+ return {
79
+ runtime: config?.runtime || Runtime.NODEJS_14_X,
80
+ architecture: config?.architecture || Architecture.ARM_64,
81
+ memorySize: config?.memorySize || 128,
82
+ functionName: lambdaName,
83
+ role: config?.role,
84
+ timeout: Duration.seconds(config?.timeout || 60),
85
+ logRetention: RetentionDays.ONE_YEAR,
86
+ reservedConcurrentExecutions: config?.reservedConcurrentExecutions || 2,
87
+ code: getAssetCode(simpleLambdaName, config),
88
+ handler: `${simpleLambdaName}.handler`,
89
+ environment,
90
+ };
91
+ }
92
+
93
+ function getAssetCode(
94
+ simpleLambdaName: string,
95
+ config?: FunctionParameters
96
+ ): AssetCode {
97
+ const lambdaPath = config?.singleLambda
98
+ ? `dist/lambda/`
99
+ : `dist/lambda/${simpleLambdaName}`;
100
+
101
+ return new AssetCode(lambdaPath);
102
+ }
103
+
104
+ /**
105
+ * Creates a base configuration for a Lambda that uses an RDS database
106
+ * @param vpc "Private" Lambdas are associated with a VPC
107
+ * @param lambdaDbSg Security Group shared by Lambda and RDS
108
+ * @param props Database connection properties for the Lambda
109
+ * @param config Lambda configuration
110
+ */
111
+ export function dbLambdaConfiguration(
112
+ vpc: IVpc,
113
+ lambdaDbSg: ISecurityGroup,
114
+ props: LambdaConfiguration,
115
+ config: FunctionParameters
116
+ ): FunctionProps {
117
+ return {
118
+ runtime: props.runtime || Runtime.NODEJS_14_X,
119
+ memorySize: props.memorySize || config.memorySize || 1024,
120
+ functionName: config.functionName,
121
+ code: config.code,
122
+ role: config.role,
123
+ handler: config.handler,
124
+ timeout: Duration.seconds(
125
+ config.timeout || props.defaultLambdaDurationSeconds || 60
126
+ ),
127
+ environment: config.environment || {
128
+ DB_USER: props.dbProps?.username ?? "",
129
+ DB_PASS: props.dbProps?.password ?? "",
130
+ DB_URI:
131
+ (config.readOnly
132
+ ? props.dbProps?.ro_uri
133
+ : props.dbProps?.uri) ?? "",
134
+ },
135
+ logRetention: RetentionDays.ONE_YEAR,
136
+ vpc: vpc,
137
+ vpcSubnets: {
138
+ subnets: vpc.privateSubnets,
139
+ },
140
+ securityGroups: [lambdaDbSg],
141
+ reservedConcurrentExecutions: config.reservedConcurrentExecutions || 3,
142
+ };
143
+ }
144
+
145
+ export function defaultLambdaConfiguration(
146
+ config: FunctionParameters
147
+ ): FunctionProps {
148
+ const props: FunctionProps = {
149
+ runtime: Runtime.NODEJS_14_X,
150
+ memorySize: config.memorySize ?? 128,
151
+ functionName: config.functionName,
152
+ handler: config.handler,
153
+ environment: config.environment ?? {},
154
+ logRetention: RetentionDays.ONE_YEAR,
155
+ reservedConcurrentExecutions: config.reservedConcurrentExecutions,
156
+ code: config.code,
157
+ role: config.role,
158
+ timeout: Duration.seconds(config.timeout || 10),
159
+ };
160
+ if (config.vpc) {
161
+ return {
162
+ ...props,
163
+ ...{
164
+ vpc: config.vpc,
165
+ vpcSubnets: {
166
+ subnets: config.vpc?.privateSubnets,
167
+ },
168
+ },
169
+ };
170
+ }
171
+ return props;
172
+ }
173
+
174
+ export interface FunctionParameters {
175
+ memorySize?: number;
176
+ timeout?: number;
177
+ functionName?: string;
178
+ code: Code;
179
+ handler: string;
180
+ readOnly?: boolean;
181
+ environment?: {
182
+ [key: string]: string;
183
+ };
184
+ reservedConcurrentExecutions?: number;
185
+ role?: Role;
186
+ vpc?: IVpc;
187
+ vpcSubnets?: SubnetSelection;
188
+ runtime?: Runtime;
189
+ architecture?: Architecture;
190
+ singleLambda?: boolean;
191
+ }
192
+
193
+ export type MonitoredFunctionParameters = {
194
+ readonly memorySize?: number;
195
+ readonly timeout?: number;
196
+ readonly functionName?: string;
197
+ readonly reservedConcurrentExecutions?: number;
198
+ readonly role?: Role;
199
+ readonly runtime?: Runtime;
200
+ readonly architecture?: Architecture;
201
+ readonly singleLambda?: boolean;
202
+
203
+ readonly durationAlarmProps?: MonitoredFunctionAlarmProps;
204
+ readonly durationWarningProps?: MonitoredFunctionAlarmProps;
205
+ readonly errorAlarmProps?: MonitoredFunctionAlarmProps;
206
+ readonly throttleAlarmProps?: MonitoredFunctionAlarmProps;
207
+ } & FunctionParameters;