@empire-builder-kit/nx 1.0.0-beta.10 → 1.0.0-beta.11
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/package.json +1 -2
- package/src/foundation/discovery.d.ts +11 -1
- package/src/foundation/discovery.js +13 -1
- package/src/foundation/discovery.js.map +1 -1
- package/src/foundation/local-database-contract.d.ts +1 -0
- package/src/foundation/local-database-contract.js +3 -0
- package/src/foundation/local-database-contract.js.map +1 -1
- package/src/foundation/preflight.js +10 -0
- package/src/foundation/preflight.js.map +1 -1
- package/src/foundation/provision-database-bindings.d.ts +9 -1
- package/src/foundation/provision-database-bindings.js +25 -5
- package/src/foundation/provision-database-bindings.js.map +1 -1
- package/src/foundation/provision-logical-database.d.ts +10 -2
- package/src/foundation/provision-logical-database.js +67 -114
- package/src/foundation/provision-logical-database.js.map +1 -1
- package/src/generators/preset/workspace-files.js +30 -1
- package/src/generators/preset/workspace-files.js.map +1 -1
- package/src/generators/slice/migration-package-lock.json +445 -0
- package/src/generators/slice/slice.d.ts +1 -1
- package/src/generators/slice/slice.js +1818 -108
- package/src/generators/slice/slice.js.map +1 -1
- package/src/foundation/aurora-logical-database.d.ts +0 -76
- package/src/foundation/aurora-logical-database.js +0 -419
- package/src/foundation/aurora-logical-database.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@empire-builder-kit/nx",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.11",
|
|
4
4
|
"description": "Nx generators, executors, and Blueprint contracts for Empire Builder Kit",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "commonjs",
|
|
@@ -57,7 +57,6 @@
|
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"@nx/devkit": "23.1.0",
|
|
59
59
|
"@aws-sdk/client-rds": "^3.700.0",
|
|
60
|
-
"@aws-sdk/client-rds-data": "^3.700.0",
|
|
61
60
|
"@aws-sdk/client-ssm": "^3.700.0",
|
|
62
61
|
"@aws-sdk/credential-providers": "^3.700.0",
|
|
63
62
|
"ajv": "8.17.1",
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { type FoundationRequirement, type StandardFoundationCapability } from './requirements.js';
|
|
2
2
|
export declare const FOUNDATION_SSM_NAMESPACE: "/ebk";
|
|
3
|
-
export declare const FOUNDATION_SSM_SCHEMA_VERSION:
|
|
3
|
+
export declare const FOUNDATION_SSM_SCHEMA_VERSION: 4;
|
|
4
4
|
export declare const FOUNDATION_SSM_KEYS: {
|
|
5
5
|
readonly alertTopicArn: "alertTopicArn";
|
|
6
6
|
readonly capabilities: "capabilities";
|
|
7
7
|
readonly clusterId: "clusterId";
|
|
8
8
|
readonly contractVersion: "contractVersion";
|
|
9
9
|
readonly databaseClusterArn: "databaseClusterArn";
|
|
10
|
+
readonly databaseClusterEndpoint: "databaseClusterEndpoint";
|
|
10
11
|
readonly databaseClusterId: "databaseClusterId";
|
|
12
|
+
readonly databaseClusterResourceId: "databaseClusterResourceId";
|
|
13
|
+
readonly databaseHost: "databaseHost";
|
|
11
14
|
readonly databaseMasterSecretArn: "databaseMasterSecretArn";
|
|
15
|
+
readonly databasePort: "databasePort";
|
|
12
16
|
readonly eventBusArn: "eventBusArn";
|
|
13
17
|
readonly eventBusName: "eventBusName";
|
|
14
18
|
readonly hasPublicDomain: "hasPublicDomain";
|
|
@@ -29,8 +33,12 @@ export interface FoundationDiscovery {
|
|
|
29
33
|
clusterId: string;
|
|
30
34
|
contractVersion: string;
|
|
31
35
|
databaseClusterArn: string;
|
|
36
|
+
databaseClusterEndpoint: string;
|
|
32
37
|
databaseClusterId: string;
|
|
38
|
+
databaseClusterResourceId: string;
|
|
39
|
+
databaseHost: string;
|
|
33
40
|
databaseMasterSecretArn: string;
|
|
41
|
+
databasePort: number;
|
|
34
42
|
eventBusArn: string;
|
|
35
43
|
eventBusName: string;
|
|
36
44
|
hasPublicDomain: boolean;
|
|
@@ -53,3 +61,5 @@ export declare function foundationSsmStageRoot(stage: string): string;
|
|
|
53
61
|
export declare function foundationSsmPath(stage: string, key: FoundationSsmKey): string;
|
|
54
62
|
export declare function productSliceRegistrationRoot(foundationStage: string): string;
|
|
55
63
|
export declare function productSliceRegistrationPath(foundationStage: string, consumerStage: string, slice: string): string;
|
|
64
|
+
export declare function productSliceMigrationPath(foundationStage: string, consumerStage: string, slice: string, database: string): string;
|
|
65
|
+
export declare function productSliceRetirementPath(foundationStage: string, consumerStage: string, slice: string, database: string): string;
|
|
@@ -5,18 +5,24 @@ exports.foundationSsmStageRoot = foundationSsmStageRoot;
|
|
|
5
5
|
exports.foundationSsmPath = foundationSsmPath;
|
|
6
6
|
exports.productSliceRegistrationRoot = productSliceRegistrationRoot;
|
|
7
7
|
exports.productSliceRegistrationPath = productSliceRegistrationPath;
|
|
8
|
+
exports.productSliceMigrationPath = productSliceMigrationPath;
|
|
9
|
+
exports.productSliceRetirementPath = productSliceRetirementPath;
|
|
8
10
|
const requirements_js_1 = require("./requirements.js");
|
|
9
11
|
const stages_js_1 = require("./stages.js");
|
|
10
12
|
exports.FOUNDATION_SSM_NAMESPACE = '/ebk';
|
|
11
|
-
exports.FOUNDATION_SSM_SCHEMA_VERSION =
|
|
13
|
+
exports.FOUNDATION_SSM_SCHEMA_VERSION = 4;
|
|
12
14
|
exports.FOUNDATION_SSM_KEYS = {
|
|
13
15
|
alertTopicArn: 'alertTopicArn',
|
|
14
16
|
capabilities: 'capabilities',
|
|
15
17
|
clusterId: 'clusterId',
|
|
16
18
|
contractVersion: 'contractVersion',
|
|
17
19
|
databaseClusterArn: 'databaseClusterArn',
|
|
20
|
+
databaseClusterEndpoint: 'databaseClusterEndpoint',
|
|
18
21
|
databaseClusterId: 'databaseClusterId',
|
|
22
|
+
databaseClusterResourceId: 'databaseClusterResourceId',
|
|
23
|
+
databaseHost: 'databaseHost',
|
|
19
24
|
databaseMasterSecretArn: 'databaseMasterSecretArn',
|
|
25
|
+
databasePort: 'databasePort',
|
|
20
26
|
eventBusArn: 'eventBusArn',
|
|
21
27
|
eventBusName: 'eventBusName',
|
|
22
28
|
hasPublicDomain: 'hasPublicDomain',
|
|
@@ -52,4 +58,10 @@ function productSliceRegistrationRoot(foundationStage) {
|
|
|
52
58
|
function productSliceRegistrationPath(foundationStage, consumerStage, slice) {
|
|
53
59
|
return `${productSliceRegistrationRoot(foundationStage)}/${(0, stages_js_1.requireStage)(consumerStage, 'Consumer stage')}/${requirePathSegment(slice, 'Product Slice name')}`;
|
|
54
60
|
}
|
|
61
|
+
function productSliceMigrationPath(foundationStage, consumerStage, slice, database) {
|
|
62
|
+
return `${productSliceRegistrationPath(foundationStage, consumerStage, slice)}/databases/${requirePathSegment(database, 'Logical database name')}/migrationStateMachineArn`;
|
|
63
|
+
}
|
|
64
|
+
function productSliceRetirementPath(foundationStage, consumerStage, slice, database) {
|
|
65
|
+
return `${productSliceRegistrationPath(foundationStage, consumerStage, slice)}/databases/${requirePathSegment(database, 'Logical database name')}/retirementStateMachineArn`;
|
|
66
|
+
}
|
|
55
67
|
//# sourceMappingURL=discovery.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../../../../packages/nx/src/foundation/discovery.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../../../../packages/nx/src/foundation/discovery.ts"],"names":[],"mappings":";;;AAuFA,wDAEC;AAED,8CAKC;AAED,oEAEC;AAED,oEAMC;AAED,8DAcC;AAED,gEAcC;AA5ID,uDAI2B;AAC3B,2CAAmE;AAEtD,QAAA,wBAAwB,GAAG,MAAe,CAAC;AAC3C,QAAA,6BAA6B,GAAG,CAAU,CAAC;AAE3C,QAAA,mBAAmB,GAAG;IACjC,aAAa,EAAE,eAAe;IAC9B,YAAY,EAAE,cAAc;IAC5B,SAAS,EAAE,WAAW;IACtB,eAAe,EAAE,iBAAiB;IAClC,kBAAkB,EAAE,oBAAoB;IACxC,uBAAuB,EAAE,yBAAyB;IAClD,iBAAiB,EAAE,mBAAmB;IACtC,yBAAyB,EAAE,2BAA2B;IACtD,YAAY,EAAE,cAAc;IAC5B,uBAAuB,EAAE,yBAAyB;IAClD,YAAY,EAAE,cAAc;IAC5B,WAAW,EAAE,aAAa;IAC1B,YAAY,EAAE,cAAc;IAC5B,eAAe,EAAE,iBAAiB;IAClC,mBAAmB,EAAE,qBAAqB;IAC1C,kBAAkB,EAAE,oBAAoB;IACxC,UAAU,EAAE,YAAY;IACxB,oBAAoB,EAAE,sBAAsB;IAC5C,SAAS,EAAE,WAAW;IACtB,aAAa,EAAE,eAAe;IAC9B,KAAK,EAAE,OAAO;CACN,CAAC;AAIE,QAAA,4BAA4B,GAAG,MAAM,CAAC,IAAI,CACrD,2BAAmB,CACE,CAAC;AAEX,QAAA,+BAA+B,GAA0B;IACpE,YAAY,EAAE,CAAC,GAAG,kDAAgC,CAAC;IACnD,QAAQ,EAAE,QAAQ;CACnB,CAAC;AAkCF,SAAS,kBAAkB,CAAC,KAAa,EAAE,KAAa;IACtD,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAChC,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CACb,GAAG,KAAK,oDAAoD,CAC7D,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,SAAgB,sBAAsB,CAAC,KAAa;IAClD,OAAO,GAAG,gCAAwB,IAAI,IAAA,kCAAsB,EAAC,KAAK,CAAC,aAAa,CAAC;AACnF,CAAC;AAED,SAAgB,iBAAiB,CAC/B,KAAa,EACb,GAAqB;IAErB,OAAO,GAAG,sBAAsB,CAAC,KAAK,CAAC,IAAI,2BAAmB,CAAC,GAAG,CAAC,EAAE,CAAC;AACxE,CAAC;AAED,SAAgB,4BAA4B,CAAC,eAAuB;IAClE,OAAO,GAAG,sBAAsB,CAAC,eAAe,CAAC,iBAAiB,CAAC;AACrE,CAAC;AAED,SAAgB,4BAA4B,CAC1C,eAAuB,EACvB,aAAqB,EACrB,KAAa;IAEb,OAAO,GAAG,4BAA4B,CAAC,eAAe,CAAC,IAAI,IAAA,wBAAY,EAAC,aAAa,EAAE,gBAAgB,CAAC,IAAI,kBAAkB,CAAC,KAAK,EAAE,oBAAoB,CAAC,EAAE,CAAC;AAChK,CAAC;AAED,SAAgB,yBAAyB,CACvC,eAAuB,EACvB,aAAqB,EACrB,KAAa,EACb,QAAgB;IAEhB,OAAO,GAAG,4BAA4B,CACpC,eAAe,EACf,aAAa,EACb,KAAK,CACN,cAAc,kBAAkB,CAC/B,QAAQ,EACR,uBAAuB,CACxB,2BAA2B,CAAC;AAC/B,CAAC;AAED,SAAgB,0BAA0B,CACxC,eAAuB,EACvB,aAAqB,EACrB,KAAa,EACb,QAAgB;IAEhB,OAAO,GAAG,4BAA4B,CACpC,eAAe,EACf,aAAa,EACb,KAAK,CACN,cAAc,kBAAkB,CAC/B,QAAQ,EACR,uBAAuB,CACxB,4BAA4B,CAAC;AAChC,CAAC"}
|
|
@@ -32,12 +32,14 @@ function resolveLogicalDatabaseIdentifiers(options) {
|
|
|
32
32
|
const database = normalizePostgresIdentifier(`${options.stage}_${options.slice}_${options.database}`);
|
|
33
33
|
const readwriteRole = `${database}_readwrite`;
|
|
34
34
|
const readonlyRole = `${database}_readonly`;
|
|
35
|
+
const migratorRole = `${database}_migrator`;
|
|
35
36
|
const localDatabase = normalizePostgresIdentifier(`${options.slice}_${options.database}`);
|
|
36
37
|
const localReadwriteRole = `${localDatabase}_readwrite`;
|
|
37
38
|
for (const [identifier, label] of [
|
|
38
39
|
[database, 'Physical database identifier'],
|
|
39
40
|
[readwriteRole, 'Physical read-write role identifier'],
|
|
40
41
|
[readonlyRole, 'Physical read-only role identifier'],
|
|
42
|
+
[migratorRole, 'Physical migrator role identifier'],
|
|
41
43
|
[localDatabase, 'Local database identifier'],
|
|
42
44
|
[localReadwriteRole, 'Local read-write role identifier'],
|
|
43
45
|
]) {
|
|
@@ -47,6 +49,7 @@ function resolveLogicalDatabaseIdentifiers(options) {
|
|
|
47
49
|
database,
|
|
48
50
|
localDatabase,
|
|
49
51
|
localReadwriteRole,
|
|
52
|
+
migratorRole,
|
|
50
53
|
readonlyRole,
|
|
51
54
|
readwriteRole,
|
|
52
55
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"local-database-contract.js","sourceRoot":"","sources":["../../../../../packages/nx/src/foundation/local-database-contract.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"local-database-contract.js","sourceRoot":"","sources":["../../../../../packages/nx/src/foundation/local-database-contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -54,6 +54,12 @@ async function evaluateFoundationPreflight(options) {
|
|
|
54
54
|
if (schemaVersion !== discovery_js_1.FOUNDATION_SSM_SCHEMA_VERSION) {
|
|
55
55
|
issues.push(`Foundation discovery schema ${value('schemaVersion') || 'missing'} does not match ${discovery_js_1.FOUNDATION_SSM_SCHEMA_VERSION}`);
|
|
56
56
|
}
|
|
57
|
+
const databasePort = Number(value('databasePort'));
|
|
58
|
+
if (!Number.isSafeInteger(databasePort) ||
|
|
59
|
+
databasePort < 1 ||
|
|
60
|
+
databasePort > 65535) {
|
|
61
|
+
issues.push('Foundation discovery databasePort must be from 1 through 65535');
|
|
62
|
+
}
|
|
57
63
|
const capabilities = value('capabilities')
|
|
58
64
|
.split(',')
|
|
59
65
|
.map((capability) => capability.trim())
|
|
@@ -80,8 +86,12 @@ async function evaluateFoundationPreflight(options) {
|
|
|
80
86
|
clusterId: value('clusterId'),
|
|
81
87
|
contractVersion: compatibility.value.contractVersion,
|
|
82
88
|
databaseClusterArn: value('databaseClusterArn'),
|
|
89
|
+
databaseClusterEndpoint: value('databaseClusterEndpoint'),
|
|
83
90
|
databaseClusterId: value('databaseClusterId'),
|
|
91
|
+
databaseClusterResourceId: value('databaseClusterResourceId'),
|
|
92
|
+
databaseHost: value('databaseHost'),
|
|
84
93
|
databaseMasterSecretArn: value('databaseMasterSecretArn'),
|
|
94
|
+
databasePort,
|
|
85
95
|
eventBusArn: value('eventBusArn'),
|
|
86
96
|
eventBusName: value('eventBusName'),
|
|
87
97
|
hasPublicDomain: value('hasPublicDomain') === 'true',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preflight.js","sourceRoot":"","sources":["../../../../../packages/nx/src/foundation/preflight.ts"],"names":[],"mappings":";;AA0CA,0EA6BC;AAED,
|
|
1
|
+
{"version":3,"file":"preflight.js","sourceRoot":"","sources":["../../../../../packages/nx/src/foundation/preflight.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,10 @@ export interface DatabaseBindingPlan {
|
|
|
10
10
|
identifiers: Readonly<Record<string, LogicalDatabaseIdentifiers>>;
|
|
11
11
|
provisioned: readonly string[];
|
|
12
12
|
}
|
|
13
|
+
export declare function selectDatabaseTarget(plan: DatabaseBindingPlan, options?: {
|
|
14
|
+
binding?: string;
|
|
15
|
+
database?: string;
|
|
16
|
+
}): string;
|
|
13
17
|
export interface ProvisionDatabaseBindingsOptions {
|
|
14
18
|
bindings: DatabaseBindingDeclaration;
|
|
15
19
|
localDev?: boolean;
|
|
@@ -19,7 +23,11 @@ export interface ProvisionDatabaseBindingsOptions {
|
|
|
19
23
|
slice: string;
|
|
20
24
|
}
|
|
21
25
|
export type ProvisionedDatabaseBindings<TBindings extends DatabaseBindingDeclaration> = {
|
|
22
|
-
|
|
26
|
+
bindings: {
|
|
27
|
+
[TBinding in keyof TBindings]: ProvisionLogicalDatabaseResult;
|
|
28
|
+
};
|
|
29
|
+
databases: Readonly<Record<string, ProvisionLogicalDatabaseResult>>;
|
|
30
|
+
plan: DatabaseBindingPlan;
|
|
23
31
|
};
|
|
24
32
|
export declare function createDatabaseBindingPlan(bindings: DatabaseBindingDeclaration, context: {
|
|
25
33
|
slice: string;
|
|
@@ -1,9 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.selectDatabaseTarget = selectDatabaseTarget;
|
|
3
4
|
exports.createDatabaseBindingPlan = createDatabaseBindingPlan;
|
|
4
5
|
exports.provisionDatabaseBindings = provisionDatabaseBindings;
|
|
5
6
|
const local_database_contract_js_1 = require("./local-database-contract.js");
|
|
6
7
|
const provision_logical_database_js_1 = require("./provision-logical-database.js");
|
|
8
|
+
function selectDatabaseTarget(plan, options = {}) {
|
|
9
|
+
const binding = options.binding ?? 'primary';
|
|
10
|
+
const requested = options.database?.trim();
|
|
11
|
+
if (options.database !== undefined && !requested) {
|
|
12
|
+
throw new Error('Database target must not be empty.');
|
|
13
|
+
}
|
|
14
|
+
const selected = requested ?? plan.active[binding];
|
|
15
|
+
if (!selected) {
|
|
16
|
+
throw new Error(`Database binding "${binding}" is required.`);
|
|
17
|
+
}
|
|
18
|
+
if (!plan.provisioned.includes(selected)) {
|
|
19
|
+
throw new Error(`Database target "${selected}" is not declared in database/bindings.json.`);
|
|
20
|
+
}
|
|
21
|
+
return selected;
|
|
22
|
+
}
|
|
7
23
|
const databaseIdentifierPattern = /^[a-z][a-z0-9]*(?:[-_][a-z0-9]+)*$/;
|
|
8
24
|
function collisionKey(value) {
|
|
9
25
|
return (0, local_database_contract_js_1.normalizePostgresIdentifier)(value).normalize('NFKC').toLowerCase();
|
|
@@ -87,7 +103,7 @@ function createDatabaseBindingPlan(bindings, context) {
|
|
|
87
103
|
function provisionDatabaseBindings(foundation, options) {
|
|
88
104
|
// Validate the complete set before the first provisioner call. This is what
|
|
89
105
|
// makes a collision or overlong identifier fail before any local Linkable,
|
|
90
|
-
//
|
|
106
|
+
// Secrets Manager container, or other infrastructure mutation exists.
|
|
91
107
|
const plan = createDatabaseBindingPlan(options.bindings, {
|
|
92
108
|
slice: options.slice,
|
|
93
109
|
stage: $app.stage,
|
|
@@ -105,9 +121,13 @@ function provisionDatabaseBindings(foundation, options) {
|
|
|
105
121
|
slice: options.slice,
|
|
106
122
|
}));
|
|
107
123
|
}
|
|
108
|
-
return
|
|
109
|
-
role,
|
|
110
|
-
|
|
111
|
-
|
|
124
|
+
return {
|
|
125
|
+
bindings: Object.fromEntries(Object.entries(plan.active).map(([role, database]) => [
|
|
126
|
+
role,
|
|
127
|
+
provisioned.get(database),
|
|
128
|
+
])),
|
|
129
|
+
databases: Object.fromEntries(provisioned),
|
|
130
|
+
plan,
|
|
131
|
+
};
|
|
112
132
|
}
|
|
113
133
|
//# sourceMappingURL=provision-database-bindings.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provision-database-bindings.js","sourceRoot":"","sources":["../../../../../packages/nx/src/foundation/provision-database-bindings.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"provision-database-bindings.js","sourceRoot":"","sources":["../../../../../packages/nx/src/foundation/provision-database-bindings.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
export interface FoundationDatabaseCapacity {
|
|
2
|
-
cluster: any;
|
|
3
2
|
clusterArn: string;
|
|
3
|
+
clusterEndpoint: unknown;
|
|
4
|
+
clusterResourceId: string;
|
|
5
|
+
host: unknown;
|
|
4
6
|
masterSecretArn: string;
|
|
7
|
+
port: unknown;
|
|
5
8
|
}
|
|
6
9
|
export interface FoundationInfrastructure {
|
|
7
10
|
database: FoundationDatabaseCapacity;
|
|
@@ -18,9 +21,14 @@ export interface ProvisionLogicalDatabaseOptions {
|
|
|
18
21
|
}
|
|
19
22
|
export interface ProvisionLogicalDatabaseResult {
|
|
20
23
|
db: any;
|
|
21
|
-
|
|
24
|
+
databaseName: string;
|
|
25
|
+
resourceName: string;
|
|
26
|
+
migratorRole: string;
|
|
27
|
+
readwriteRole: string;
|
|
28
|
+
readonlyRole: string;
|
|
22
29
|
readwriteSecretArn?: any;
|
|
23
30
|
readonlySecretArn?: any;
|
|
31
|
+
rotationToken?: string;
|
|
24
32
|
}
|
|
25
33
|
export declare function defaultDatabaseLinkableName(slice: string, database: string): string;
|
|
26
34
|
export declare function provisionLogicalDatabase(foundation: FoundationInfrastructure, options: ProvisionLogicalDatabaseOptions): ProvisionLogicalDatabaseResult;
|
|
@@ -2,56 +2,38 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.defaultDatabaseLinkableName = defaultDatabaseLinkableName;
|
|
4
4
|
exports.provisionLogicalDatabase = provisionLogicalDatabase;
|
|
5
|
-
const aurora_logical_database_js_1 = require("./aurora-logical-database.js");
|
|
6
5
|
const local_database_contract_js_1 = require("./local-database-contract.js");
|
|
6
|
+
const stages_js_1 = require("./stages.js");
|
|
7
7
|
function classNameForDatabaseComponent(value) {
|
|
8
|
-
// 'example-primary' -> 'ExamplePrimary'. Simple normalizer; the db
|
|
9
|
-
// generator always passes already-kebab-cased segments.
|
|
10
8
|
return value
|
|
11
9
|
.split(/[-_]/)
|
|
12
10
|
.filter(Boolean)
|
|
13
|
-
.map((
|
|
11
|
+
.map((part) => part.charAt(0).toUpperCase() + part.slice(1))
|
|
14
12
|
.join('');
|
|
15
13
|
}
|
|
16
14
|
function defaultDatabaseLinkableName(slice, database) {
|
|
17
15
|
return `${classNameForDatabaseComponent(slice)}${classNameForDatabaseComponent(database)}Database`;
|
|
18
16
|
}
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
// * `<app>_<database>` logical Postgres database on the shared cluster
|
|
22
|
-
// * `<app>_readwrite` role (full DML + DDL) + `<app>_readonly` role (SELECT only)
|
|
23
|
-
// * AWS Secrets Manager secrets for each role at
|
|
24
|
-
// `ebk/<stage>/<slice>/database/<database>/<access-mode>` with JSON
|
|
25
|
-
// `{ host, port, database, username, password }`
|
|
26
|
-
// * An `sst.Linkable` exposing the readwrite credentials — consumers link
|
|
27
|
-
// this into their Nextjs / Service / Function stacks so runtime code sees
|
|
28
|
-
// `Resource.<Linkable>.host/port/database/username/password` unchanged
|
|
17
|
+
// Declares a Slice-scoped logical database contract without executing SQL or
|
|
18
|
+
// materializing a database password during infrastructure deployment.
|
|
29
19
|
//
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
//
|
|
33
|
-
//
|
|
34
|
-
// runbook in this package's README).
|
|
35
|
-
//
|
|
36
|
-
// DO NOT pass `core.db.cluster` (the raw Aurora handle) into
|
|
37
|
-
// `new sst.aws.Nextjs({ link })` — that leaks the master password. This
|
|
38
|
-
// helper is the sanctioned consumer path.
|
|
20
|
+
// In deployed stages this creates two empty Secrets Manager containers and a
|
|
21
|
+
// Linkable carrying only connection metadata plus the read/write secret ARN.
|
|
22
|
+
// The generated AWS-internal bootstrap task converges the actual database,
|
|
23
|
+
// roles, and secret versions before the migration task runs.
|
|
39
24
|
function provisionLogicalDatabase(foundation, options) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
25
|
+
const consumerStage = (0, stages_js_1.requireStage)($app.stage, 'Consumer stage');
|
|
26
|
+
if (options.rotationToken !== undefined &&
|
|
27
|
+
options.rotationToken.trim() === '') {
|
|
28
|
+
throw new Error('Logical database rotationToken must be a non-empty string when supplied.');
|
|
29
|
+
}
|
|
44
30
|
const identifiers = (0, local_database_contract_js_1.resolveLogicalDatabaseIdentifiers)({
|
|
45
31
|
database: options.database,
|
|
46
32
|
slice: options.slice,
|
|
47
|
-
stage:
|
|
33
|
+
stage: consumerStage,
|
|
48
34
|
});
|
|
49
|
-
const
|
|
35
|
+
const resourceName = options.linkableName ??
|
|
50
36
|
defaultDatabaseLinkableName(options.slice, options.database);
|
|
51
|
-
// Local live mode needs only the workload-facing Linkable. Return before
|
|
52
|
-
// constructing the Pulumi dynamic resource or either Secrets Manager secret
|
|
53
|
-
// so `sst dev` does not provision unused AWS database resources merely to
|
|
54
|
-
// point the application at Docker Postgres.
|
|
55
37
|
if ($dev && (options.localDev ?? true)) {
|
|
56
38
|
const localDatabase = (0, local_database_contract_js_1.resolveLocalDatabaseContract)({
|
|
57
39
|
database: options.database,
|
|
@@ -60,104 +42,75 @@ function provisionLogicalDatabase(foundation, options) {
|
|
|
60
42
|
slice: options.slice,
|
|
61
43
|
});
|
|
62
44
|
return {
|
|
63
|
-
db: new sst.Linkable(
|
|
64
|
-
properties:
|
|
45
|
+
db: new sst.Linkable(resourceName, {
|
|
46
|
+
properties: {
|
|
47
|
+
provider: 'local',
|
|
48
|
+
...localDatabase,
|
|
49
|
+
},
|
|
65
50
|
}),
|
|
51
|
+
databaseName: localDatabase.database,
|
|
52
|
+
migratorRole: identifiers.migratorRole,
|
|
53
|
+
readonlyRole: identifiers.readonlyRole,
|
|
54
|
+
readwriteRole: identifiers.readwriteRole,
|
|
55
|
+
resourceName,
|
|
66
56
|
};
|
|
67
57
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
//
|
|
81
|
-
//
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
// Callers can override explicitly via `options.removalPolicy`.
|
|
85
|
-
const canonicalStages = new Set(['development', 'staging', 'production']);
|
|
86
|
-
const defaultRemovalPolicy = canonicalStages.has($app.stage)
|
|
87
|
-
? 'retain'
|
|
88
|
-
: 'destroy';
|
|
89
|
-
const logicalDb = (0, aurora_logical_database_js_1.createAuroraLogicalDbResource)({
|
|
90
|
-
name: linkableName,
|
|
91
|
-
args: {
|
|
92
|
-
clusterArn: foundation.database.clusterArn,
|
|
93
|
-
masterSecretArn: foundation.database.masterSecretArn,
|
|
94
|
-
database: databaseIdentifier,
|
|
95
|
-
readwriteRole,
|
|
96
|
-
readonlyRole,
|
|
97
|
-
removalPolicy: options.removalPolicy ?? defaultRemovalPolicy,
|
|
98
|
-
// Only include the rotation trigger when the caller set one — keeping
|
|
99
|
-
// the key out of the inputs entirely when unset avoids a spurious
|
|
100
|
-
// `undefined` diff against resources created before this option existed.
|
|
101
|
-
...(options.rotationToken !== undefined
|
|
102
|
-
? { rotationToken: options.rotationToken }
|
|
103
|
-
: {}),
|
|
104
|
-
},
|
|
105
|
-
});
|
|
106
|
-
// `core.db.cluster.host` auto-resolves to the proxy endpoint when proxy is
|
|
107
|
-
// enabled (production) or the cluster writer endpoint otherwise.
|
|
108
|
-
// `core.db.cluster.port` similarly resolves to either the proxy port or the
|
|
109
|
-
// cluster port.
|
|
110
|
-
const host = foundation.database.cluster.host;
|
|
111
|
-
const port = foundation.database.cluster.port;
|
|
112
|
-
// Outputs from the dynamic resource — Pulumi unwraps them on link.
|
|
113
|
-
const readwritePassword = logicalDb.readwritePassword;
|
|
114
|
-
const readonlyPassword = logicalDb.readonlyPassword;
|
|
115
|
-
const secretJsonFor = (role, password) => $interpolate `{"host":"${host}","port":${port},"database":"${databaseIdentifier}","username":"${role}","password":"${password}"}`;
|
|
116
|
-
// Secret paths are keyed by the CONSUMER's stage, not core's. Two stages
|
|
117
|
-
// pointing at the same core via `EBK_CORE_STAGE` (e.g. `pr-123` → `development`)
|
|
118
|
-
// would otherwise collide on `ebk/development/<app>/db/<db>/...`. Keying by
|
|
119
|
-
// `$app.stage` isolates each consumer's secret namespace while the actual
|
|
120
|
-
// cluster remains shared.
|
|
121
|
-
const secretBasePath = `ebk/${$app.stage}/${options.slice}/database/${options.database}`;
|
|
122
|
-
// `recoveryWindowInDays: 0` skips the default 7-day soft-delete window.
|
|
123
|
-
// Destroy frees the secret name immediately so a subsequent create (or a
|
|
124
|
-
// redeploy after `sst remove`) doesn't hit `InvalidRequestException:
|
|
125
|
-
// ...already scheduled for deletion`. App-scoped DB role credentials are
|
|
126
|
-
// regenerated on every create() anyway — a recovery window serves no
|
|
127
|
-
// purpose here.
|
|
128
|
-
const readwriteSecret = new aws.secretsmanager.Secret(`${linkableName}ReadwriteSecret`, {
|
|
58
|
+
if (options.removalPolicy === 'destroy') {
|
|
59
|
+
throw new Error('Logical database removalPolicy "destroy" requires a reviewed AWS-internal retirement workflow and is not supported by the v1 protected bootstrap.');
|
|
60
|
+
}
|
|
61
|
+
const host = foundation.database.host;
|
|
62
|
+
const port = foundation.database.port;
|
|
63
|
+
const secretBasePath = `ebk/${consumerStage}/${options.slice}/database/${options.database}`;
|
|
64
|
+
const tags = {
|
|
65
|
+
'ebk:database': options.database,
|
|
66
|
+
'ebk:management': 'generated-database-credential',
|
|
67
|
+
'ebk:slice': options.slice,
|
|
68
|
+
'sst:stage': consumerStage,
|
|
69
|
+
};
|
|
70
|
+
// Secret containers deliberately have no SecretVersion resources. Their
|
|
71
|
+
// values are generated inside AWS and written by the exact bootstrap task.
|
|
72
|
+
const readwriteSecret = new aws.secretsmanager.Secret(`${resourceName}ReadwriteSecret`, {
|
|
73
|
+
description: `EBK generated read/write credential for ${options.slice}/${options.database}`,
|
|
129
74
|
name: `${secretBasePath}/readwrite`,
|
|
130
75
|
recoveryWindowInDays: 0,
|
|
131
|
-
|
|
132
|
-
const readwriteSecretVersion = new aws.secretsmanager.SecretVersion(`${linkableName}ReadwriteSecretVersion`, {
|
|
133
|
-
secretId: readwriteSecret.id,
|
|
134
|
-
secretString: secretJsonFor(readwriteRole, readwritePassword),
|
|
76
|
+
tags,
|
|
135
77
|
});
|
|
136
|
-
const readonlySecret = new aws.secretsmanager.Secret(`${
|
|
78
|
+
const readonlySecret = new aws.secretsmanager.Secret(`${resourceName}ReadonlySecret`, {
|
|
79
|
+
description: `EBK generated read-only credential for ${options.slice}/${options.database}`,
|
|
137
80
|
name: `${secretBasePath}/readonly`,
|
|
138
81
|
recoveryWindowInDays: 0,
|
|
139
|
-
|
|
140
|
-
const readonlySecretVersion = new aws.secretsmanager.SecretVersion(`${linkableName}ReadonlySecretVersion`, {
|
|
141
|
-
secretId: readonlySecret.id,
|
|
142
|
-
secretString: secretJsonFor(readonlyRole, readonlyPassword),
|
|
82
|
+
tags,
|
|
143
83
|
});
|
|
144
|
-
const linkable = new sst.Linkable(
|
|
84
|
+
const linkable = new sst.Linkable(resourceName, {
|
|
145
85
|
properties: {
|
|
86
|
+
database: identifiers.database,
|
|
146
87
|
host,
|
|
147
88
|
port,
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
89
|
+
provider: 'aws-secrets-manager',
|
|
90
|
+
secretArn: readwriteSecret.arn,
|
|
91
|
+
username: identifiers.readwriteRole,
|
|
151
92
|
},
|
|
93
|
+
include: [
|
|
94
|
+
sst.aws.permission({
|
|
95
|
+
actions: ['secretsmanager:GetSecretValue'],
|
|
96
|
+
resources: [readwriteSecret.arn],
|
|
97
|
+
}),
|
|
98
|
+
],
|
|
152
99
|
});
|
|
153
|
-
// Touch the version refs so Pulumi tracks them + keep them alive in GC.
|
|
154
|
-
void readwriteSecretVersion;
|
|
155
|
-
void readonlySecretVersion;
|
|
156
100
|
return {
|
|
101
|
+
databaseName: identifiers.database,
|
|
157
102
|
db: linkable,
|
|
158
|
-
|
|
159
|
-
|
|
103
|
+
migratorRole: identifiers.migratorRole,
|
|
104
|
+
readonlyRole: identifiers.readonlyRole,
|
|
160
105
|
readonlySecretArn: readonlySecret.arn,
|
|
106
|
+
readwriteRole: identifiers.readwriteRole,
|
|
107
|
+
readwriteSecretArn: readwriteSecret.arn,
|
|
108
|
+
resourceName,
|
|
109
|
+
// The cutover token forces one rotation for credentials that may still be
|
|
110
|
+
// present in historical pre-bootstrap Pulumi state. The token is stored
|
|
111
|
+
// only as non-secret metadata inside the new runtime secret version, so
|
|
112
|
+
// later bootstrap executions converge without rotating again.
|
|
113
|
+
rotationToken: options.rotationToken ?? 'aws-bootstrap-v1',
|
|
161
114
|
};
|
|
162
115
|
}
|
|
163
116
|
//# sourceMappingURL=provision-logical-database.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provision-logical-database.js","sourceRoot":"","sources":["../../../../../packages/nx/src/foundation/provision-logical-database.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"provision-logical-database.js","sourceRoot":"","sources":["../../../../../packages/nx/src/foundation/provision-logical-database.ts"],"names":[],"mappings":"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"}
|