@superblocksteam/shared 0.9603.2 → 0.9604.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/database-lifecycle/capacityPolicy.d.ts +51 -0
- package/dist/database-lifecycle/capacityPolicy.d.ts.map +1 -0
- package/dist/database-lifecycle/capacityPolicy.js +159 -0
- package/dist/database-lifecycle/capacityPolicy.js.map +1 -0
- package/dist/database-lifecycle/capacityPolicy.test.d.ts +2 -0
- package/dist/database-lifecycle/capacityPolicy.test.d.ts.map +1 -0
- package/dist/database-lifecycle/capacityPolicy.test.js +159 -0
- package/dist/database-lifecycle/capacityPolicy.test.js.map +1 -0
- package/dist/database-lifecycle/edit-lifecycle-capability.d.ts +18 -0
- package/dist/database-lifecycle/edit-lifecycle-capability.d.ts.map +1 -0
- package/dist/database-lifecycle/edit-lifecycle-capability.js +32 -0
- package/dist/database-lifecycle/edit-lifecycle-capability.js.map +1 -0
- package/dist/database-lifecycle/edit-lifecycle-capability.test.d.ts +2 -0
- package/dist/database-lifecycle/edit-lifecycle-capability.test.d.ts.map +1 -0
- package/dist/database-lifecycle/edit-lifecycle-capability.test.js +91 -0
- package/dist/database-lifecycle/edit-lifecycle-capability.test.js.map +1 -0
- package/dist/database-lifecycle/index.d.ts +50 -27
- package/dist/database-lifecycle/index.d.ts.map +1 -1
- package/dist/database-lifecycle/index.js +78 -54
- package/dist/database-lifecycle/index.js.map +1 -1
- package/dist/database-lifecycle/index.test.js +120 -77
- package/dist/database-lifecycle/index.test.js.map +1 -1
- package/dist/database-lifecycle/physicalPoolIdentity.d.ts +29 -0
- package/dist/database-lifecycle/physicalPoolIdentity.d.ts.map +1 -0
- package/dist/database-lifecycle/physicalPoolIdentity.js +64 -0
- package/dist/database-lifecycle/physicalPoolIdentity.js.map +1 -0
- package/dist/database-lifecycle/physicalPoolIdentity.test.d.ts +2 -0
- package/dist/database-lifecycle/physicalPoolIdentity.test.d.ts.map +1 -0
- package/dist/database-lifecycle/physicalPoolIdentity.test.js +51 -0
- package/dist/database-lifecycle/physicalPoolIdentity.test.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/types/audit/ocsf.d.ts +60 -6
- package/dist/types/audit/ocsf.d.ts.map +1 -1
- package/dist/types/audit/ocsf.js +12 -1
- package/dist/types/audit/ocsf.js.map +1 -1
- package/dist/types/deployment/deployQueueStatus.d.ts +13 -0
- package/dist/types/deployment/deployQueueStatus.d.ts.map +1 -1
- package/dist/types/deployment/index.d.ts +1 -1
- package/dist/types/deployment/index.d.ts.map +1 -1
- package/dist/types/deployment/index.js.map +1 -1
- package/dist/types/policyGate/index.d.ts +5 -0
- package/dist/types/policyGate/index.d.ts.map +1 -1
- package/dist/types/policyGate/index.js +5 -1
- package/dist/types/policyGate/index.js.map +1 -1
- package/dist/types/publishPipeline/plan.js +1 -1
- package/dist/types/publishPipeline/plan.js.map +1 -1
- package/dist/types/publishPipeline/plan.test.js +3 -3
- package/dist/types/publishPipeline/plan.test.js.map +1 -1
- package/dist/types/rbac/index.d.ts +2 -0
- package/dist/types/rbac/index.d.ts.map +1 -1
- package/dist/types/rbac/index.js +3 -1
- package/dist/types/rbac/index.js.map +1 -1
- package/dist/types/reviewPolicy/index.d.ts +30 -4
- package/dist/types/reviewPolicy/index.d.ts.map +1 -1
- package/dist/types/reviewPolicy/index.js +8 -1
- package/dist/types/reviewPolicy/index.js.map +1 -1
- package/dist-esm/database-lifecycle/capacityPolicy.d.ts +51 -0
- package/dist-esm/database-lifecycle/capacityPolicy.d.ts.map +1 -0
- package/dist-esm/database-lifecycle/capacityPolicy.js +150 -0
- package/dist-esm/database-lifecycle/capacityPolicy.js.map +1 -0
- package/dist-esm/database-lifecycle/capacityPolicy.test.d.ts +2 -0
- package/dist-esm/database-lifecycle/capacityPolicy.test.d.ts.map +1 -0
- package/dist-esm/database-lifecycle/capacityPolicy.test.js +157 -0
- package/dist-esm/database-lifecycle/capacityPolicy.test.js.map +1 -0
- package/dist-esm/database-lifecycle/edit-lifecycle-capability.d.ts +18 -0
- package/dist-esm/database-lifecycle/edit-lifecycle-capability.d.ts.map +1 -0
- package/dist-esm/database-lifecycle/edit-lifecycle-capability.js +29 -0
- package/dist-esm/database-lifecycle/edit-lifecycle-capability.js.map +1 -0
- package/dist-esm/database-lifecycle/edit-lifecycle-capability.test.d.ts +2 -0
- package/dist-esm/database-lifecycle/edit-lifecycle-capability.test.d.ts.map +1 -0
- package/dist-esm/database-lifecycle/edit-lifecycle-capability.test.js +89 -0
- package/dist-esm/database-lifecycle/edit-lifecycle-capability.test.js.map +1 -0
- package/dist-esm/database-lifecycle/index.d.ts +50 -27
- package/dist-esm/database-lifecycle/index.d.ts.map +1 -1
- package/dist-esm/database-lifecycle/index.js +62 -51
- package/dist-esm/database-lifecycle/index.js.map +1 -1
- package/dist-esm/database-lifecycle/index.test.js +90 -47
- package/dist-esm/database-lifecycle/index.test.js.map +1 -1
- package/dist-esm/database-lifecycle/physicalPoolIdentity.d.ts +29 -0
- package/dist-esm/database-lifecycle/physicalPoolIdentity.d.ts.map +1 -0
- package/dist-esm/database-lifecycle/physicalPoolIdentity.js +59 -0
- package/dist-esm/database-lifecycle/physicalPoolIdentity.js.map +1 -0
- package/dist-esm/database-lifecycle/physicalPoolIdentity.test.d.ts +2 -0
- package/dist-esm/database-lifecycle/physicalPoolIdentity.test.d.ts.map +1 -0
- package/dist-esm/database-lifecycle/physicalPoolIdentity.test.js +49 -0
- package/dist-esm/database-lifecycle/physicalPoolIdentity.test.js.map +1 -0
- package/dist-esm/index.d.ts +1 -0
- package/dist-esm/index.d.ts.map +1 -1
- package/dist-esm/index.js +1 -0
- package/dist-esm/index.js.map +1 -1
- package/dist-esm/types/audit/ocsf.d.ts +60 -6
- package/dist-esm/types/audit/ocsf.d.ts.map +1 -1
- package/dist-esm/types/audit/ocsf.js +12 -1
- package/dist-esm/types/audit/ocsf.js.map +1 -1
- package/dist-esm/types/deployment/deployQueueStatus.d.ts +13 -0
- package/dist-esm/types/deployment/deployQueueStatus.d.ts.map +1 -1
- package/dist-esm/types/deployment/index.d.ts +1 -1
- package/dist-esm/types/deployment/index.d.ts.map +1 -1
- package/dist-esm/types/deployment/index.js.map +1 -1
- package/dist-esm/types/policyGate/index.d.ts +5 -0
- package/dist-esm/types/policyGate/index.d.ts.map +1 -1
- package/dist-esm/types/policyGate/index.js +5 -1
- package/dist-esm/types/policyGate/index.js.map +1 -1
- package/dist-esm/types/publishPipeline/plan.js +1 -1
- package/dist-esm/types/publishPipeline/plan.js.map +1 -1
- package/dist-esm/types/publishPipeline/plan.test.js +3 -3
- package/dist-esm/types/publishPipeline/plan.test.js.map +1 -1
- package/dist-esm/types/rbac/index.d.ts +2 -0
- package/dist-esm/types/rbac/index.d.ts.map +1 -1
- package/dist-esm/types/rbac/index.js +3 -1
- package/dist-esm/types/rbac/index.js.map +1 -1
- package/dist-esm/types/reviewPolicy/index.d.ts +30 -4
- package/dist-esm/types/reviewPolicy/index.d.ts.map +1 -1
- package/dist-esm/types/reviewPolicy/index.js +7 -0
- package/dist-esm/types/reviewPolicy/index.js.map +1 -1
- package/package.json +1 -1
- package/src/database-lifecycle/capacityPolicy.test.ts +209 -0
- package/src/database-lifecycle/capacityPolicy.ts +197 -0
- package/src/database-lifecycle/edit-lifecycle-capability.test.ts +116 -0
- package/src/database-lifecycle/edit-lifecycle-capability.ts +34 -0
- package/src/database-lifecycle/index.test.ts +105 -48
- package/src/database-lifecycle/index.ts +157 -90
- package/src/database-lifecycle/physicalPoolIdentity.test.ts +64 -0
- package/src/database-lifecycle/physicalPoolIdentity.ts +75 -0
- package/src/index.ts +1 -0
- package/src/types/audit/ocsf.ts +73 -7
- package/src/types/deployment/deployQueueStatus.ts +14 -0
- package/src/types/deployment/index.ts +2 -1
- package/src/types/policyGate/index.ts +5 -1
- package/src/types/publishPipeline/plan.test.ts +3 -3
- package/src/types/publishPipeline/plan.ts +1 -1
- package/src/types/rbac/index.ts +3 -1
- package/src/types/reviewPolicy/index.ts +44 -5
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { describe, expect, test } from 'vitest';
|
|
2
2
|
|
|
3
|
+
import { ApiTriggerType } from '../types/api/index.js';
|
|
3
4
|
import {
|
|
5
|
+
DATABASE_LIFECYCLE_MANAGED_BY,
|
|
6
|
+
LIFECYCLE_OPERATIONS,
|
|
4
7
|
computeBindingKey,
|
|
5
8
|
computeDesiredSpecHash,
|
|
6
9
|
computeNativeDbApplicationToken,
|
|
7
|
-
|
|
8
|
-
computeNativeDbDatabaseName,
|
|
10
|
+
computeNativeDbProfileToken,
|
|
9
11
|
computeRequirementKey,
|
|
10
12
|
containsCredentialMaterial,
|
|
13
|
+
isLifecycleManagedIntegrationAllowedForApiTrigger,
|
|
11
14
|
isSecretKey,
|
|
12
15
|
isTerminalLifecycleState,
|
|
13
16
|
nativeDbIamSessionPolicy,
|
|
@@ -16,6 +19,21 @@ import {
|
|
|
16
19
|
} from './index.js';
|
|
17
20
|
|
|
18
21
|
describe('database lifecycle contracts', () => {
|
|
22
|
+
// Postgres `ALTER TYPE ... ADD VALUE` appends. TypeORM's entity-vs-schema
|
|
23
|
+
// check treats enum label order as part of the contract, so this array must
|
|
24
|
+
// match the live `lifecycle_operation_enum` order rather than alphabetical
|
|
25
|
+
// or semantic grouping.
|
|
26
|
+
test('lists lifecycle operations in Postgres enum order', () => {
|
|
27
|
+
expect(LIFECYCLE_OPERATIONS).toEqual(['ensure_database', 'migrate_schema', 'retire_database', 'ensure_physical_database_instance']);
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
test('allows lifecycle-managed integrations only in application APIs', () => {
|
|
31
|
+
expect(isLifecycleManagedIntegrationAllowedForApiTrigger(ApiTriggerType.UI, DATABASE_LIFECYCLE_MANAGED_BY)).toBe(true);
|
|
32
|
+
expect(isLifecycleManagedIntegrationAllowedForApiTrigger(ApiTriggerType.WORKFLOW, DATABASE_LIFECYCLE_MANAGED_BY)).toBe(false);
|
|
33
|
+
expect(isLifecycleManagedIntegrationAllowedForApiTrigger(ApiTriggerType.SCHEDULE, DATABASE_LIFECYCLE_MANAGED_BY)).toBe(false);
|
|
34
|
+
expect(isLifecycleManagedIntegrationAllowedForApiTrigger(ApiTriggerType.WORKFLOW, null)).toBe(true);
|
|
35
|
+
});
|
|
36
|
+
|
|
19
37
|
test('computes stable requirement, binding, and desired spec identifiers', async () => {
|
|
20
38
|
const requirement = {
|
|
21
39
|
logicalName: 'Orders DB',
|
|
@@ -32,27 +50,28 @@ describe('database lifecycle contracts', () => {
|
|
|
32
50
|
expect(computeRequirementKey({ logicalName: 'orders/db', engine: 'postgres' })).toBe('orders-db~orders%2Fdb:postgres');
|
|
33
51
|
expect(computeRequirementKey({ logicalName: 'orders-db', engine: 'postgres' })).toBe('orders-db~orders-db:postgres');
|
|
34
52
|
// binding_key excludes the logical name on purpose: one database per
|
|
35
|
-
// (organization, application,
|
|
36
|
-
//
|
|
53
|
+
// (organization, application, profile). Two different logical names under
|
|
54
|
+
// the same profile resolve to the same binding_key.
|
|
37
55
|
expect(
|
|
38
56
|
computeBindingKey({
|
|
39
57
|
organizationId: 'org-1',
|
|
40
58
|
applicationId: 'app-1',
|
|
41
|
-
environment: 'edit',
|
|
42
59
|
profile: 'Staging EU'
|
|
43
60
|
})
|
|
44
|
-
).toBe('org-1:app-1:
|
|
61
|
+
).toBe('org-1:app-1:staging-eu~Staging%20EU');
|
|
45
62
|
expect(
|
|
46
63
|
computeBindingKey({
|
|
47
64
|
organizationId: 'org-1',
|
|
48
65
|
applicationId: 'app-1',
|
|
49
|
-
environment: 'edit',
|
|
50
66
|
profile: 'staging'
|
|
51
67
|
})
|
|
52
|
-
).toBe('org-1:app-1:
|
|
68
|
+
).toBe('org-1:app-1:staging~staging');
|
|
53
69
|
|
|
54
70
|
await expect(computeDesiredSpecHash(requirement)).resolves.toBe(
|
|
55
|
-
await computeDesiredSpecHash({
|
|
71
|
+
await computeDesiredSpecHash({
|
|
72
|
+
...requirement,
|
|
73
|
+
extensions: ['uuid-ossp', 'pgcrypto']
|
|
74
|
+
})
|
|
56
75
|
);
|
|
57
76
|
await expect(computeDesiredSpecHash(requirement)).resolves.toBe('QsCl6RVzJVEwf4Nuk0D27rRtycYe2vQZMxcXLt9WUkQ=');
|
|
58
77
|
});
|
|
@@ -67,8 +86,14 @@ describe('database lifecycle contracts', () => {
|
|
|
67
86
|
} as const;
|
|
68
87
|
|
|
69
88
|
const withoutDirectory = await computeDesiredSpecHash(infrastructureSpec);
|
|
70
|
-
const withDirectory = await computeDesiredSpecHash({
|
|
71
|
-
|
|
89
|
+
const withDirectory = await computeDesiredSpecHash({
|
|
90
|
+
...infrastructureSpec,
|
|
91
|
+
migrationDirectory: 'db/migrations'
|
|
92
|
+
});
|
|
93
|
+
const withOtherDirectory = await computeDesiredSpecHash({
|
|
94
|
+
...infrastructureSpec,
|
|
95
|
+
migrationDirectory: 'db/other-migrations'
|
|
96
|
+
});
|
|
72
97
|
|
|
73
98
|
// migrationDirectory only says where the SQL files live, not what
|
|
74
99
|
// infrastructure to provision, so changing it must not look like drift.
|
|
@@ -91,7 +116,7 @@ describe('database lifecycle contracts', () => {
|
|
|
91
116
|
expect(first).toBe(second);
|
|
92
117
|
});
|
|
93
118
|
|
|
94
|
-
test('redacts raw credential material while preserving
|
|
119
|
+
test('redacts raw credential material and generic credential refs while preserving physical masterCredentialRef', () => {
|
|
95
120
|
const redacted = redactLifecycleSecrets({
|
|
96
121
|
host: 'db.internal',
|
|
97
122
|
password: 'raw-password',
|
|
@@ -108,6 +133,11 @@ describe('database lifecycle contracts', () => {
|
|
|
108
133
|
ref: 'database/orders',
|
|
109
134
|
field: 'password'
|
|
110
135
|
}
|
|
136
|
+
},
|
|
137
|
+
masterCredentialRef: {
|
|
138
|
+
resolver: 'aws_secrets_manager',
|
|
139
|
+
ref: 'physical-instance/master',
|
|
140
|
+
field: 'password'
|
|
111
141
|
}
|
|
112
142
|
});
|
|
113
143
|
|
|
@@ -122,11 +152,12 @@ describe('database lifecycle contracts', () => {
|
|
|
122
152
|
}
|
|
123
153
|
},
|
|
124
154
|
credential_refs: {
|
|
125
|
-
password:
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
155
|
+
password: '[REDACTED]'
|
|
156
|
+
},
|
|
157
|
+
masterCredentialRef: {
|
|
158
|
+
resolver: 'aws_secrets_manager',
|
|
159
|
+
ref: 'physical-instance/master',
|
|
160
|
+
field: 'password'
|
|
130
161
|
}
|
|
131
162
|
});
|
|
132
163
|
});
|
|
@@ -158,17 +189,17 @@ describe('database lifecycle contracts', () => {
|
|
|
158
189
|
test('builds a canonical session policy from a valid managed Postgres IAM descriptor', () => {
|
|
159
190
|
const descriptor = parseNativeDbIamDescriptor({
|
|
160
191
|
application_id: 'application-id',
|
|
161
|
-
auth_descriptor_version:
|
|
192
|
+
auth_descriptor_version: 3,
|
|
162
193
|
auth_mode: 'aws_iam_role',
|
|
163
194
|
aws_account_id: '123456789012',
|
|
164
195
|
binding_id: 'binding-id',
|
|
165
196
|
cluster_resource_id: 'cluster-ABC123DEF456EXAMPLE',
|
|
166
197
|
connector_role_arn: 'arn:aws:iam::123456789012:role/superblocks-native-db-connector-prod',
|
|
167
|
-
database: '
|
|
198
|
+
database: 'sbndb_abcdef1234567890_0123456789abcdef01234567',
|
|
168
199
|
host: 'native-db.cluster-example.us-west-2.rds.amazonaws.com',
|
|
169
200
|
port: 5432,
|
|
170
201
|
region: 'us-west-2',
|
|
171
|
-
username: '
|
|
202
|
+
username: 'sbndb_abcdef1234567890_0123456789abcdef01234567_runtime'
|
|
172
203
|
});
|
|
173
204
|
|
|
174
205
|
expect(descriptor).toBeDefined();
|
|
@@ -176,57 +207,57 @@ describe('database lifecycle contracts', () => {
|
|
|
176
207
|
throw new Error('Expected a valid IAM descriptor');
|
|
177
208
|
}
|
|
178
209
|
expect(nativeDbIamSessionPolicy(descriptor)).toBe(
|
|
179
|
-
'{"Version":"2012-10-17","Statement":[{"Sid":"ConnectToThisNativeDatabaseUser","Effect":"Allow","Action":"rds-db:connect","Resource":"arn:aws:rds-db:us-west-2:123456789012:dbuser:cluster-ABC123DEF456EXAMPLE/
|
|
210
|
+
'{"Version":"2012-10-17","Statement":[{"Sid":"ConnectToThisNativeDatabaseUser","Effect":"Allow","Action":"rds-db:connect","Resource":"arn:aws:rds-db:us-west-2:123456789012:dbuser:cluster-ABC123DEF456EXAMPLE/sbndb_abcdef1234567890_0123456789abcdef01234567_runtime"}]}'
|
|
180
211
|
);
|
|
181
212
|
});
|
|
182
213
|
|
|
183
|
-
test('reads
|
|
214
|
+
test('reads managed Postgres IAM descriptors with auth_descriptor_version 3', () => {
|
|
184
215
|
expect(
|
|
185
216
|
parseNativeDbIamDescriptor({
|
|
186
217
|
application_id: 'application-id',
|
|
187
|
-
auth_descriptor_version:
|
|
218
|
+
auth_descriptor_version: 3,
|
|
188
219
|
auth_mode: 'aws_iam_role',
|
|
189
220
|
aws_account_id: '123456789012',
|
|
190
221
|
binding_id: 'binding-id',
|
|
191
222
|
cluster_resource_id: 'cluster-ABC123DEF456EXAMPLE',
|
|
192
223
|
connector_role_arn: 'arn:aws:iam::123456789012:role/superblocks-native-db-connector-prod',
|
|
193
|
-
database: '
|
|
224
|
+
database: 'sbndb_abcdef1234567890_0123456789abcdef01234567',
|
|
194
225
|
host: 'native-db.cluster-example.us-west-2.rds.amazonaws.com',
|
|
195
226
|
port: 5432,
|
|
196
227
|
region: 'us-west-2',
|
|
197
|
-
username: '
|
|
228
|
+
username: 'sbndb_abcdef1234567890_0123456789abcdef01234567_runtime'
|
|
198
229
|
})
|
|
199
230
|
).toEqual({
|
|
200
231
|
application_id: 'application-id',
|
|
201
|
-
auth_descriptor_version:
|
|
232
|
+
auth_descriptor_version: 3,
|
|
202
233
|
auth_mode: 'aws_iam_role',
|
|
203
234
|
aws_account_id: '123456789012',
|
|
204
235
|
binding_id: 'binding-id',
|
|
205
236
|
cluster_resource_id: 'cluster-ABC123DEF456EXAMPLE',
|
|
206
237
|
connector_role_arn: 'arn:aws:iam::123456789012:role/superblocks-native-db-connector-prod',
|
|
207
|
-
database: '
|
|
238
|
+
database: 'sbndb_abcdef1234567890_0123456789abcdef01234567',
|
|
208
239
|
host: 'native-db.cluster-example.us-west-2.rds.amazonaws.com',
|
|
209
240
|
port: 5432,
|
|
210
241
|
region: 'us-west-2',
|
|
211
|
-
username: '
|
|
242
|
+
username: 'sbndb_abcdef1234567890_0123456789abcdef01234567_runtime'
|
|
212
243
|
});
|
|
213
244
|
});
|
|
214
245
|
|
|
215
|
-
test('rejects
|
|
246
|
+
test('rejects descriptors when database and runtime username do not match', () => {
|
|
216
247
|
expect(
|
|
217
248
|
parseNativeDbIamDescriptor({
|
|
218
249
|
application_id: 'application-id',
|
|
219
|
-
auth_descriptor_version:
|
|
250
|
+
auth_descriptor_version: 3,
|
|
220
251
|
auth_mode: 'aws_iam_role',
|
|
221
252
|
aws_account_id: '123456789012',
|
|
222
253
|
binding_id: 'binding-id',
|
|
223
254
|
cluster_resource_id: 'cluster-ABC123DEF456EXAMPLE',
|
|
224
255
|
connector_role_arn: 'arn:aws:iam::123456789012:role/superblocks-native-db-connector-prod',
|
|
225
|
-
database: '
|
|
256
|
+
database: 'sbndb_abcdef1234567890_0123456789abcdef01234567',
|
|
226
257
|
host: 'native-db.cluster-example.us-west-2.rds.amazonaws.com',
|
|
227
258
|
port: 5432,
|
|
228
259
|
region: 'us-west-2',
|
|
229
|
-
username: '
|
|
260
|
+
username: 'sbndb_abcdef1234567890_fedcba9876543210fedcba98_runtime'
|
|
230
261
|
})
|
|
231
262
|
).toBeUndefined();
|
|
232
263
|
});
|
|
@@ -234,56 +265,82 @@ describe('database lifecycle contracts', () => {
|
|
|
234
265
|
test('rejects malformed or non-commercial managed Postgres IAM descriptors', () => {
|
|
235
266
|
const descriptor = {
|
|
236
267
|
application_id: 'application-id',
|
|
237
|
-
auth_descriptor_version:
|
|
268
|
+
auth_descriptor_version: 3,
|
|
238
269
|
auth_mode: 'aws_iam_role',
|
|
239
270
|
aws_account_id: '123456789012',
|
|
240
271
|
binding_id: 'binding-id',
|
|
241
272
|
cluster_resource_id: 'cluster-ABC123DEF456EXAMPLE',
|
|
242
273
|
connector_role_arn: 'arn:aws:iam::123456789012:role/superblocks-native-db-connector-prod',
|
|
243
|
-
database: '
|
|
274
|
+
database: 'sbndb_abcdef1234567890_0123456789abcdef01234567',
|
|
244
275
|
host: 'native-db.cluster-example.us-west-2.rds.amazonaws.com',
|
|
245
276
|
port: 5432,
|
|
246
277
|
region: 'us-west-2',
|
|
247
|
-
username: '
|
|
278
|
+
username: 'sbndb_abcdef1234567890_0123456789abcdef01234567_runtime'
|
|
248
279
|
};
|
|
249
280
|
|
|
250
|
-
expect(parseNativeDbIamDescriptor({ ...descriptor, auth_descriptor_version:
|
|
251
|
-
expect(parseNativeDbIamDescriptor({ ...descriptor,
|
|
252
|
-
expect(
|
|
281
|
+
expect(parseNativeDbIamDescriptor({ ...descriptor, auth_descriptor_version: 1 })).toBeUndefined();
|
|
282
|
+
expect(parseNativeDbIamDescriptor({ ...descriptor, auth_descriptor_version: 2 })).toBeUndefined();
|
|
283
|
+
expect(
|
|
284
|
+
parseNativeDbIamDescriptor({
|
|
285
|
+
...descriptor,
|
|
286
|
+
cluster_resource_id: 'not-an-rds-resource'
|
|
287
|
+
})
|
|
288
|
+
).toBeUndefined();
|
|
289
|
+
expect(
|
|
290
|
+
parseNativeDbIamDescriptor({
|
|
291
|
+
...descriptor,
|
|
292
|
+
connector_role_arn: 'arn:aws:iam::210987654321:role/other'
|
|
293
|
+
})
|
|
294
|
+
).toBeUndefined();
|
|
253
295
|
expect(parseNativeDbIamDescriptor({ ...descriptor, database: 'orders' })).toBeUndefined();
|
|
254
|
-
expect(
|
|
255
|
-
|
|
296
|
+
expect(
|
|
297
|
+
parseNativeDbIamDescriptor({
|
|
298
|
+
...descriptor,
|
|
299
|
+
host: descriptor.host.toUpperCase()
|
|
300
|
+
})
|
|
301
|
+
).toBeUndefined();
|
|
302
|
+
expect(
|
|
303
|
+
parseNativeDbIamDescriptor({
|
|
304
|
+
...descriptor,
|
|
305
|
+
host: 'native-db.cluster-example.us-east-1.rds.amazonaws.com'
|
|
306
|
+
})
|
|
307
|
+
).toBeUndefined();
|
|
256
308
|
expect(parseNativeDbIamDescriptor({ ...descriptor, port: 0 })).toBeUndefined();
|
|
257
309
|
expect(parseNativeDbIamDescriptor({ ...descriptor, region: 'cn-north-1' })).toBeUndefined();
|
|
258
310
|
expect(parseNativeDbIamDescriptor({ ...descriptor, region: 'us-gov-west-1' })).toBeUndefined();
|
|
259
|
-
expect(
|
|
311
|
+
expect(
|
|
312
|
+
parseNativeDbIamDescriptor({
|
|
313
|
+
...descriptor,
|
|
314
|
+
username: 'sbndb_0000000000000000_7bfeae1170db923274f1943f_runtime'
|
|
315
|
+
})
|
|
316
|
+
).toBeUndefined();
|
|
260
317
|
});
|
|
261
318
|
|
|
262
319
|
test('accepts standalone RDS IAM resource IDs', () => {
|
|
263
320
|
expect(
|
|
264
321
|
parseNativeDbIamDescriptor({
|
|
265
322
|
application_id: 'application-id',
|
|
266
|
-
auth_descriptor_version:
|
|
323
|
+
auth_descriptor_version: 3,
|
|
267
324
|
auth_mode: 'aws_iam_role',
|
|
268
325
|
aws_account_id: '123456789012',
|
|
269
326
|
binding_id: 'binding-id',
|
|
270
327
|
cluster_resource_id: 'db-ABCDEF0123456789-1',
|
|
271
328
|
connector_role_arn: 'arn:aws:iam::123456789012:role/superblocks-native-db-connector-prod',
|
|
272
|
-
database: '
|
|
329
|
+
database: 'sbndb_abcdef1234567890_0123456789abcdef01234567',
|
|
273
330
|
host: 'native-db.example.us-west-2.rds.amazonaws.com',
|
|
274
331
|
port: 5432,
|
|
275
332
|
region: 'us-west-2',
|
|
276
|
-
username: '
|
|
333
|
+
username: 'sbndb_abcdef1234567890_0123456789abcdef01234567_runtime'
|
|
277
334
|
})
|
|
278
335
|
).toBeDefined();
|
|
279
336
|
});
|
|
280
337
|
|
|
281
|
-
test('derives canonical IAM
|
|
338
|
+
test('derives canonical IAM application token', async () => {
|
|
282
339
|
await expect(computeNativeDbApplicationToken('application-id')).resolves.toBe('7bfeae1170db923274f1943f');
|
|
283
|
-
await expect(computeNativeDbDatabaseName('abcdef123456', 'database-id')).resolves.toBe('sbndb_abcdef123456_dad72612f7a80580b028178f');
|
|
284
340
|
});
|
|
285
341
|
|
|
286
|
-
test('derives
|
|
287
|
-
await expect(
|
|
342
|
+
test('derives canonical IAM profile token', async () => {
|
|
343
|
+
await expect(computeNativeDbProfileToken('production')).resolves.toHaveLength(16);
|
|
344
|
+
await expect(computeNativeDbProfileToken('Production')).resolves.toBe(await computeNativeDbProfileToken('production'));
|
|
288
345
|
});
|
|
289
346
|
});
|