@digitraffic/common 2023.1.18-1 → 2023.1.23-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/canaries/canary-alarm.js +11 -13
- package/dist/aws/infra/canaries/canary.js +2 -4
- package/dist/aws/infra/canaries/database-checker.js +4 -1
- package/dist/aws/infra/canaries/url-canary.js +1 -0
- package/dist/aws/infra/canaries/url-checker.d.ts +2 -2
- package/dist/aws/infra/canaries/url-checker.js +24 -5
- package/dist/aws/infra/sqs-integration.d.ts +1 -3
- package/dist/aws/infra/sqs-integration.js +28 -32
- package/dist/aws/infra/sqs-queue.d.ts +0 -2
- package/dist/aws/infra/sqs-queue.js +31 -24
- package/dist/aws/infra/stack/lambda-configs.d.ts +2 -31
- package/dist/aws/infra/stack/lambda-configs.js +5 -38
- package/dist/aws/infra/stack/monitoredfunction.js +3 -1
- package/dist/aws/infra/stacks/db-stack.js +1 -1
- package/dist/aws/infra/stacks/network-stack.d.ts +2 -1
- package/dist/aws/infra/stacks/network-stack.js +4 -2
- package/dist/aws/runtime/secrets/dbsecret.d.ts +0 -39
- package/dist/aws/runtime/secrets/dbsecret.js +1 -71
- package/dist/aws/runtime/secrets/proxy-holder.js +5 -4
- package/dist/aws/runtime/secrets/rds-holder.js +5 -4
- package/dist/aws/runtime/secrets/secret-holder.d.ts +0 -4
- package/dist/aws/runtime/secrets/secret-holder.js +6 -12
- package/dist/aws/runtime/secrets/secret.d.ts +0 -6
- package/dist/aws/runtime/secrets/secret.js +8 -17
- package/dist/database/database.d.ts +7 -0
- package/dist/database/database.js +19 -8
- package/dist/test/db-testutils.js +4 -5
- package/dist/utils/utils.d.ts +15 -0
- package/dist/utils/utils.js +3 -1
- package/package.json +1 -1
- package/src/aws/infra/canaries/canary-alarm.ts +26 -24
- package/src/aws/infra/canaries/canary.ts +2 -4
- package/src/aws/infra/canaries/database-checker.ts +4 -1
- package/src/aws/infra/canaries/url-canary.ts +2 -1
- package/src/aws/infra/canaries/url-checker.ts +28 -11
- package/src/aws/infra/sqs-integration.ts +51 -47
- package/src/aws/infra/sqs-queue.ts +85 -53
- package/src/aws/infra/stack/lambda-configs.ts +6 -69
- package/src/aws/infra/stack/monitoredfunction.ts +2 -1
- package/src/aws/infra/stacks/db-stack.ts +1 -1
- package/src/aws/infra/stacks/network-stack.ts +7 -3
- package/src/aws/runtime/secrets/dbsecret.ts +1 -117
- package/src/aws/runtime/secrets/proxy-holder.ts +2 -5
- package/src/aws/runtime/secrets/rds-holder.ts +2 -1
- package/src/aws/runtime/secrets/secret-holder.ts +8 -20
- package/src/aws/runtime/secrets/secret.ts +17 -22
- package/src/database/database.ts +14 -3
- package/src/test/db-testutils.ts +5 -2
- package/src/utils/utils.ts +2 -2
- package/dist/test/secret.d.ts +0 -3
- package/dist/test/secret.js +0 -25
- package/src/test/secret.ts +0 -23
@@ -3,12 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.NetworkStack = void 0;
|
4
4
|
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
5
5
|
const aws_ec2_1 = require("aws-cdk-lib/aws-ec2");
|
6
|
+
const import_util_1 = require("../import-util");
|
6
7
|
class NetworkStack extends aws_cdk_lib_1.Stack {
|
7
8
|
constructor(scope, id, isc, configuration) {
|
8
9
|
super(scope, id, {
|
9
10
|
env: isc.env,
|
10
11
|
});
|
11
|
-
this.createVpc(configuration);
|
12
|
+
this.vpc = this.createVpc(configuration);
|
13
|
+
(0, import_util_1.exportValue)(this, isc.environmentName, "VPCID", this.vpc.vpcId);
|
12
14
|
}
|
13
15
|
createVpc(configuration) {
|
14
16
|
return new aws_ec2_1.Vpc(this, "DigitrafficVPC", {
|
@@ -26,7 +28,7 @@ class NetworkStack extends aws_cdk_lib_1.Stack {
|
|
26
28
|
{
|
27
29
|
name: "private",
|
28
30
|
cidrMask: 24,
|
29
|
-
subnetType: aws_ec2_1.SubnetType.
|
31
|
+
subnetType: aws_ec2_1.SubnetType.PRIVATE_WITH_EGRESS,
|
30
32
|
},
|
31
33
|
],
|
32
34
|
});
|
@@ -1,10 +1,4 @@
|
|
1
1
|
import { GenericSecret } from "./secret";
|
2
|
-
export interface DbSecret {
|
3
|
-
readonly username: string;
|
4
|
-
readonly password: string;
|
5
|
-
readonly host: string;
|
6
|
-
readonly ro_host: string;
|
7
|
-
}
|
8
2
|
export declare enum RdsProxySecretKey {
|
9
3
|
username = "username",
|
10
4
|
password = "password",
|
@@ -19,37 +13,4 @@ export declare enum RdsSecretKey {
|
|
19
13
|
}
|
20
14
|
export type RdsProxySecret = Record<RdsProxySecretKey, string>;
|
21
15
|
export type RdsSecret = Record<RdsSecretKey, string>;
|
22
|
-
export declare enum DatabaseEnvironmentKeys {
|
23
|
-
DB_USER = "DB_USER",
|
24
|
-
DB_PASS = "DB_PASS",
|
25
|
-
DB_URI = "DB_URI",
|
26
|
-
DB_RO_URI = "DB_RO_URI",
|
27
|
-
DB_APPLICATION = "DB_APPLICATION"
|
28
|
-
}
|
29
|
-
/**
|
30
|
-
* You can give the following options for retrieving a secret:
|
31
|
-
*
|
32
|
-
* expectedKeys: the list of keys the secret must include. If not, an error will be thrown.
|
33
|
-
* prefix: a prefix that's included in retrieved secret's keys. Only keys begining with the prefix will be included.
|
34
|
-
* The secret that is passed to the given function will not include the prefix in it's keys.
|
35
|
-
|
36
|
-
*/
|
37
|
-
export interface SecretOptions {
|
38
|
-
readonly expectedKeys?: string[];
|
39
|
-
readonly prefix?: string;
|
40
|
-
}
|
41
|
-
export type SecretToPromiseFunction<Secret, Response = void> = (secret: Secret) => Promise<Response> | void;
|
42
|
-
export type SecretFunction<Secret, Response = void> = (secretId: string, fn: SecretToPromiseFunction<Secret, Response>, options?: SecretOptions) => Promise<Response | void>;
|
43
|
-
export type EmptySecretFunction<Response = void> = SecretFunction<DbSecret, Response>;
|
44
|
-
/**
|
45
|
-
* Run the given function with secret retrieved from Secrets Manager. Also injects database-credentials into environment.
|
46
|
-
*
|
47
|
-
* @deprecated use SecretHolder & ProxyHolder
|
48
|
-
* @see SecretOptions
|
49
|
-
*
|
50
|
-
* @param {string} secretId
|
51
|
-
* @param {function} fn
|
52
|
-
* @param {SecretOptions} options
|
53
|
-
*/
|
54
|
-
export declare function withDbSecret<Secret, Response>(secretId: string, fn: SecretToPromiseFunction<Secret, Response>, options?: SecretOptions): Promise<Response | void>;
|
55
16
|
export declare function checkExpectedSecretKeys<Secret extends GenericSecret>(keys: string[], secret: Secret): void;
|
@@ -1,7 +1,6 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.checkExpectedSecretKeys = exports.
|
4
|
-
const secret_1 = require("./secret");
|
3
|
+
exports.checkExpectedSecretKeys = exports.RdsSecretKey = exports.RdsProxySecretKey = void 0;
|
5
4
|
var RdsProxySecretKey;
|
6
5
|
(function (RdsProxySecretKey) {
|
7
6
|
RdsProxySecretKey["username"] = "username";
|
@@ -16,75 +15,6 @@ var RdsSecretKey;
|
|
16
15
|
RdsSecretKey["host"] = "host";
|
17
16
|
RdsSecretKey["ro_host"] = "ro_host";
|
18
17
|
})(RdsSecretKey = exports.RdsSecretKey || (exports.RdsSecretKey = {}));
|
19
|
-
var DatabaseEnvironmentKeys;
|
20
|
-
(function (DatabaseEnvironmentKeys) {
|
21
|
-
DatabaseEnvironmentKeys["DB_USER"] = "DB_USER";
|
22
|
-
DatabaseEnvironmentKeys["DB_PASS"] = "DB_PASS";
|
23
|
-
DatabaseEnvironmentKeys["DB_URI"] = "DB_URI";
|
24
|
-
DatabaseEnvironmentKeys["DB_RO_URI"] = "DB_RO_URI";
|
25
|
-
DatabaseEnvironmentKeys["DB_APPLICATION"] = "DB_APPLICATION";
|
26
|
-
})(DatabaseEnvironmentKeys = exports.DatabaseEnvironmentKeys || (exports.DatabaseEnvironmentKeys = {}));
|
27
|
-
function setDbSecret(secret) {
|
28
|
-
process.env[DatabaseEnvironmentKeys.DB_USER] = secret.username;
|
29
|
-
process.env[DatabaseEnvironmentKeys.DB_PASS] = secret.password;
|
30
|
-
process.env[DatabaseEnvironmentKeys.DB_URI] = secret.host;
|
31
|
-
process.env[DatabaseEnvironmentKeys.DB_RO_URI] = secret.ro_host;
|
32
|
-
}
|
33
|
-
// cached at Lambda container level
|
34
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
35
|
-
let cachedSecret;
|
36
|
-
const missingSecretErrorText = "Missing or empty secretId";
|
37
|
-
/**
|
38
|
-
* Run the given function with secret retrieved from Secrets Manager. Also injects database-credentials into environment.
|
39
|
-
*
|
40
|
-
* @deprecated use SecretHolder & ProxyHolder
|
41
|
-
* @see SecretOptions
|
42
|
-
*
|
43
|
-
* @param {string} secretId
|
44
|
-
* @param {function} fn
|
45
|
-
* @param {SecretOptions} options
|
46
|
-
*/
|
47
|
-
async function withDbSecret(secretId, fn, options) {
|
48
|
-
if (!secretId) {
|
49
|
-
console.error(missingSecretErrorText);
|
50
|
-
return Promise.reject(missingSecretErrorText);
|
51
|
-
}
|
52
|
-
if (!cachedSecret) {
|
53
|
-
// if prefix is given, first set db values and then fetch secret
|
54
|
-
if (options?.prefix) {
|
55
|
-
// first set db values
|
56
|
-
await (0, secret_1.withSecret)(secretId, (fetchedSecret) => {
|
57
|
-
setDbSecret(fetchedSecret);
|
58
|
-
});
|
59
|
-
// then actual secret
|
60
|
-
await (0, secret_1.withSecretAndPrefix)(secretId, options.prefix, (fetchedSecret) => {
|
61
|
-
cachedSecret = fetchedSecret;
|
62
|
-
});
|
63
|
-
}
|
64
|
-
else {
|
65
|
-
await (0, secret_1.withSecret)(secretId, (fetchedSecret) => {
|
66
|
-
setDbSecret(fetchedSecret);
|
67
|
-
cachedSecret = fetchedSecret;
|
68
|
-
});
|
69
|
-
}
|
70
|
-
}
|
71
|
-
try {
|
72
|
-
if (options?.expectedKeys?.length) {
|
73
|
-
checkExpectedSecretKeys(options.expectedKeys, cachedSecret);
|
74
|
-
}
|
75
|
-
return fn(cachedSecret);
|
76
|
-
}
|
77
|
-
catch (error) {
|
78
|
-
console.error("method=withDbSecret Caught an error, refreshing secret", error);
|
79
|
-
// try to refetch secret in case it has changed
|
80
|
-
await (0, secret_1.withSecret)(secretId, (fetchedSecret) => {
|
81
|
-
setDbSecret(fetchedSecret);
|
82
|
-
cachedSecret = fetchedSecret;
|
83
|
-
});
|
84
|
-
return fn(cachedSecret);
|
85
|
-
}
|
86
|
-
}
|
87
|
-
exports.withDbSecret = withDbSecret;
|
88
18
|
function checkExpectedSecretKeys(keys, secret) {
|
89
19
|
const missingKeys = keys.filter((key) => !(key in secret));
|
90
20
|
if (missingKeys.length) {
|
@@ -4,6 +4,7 @@ exports.ProxyHolder = void 0;
|
|
4
4
|
const secret_holder_1 = require("./secret-holder");
|
5
5
|
const dbsecret_1 = require("./dbsecret");
|
6
6
|
const utils_1 = require("../../../utils/utils");
|
7
|
+
const database_1 = require("../../../database/database");
|
7
8
|
const RDS_PROXY_SECRET_KEYS = Object.values(dbsecret_1.RdsProxySecretKey);
|
8
9
|
/**
|
9
10
|
* Holds credentials for RDS Proxy access.
|
@@ -17,10 +18,10 @@ class ProxyHolder {
|
|
17
18
|
}
|
18
19
|
async setCredentials() {
|
19
20
|
const secret = await this.secretHolder.get();
|
20
|
-
process.env[
|
21
|
-
process.env[
|
22
|
-
process.env[
|
23
|
-
process.env[
|
21
|
+
process.env[database_1.DatabaseEnvironmentKeys.DB_USER] = secret.username;
|
22
|
+
process.env[database_1.DatabaseEnvironmentKeys.DB_PASS] = secret.password;
|
23
|
+
process.env[database_1.DatabaseEnvironmentKeys.DB_URI] = secret.proxy_host;
|
24
|
+
process.env[database_1.DatabaseEnvironmentKeys.DB_RO_URI] = secret.proxy_ro_host;
|
24
25
|
}
|
25
26
|
}
|
26
27
|
exports.ProxyHolder = ProxyHolder;
|
@@ -4,6 +4,7 @@ exports.RdsHolder = void 0;
|
|
4
4
|
const secret_holder_1 = require("./secret-holder");
|
5
5
|
const dbsecret_1 = require("./dbsecret");
|
6
6
|
const utils_1 = require("../../../utils/utils");
|
7
|
+
const database_1 = require("../../../database/database");
|
7
8
|
const RDS_SECRET_KEYS = Object.values(dbsecret_1.RdsSecretKey);
|
8
9
|
/**
|
9
10
|
* Holds credentials for RDS access.
|
@@ -17,10 +18,10 @@ class RdsHolder {
|
|
17
18
|
}
|
18
19
|
async setCredentials() {
|
19
20
|
const secret = await this.secretHolder.get();
|
20
|
-
process.env[
|
21
|
-
process.env[
|
22
|
-
process.env[
|
23
|
-
process.env[
|
21
|
+
process.env[database_1.DatabaseEnvironmentKeys.DB_USER] = secret.username;
|
22
|
+
process.env[database_1.DatabaseEnvironmentKeys.DB_PASS] = secret.password;
|
23
|
+
process.env[database_1.DatabaseEnvironmentKeys.DB_URI] = secret.host;
|
24
|
+
process.env[database_1.DatabaseEnvironmentKeys.DB_RO_URI] = secret.ro_host;
|
24
25
|
}
|
25
26
|
}
|
26
27
|
exports.RdsHolder = RdsHolder;
|
@@ -4,7 +4,7 @@ exports.SecretHolder = void 0;
|
|
4
4
|
const secret_1 = require("./secret");
|
5
5
|
const dbsecret_1 = require("./dbsecret");
|
6
6
|
const utils_1 = require("../../../utils/utils");
|
7
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-assignment
|
8
8
|
const NodeTtl = require("node-ttl");
|
9
9
|
const DEFAULT_PREFIX = "";
|
10
10
|
const DEFAULT_SECRET_KEY = "SECRET";
|
@@ -24,11 +24,13 @@ class SecretHolder {
|
|
24
24
|
this.secretId = secretId;
|
25
25
|
this.prefix = prefix;
|
26
26
|
this.expectedKeys = expectedKeys;
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
|
27
28
|
this.secretCache = new NodeTtl(configuration);
|
28
29
|
}
|
29
30
|
async initSecret() {
|
30
31
|
const secretValue = await (0, secret_1.getSecret)(this.secretId);
|
31
32
|
console.info("refreshing secret " + this.secretId);
|
33
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
|
32
34
|
this.secretCache.push(DEFAULT_SECRET_KEY, secretValue);
|
33
35
|
}
|
34
36
|
static create(prefix = DEFAULT_PREFIX, expectedKeys = []) {
|
@@ -55,21 +57,13 @@ class SecretHolder {
|
|
55
57
|
return parsed;
|
56
58
|
}
|
57
59
|
async getSecret() {
|
60
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
58
61
|
const secret = this.secretCache.get(DEFAULT_SECRET_KEY);
|
59
62
|
if (!secret) {
|
60
63
|
await this.initSecret();
|
61
64
|
}
|
62
|
-
|
63
|
-
|
64
|
-
/**
|
65
|
-
* @deprecated Use ProxyHolder
|
66
|
-
*/
|
67
|
-
async setDatabaseCredentials() {
|
68
|
-
const secret = await this.getSecret();
|
69
|
-
process.env[dbsecret_1.DatabaseEnvironmentKeys.DB_USER] = secret.username;
|
70
|
-
process.env[dbsecret_1.DatabaseEnvironmentKeys.DB_PASS] = secret.password;
|
71
|
-
process.env[dbsecret_1.DatabaseEnvironmentKeys.DB_URI] = secret.host;
|
72
|
-
process.env[dbsecret_1.DatabaseEnvironmentKeys.DB_RO_URI] = secret.ro_host;
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
66
|
+
return secret ?? this.secretCache.get(DEFAULT_SECRET_KEY);
|
73
67
|
}
|
74
68
|
}
|
75
69
|
exports.SecretHolder = SecretHolder;
|
@@ -1,8 +1,2 @@
|
|
1
|
-
import { SecretToPromiseFunction } from "./dbsecret";
|
2
1
|
export type GenericSecret = Record<string, string>;
|
3
|
-
/**
|
4
|
-
@deprecated use SecretHolder & ProxyHolder
|
5
|
-
*/
|
6
|
-
export declare function withSecret<Secret, Response>(secretId: string, fn: SecretToPromiseFunction<Secret, Response>): Promise<Response | void>;
|
7
2
|
export declare function getSecret<Secret>(secretId: string, prefix?: string): Promise<Secret>;
|
8
|
-
export declare function withSecretAndPrefix<Secret, Response>(secretId: string, prefix: string, fn: SecretToPromiseFunction<Secret, Response>): Promise<Response | void>;
|
@@ -1,26 +1,21 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.
|
3
|
+
exports.getSecret = void 0;
|
4
4
|
const aws_sdk_1 = require("aws-sdk");
|
5
5
|
const smClient = new aws_sdk_1.SecretsManager({
|
6
6
|
region: process.env.AWS_REGION,
|
7
7
|
});
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
async function withSecret(secretId, fn) {
|
12
|
-
return fn(await getSecret(secretId));
|
13
|
-
}
|
14
|
-
exports.withSecret = withSecret;
|
15
|
-
async function getSecret(secretId, prefix = '') {
|
16
|
-
const secretObj = await smClient.getSecretValue({
|
8
|
+
async function getSecret(secretId, prefix = "") {
|
9
|
+
const secretObj = await smClient
|
10
|
+
.getSecretValue({
|
17
11
|
SecretId: secretId,
|
18
|
-
})
|
12
|
+
})
|
13
|
+
.promise();
|
19
14
|
if (!secretObj.SecretString) {
|
20
|
-
throw new Error(
|
15
|
+
throw new Error("No secret found!");
|
21
16
|
}
|
22
17
|
const secret = JSON.parse(secretObj.SecretString);
|
23
|
-
if (prefix
|
18
|
+
if (!prefix) {
|
24
19
|
return secret;
|
25
20
|
}
|
26
21
|
return parseSecret(secret, `${prefix}.`);
|
@@ -36,8 +31,4 @@ function parseSecret(secret, prefix) {
|
|
36
31
|
}
|
37
32
|
return parsed;
|
38
33
|
}
|
39
|
-
async function withSecretAndPrefix(secretId, prefix, fn) {
|
40
|
-
return fn(await getSecret(secretId, prefix));
|
41
|
-
}
|
42
|
-
exports.withSecretAndPrefix = withSecretAndPrefix;
|
43
34
|
//# sourceMappingURL=secret.js.map
|
@@ -1,4 +1,11 @@
|
|
1
1
|
import { IDatabase, ITask } from "pg-promise";
|
2
|
+
export declare enum DatabaseEnvironmentKeys {
|
3
|
+
DB_USER = "DB_USER",
|
4
|
+
DB_PASS = "DB_PASS",
|
5
|
+
DB_URI = "DB_URI",
|
6
|
+
DB_RO_URI = "DB_RO_URI",
|
7
|
+
DB_APPLICATION = "DB_APPLICATION"
|
8
|
+
}
|
2
9
|
export type DTDatabase = IDatabase<unknown>;
|
3
10
|
export type DTTransaction = ITask<unknown>;
|
4
11
|
/**
|
@@ -1,18 +1,28 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.inDatabaseReadonly = exports.inDatabase = exports.inTransaction = exports.initDbConnection = void 0;
|
4
|
-
const dbsecret_1 = require("../aws/runtime/secrets/dbsecret");
|
3
|
+
exports.inDatabaseReadonly = exports.inDatabase = exports.inTransaction = exports.initDbConnection = exports.DatabaseEnvironmentKeys = void 0;
|
5
4
|
const utils_1 = require("../utils/utils");
|
6
5
|
const environment_1 = require("../aws/runtime/environment");
|
7
|
-
|
6
|
+
var DatabaseEnvironmentKeys;
|
7
|
+
(function (DatabaseEnvironmentKeys) {
|
8
|
+
DatabaseEnvironmentKeys["DB_USER"] = "DB_USER";
|
9
|
+
DatabaseEnvironmentKeys["DB_PASS"] = "DB_PASS";
|
10
|
+
DatabaseEnvironmentKeys["DB_URI"] = "DB_URI";
|
11
|
+
DatabaseEnvironmentKeys["DB_RO_URI"] = "DB_RO_URI";
|
12
|
+
DatabaseEnvironmentKeys["DB_APPLICATION"] = "DB_APPLICATION";
|
13
|
+
})(DatabaseEnvironmentKeys = exports.DatabaseEnvironmentKeys || (exports.DatabaseEnvironmentKeys = {}));
|
14
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call
|
8
15
|
const pgp = require("pg-promise")();
|
9
16
|
// convert numeric types to number instead of string
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
10
18
|
pgp.pg.types.setTypeParser(pgp.pg.types.builtins.INT8, (value) => {
|
11
19
|
return parseInt(value);
|
12
20
|
});
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
13
22
|
pgp.pg.types.setTypeParser(pgp.pg.types.builtins.FLOAT8, (value) => {
|
14
23
|
return parseFloat(value);
|
15
24
|
});
|
25
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
16
26
|
pgp.pg.types.setTypeParser(pgp.pg.types.builtins.NUMERIC, (value) => {
|
17
27
|
return parseFloat(value);
|
18
28
|
});
|
@@ -30,6 +40,7 @@ pgp.pg.types.setTypeParser(pgp.pg.types.builtins.NUMERIC, (value) => {
|
|
30
40
|
*/
|
31
41
|
function initDbConnection(username, password, applicationName, url, options) {
|
32
42
|
const finalUrl = `postgresql://${username}:${password}@${url}?application_name=${applicationName}`;
|
43
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call
|
33
44
|
return pgp(finalUrl, options);
|
34
45
|
}
|
35
46
|
exports.initDbConnection = initDbConnection;
|
@@ -46,11 +57,11 @@ function inDatabaseReadonly(fn) {
|
|
46
57
|
}
|
47
58
|
exports.inDatabaseReadonly = inDatabaseReadonly;
|
48
59
|
async function doInDatabase(readonly, fn) {
|
49
|
-
const db_application = (0, environment_1.envValue)(
|
60
|
+
const db_application = (0, environment_1.envValue)(DatabaseEnvironmentKeys.DB_APPLICATION, "unknown-cdk-application");
|
50
61
|
const db_uri = readonly
|
51
|
-
? (0, environment_1.envValue)(
|
52
|
-
: (0, environment_1.envValue)(
|
53
|
-
const db = initDbConnection((0, utils_1.getEnvVariable)(
|
62
|
+
? (0, environment_1.envValue)(DatabaseEnvironmentKeys.DB_RO_URI)
|
63
|
+
: (0, environment_1.envValue)(DatabaseEnvironmentKeys.DB_URI);
|
64
|
+
const db = initDbConnection((0, utils_1.getEnvVariable)(DatabaseEnvironmentKeys.DB_USER), (0, utils_1.getEnvVariable)(DatabaseEnvironmentKeys.DB_PASS), db_application, db_uri);
|
54
65
|
try {
|
55
66
|
// deallocate all prepared statements to allow for connection pooling
|
56
67
|
// DISCARD instead of DEALLOCATE as it didn't always clean all prepared statements
|
@@ -62,7 +73,7 @@ async function doInDatabase(readonly, fn) {
|
|
62
73
|
throw e;
|
63
74
|
}
|
64
75
|
finally {
|
65
|
-
db.$pool.end();
|
76
|
+
await db.$pool.end();
|
66
77
|
}
|
67
78
|
}
|
68
79
|
//# sourceMappingURL=database.js.map
|
@@ -2,7 +2,6 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.dbTestBase = exports.assertCount = void 0;
|
4
4
|
const database_1 = require("../database/database");
|
5
|
-
const dbsecret_1 = require("../aws/runtime/secrets/dbsecret");
|
6
5
|
async function assertCount(db, sql, count) {
|
7
6
|
await db.one(sql).then((x) => expect(x.count).toEqual(count));
|
8
7
|
}
|
@@ -15,10 +14,10 @@ function dbTestBase(fn, truncateFn, dbUser, dbPass, dbUri) {
|
|
15
14
|
noWarnings: true, // ignore duplicate connection warning for tests
|
16
15
|
});
|
17
16
|
beforeAll(async () => {
|
18
|
-
process.env[
|
19
|
-
process.env[
|
20
|
-
process.env[
|
21
|
-
process.env[
|
17
|
+
process.env[database_1.DatabaseEnvironmentKeys.DB_USER] = dbUser;
|
18
|
+
process.env[database_1.DatabaseEnvironmentKeys.DB_PASS] = dbPass;
|
19
|
+
process.env[database_1.DatabaseEnvironmentKeys.DB_URI] = theDbUri;
|
20
|
+
process.env[database_1.DatabaseEnvironmentKeys.DB_RO_URI] = theDbUri;
|
22
21
|
await truncateFn(db);
|
23
22
|
});
|
24
23
|
afterAll(async () => {
|
package/dist/utils/utils.d.ts
CHANGED
@@ -44,3 +44,18 @@ export declare function getEnvVariable(key: string): string;
|
|
44
44
|
* @return Either<string>
|
45
45
|
*/
|
46
46
|
export declare function getEnvVariableSafe(key: string): Either<string>;
|
47
|
+
/**
|
48
|
+
* Gets environment variable. If environment variable is undefined, returns value of given function.
|
49
|
+
*
|
50
|
+
* @param key Environment key
|
51
|
+
* @param fn Alternative function
|
52
|
+
*/
|
53
|
+
export declare function getEnvVariableOr<T>(key: string, fn: () => T): string | T;
|
54
|
+
/**
|
55
|
+
* Gets environment variable. If environment variable is undefined, returns given value.
|
56
|
+
* Use to return an explicit alternative value e.g. in cases where environment variable may be undefined.
|
57
|
+
*
|
58
|
+
* @param key Environment key
|
59
|
+
* @param orElse Alternative value
|
60
|
+
*/
|
61
|
+
export declare function getEnvVariableOrElse<T>(key: string, orElse: T): string | T;
|
package/dist/utils/utils.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.getEnvVariableSafe = exports.getEnvVariable = exports.getFirst = exports.getLast = exports.bothArraysHasSameValues = void 0;
|
3
|
+
exports.getEnvVariableOrElse = exports.getEnvVariableOr = exports.getEnvVariableSafe = exports.getEnvVariable = exports.getFirst = exports.getLast = exports.bothArraysHasSameValues = void 0;
|
4
4
|
function bothArraysHasSameValues(a, b) {
|
5
5
|
if ((a && !b) || (!a && b)) {
|
6
6
|
return false;
|
@@ -85,6 +85,7 @@ function getEnvVariableOr(key, fn) {
|
|
85
85
|
}
|
86
86
|
return fn();
|
87
87
|
}
|
88
|
+
exports.getEnvVariableOr = getEnvVariableOr;
|
88
89
|
/**
|
89
90
|
* Gets environment variable. If environment variable is undefined, returns given value.
|
90
91
|
* Use to return an explicit alternative value e.g. in cases where environment variable may be undefined.
|
@@ -95,4 +96,5 @@ function getEnvVariableOr(key, fn) {
|
|
95
96
|
function getEnvVariableOrElse(key, orElse) {
|
96
97
|
return getEnvVariableOr(key, () => orElse);
|
97
98
|
}
|
99
|
+
exports.getEnvVariableOrElse = getEnvVariableOrElse;
|
98
100
|
//# sourceMappingURL=utils.js.map
|
package/package.json
CHANGED
@@ -1,31 +1,33 @@
|
|
1
|
-
import {Construct} from "constructs";
|
2
|
-
import {CanaryParameters} from "./canary-parameters";
|
3
|
-
import {Alarm, ComparisonOperator} from "aws-cdk-lib/aws-cloudwatch";
|
4
|
-
import {Canary} from "@aws-cdk/aws-synthetics-alpha";
|
5
|
-
import {SnsAction} from "aws-cdk-lib/aws-cloudwatch-actions";
|
6
|
-
import {Topic} from "aws-cdk-lib/aws-sns";
|
1
|
+
import { Construct } from "constructs";
|
2
|
+
import { CanaryParameters } from "./canary-parameters";
|
3
|
+
import { Alarm, ComparisonOperator } from "aws-cdk-lib/aws-cloudwatch";
|
4
|
+
import { Canary } from "@aws-cdk/aws-synthetics-alpha";
|
5
|
+
import { SnsAction } from "aws-cdk-lib/aws-cloudwatch-actions";
|
6
|
+
import { Topic } from "aws-cdk-lib/aws-sns";
|
7
7
|
|
8
8
|
export class CanaryAlarm {
|
9
|
-
constructor(stack: Construct,
|
10
|
-
|
11
|
-
params: CanaryParameters) {
|
12
|
-
if (params.alarm ?? true) {
|
13
|
-
const alarmName = params.alarm?.alarmName ?? `${params.name}-alarm`;
|
9
|
+
constructor(stack: Construct, canary: Canary, params: CanaryParameters) {
|
10
|
+
const alarmName = params.alarm?.alarmName ?? `${params.name}-alarm`;
|
14
11
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
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
|
+
});
|
23
20
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
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
|
+
);
|
29
31
|
}
|
30
32
|
}
|
31
33
|
}
|
@@ -31,7 +31,7 @@ export class DigitrafficCanary extends Canary {
|
|
31
31
|
}),
|
32
32
|
environmentVariables: {
|
33
33
|
...environmentVariables,
|
34
|
-
...params
|
34
|
+
...params.canaryEnv,
|
35
35
|
},
|
36
36
|
canaryName,
|
37
37
|
schedule: params.schedule ?? Schedule.rate(Duration.minutes(15)),
|
@@ -39,8 +39,6 @@ export class DigitrafficCanary extends Canary {
|
|
39
39
|
|
40
40
|
this.artifactsBucket.grantWrite(role);
|
41
41
|
|
42
|
-
|
43
|
-
new CanaryAlarm(scope, this, params);
|
44
|
-
}
|
42
|
+
new CanaryAlarm(scope, this, params);
|
45
43
|
}
|
46
44
|
}
|
@@ -4,7 +4,7 @@ import { RdsHolder } from "../../runtime/secrets/rds-holder";
|
|
4
4
|
import { getEnvVariable } from "../../../utils/utils";
|
5
5
|
import { Countable } from "../../../database/models";
|
6
6
|
|
7
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-var-requires
|
8
8
|
const synthetics = require("Synthetics");
|
9
9
|
|
10
10
|
abstract class DatabaseCheck<T> {
|
@@ -88,7 +88,9 @@ export class DatabaseCountChecker {
|
|
88
88
|
private constructor(credentialsFunction: () => Promise<void>) {
|
89
89
|
this.credentialsFunction = credentialsFunction;
|
90
90
|
|
91
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
91
92
|
synthetics.getConfiguration().disableRequestMetrics();
|
93
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
92
94
|
synthetics.getConfiguration().withFailedCanaryMetric(true);
|
93
95
|
}
|
94
96
|
|
@@ -146,6 +148,7 @@ export class DatabaseCountChecker {
|
|
146
148
|
check.check(value);
|
147
149
|
};
|
148
150
|
|
151
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
149
152
|
synthetics.executeStep(check.name, checkFunction, stepConfig);
|
150
153
|
}
|
151
154
|
});
|
@@ -48,7 +48,8 @@ export class UrlCanary extends DigitrafficCanary {
|
|
48
48
|
): UrlCanary {
|
49
49
|
return new UrlCanary(stack, role, {
|
50
50
|
...{
|
51
|
-
|
51
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
52
|
+
handler: `${params.name!}.handler`,
|
52
53
|
hostname: publicApi.hostname(),
|
53
54
|
apiKeyId: this.getApiKey(publicApi),
|
54
55
|
},
|