@de-otio/chaoskb-server 0.2.0
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/lib/admin-handler/index.d.ts +22 -0
- package/dist/lib/admin-handler/index.d.ts.map +1 -0
- package/dist/lib/admin-handler/index.js +92 -0
- package/dist/lib/admin-handler/index.js.map +1 -0
- package/dist/lib/admin-handler/index.ts +123 -0
- package/dist/lib/admin-handler/routes/metrics.d.ts +11 -0
- package/dist/lib/admin-handler/routes/metrics.d.ts.map +1 -0
- package/dist/lib/admin-handler/routes/metrics.js +200 -0
- package/dist/lib/admin-handler/routes/metrics.js.map +1 -0
- package/dist/lib/admin-handler/routes/metrics.ts +234 -0
- package/dist/lib/admin-handler/routes/overview.d.ts +9 -0
- package/dist/lib/admin-handler/routes/overview.d.ts.map +1 -0
- package/dist/lib/admin-handler/routes/overview.js +110 -0
- package/dist/lib/admin-handler/routes/overview.js.map +1 -0
- package/dist/lib/admin-handler/routes/overview.ts +133 -0
- package/dist/lib/admin-handler/routes/tenants.d.ts +10 -0
- package/dist/lib/admin-handler/routes/tenants.d.ts.map +1 -0
- package/dist/lib/admin-handler/routes/tenants.js +108 -0
- package/dist/lib/admin-handler/routes/tenants.js.map +1 -0
- package/dist/lib/admin-handler/routes/tenants.ts +134 -0
- package/dist/lib/chaoskb-stack.d.ts +22 -0
- package/dist/lib/chaoskb-stack.d.ts.map +1 -0
- package/dist/lib/chaoskb-stack.js +60 -0
- package/dist/lib/chaoskb-stack.js.map +1 -0
- package/dist/lib/constructs/admin-api.d.ts +16 -0
- package/dist/lib/constructs/admin-api.d.ts.map +1 -0
- package/dist/lib/constructs/admin-api.js +93 -0
- package/dist/lib/constructs/admin-api.js.map +1 -0
- package/dist/lib/constructs/admin-dashboard.d.ts +18 -0
- package/dist/lib/constructs/admin-dashboard.d.ts.map +1 -0
- package/dist/lib/constructs/admin-dashboard.js +172 -0
- package/dist/lib/constructs/admin-dashboard.js.map +1 -0
- package/dist/lib/constructs/api.d.ts +17 -0
- package/dist/lib/constructs/api.d.ts.map +1 -0
- package/dist/lib/constructs/api.js +81 -0
- package/dist/lib/constructs/api.js.map +1 -0
- package/dist/lib/constructs/auth.d.ts +11 -0
- package/dist/lib/constructs/auth.d.ts.map +1 -0
- package/dist/lib/constructs/auth.js +18 -0
- package/dist/lib/constructs/auth.js.map +1 -0
- package/dist/lib/constructs/blob-store.d.ts +10 -0
- package/dist/lib/constructs/blob-store.d.ts.map +1 -0
- package/dist/lib/constructs/blob-store.js +31 -0
- package/dist/lib/constructs/blob-store.js.map +1 -0
- package/dist/lib/deploy-cli.d.ts +3 -0
- package/dist/lib/deploy-cli.d.ts.map +1 -0
- package/dist/lib/deploy-cli.js +49 -0
- package/dist/lib/deploy-cli.js.map +1 -0
- package/dist/lib/handler/index.d.ts +23 -0
- package/dist/lib/handler/index.d.ts.map +1 -0
- package/dist/lib/handler/index.js +276 -0
- package/dist/lib/handler/index.js.map +1 -0
- package/dist/lib/handler/index.ts +372 -0
- package/dist/lib/handler/logger.d.ts +16 -0
- package/dist/lib/handler/logger.d.ts.map +1 -0
- package/dist/lib/handler/logger.js +26 -0
- package/dist/lib/handler/logger.js.map +1 -0
- package/dist/lib/handler/logger.ts +36 -0
- package/dist/lib/handler/middleware/input-validation.d.ts +6 -0
- package/dist/lib/handler/middleware/input-validation.d.ts.map +1 -0
- package/dist/lib/handler/middleware/input-validation.js +36 -0
- package/dist/lib/handler/middleware/input-validation.js.map +1 -0
- package/dist/lib/handler/middleware/input-validation.ts +44 -0
- package/dist/lib/handler/middleware/rate-limit.d.ts +14 -0
- package/dist/lib/handler/middleware/rate-limit.d.ts.map +1 -0
- package/dist/lib/handler/middleware/rate-limit.js +94 -0
- package/dist/lib/handler/middleware/rate-limit.js.map +1 -0
- package/dist/lib/handler/middleware/rate-limit.ts +121 -0
- package/dist/lib/handler/middleware/ssh-auth.d.ts +48 -0
- package/dist/lib/handler/middleware/ssh-auth.d.ts.map +1 -0
- package/dist/lib/handler/middleware/ssh-auth.js +256 -0
- package/dist/lib/handler/middleware/ssh-auth.js.map +1 -0
- package/dist/lib/handler/middleware/ssh-auth.ts +300 -0
- package/dist/lib/handler/routes/audit.d.ts +24 -0
- package/dist/lib/handler/routes/audit.d.ts.map +1 -0
- package/dist/lib/handler/routes/audit.js +94 -0
- package/dist/lib/handler/routes/audit.js.map +1 -0
- package/dist/lib/handler/routes/audit.ts +101 -0
- package/dist/lib/handler/routes/blobs.d.ts +13 -0
- package/dist/lib/handler/routes/blobs.d.ts.map +1 -0
- package/dist/lib/handler/routes/blobs.js +298 -0
- package/dist/lib/handler/routes/blobs.js.map +1 -0
- package/dist/lib/handler/routes/blobs.ts +348 -0
- package/dist/lib/handler/routes/devices.d.ts +48 -0
- package/dist/lib/handler/routes/devices.d.ts.map +1 -0
- package/dist/lib/handler/routes/devices.js +394 -0
- package/dist/lib/handler/routes/devices.js.map +1 -0
- package/dist/lib/handler/routes/devices.ts +458 -0
- package/dist/lib/handler/routes/export.d.ts +9 -0
- package/dist/lib/handler/routes/export.d.ts.map +1 -0
- package/dist/lib/handler/routes/export.js +40 -0
- package/dist/lib/handler/routes/export.js.map +1 -0
- package/dist/lib/handler/routes/export.ts +55 -0
- package/dist/lib/handler/routes/github.d.ts +31 -0
- package/dist/lib/handler/routes/github.d.ts.map +1 -0
- package/dist/lib/handler/routes/github.js +118 -0
- package/dist/lib/handler/routes/github.js.map +1 -0
- package/dist/lib/handler/routes/github.ts +162 -0
- package/dist/lib/handler/routes/health.d.ts +6 -0
- package/dist/lib/handler/routes/health.d.ts.map +1 -0
- package/dist/lib/handler/routes/health.js +14 -0
- package/dist/lib/handler/routes/health.js.map +1 -0
- package/dist/lib/handler/routes/health.ts +10 -0
- package/dist/lib/handler/routes/invites.d.ts +24 -0
- package/dist/lib/handler/routes/invites.d.ts.map +1 -0
- package/dist/lib/handler/routes/invites.js +445 -0
- package/dist/lib/handler/routes/invites.js.map +1 -0
- package/dist/lib/handler/routes/invites.ts +527 -0
- package/dist/lib/handler/routes/notifications.d.ts +39 -0
- package/dist/lib/handler/routes/notifications.d.ts.map +1 -0
- package/dist/lib/handler/routes/notifications.js +150 -0
- package/dist/lib/handler/routes/notifications.js.map +1 -0
- package/dist/lib/handler/routes/notifications.ts +163 -0
- package/dist/lib/handler/routes/projects.d.ts +24 -0
- package/dist/lib/handler/routes/projects.d.ts.map +1 -0
- package/dist/lib/handler/routes/projects.js +47 -0
- package/dist/lib/handler/routes/projects.js.map +1 -0
- package/dist/lib/handler/routes/projects.ts +69 -0
- package/dist/lib/handler/routes/register.d.ts +19 -0
- package/dist/lib/handler/routes/register.d.ts.map +1 -0
- package/dist/lib/handler/routes/register.js +327 -0
- package/dist/lib/handler/routes/register.js.map +1 -0
- package/dist/lib/handler/routes/register.ts +363 -0
- package/dist/lib/handler/routes/restore.d.ts +9 -0
- package/dist/lib/handler/routes/restore.d.ts.map +1 -0
- package/dist/lib/handler/routes/restore.js +52 -0
- package/dist/lib/handler/routes/restore.js.map +1 -0
- package/dist/lib/handler/routes/restore.ts +73 -0
- package/dist/lib/handler/routes/revocation.d.ts +13 -0
- package/dist/lib/handler/routes/revocation.d.ts.map +1 -0
- package/dist/lib/handler/routes/revocation.js +63 -0
- package/dist/lib/handler/routes/revocation.js.map +1 -0
- package/dist/lib/handler/routes/revocation.ts +87 -0
- package/dist/lib/handler/routes/rotation.d.ts +24 -0
- package/dist/lib/handler/routes/rotation.d.ts.map +1 -0
- package/dist/lib/handler/routes/rotation.js +291 -0
- package/dist/lib/handler/routes/rotation.js.map +1 -0
- package/dist/lib/handler/routes/rotation.ts +336 -0
- package/dist/lib/handler/routes/tenants.d.ts +11 -0
- package/dist/lib/handler/routes/tenants.d.ts.map +1 -0
- package/dist/lib/handler/routes/tenants.js +181 -0
- package/dist/lib/handler/routes/tenants.js.map +1 -0
- package/dist/lib/handler/routes/tenants.ts +198 -0
- package/dist/lib/handler/routes/wrapped-key.d.ts +21 -0
- package/dist/lib/handler/routes/wrapped-key.d.ts.map +1 -0
- package/dist/lib/handler/routes/wrapped-key.js +76 -0
- package/dist/lib/handler/routes/wrapped-key.js.map +1 -0
- package/dist/lib/handler/routes/wrapped-key.ts +108 -0
- package/dist/lib/index.d.ts +7 -0
- package/dist/lib/index.d.ts.map +1 -0
- package/dist/lib/index.js +16 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/vitest.config.d.ts +3 -0
- package/dist/vitest.config.d.ts.map +1 -0
- package/dist/vitest.config.js +18 -0
- package/dist/vitest.config.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { DynamoDBDocumentClient, ScanCommand, QueryCommand } from '@aws-sdk/lib-dynamodb';
|
|
2
|
+
import { logger } from '../../handler/logger.js';
|
|
3
|
+
|
|
4
|
+
interface RouteResult {
|
|
5
|
+
statusCode: number;
|
|
6
|
+
body: string;
|
|
7
|
+
headers: Record<string, string>;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const PAGE_SIZE = 25;
|
|
11
|
+
|
|
12
|
+
export async function handleListTenants(
|
|
13
|
+
page: number,
|
|
14
|
+
ddb: DynamoDBDocumentClient,
|
|
15
|
+
tableName: string,
|
|
16
|
+
): Promise<RouteResult> {
|
|
17
|
+
try {
|
|
18
|
+
const validPage = Math.max(1, page);
|
|
19
|
+
|
|
20
|
+
// Scan for all META records to get tenant list
|
|
21
|
+
const allTenants: Record<string, unknown>[] = [];
|
|
22
|
+
let exclusiveStartKey: Record<string, unknown> | undefined;
|
|
23
|
+
|
|
24
|
+
do {
|
|
25
|
+
const result = await ddb.send(
|
|
26
|
+
new ScanCommand({
|
|
27
|
+
TableName: tableName,
|
|
28
|
+
FilterExpression: 'SK = :sk',
|
|
29
|
+
ExpressionAttributeValues: { ':sk': 'META' },
|
|
30
|
+
ProjectionExpression: 'PK, publicKey, createdAt, updatedAt, storageUsedBytes',
|
|
31
|
+
ExclusiveStartKey: exclusiveStartKey,
|
|
32
|
+
}),
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
if (result.Items) {
|
|
36
|
+
allTenants.push(...result.Items);
|
|
37
|
+
}
|
|
38
|
+
exclusiveStartKey = result.LastEvaluatedKey;
|
|
39
|
+
} while (exclusiveStartKey);
|
|
40
|
+
|
|
41
|
+
const total = allTenants.length;
|
|
42
|
+
const startIndex = (validPage - 1) * PAGE_SIZE;
|
|
43
|
+
const paginatedTenants = allTenants.slice(startIndex, startIndex + PAGE_SIZE).map((item) => ({
|
|
44
|
+
tenantId: (item['PK'] as string).replace('TENANT#', ''),
|
|
45
|
+
publicKey: item['publicKey'],
|
|
46
|
+
createdAt: item['createdAt'],
|
|
47
|
+
updatedAt: item['updatedAt'],
|
|
48
|
+
storageUsedBytes: item['storageUsedBytes'] ?? 0,
|
|
49
|
+
}));
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
statusCode: 200,
|
|
53
|
+
body: JSON.stringify({
|
|
54
|
+
tenants: paginatedTenants,
|
|
55
|
+
total,
|
|
56
|
+
page: validPage,
|
|
57
|
+
pageSize: PAGE_SIZE,
|
|
58
|
+
}),
|
|
59
|
+
headers: { 'Content-Type': 'application/json' },
|
|
60
|
+
};
|
|
61
|
+
} catch (err) {
|
|
62
|
+
logger.error('Failed to list tenants', { error: String(err) });
|
|
63
|
+
return {
|
|
64
|
+
statusCode: 500,
|
|
65
|
+
body: JSON.stringify({ error: 'internal_error', message: 'Failed to list tenants' }),
|
|
66
|
+
headers: { 'Content-Type': 'application/json' },
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export async function handleGetTenantDetail(
|
|
72
|
+
tenantId: string,
|
|
73
|
+
ddb: DynamoDBDocumentClient,
|
|
74
|
+
tableName: string,
|
|
75
|
+
): Promise<RouteResult> {
|
|
76
|
+
try {
|
|
77
|
+
// Query for the META record
|
|
78
|
+
const metaResult = await ddb.send(
|
|
79
|
+
new QueryCommand({
|
|
80
|
+
TableName: tableName,
|
|
81
|
+
KeyConditionExpression: 'PK = :pk AND SK = :sk',
|
|
82
|
+
ExpressionAttributeValues: {
|
|
83
|
+
':pk': `TENANT#${tenantId}`,
|
|
84
|
+
':sk': 'META',
|
|
85
|
+
},
|
|
86
|
+
}),
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
if (!metaResult.Items || metaResult.Items.length === 0) {
|
|
90
|
+
return {
|
|
91
|
+
statusCode: 404,
|
|
92
|
+
body: JSON.stringify({ error: 'not_found', message: 'Tenant not found' }),
|
|
93
|
+
headers: { 'Content-Type': 'application/json' },
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const meta = metaResult.Items[0];
|
|
98
|
+
|
|
99
|
+
// Count blobs for this tenant
|
|
100
|
+
const blobResult = await ddb.send(
|
|
101
|
+
new QueryCommand({
|
|
102
|
+
TableName: tableName,
|
|
103
|
+
KeyConditionExpression: 'PK = :pk AND begins_with(SK, :sk)',
|
|
104
|
+
ExpressionAttributeValues: {
|
|
105
|
+
':pk': `TENANT#${tenantId}`,
|
|
106
|
+
':sk': 'BLOB#',
|
|
107
|
+
},
|
|
108
|
+
Select: 'COUNT',
|
|
109
|
+
}),
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
const blobCount = blobResult.Count ?? 0;
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
statusCode: 200,
|
|
116
|
+
body: JSON.stringify({
|
|
117
|
+
tenantId,
|
|
118
|
+
publicKey: meta['publicKey'],
|
|
119
|
+
createdAt: meta['createdAt'],
|
|
120
|
+
updatedAt: meta['updatedAt'],
|
|
121
|
+
storageUsedBytes: meta['storageUsedBytes'] ?? 0,
|
|
122
|
+
blobCount,
|
|
123
|
+
}),
|
|
124
|
+
headers: { 'Content-Type': 'application/json' },
|
|
125
|
+
};
|
|
126
|
+
} catch (err) {
|
|
127
|
+
logger.error('Failed to get tenant detail', { error: String(err) });
|
|
128
|
+
return {
|
|
129
|
+
statusCode: 500,
|
|
130
|
+
body: JSON.stringify({ error: 'internal_error', message: 'Failed to get tenant detail' }),
|
|
131
|
+
headers: { 'Content-Type': 'application/json' },
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Stack, StackProps } from 'aws-cdk-lib';
|
|
2
|
+
import { Construct } from 'constructs';
|
|
3
|
+
import { BlobStore } from './constructs/blob-store.js';
|
|
4
|
+
import { Auth } from './constructs/auth.js';
|
|
5
|
+
import { Api } from './constructs/api.js';
|
|
6
|
+
import { AdminDashboard } from './constructs/admin-dashboard.js';
|
|
7
|
+
import { AdminApi } from './constructs/admin-api.js';
|
|
8
|
+
export interface ChaosKBStackProps extends StackProps {
|
|
9
|
+
readonly environment: string;
|
|
10
|
+
readonly signupsEnabled?: boolean;
|
|
11
|
+
readonly reservedConcurrency?: number;
|
|
12
|
+
readonly allowedOrigins?: string[];
|
|
13
|
+
}
|
|
14
|
+
export declare class ChaosKBStack extends Stack {
|
|
15
|
+
readonly blobStore: BlobStore;
|
|
16
|
+
readonly auth: Auth;
|
|
17
|
+
readonly api: Api;
|
|
18
|
+
readonly adminDashboard: AdminDashboard;
|
|
19
|
+
readonly adminApi: AdminApi;
|
|
20
|
+
constructor(scope: Construct, id: string, props: ChaosKBStackProps);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=chaoskb-stack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chaoskb-stack.d.ts","sourceRoot":"","sources":["../../lib/chaoskb-stack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,UAAU,EAAa,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AAErD,MAAM,WAAW,iBAAkB,SAAQ,UAAU;IACnD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,CAAC,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CACpC;AAED,qBAAa,YAAa,SAAQ,KAAK;IACrC,SAAgB,SAAS,EAAE,SAAS,CAAC;IACrC,SAAgB,IAAI,EAAE,IAAI,CAAC;IAC3B,SAAgB,GAAG,EAAE,GAAG,CAAC;IACzB,SAAgB,cAAc,EAAE,cAAc,CAAC;IAC/C,SAAgB,QAAQ,EAAE,QAAQ,CAAC;gBAEvB,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,iBAAiB;CAmDnE"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ChaosKBStack = void 0;
|
|
4
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
5
|
+
const blob_store_js_1 = require("./constructs/blob-store.js");
|
|
6
|
+
const auth_js_1 = require("./constructs/auth.js");
|
|
7
|
+
const api_js_1 = require("./constructs/api.js");
|
|
8
|
+
const admin_dashboard_js_1 = require("./constructs/admin-dashboard.js");
|
|
9
|
+
const admin_api_js_1 = require("./constructs/admin-api.js");
|
|
10
|
+
class ChaosKBStack extends aws_cdk_lib_1.Stack {
|
|
11
|
+
blobStore;
|
|
12
|
+
auth;
|
|
13
|
+
api;
|
|
14
|
+
adminDashboard;
|
|
15
|
+
adminApi;
|
|
16
|
+
constructor(scope, id, props) {
|
|
17
|
+
super(scope, id, props);
|
|
18
|
+
this.blobStore = new blob_store_js_1.BlobStore(this, 'BlobStore', {
|
|
19
|
+
environment: props.environment,
|
|
20
|
+
});
|
|
21
|
+
this.auth = new auth_js_1.Auth(this, 'Auth', {
|
|
22
|
+
environment: props.environment,
|
|
23
|
+
signupsEnabled: props.signupsEnabled ?? true,
|
|
24
|
+
});
|
|
25
|
+
this.api = new api_js_1.Api(this, 'Api', {
|
|
26
|
+
table: this.blobStore.table,
|
|
27
|
+
environment: props.environment,
|
|
28
|
+
signupsEnabledParam: this.auth.signupsEnabledParam,
|
|
29
|
+
reservedConcurrency: props.reservedConcurrency,
|
|
30
|
+
});
|
|
31
|
+
this.adminDashboard = new admin_dashboard_js_1.AdminDashboard(this, 'AdminDashboard', {
|
|
32
|
+
environment: props.environment,
|
|
33
|
+
lambdaFunction: this.api.handler,
|
|
34
|
+
table: this.blobStore.table,
|
|
35
|
+
});
|
|
36
|
+
this.adminApi = new admin_api_js_1.AdminApi(this, 'AdminApi', {
|
|
37
|
+
table: this.blobStore.table,
|
|
38
|
+
environment: props.environment,
|
|
39
|
+
allowedOrigins: props.allowedOrigins ?? [],
|
|
40
|
+
});
|
|
41
|
+
new aws_cdk_lib_1.CfnOutput(this, 'FunctionUrl', {
|
|
42
|
+
value: this.api.functionUrl.url,
|
|
43
|
+
description: 'ChaosKB API Function URL',
|
|
44
|
+
});
|
|
45
|
+
new aws_cdk_lib_1.CfnOutput(this, 'TableName', {
|
|
46
|
+
value: this.blobStore.table.tableName,
|
|
47
|
+
description: 'ChaosKB DynamoDB table name',
|
|
48
|
+
});
|
|
49
|
+
new aws_cdk_lib_1.CfnOutput(this, 'AlarmTopicArn', {
|
|
50
|
+
value: this.adminDashboard.alarmTopic.topicArn,
|
|
51
|
+
description: 'ChaosKB alarm SNS topic ARN',
|
|
52
|
+
});
|
|
53
|
+
new aws_cdk_lib_1.CfnOutput(this, 'AdminApiUrl', {
|
|
54
|
+
value: this.adminApi.functionUrl.url,
|
|
55
|
+
description: 'ChaosKB Admin API Function URL',
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
exports.ChaosKBStack = ChaosKBStack;
|
|
60
|
+
//# sourceMappingURL=chaoskb-stack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chaoskb-stack.js","sourceRoot":"","sources":["../../lib/chaoskb-stack.ts"],"names":[],"mappings":";;;AAAA,6CAA2D;AAE3D,8DAAuD;AACvD,kDAA4C;AAC5C,gDAA0C;AAC1C,wEAAiE;AACjE,4DAAqD;AASrD,MAAa,YAAa,SAAQ,mBAAK;IACrB,SAAS,CAAY;IACrB,IAAI,CAAO;IACX,GAAG,CAAM;IACT,cAAc,CAAiB;IAC/B,QAAQ,CAAW;IAEnC,YAAY,KAAgB,EAAE,EAAU,EAAE,KAAwB;QAChE,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;QAExB,IAAI,CAAC,SAAS,GAAG,IAAI,yBAAS,CAAC,IAAI,EAAE,WAAW,EAAE;YAChD,WAAW,EAAE,KAAK,CAAC,WAAW;SAC/B,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,GAAG,IAAI,cAAI,CAAC,IAAI,EAAE,MAAM,EAAE;YACjC,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,cAAc,EAAE,KAAK,CAAC,cAAc,IAAI,IAAI;SAC7C,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,GAAG,IAAI,YAAG,CAAC,IAAI,EAAE,KAAK,EAAE;YAC9B,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK;YAC3B,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,mBAAmB,EAAE,IAAI,CAAC,IAAI,CAAC,mBAAmB;YAClD,mBAAmB,EAAE,KAAK,CAAC,mBAAmB;SAC/C,CAAC,CAAC;QAEH,IAAI,CAAC,cAAc,GAAG,IAAI,mCAAc,CAAC,IAAI,EAAE,gBAAgB,EAAE;YAC/D,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,cAAc,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO;YAChC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK;SAC5B,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,GAAG,IAAI,uBAAQ,CAAC,IAAI,EAAE,UAAU,EAAE;YAC7C,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK;YAC3B,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,cAAc,EAAE,KAAK,CAAC,cAAc,IAAI,EAAE;SAC3C,CAAC,CAAC;QAEH,IAAI,uBAAS,CAAC,IAAI,EAAE,aAAa,EAAE;YACjC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG;YAC/B,WAAW,EAAE,0BAA0B;SACxC,CAAC,CAAC;QAEH,IAAI,uBAAS,CAAC,IAAI,EAAE,WAAW,EAAE;YAC/B,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS;YACrC,WAAW,EAAE,6BAA6B;SAC3C,CAAC,CAAC;QAEH,IAAI,uBAAS,CAAC,IAAI,EAAE,eAAe,EAAE;YACnC,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,QAAQ;YAC9C,WAAW,EAAE,6BAA6B;SAC3C,CAAC,CAAC;QAEH,IAAI,uBAAS,CAAC,IAAI,EAAE,aAAa,EAAE;YACjC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG;YACpC,WAAW,EAAE,gCAAgC;SAC9C,CAAC,CAAC;IACL,CAAC;CACF;AA1DD,oCA0DC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
|
|
2
|
+
import { FunctionUrl } from 'aws-cdk-lib/aws-lambda';
|
|
3
|
+
import { TableV2 } from 'aws-cdk-lib/aws-dynamodb';
|
|
4
|
+
import { Construct } from 'constructs';
|
|
5
|
+
export interface AdminApiProps {
|
|
6
|
+
readonly environment: string;
|
|
7
|
+
readonly table: TableV2;
|
|
8
|
+
readonly allowedOrigins: string[];
|
|
9
|
+
readonly reservedConcurrency?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare class AdminApi extends Construct {
|
|
12
|
+
readonly handler: NodejsFunction;
|
|
13
|
+
readonly functionUrl: FunctionUrl;
|
|
14
|
+
constructor(scope: Construct, id: string, props: AdminApiProps);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=admin-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-api.d.ts","sourceRoot":"","sources":["../../../lib/constructs/admin-api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAuD,MAAM,wBAAwB,CAAC;AAC1G,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAEnD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvC,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;CACvC;AAED,qBAAa,QAAS,SAAQ,SAAS;IACrC,SAAgB,OAAO,EAAE,cAAc,CAAC;IACxC,SAAgB,WAAW,EAAE,WAAW,CAAC;gBAE7B,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa;CAwD/D"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.AdminApi = void 0;
|
|
37
|
+
const cdk = __importStar(require("aws-cdk-lib"));
|
|
38
|
+
const aws_lambda_nodejs_1 = require("aws-cdk-lib/aws-lambda-nodejs");
|
|
39
|
+
const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
|
|
40
|
+
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
|
|
41
|
+
const constructs_1 = require("constructs");
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
class AdminApi extends constructs_1.Construct {
|
|
44
|
+
handler;
|
|
45
|
+
functionUrl;
|
|
46
|
+
constructor(scope, id, props) {
|
|
47
|
+
super(scope, id);
|
|
48
|
+
this.handler = new aws_lambda_nodejs_1.NodejsFunction(this, 'Handler', {
|
|
49
|
+
runtime: aws_lambda_1.Runtime.NODEJS_22_X,
|
|
50
|
+
architecture: aws_lambda_1.Architecture.ARM_64,
|
|
51
|
+
entry: path.join(__dirname, '../admin-handler/index.ts'),
|
|
52
|
+
handler: 'handler',
|
|
53
|
+
memorySize: 256,
|
|
54
|
+
timeout: cdk.Duration.seconds(30),
|
|
55
|
+
reservedConcurrentExecutions: props.reservedConcurrency ?? 5,
|
|
56
|
+
tracing: aws_lambda_1.Tracing.ACTIVE,
|
|
57
|
+
environment: {
|
|
58
|
+
TABLE_NAME: props.table.tableName,
|
|
59
|
+
ENVIRONMENT: props.environment,
|
|
60
|
+
ALLOWED_ORIGINS: props.allowedOrigins.join(','),
|
|
61
|
+
},
|
|
62
|
+
bundling: {
|
|
63
|
+
minify: true,
|
|
64
|
+
sourceMap: true,
|
|
65
|
+
target: 'node22',
|
|
66
|
+
format: undefined, // default cjs for Lambda
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
this.functionUrl = this.handler.addFunctionUrl({
|
|
70
|
+
authType: aws_lambda_1.FunctionUrlAuthType.NONE,
|
|
71
|
+
});
|
|
72
|
+
// DynamoDB read-only access
|
|
73
|
+
this.handler.addToRolePolicy(new aws_iam_1.PolicyStatement({
|
|
74
|
+
effect: aws_iam_1.Effect.ALLOW,
|
|
75
|
+
actions: ['dynamodb:Scan', 'dynamodb:Query', 'dynamodb:GetItem'],
|
|
76
|
+
resources: [props.table.tableArn],
|
|
77
|
+
}));
|
|
78
|
+
// CloudWatch read access
|
|
79
|
+
this.handler.addToRolePolicy(new aws_iam_1.PolicyStatement({
|
|
80
|
+
effect: aws_iam_1.Effect.ALLOW,
|
|
81
|
+
actions: ['cloudwatch:DescribeAlarms', 'cloudwatch:GetMetricData'],
|
|
82
|
+
resources: ['*'],
|
|
83
|
+
}));
|
|
84
|
+
// Cost Explorer read access
|
|
85
|
+
this.handler.addToRolePolicy(new aws_iam_1.PolicyStatement({
|
|
86
|
+
effect: aws_iam_1.Effect.ALLOW,
|
|
87
|
+
actions: ['ce:GetCostAndUsage', 'ce:GetCostForecast'],
|
|
88
|
+
resources: ['*'],
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
exports.AdminApi = AdminApi;
|
|
93
|
+
//# sourceMappingURL=admin-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-api.js","sourceRoot":"","sources":["../../../lib/constructs/admin-api.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iDAAmC;AACnC,qEAA+D;AAC/D,uDAA0G;AAE1G,iDAA8D;AAC9D,2CAAuC;AACvC,2CAA6B;AAS7B,MAAa,QAAS,SAAQ,sBAAS;IACrB,OAAO,CAAiB;IACxB,WAAW,CAAc;IAEzC,YAAY,KAAgB,EAAE,EAAU,EAAE,KAAoB;QAC5D,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAEjB,IAAI,CAAC,OAAO,GAAG,IAAI,kCAAc,CAAC,IAAI,EAAE,SAAS,EAAE;YACjD,OAAO,EAAE,oBAAO,CAAC,WAAW;YAC5B,YAAY,EAAE,yBAAY,CAAC,MAAM;YACjC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,2BAA2B,CAAC;YACxD,OAAO,EAAE,SAAS;YAClB,UAAU,EAAE,GAAG;YACf,OAAO,EAAE,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACjC,4BAA4B,EAAE,KAAK,CAAC,mBAAmB,IAAI,CAAC;YAC5D,OAAO,EAAE,oBAAO,CAAC,MAAM;YACvB,WAAW,EAAE;gBACX,UAAU,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS;gBACjC,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,eAAe,EAAE,KAAK,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC;aAChD;YACD,QAAQ,EAAE;gBACR,MAAM,EAAE,IAAI;gBACZ,SAAS,EAAE,IAAI;gBACf,MAAM,EAAE,QAAQ;gBAChB,MAAM,EAAE,SAAS,EAAE,yBAAyB;aAC7C;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC;YAC7C,QAAQ,EAAE,gCAAmB,CAAC,IAAI;SACnC,CAAC,CAAC;QAEH,4BAA4B;QAC5B,IAAI,CAAC,OAAO,CAAC,eAAe,CAC1B,IAAI,yBAAe,CAAC;YAClB,MAAM,EAAE,gBAAM,CAAC,KAAK;YACpB,OAAO,EAAE,CAAC,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,CAAC;YAChE,SAAS,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC;SAClC,CAAC,CACH,CAAC;QAEF,yBAAyB;QACzB,IAAI,CAAC,OAAO,CAAC,eAAe,CAC1B,IAAI,yBAAe,CAAC;YAClB,MAAM,EAAE,gBAAM,CAAC,KAAK;YACpB,OAAO,EAAE,CAAC,2BAA2B,EAAE,0BAA0B,CAAC;YAClE,SAAS,EAAE,CAAC,GAAG,CAAC;SACjB,CAAC,CACH,CAAC;QAEF,4BAA4B;QAC5B,IAAI,CAAC,OAAO,CAAC,eAAe,CAC1B,IAAI,yBAAe,CAAC;YAClB,MAAM,EAAE,gBAAM,CAAC,KAAK;YACpB,OAAO,EAAE,CAAC,oBAAoB,EAAE,oBAAoB,CAAC;YACrD,SAAS,EAAE,CAAC,GAAG,CAAC;SACjB,CAAC,CACH,CAAC;IACJ,CAAC;CACF;AA5DD,4BA4DC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Dashboard } from 'aws-cdk-lib/aws-cloudwatch';
|
|
2
|
+
import { Topic } from 'aws-cdk-lib/aws-sns';
|
|
3
|
+
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
|
|
4
|
+
import { TableV2 } from 'aws-cdk-lib/aws-dynamodb';
|
|
5
|
+
import { LogGroup } from 'aws-cdk-lib/aws-logs';
|
|
6
|
+
import { Construct } from 'constructs';
|
|
7
|
+
export interface AdminDashboardProps {
|
|
8
|
+
readonly environment: string;
|
|
9
|
+
readonly lambdaFunction: NodejsFunction;
|
|
10
|
+
readonly table: TableV2;
|
|
11
|
+
readonly lambdaLogGroup?: LogGroup;
|
|
12
|
+
}
|
|
13
|
+
export declare class AdminDashboard extends Construct {
|
|
14
|
+
readonly alarmTopic: Topic;
|
|
15
|
+
readonly dashboard: Dashboard;
|
|
16
|
+
constructor(scope: Construct, id: string, props: AdminDashboardProps);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=admin-dashboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-dashboard.d.ts","sourceRoot":"","sources":["../../../lib/constructs/admin-dashboard.ts"],"names":[],"mappings":"AACA,OAAO,EACL,SAAS,EAQV,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EAAE,QAAQ,EAA+B,MAAM,sBAAsB,CAAC;AAC7E,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;IACxC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,cAAc,CAAC,EAAE,QAAQ,CAAC;CACpC;AAED,qBAAa,cAAe,SAAQ,SAAS;IAC3C,SAAgB,UAAU,EAAE,KAAK,CAAC;IAClC,SAAgB,SAAS,EAAE,SAAS,CAAC;gBAEzB,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB;CAkLrE"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AdminDashboard = void 0;
|
|
4
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
5
|
+
const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
|
|
6
|
+
const aws_cloudwatch_actions_1 = require("aws-cdk-lib/aws-cloudwatch-actions");
|
|
7
|
+
const aws_sns_1 = require("aws-cdk-lib/aws-sns");
|
|
8
|
+
const aws_logs_1 = require("aws-cdk-lib/aws-logs");
|
|
9
|
+
const constructs_1 = require("constructs");
|
|
10
|
+
class AdminDashboard extends constructs_1.Construct {
|
|
11
|
+
alarmTopic;
|
|
12
|
+
dashboard;
|
|
13
|
+
constructor(scope, id, props) {
|
|
14
|
+
super(scope, id);
|
|
15
|
+
this.alarmTopic = new aws_sns_1.Topic(this, 'AlarmTopic', {
|
|
16
|
+
displayName: `ChaosKB ${props.environment} Alarms`,
|
|
17
|
+
});
|
|
18
|
+
const snsAction = new aws_cloudwatch_actions_1.SnsAction(this.alarmTopic);
|
|
19
|
+
// Lambda metrics
|
|
20
|
+
const invocations = props.lambdaFunction.metricInvocations({ period: aws_cdk_lib_1.Duration.minutes(5) });
|
|
21
|
+
const errors = props.lambdaFunction.metricErrors({ period: aws_cdk_lib_1.Duration.minutes(5) });
|
|
22
|
+
const durationP50 = props.lambdaFunction.metricDuration({ period: aws_cdk_lib_1.Duration.minutes(5), statistic: 'p50' });
|
|
23
|
+
const durationP95 = props.lambdaFunction.metricDuration({ period: aws_cdk_lib_1.Duration.minutes(5), statistic: 'p95' });
|
|
24
|
+
const durationP99 = props.lambdaFunction.metricDuration({ period: aws_cdk_lib_1.Duration.minutes(5), statistic: 'p99' });
|
|
25
|
+
// DynamoDB metrics
|
|
26
|
+
const readCapacity = new aws_cloudwatch_1.Metric({
|
|
27
|
+
namespace: 'AWS/DynamoDB',
|
|
28
|
+
metricName: 'ConsumedReadCapacityUnits',
|
|
29
|
+
dimensionsMap: { TableName: props.table.tableName },
|
|
30
|
+
period: aws_cdk_lib_1.Duration.minutes(5),
|
|
31
|
+
statistic: 'Sum',
|
|
32
|
+
});
|
|
33
|
+
const writeCapacity = new aws_cloudwatch_1.Metric({
|
|
34
|
+
namespace: 'AWS/DynamoDB',
|
|
35
|
+
metricName: 'ConsumedWriteCapacityUnits',
|
|
36
|
+
dimensionsMap: { TableName: props.table.tableName },
|
|
37
|
+
period: aws_cdk_lib_1.Duration.minutes(5),
|
|
38
|
+
statistic: 'Sum',
|
|
39
|
+
});
|
|
40
|
+
const throttledRequests = new aws_cloudwatch_1.Metric({
|
|
41
|
+
namespace: 'AWS/DynamoDB',
|
|
42
|
+
metricName: 'ThrottledRequests',
|
|
43
|
+
dimensionsMap: { TableName: props.table.tableName },
|
|
44
|
+
period: aws_cdk_lib_1.Duration.minutes(1),
|
|
45
|
+
statistic: 'Sum',
|
|
46
|
+
});
|
|
47
|
+
// Dashboard
|
|
48
|
+
this.dashboard = new aws_cloudwatch_1.Dashboard(this, 'Dashboard', {
|
|
49
|
+
// CDK auto-generates the dashboard name
|
|
50
|
+
widgets: [
|
|
51
|
+
[
|
|
52
|
+
new aws_cloudwatch_1.GraphWidget({
|
|
53
|
+
title: 'Lambda Invocations & Errors',
|
|
54
|
+
left: [invocations],
|
|
55
|
+
right: [errors],
|
|
56
|
+
width: 12,
|
|
57
|
+
}),
|
|
58
|
+
new aws_cloudwatch_1.GraphWidget({
|
|
59
|
+
title: 'Lambda Duration (p50/p95/p99)',
|
|
60
|
+
left: [durationP50, durationP95, durationP99],
|
|
61
|
+
width: 12,
|
|
62
|
+
}),
|
|
63
|
+
],
|
|
64
|
+
[
|
|
65
|
+
new aws_cloudwatch_1.GraphWidget({
|
|
66
|
+
title: 'DynamoDB Read/Write Capacity',
|
|
67
|
+
left: [readCapacity],
|
|
68
|
+
right: [writeCapacity],
|
|
69
|
+
width: 12,
|
|
70
|
+
}),
|
|
71
|
+
new aws_cloudwatch_1.GraphWidget({
|
|
72
|
+
title: 'DynamoDB Throttled Requests',
|
|
73
|
+
left: [throttledRequests],
|
|
74
|
+
width: 12,
|
|
75
|
+
}),
|
|
76
|
+
],
|
|
77
|
+
],
|
|
78
|
+
});
|
|
79
|
+
// Alarms
|
|
80
|
+
// Lambda error rate > 1% over 5 min
|
|
81
|
+
const errorRate = new aws_cloudwatch_1.MathExpression({
|
|
82
|
+
expression: 'IF(invocations > 0, 100 * errors / invocations, 0)',
|
|
83
|
+
usingMetrics: {
|
|
84
|
+
errors,
|
|
85
|
+
invocations,
|
|
86
|
+
},
|
|
87
|
+
period: aws_cdk_lib_1.Duration.minutes(5),
|
|
88
|
+
});
|
|
89
|
+
const errorRateAlarm = new aws_cloudwatch_1.Alarm(this, 'LambdaErrorRateAlarm', {
|
|
90
|
+
alarmDescription: 'Lambda error rate exceeds 1%',
|
|
91
|
+
metric: errorRate,
|
|
92
|
+
threshold: 1,
|
|
93
|
+
evaluationPeriods: 1,
|
|
94
|
+
comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
95
|
+
treatMissingData: aws_cloudwatch_1.TreatMissingData.NOT_BREACHING,
|
|
96
|
+
});
|
|
97
|
+
errorRateAlarm.addAlarmAction(snsAction);
|
|
98
|
+
// DynamoDB throttles > 0 over 1 min
|
|
99
|
+
const throttleAlarm = new aws_cloudwatch_1.Alarm(this, 'DynamoThrottleAlarm', {
|
|
100
|
+
alarmDescription: 'DynamoDB throttled requests detected',
|
|
101
|
+
metric: throttledRequests,
|
|
102
|
+
threshold: 0,
|
|
103
|
+
evaluationPeriods: 1,
|
|
104
|
+
comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
105
|
+
treatMissingData: aws_cloudwatch_1.TreatMissingData.NOT_BREACHING,
|
|
106
|
+
});
|
|
107
|
+
throttleAlarm.addAlarmAction(snsAction);
|
|
108
|
+
// Lambda duration p99 > 5s
|
|
109
|
+
const durationAlarm = new aws_cloudwatch_1.Alarm(this, 'LambdaDurationAlarm', {
|
|
110
|
+
alarmDescription: 'Lambda p99 duration exceeds 5 seconds',
|
|
111
|
+
metric: props.lambdaFunction.metricDuration({
|
|
112
|
+
period: aws_cdk_lib_1.Duration.minutes(5),
|
|
113
|
+
statistic: 'p99',
|
|
114
|
+
unit: aws_cloudwatch_1.Unit.MILLISECONDS,
|
|
115
|
+
}),
|
|
116
|
+
threshold: 5000,
|
|
117
|
+
evaluationPeriods: 1,
|
|
118
|
+
comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
119
|
+
treatMissingData: aws_cloudwatch_1.TreatMissingData.NOT_BREACHING,
|
|
120
|
+
});
|
|
121
|
+
durationAlarm.addAlarmAction(snsAction);
|
|
122
|
+
// Metric filters for sync operations and auth failures (if log group provided)
|
|
123
|
+
if (props.lambdaLogGroup) {
|
|
124
|
+
const _syncOpsFilter = new aws_logs_1.MetricFilter(this, 'SyncOpsMetricFilter', {
|
|
125
|
+
logGroup: props.lambdaLogGroup,
|
|
126
|
+
filterPattern: aws_logs_1.FilterPattern.literal('{ $.operation = "sync" }'),
|
|
127
|
+
metricNamespace: 'ChaosKB',
|
|
128
|
+
metricName: 'SyncOperations',
|
|
129
|
+
metricValue: '1',
|
|
130
|
+
});
|
|
131
|
+
const _authFailuresFilter = new aws_logs_1.MetricFilter(this, 'AuthFailuresMetricFilter', {
|
|
132
|
+
logGroup: props.lambdaLogGroup,
|
|
133
|
+
filterPattern: aws_logs_1.FilterPattern.literal('{ $.error = "auth_error" }'),
|
|
134
|
+
metricNamespace: 'ChaosKB',
|
|
135
|
+
metricName: 'AuthFailures',
|
|
136
|
+
metricValue: '1',
|
|
137
|
+
});
|
|
138
|
+
const syncOpsMetric = new aws_cloudwatch_1.Metric({
|
|
139
|
+
namespace: 'ChaosKB',
|
|
140
|
+
metricName: 'SyncOperations',
|
|
141
|
+
period: aws_cdk_lib_1.Duration.minutes(5),
|
|
142
|
+
statistic: 'Sum',
|
|
143
|
+
});
|
|
144
|
+
const authFailuresMetric = new aws_cloudwatch_1.Metric({
|
|
145
|
+
namespace: 'ChaosKB',
|
|
146
|
+
metricName: 'AuthFailures',
|
|
147
|
+
period: aws_cdk_lib_1.Duration.minutes(5),
|
|
148
|
+
statistic: 'Sum',
|
|
149
|
+
});
|
|
150
|
+
const authFailuresAlarm = new aws_cloudwatch_1.Alarm(this, 'AuthFailuresAlarm', {
|
|
151
|
+
alarmDescription: 'Auth failures exceed 10 in 5 minutes',
|
|
152
|
+
metric: authFailuresMetric,
|
|
153
|
+
threshold: 10,
|
|
154
|
+
evaluationPeriods: 1,
|
|
155
|
+
comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
156
|
+
treatMissingData: aws_cloudwatch_1.TreatMissingData.NOT_BREACHING,
|
|
157
|
+
});
|
|
158
|
+
authFailuresAlarm.addAlarmAction(snsAction);
|
|
159
|
+
this.dashboard.addWidgets(new aws_cloudwatch_1.GraphWidget({
|
|
160
|
+
title: 'Sync Operations',
|
|
161
|
+
left: [syncOpsMetric],
|
|
162
|
+
width: 12,
|
|
163
|
+
}), new aws_cloudwatch_1.GraphWidget({
|
|
164
|
+
title: 'Auth Failures',
|
|
165
|
+
left: [authFailuresMetric],
|
|
166
|
+
width: 12,
|
|
167
|
+
}));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
exports.AdminDashboard = AdminDashboard;
|
|
172
|
+
//# sourceMappingURL=admin-dashboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin-dashboard.js","sourceRoot":"","sources":["../../../lib/constructs/admin-dashboard.ts"],"names":[],"mappings":";;;AAAA,6CAAuC;AACvC,+DASoC;AACpC,+EAA+D;AAC/D,iDAA4C;AAG5C,mDAA6E;AAC7E,2CAAuC;AASvC,MAAa,cAAe,SAAQ,sBAAS;IAC3B,UAAU,CAAQ;IAClB,SAAS,CAAY;IAErC,YAAY,KAAgB,EAAE,EAAU,EAAE,KAA0B;QAClE,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAEjB,IAAI,CAAC,UAAU,GAAG,IAAI,eAAK,CAAC,IAAI,EAAE,YAAY,EAAE;YAC9C,WAAW,EAAE,WAAW,KAAK,CAAC,WAAW,SAAS;SACnD,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,IAAI,kCAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAEjD,iBAAiB;QACjB,MAAM,WAAW,GAAG,KAAK,CAAC,cAAc,CAAC,iBAAiB,CAAC,EAAE,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC5F,MAAM,MAAM,GAAG,KAAK,CAAC,cAAc,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAClF,MAAM,WAAW,GAAG,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3G,MAAM,WAAW,GAAG,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3G,MAAM,WAAW,GAAG,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QAE3G,mBAAmB;QACnB,MAAM,YAAY,GAAG,IAAI,uBAAM,CAAC;YAC9B,SAAS,EAAE,cAAc;YACzB,UAAU,EAAE,2BAA2B;YACvC,aAAa,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE;YACnD,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;YAC3B,SAAS,EAAE,KAAK;SACjB,CAAC,CAAC;QAEH,MAAM,aAAa,GAAG,IAAI,uBAAM,CAAC;YAC/B,SAAS,EAAE,cAAc;YACzB,UAAU,EAAE,4BAA4B;YACxC,aAAa,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE;YACnD,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;YAC3B,SAAS,EAAE,KAAK;SACjB,CAAC,CAAC;QAEH,MAAM,iBAAiB,GAAG,IAAI,uBAAM,CAAC;YACnC,SAAS,EAAE,cAAc;YACzB,UAAU,EAAE,mBAAmB;YAC/B,aAAa,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE;YACnD,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;YAC3B,SAAS,EAAE,KAAK;SACjB,CAAC,CAAC;QAEH,YAAY;QACZ,IAAI,CAAC,SAAS,GAAG,IAAI,0BAAS,CAAC,IAAI,EAAE,WAAW,EAAE;YAChD,wCAAwC;YACxC,OAAO,EAAE;gBACP;oBACE,IAAI,4BAAW,CAAC;wBACd,KAAK,EAAE,6BAA6B;wBACpC,IAAI,EAAE,CAAC,WAAW,CAAC;wBACnB,KAAK,EAAE,CAAC,MAAM,CAAC;wBACf,KAAK,EAAE,EAAE;qBACV,CAAC;oBACF,IAAI,4BAAW,CAAC;wBACd,KAAK,EAAE,+BAA+B;wBACtC,IAAI,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,WAAW,CAAC;wBAC7C,KAAK,EAAE,EAAE;qBACV,CAAC;iBACH;gBACD;oBACE,IAAI,4BAAW,CAAC;wBACd,KAAK,EAAE,8BAA8B;wBACrC,IAAI,EAAE,CAAC,YAAY,CAAC;wBACpB,KAAK,EAAE,CAAC,aAAa,CAAC;wBACtB,KAAK,EAAE,EAAE;qBACV,CAAC;oBACF,IAAI,4BAAW,CAAC;wBACd,KAAK,EAAE,6BAA6B;wBACpC,IAAI,EAAE,CAAC,iBAAiB,CAAC;wBACzB,KAAK,EAAE,EAAE;qBACV,CAAC;iBACH;aACF;SACF,CAAC,CAAC;QAEH,SAAS;QAET,oCAAoC;QACpC,MAAM,SAAS,GAAG,IAAI,+BAAc,CAAC;YACnC,UAAU,EAAE,oDAAoD;YAChE,YAAY,EAAE;gBACZ,MAAM;gBACN,WAAW;aACZ;YACD,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;SAC5B,CAAC,CAAC;QAEH,MAAM,cAAc,GAAG,IAAI,sBAAK,CAAC,IAAI,EAAE,sBAAsB,EAAE;YAC7D,gBAAgB,EAAE,8BAA8B;YAChD,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,CAAC;YACZ,iBAAiB,EAAE,CAAC;YACpB,kBAAkB,EAAE,mCAAkB,CAAC,sBAAsB;YAC7D,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;SACjD,CAAC,CAAC;QACH,cAAc,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAEzC,oCAAoC;QACpC,MAAM,aAAa,GAAG,IAAI,sBAAK,CAAC,IAAI,EAAE,qBAAqB,EAAE;YAC3D,gBAAgB,EAAE,sCAAsC;YACxD,MAAM,EAAE,iBAAiB;YACzB,SAAS,EAAE,CAAC;YACZ,iBAAiB,EAAE,CAAC;YACpB,kBAAkB,EAAE,mCAAkB,CAAC,sBAAsB;YAC7D,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;SACjD,CAAC,CAAC;QACH,aAAa,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAExC,2BAA2B;QAC3B,MAAM,aAAa,GAAG,IAAI,sBAAK,CAAC,IAAI,EAAE,qBAAqB,EAAE;YAC3D,gBAAgB,EAAE,uCAAuC;YACzD,MAAM,EAAE,KAAK,CAAC,cAAc,CAAC,cAAc,CAAC;gBAC1C,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;gBAC3B,SAAS,EAAE,KAAK;gBAChB,IAAI,EAAE,qBAAI,CAAC,YAAY;aACxB,CAAC;YACF,SAAS,EAAE,IAAI;YACf,iBAAiB,EAAE,CAAC;YACpB,kBAAkB,EAAE,mCAAkB,CAAC,sBAAsB;YAC7D,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;SACjD,CAAC,CAAC;QACH,aAAa,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAExC,+EAA+E;QAC/E,IAAI,KAAK,CAAC,cAAc,EAAE,CAAC;YACzB,MAAM,cAAc,GAAG,IAAI,uBAAY,CAAC,IAAI,EAAE,qBAAqB,EAAE;gBACnE,QAAQ,EAAE,KAAK,CAAC,cAAc;gBAC9B,aAAa,EAAE,wBAAa,CAAC,OAAO,CAAC,0BAA0B,CAAC;gBAChE,eAAe,EAAE,SAAS;gBAC1B,UAAU,EAAE,gBAAgB;gBAC5B,WAAW,EAAE,GAAG;aACjB,CAAC,CAAC;YAEH,MAAM,mBAAmB,GAAG,IAAI,uBAAY,CAAC,IAAI,EAAE,0BAA0B,EAAE;gBAC7E,QAAQ,EAAE,KAAK,CAAC,cAAc;gBAC9B,aAAa,EAAE,wBAAa,CAAC,OAAO,CAAC,4BAA4B,CAAC;gBAClE,eAAe,EAAE,SAAS;gBAC1B,UAAU,EAAE,cAAc;gBAC1B,WAAW,EAAE,GAAG;aACjB,CAAC,CAAC;YAEH,MAAM,aAAa,GAAG,IAAI,uBAAM,CAAC;gBAC/B,SAAS,EAAE,SAAS;gBACpB,UAAU,EAAE,gBAAgB;gBAC5B,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;gBAC3B,SAAS,EAAE,KAAK;aACjB,CAAC,CAAC;YAEH,MAAM,kBAAkB,GAAG,IAAI,uBAAM,CAAC;gBACpC,SAAS,EAAE,SAAS;gBACpB,UAAU,EAAE,cAAc;gBAC1B,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;gBAC3B,SAAS,EAAE,KAAK;aACjB,CAAC,CAAC;YAEH,MAAM,iBAAiB,GAAG,IAAI,sBAAK,CAAC,IAAI,EAAE,mBAAmB,EAAE;gBAC7D,gBAAgB,EAAE,sCAAsC;gBACxD,MAAM,EAAE,kBAAkB;gBAC1B,SAAS,EAAE,EAAE;gBACb,iBAAiB,EAAE,CAAC;gBACpB,kBAAkB,EAAE,mCAAkB,CAAC,sBAAsB;gBAC7D,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;aACjD,CAAC,CAAC;YACH,iBAAiB,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;YAE5C,IAAI,CAAC,SAAS,CAAC,UAAU,CACvB,IAAI,4BAAW,CAAC;gBACd,KAAK,EAAE,iBAAiB;gBACxB,IAAI,EAAE,CAAC,aAAa,CAAC;gBACrB,KAAK,EAAE,EAAE;aACV,CAAC,EACF,IAAI,4BAAW,CAAC;gBACd,KAAK,EAAE,eAAe;gBACtB,IAAI,EAAE,CAAC,kBAAkB,CAAC;gBAC1B,KAAK,EAAE,EAAE;aACV,CAAC,CACH,CAAC;QACJ,CAAC;IACH,CAAC;CACF;AAtLD,wCAsLC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { FunctionUrl } from 'aws-cdk-lib/aws-lambda';
|
|
2
|
+
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
|
|
3
|
+
import { TableV2 } from 'aws-cdk-lib/aws-dynamodb';
|
|
4
|
+
import { StringParameter } from 'aws-cdk-lib/aws-ssm';
|
|
5
|
+
import { Construct } from 'constructs';
|
|
6
|
+
export interface ApiProps {
|
|
7
|
+
readonly table: TableV2;
|
|
8
|
+
readonly environment: string;
|
|
9
|
+
readonly signupsEnabledParam: StringParameter;
|
|
10
|
+
readonly reservedConcurrency?: number;
|
|
11
|
+
}
|
|
12
|
+
export declare class Api extends Construct {
|
|
13
|
+
readonly functionUrl: FunctionUrl;
|
|
14
|
+
readonly handler: NodejsFunction;
|
|
15
|
+
constructor(scope: Construct, id: string, props: ApiProps);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../lib/constructs/api.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,WAAW,EAAyC,MAAM,wBAAwB,CAAC;AAC1G,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AAEnD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvC,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,mBAAmB,EAAE,eAAe,CAAC;IAC9C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;CACvC;AAED,qBAAa,GAAI,SAAQ,SAAS;IAChC,SAAgB,WAAW,EAAE,WAAW,CAAC;IACzC,SAAgB,OAAO,EAAE,cAAc,CAAC;gBAE5B,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ;CAqC1D"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.Api = void 0;
|
|
37
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
38
|
+
const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
|
|
39
|
+
const aws_lambda_nodejs_1 = require("aws-cdk-lib/aws-lambda-nodejs");
|
|
40
|
+
const aws_sqs_1 = require("aws-cdk-lib/aws-sqs");
|
|
41
|
+
const constructs_1 = require("constructs");
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
class Api extends constructs_1.Construct {
|
|
44
|
+
functionUrl;
|
|
45
|
+
handler;
|
|
46
|
+
constructor(scope, id, props) {
|
|
47
|
+
super(scope, id);
|
|
48
|
+
const deadLetterQueue = new aws_sqs_1.Queue(this, 'DeadLetterQueue', {
|
|
49
|
+
retentionPeriod: aws_cdk_lib_1.Duration.days(14),
|
|
50
|
+
});
|
|
51
|
+
this.handler = new aws_lambda_nodejs_1.NodejsFunction(this, 'Handler', {
|
|
52
|
+
runtime: aws_lambda_1.Runtime.NODEJS_22_X,
|
|
53
|
+
architecture: aws_lambda_1.Architecture.ARM_64,
|
|
54
|
+
entry: path.join(__dirname, '..', 'handler', 'index.ts'),
|
|
55
|
+
handler: 'handler',
|
|
56
|
+
memorySize: 256,
|
|
57
|
+
timeout: aws_cdk_lib_1.Duration.seconds(30),
|
|
58
|
+
environment: {
|
|
59
|
+
TABLE_NAME: props.table.tableName,
|
|
60
|
+
ENVIRONMENT: props.environment,
|
|
61
|
+
SIGNUPS_ENABLED_PARAM: props.signupsEnabledParam.parameterName,
|
|
62
|
+
},
|
|
63
|
+
reservedConcurrentExecutions: props.reservedConcurrency ?? 10,
|
|
64
|
+
deadLetterQueue,
|
|
65
|
+
tracing: aws_lambda_1.Tracing.ACTIVE,
|
|
66
|
+
bundling: {
|
|
67
|
+
minify: true,
|
|
68
|
+
sourceMap: true,
|
|
69
|
+
target: 'node22',
|
|
70
|
+
format: undefined, // default cjs for Lambda
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
this.functionUrl = this.handler.addFunctionUrl({
|
|
74
|
+
authType: aws_lambda_1.FunctionUrlAuthType.NONE,
|
|
75
|
+
});
|
|
76
|
+
props.table.grantReadWriteData(this.handler);
|
|
77
|
+
props.signupsEnabledParam.grantRead(this.handler);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
exports.Api = Api;
|
|
81
|
+
//# sourceMappingURL=api.js.map
|