@highstate/backend 0.9.18 → 0.9.19
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/chunk-5WVU2AK4.js +1535 -0
- package/dist/chunk-5WVU2AK4.js.map +1 -0
- package/dist/{chunk-OU5OQBLB.js → chunk-I7BWSAN6.js} +3 -28
- package/dist/{chunk-OU5OQBLB.js.map → chunk-I7BWSAN6.js.map} +1 -1
- package/dist/chunk-VB4YL327.js +139 -0
- package/dist/chunk-VB4YL327.js.map +1 -0
- package/dist/database/local/prisma.config.js +26 -0
- package/dist/database/local/prisma.config.js.map +1 -0
- package/dist/highstate.manifest.json +2 -1
- package/dist/index.js +7587 -7291
- package/dist/index.js.map +1 -1
- package/dist/library/package-resolution-worker.js +1 -1
- package/dist/library/package-resolution-worker.js.map +1 -1
- package/dist/library/worker/main.js +35 -29
- package/dist/library/worker/main.js.map +1 -1
- package/dist/shared/index.js +2 -2
- package/package.json +18 -9
- package/prisma/backend/_schema/layout.prisma +7 -0
- package/prisma/backend/_schema/library.prisma +17 -0
- package/prisma/backend/_schema/project.prisma +101 -0
- package/prisma/backend/_schema/pulumi.prisma +17 -0
- package/prisma/backend/postgresql/main.prisma +17 -0
- package/prisma/backend/sqlite/main.prisma +17 -0
- package/prisma/backend/sqlite/migrations/20250817070609_initiial/migration.sql +34 -0
- package/prisma/backend/sqlite/migrations/20250817104948_add_fields/migration.sql +59 -0
- package/prisma/backend/sqlite/migrations/20250818082732_add_models/migration.sql +41 -0
- package/prisma/backend/sqlite/migrations/20250818083106_a/migration.sql +19 -0
- package/prisma/backend/sqlite/migrations/20250818101945_hi/migration.sql +1 -0
- package/prisma/backend/sqlite/migrations/20250819082315_a/migration.sql +5 -0
- package/prisma/backend/sqlite/migrations/migration_lock.toml +3 -0
- package/prisma/project/api-key.prisma +27 -0
- package/prisma/project/artifact.prisma +52 -0
- package/prisma/project/custom-status.prisma +46 -0
- package/prisma/project/evaluation.prisma +35 -0
- package/prisma/project/instance.prisma +160 -0
- package/prisma/project/layout.prisma +23 -0
- package/prisma/project/lock.prisma +18 -0
- package/prisma/project/main.prisma +17 -0
- package/prisma/project/migrations/20250816081310_initial/migration.sql +300 -0
- package/prisma/project/migrations/20250816082523_test/migration.sql +72 -0
- package/prisma/project/migrations/20250818065643_update/migration.sql +42 -0
- package/prisma/project/migrations/20250818070758_a/migration.sql +8 -0
- package/prisma/project/migrations/20250818070913_a/migration.sql +8 -0
- package/prisma/project/migrations/20250818082720_add_motels/migration.sql +11 -0
- package/prisma/project/migrations/20250818112523_hello/migration.sql +35 -0
- package/prisma/project/migrations/20250819082305_a/migration.sql +14 -0
- package/prisma/project/migrations/20250819165004_add_missing_fields/migration.sql +216 -0
- package/prisma/project/migrations/20250819171309_a/migration.sql +22 -0
- package/prisma/project/migrations/20250820113949_a/migration.sql +66 -0
- package/prisma/project/migrations/20250820144256_b/migration.sql +31 -0
- package/prisma/project/migrations/20250820145547_a/migration.sql +24 -0
- package/prisma/project/migrations/20250820182517_b/migration.sql +2 -0
- package/prisma/project/migrations/20250821172324_a/migration.sql +2 -0
- package/prisma/project/migrations/20250822081339_a/migration.sql +219 -0
- package/prisma/project/migrations/20250822083742_b/migration.sql +1 -0
- package/prisma/project/migrations/20250822105134_boom/migration.sql +1 -0
- package/prisma/project/migrations/20250822141028_b/migration.sql +1 -0
- package/prisma/project/migrations/20250822142342_b/migration.sql +16 -0
- package/prisma/project/migrations/20250824072720_a/migration.sql +1 -0
- package/prisma/project/migrations/20250824093656_b/migration.sql +21 -0
- package/prisma/project/migrations/20250825082518_a/migration.sql +1 -0
- package/prisma/project/migrations/20250825085343_b/migration.sql +1 -0
- package/prisma/project/migrations/20250825091312_a/migration.sql +1 -0
- package/prisma/project/migrations/20250903095431_hi/migration.sql +44 -0
- package/prisma/project/migrations/20250903174255_a/migration.sql +24 -0
- package/prisma/project/migrations/20250908095205_hi/migration.sql +18 -0
- package/prisma/project/migrations/20250909155857_hi/migration.sql +15 -0
- package/prisma/project/migrations/migration_lock.toml +3 -0
- package/prisma/project/model.prisma +37 -0
- package/prisma/project/operation.prisma +148 -0
- package/prisma/project/page.prisma +41 -0
- package/prisma/project/secret.prisma +42 -0
- package/prisma/project/service-account.prisma +36 -0
- package/prisma/project/terminal.prisma +90 -0
- package/prisma/project/trigger.prisma +31 -0
- package/prisma/project/unlock-method.prisma +32 -0
- package/prisma/project/worker.prisma +138 -0
- package/src/artifact/abstractions.ts +13 -13
- package/src/artifact/encryption.ts +30 -54
- package/src/artifact/factory.ts +6 -9
- package/src/artifact/local.ts +33 -46
- package/src/business/api-key.ts +24 -36
- package/src/business/artifact.test.ts +978 -0
- package/src/business/artifact.ts +136 -216
- package/src/business/evaluation.ts +328 -0
- package/src/business/index.ts +5 -2
- package/src/business/instance-lock.test.ts +1060 -0
- package/src/business/instance-lock.ts +387 -78
- package/src/business/instance-state.test.ts +735 -0
- package/src/business/instance-state.ts +582 -337
- package/src/business/operation.test.ts +439 -0
- package/src/business/operation.ts +174 -208
- package/src/business/project-model.ts +258 -0
- package/src/business/project-unlock.ts +168 -126
- package/src/business/project.ts +287 -179
- package/src/business/secret.test.ts +465 -130
- package/src/business/secret.ts +186 -217
- package/src/business/settings.test.ts +695 -0
- package/src/business/settings.ts +855 -0
- package/src/business/terminal-session.ts +90 -0
- package/src/business/unit-extra.test.ts +539 -0
- package/src/business/unit-extra.ts +160 -0
- package/src/business/worker.test.ts +356 -579
- package/src/business/worker.ts +238 -339
- package/src/common/codebase.ts +65 -0
- package/src/common/index.ts +3 -5
- package/src/common/logger.ts +5 -0
- package/src/common/utils.ts +4 -3
- package/src/config.ts +10 -11
- package/src/database/_generated/backend/postgresql/client.ts +72 -0
- package/src/database/_generated/backend/postgresql/commonInputTypes.ts +350 -0
- package/src/database/_generated/backend/postgresql/enums.ts +13 -0
- package/src/database/_generated/backend/postgresql/internal/class.ts +320 -0
- package/src/database/_generated/backend/postgresql/internal/prismaNamespace.ts +1238 -0
- package/src/database/_generated/backend/postgresql/models/Library.ts +1263 -0
- package/src/database/_generated/backend/postgresql/models/Project.ts +2175 -0
- package/src/database/_generated/backend/postgresql/models/ProjectModelStorage.ts +1263 -0
- package/src/database/_generated/backend/postgresql/models/ProjectSpace.ts +1602 -0
- package/src/database/_generated/backend/postgresql/models/PulumiBackend.ts +1263 -0
- package/src/database/_generated/backend/postgresql/models/UserWorkspaseLayout.ts +1065 -0
- package/src/database/_generated/backend/postgresql/models.ts +16 -0
- package/src/database/_generated/backend/postgresql/pjtg.ts +182 -0
- package/src/database/_generated/backend/sqlite/client.ts +72 -0
- package/src/database/_generated/backend/sqlite/commonInputTypes.ts +331 -0
- package/src/database/_generated/backend/sqlite/enums.ts +13 -0
- package/src/database/_generated/backend/sqlite/internal/class.ts +318 -0
- package/src/database/_generated/backend/sqlite/internal/prismaNamespace.ts +1207 -0
- package/src/database/_generated/backend/sqlite/models/Library.ts +1261 -0
- package/src/database/_generated/backend/sqlite/models/Project.ts +2169 -0
- package/src/database/_generated/backend/sqlite/models/ProjectModelStorage.ts +1261 -0
- package/src/database/_generated/backend/sqlite/models/ProjectSpace.ts +1599 -0
- package/src/database/_generated/backend/sqlite/models/PulumiBackend.ts +1261 -0
- package/src/database/_generated/backend/sqlite/models/UserWorkspaseLayout.ts +1063 -0
- package/src/database/_generated/backend/sqlite/models.ts +16 -0
- package/src/database/_generated/backend/sqlite/pjtg.ts +182 -0
- package/src/database/_generated/project/client.ts +204 -0
- package/src/database/_generated/project/commonInputTypes.ts +827 -0
- package/src/database/_generated/project/enums.ts +104 -0
- package/src/database/_generated/project/internal/class.ts +479 -0
- package/src/database/_generated/project/internal/prismaNamespace.ts +2974 -0
- package/src/database/_generated/project/models/ApiKey.ts +1506 -0
- package/src/database/_generated/project/models/Artifact.ts +2051 -0
- package/src/database/_generated/project/models/HubModel.ts +1125 -0
- package/src/database/_generated/project/models/InstanceCustomStatus.ts +1713 -0
- package/src/database/_generated/project/models/InstanceEvaluationState.ts +1312 -0
- package/src/database/_generated/project/models/InstanceLock.ts +1268 -0
- package/src/database/_generated/project/models/InstanceModel.ts +1125 -0
- package/src/database/_generated/project/models/InstanceOperationState.ts +1707 -0
- package/src/database/_generated/project/models/InstanceState.ts +4613 -0
- package/src/database/_generated/project/models/Operation.ts +1647 -0
- package/src/database/_generated/project/models/OperationLog.ts +1455 -0
- package/src/database/_generated/project/models/Page.ts +1838 -0
- package/src/database/_generated/project/models/Secret.ts +1692 -0
- package/src/database/_generated/project/models/ServiceAccount.ts +2165 -0
- package/src/database/_generated/project/models/Terminal.ts +2038 -0
- package/src/database/_generated/project/models/TerminalSession.ts +1454 -0
- package/src/database/_generated/project/models/TerminalSessionLog.ts +1280 -0
- package/src/database/_generated/project/models/Trigger.ts +1430 -0
- package/src/database/_generated/project/models/UnlockMethod.ts +1220 -0
- package/src/database/_generated/project/models/UserCompositeViewport.ts +1280 -0
- package/src/database/_generated/project/models/UserProjectViewport.ts +1059 -0
- package/src/database/_generated/project/models/Worker.ts +1459 -0
- package/src/database/_generated/project/models/WorkerUnitRegistration.ts +1524 -0
- package/src/database/_generated/project/models/WorkerVersion.ts +1974 -0
- package/src/database/_generated/project/models/WorkerVersionLog.ts +1318 -0
- package/src/database/_generated/project/models.ts +35 -0
- package/src/database/_generated/project/pjtg.ts +182 -0
- package/src/database/abstractions.ts +19 -0
- package/src/database/factory.ts +37 -0
- package/src/database/index.ts +6 -0
- package/src/database/local/backend.ts +134 -0
- package/src/database/local/index.ts +3 -0
- package/src/database/local/meta.ts +46 -0
- package/src/database/local/prisma.config.ts +25 -0
- package/src/database/local/project.ts +39 -0
- package/src/database/manager.ts +181 -0
- package/src/database/migrate.ts +35 -0
- package/src/database/prisma.ts +56 -0
- package/src/database/well-known.ts +38 -0
- package/src/index.ts +4 -4
- package/src/library/abstractions.ts +3 -5
- package/src/library/factory.ts +1 -1
- package/src/library/local.ts +81 -26
- package/src/library/package-resolution-worker.ts +1 -1
- package/src/library/worker/evaluator.ts +40 -23
- package/src/library/worker/loader.lite.ts +1 -1
- package/src/library/worker/main.ts +3 -10
- package/src/library/worker/protocol.ts +0 -1
- package/src/lock/index.ts +0 -1
- package/src/lock/manager.ts +0 -10
- package/src/orchestrator/manager.ts +190 -104
- package/src/orchestrator/operation-context.ts +357 -0
- package/src/orchestrator/operation-plan.destroy.test.md +357 -0
- package/src/orchestrator/operation-plan.destroy.test.ts +775 -0
- package/src/orchestrator/operation-plan.fixtures.ts +213 -0
- package/src/orchestrator/operation-plan.md +198 -0
- package/src/orchestrator/operation-plan.refresh.test.md +199 -0
- package/src/orchestrator/operation-plan.refresh.test.ts +367 -0
- package/src/orchestrator/operation-plan.ts +709 -0
- package/src/orchestrator/operation-plan.update.test.md +485 -0
- package/src/orchestrator/operation-plan.update.test.ts +1066 -0
- package/src/orchestrator/operation-workset.ts +233 -578
- package/src/orchestrator/operation.ts +435 -948
- package/src/orchestrator/plan-test-builder.ts +267 -0
- package/src/project-model/abstractions.ts +118 -0
- package/src/project-model/backends/codebase.ts +365 -0
- package/src/project-model/backends/database.ts +440 -0
- package/src/project-model/errors.ts +81 -0
- package/src/project-model/factory.ts +24 -0
- package/src/project-model/index.ts +4 -0
- package/src/project-model/utils.test.ts +544 -0
- package/src/project-model/utils.ts +242 -0
- package/src/pubsub/abstractions.ts +10 -1
- package/src/pubsub/factory.ts +4 -4
- package/src/pubsub/index.ts +1 -0
- package/src/pubsub/manager.ts +29 -13
- package/src/pubsub/memory.ts +31 -0
- package/src/runner/abstractions.ts +33 -41
- package/src/runner/artifact-env.ts +19 -8
- package/src/runner/factory.ts +6 -6
- package/src/runner/force-abort.ts +3 -6
- package/src/runner/local.ts +64 -67
- package/src/runner/pulumi.ts +23 -63
- package/src/services.ts +181 -123
- package/src/shared/models/backend/index.ts +3 -1
- package/src/shared/models/backend/library.ts +9 -1
- package/src/shared/models/backend/project.ts +43 -42
- package/src/shared/models/backend/pulumi.ts +14 -0
- package/src/shared/models/backend/unlock-method.ts +1 -1
- package/src/shared/models/backend/well-known.ts +58 -0
- package/src/shared/models/base.ts +40 -26
- package/src/shared/models/errors.ts +82 -1
- package/src/shared/models/index.ts +3 -2
- package/src/shared/models/prisma.ts +36 -0
- package/src/shared/models/project/api-key.ts +37 -59
- package/src/shared/models/project/artifact.ts +16 -76
- package/src/shared/models/project/custom-status.ts +12 -0
- package/src/shared/models/project/index.ts +8 -7
- package/src/shared/models/project/lock.ts +10 -78
- package/src/shared/models/project/model.ts +19 -1
- package/src/shared/models/project/operation.ts +222 -99
- package/src/shared/models/project/page.ts +37 -48
- package/src/shared/models/project/secret.ts +29 -89
- package/src/shared/models/project/service-account.ts +12 -17
- package/src/shared/models/project/state.ts +100 -407
- package/src/shared/models/project/terminal.ts +75 -88
- package/src/shared/models/project/trigger.ts +13 -49
- package/src/shared/models/project/unlock-method.ts +20 -26
- package/src/shared/models/project/worker.ts +89 -90
- package/src/shared/resolvers/graph-resolver.ts +21 -0
- package/src/shared/resolvers/index.ts +1 -1
- package/src/shared/resolvers/input-hash.ts +24 -14
- package/src/shared/resolvers/input.ts +1 -1
- package/src/shared/resolvers/registry.ts +5 -4
- package/src/shared/resolvers/state.ts +12 -1
- package/src/shared/resolvers/validation.ts +7 -3
- package/src/shared/utils/index.ts +1 -2
- package/src/shared/utils/promise-tracker.ts +30 -3
- package/src/terminal/abstractions.ts +1 -1
- package/src/terminal/docker.ts +3 -3
- package/src/terminal/manager.ts +102 -118
- package/src/test-utils/database.ts +119 -0
- package/src/test-utils/index.ts +2 -0
- package/src/test-utils/services.ts +134 -0
- package/src/unlock/abstractions.ts +5 -23
- package/src/unlock/memory.ts +9 -14
- package/src/worker/abstractions.ts +7 -4
- package/src/worker/docker.ts +14 -19
- package/src/worker/manager.ts +366 -97
- package/dist/chunk-NAAIDR4U.js +0 -8499
- package/dist/chunk-NAAIDR4U.js.map +0 -1
- package/dist/chunk-Y7DXREVO.js +0 -1745
- package/dist/chunk-Y7DXREVO.js.map +0 -1
- package/dist/magic-string.es-5ABAC4JN.js +0 -1292
- package/dist/magic-string.es-5ABAC4JN.js.map +0 -1
- package/src/business/__traces__/secret/update-instance-secrets/create-and-delete-secrets-simultaneously.md +0 -356
- package/src/business/__traces__/secret/update-instance-secrets/create-new-secrets-for-instance.md +0 -274
- package/src/business/__traces__/secret/update-instance-secrets/delete-existing-secrets.md +0 -223
- package/src/business/__traces__/secret/update-instance-secrets/no-op-when-no-changes.md +0 -147
- package/src/business/__traces__/secret/update-instance-secrets/update-existing-secrets.md +0 -280
- package/src/business/__traces__/worker/update-unit-registrations/add-new-unit-registration-when-other-exists.md +0 -360
- package/src/business/__traces__/worker/update-unit-registrations/add-new-unit-registration.md +0 -215
- package/src/business/__traces__/worker/update-unit-registrations/create-multiple-workers-with-different-identities.md +0 -427
- package/src/business/__traces__/worker/update-unit-registrations/handle-nonexistent-registration-id-gracefully.md +0 -217
- package/src/business/__traces__/worker/update-unit-registrations/no-op-when-no-changes.md +0 -132
- package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-when-image-changes.md +0 -454
- package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-when-image-version-changes.md +0 -426
- package/src/business/__traces__/worker/update-unit-registrations/recreate-worker-with-same-identity-reuses-service-account.md +0 -372
- package/src/business/__traces__/worker/update-unit-registrations/remove-one-of-multiple-unit-registrations.md +0 -383
- package/src/business/__traces__/worker/update-unit-registrations/remove-unit-registration.md +0 -245
- package/src/business/__traces__/worker/update-unit-registrations/update-existing-unit-registration-when-params-change.md +0 -174
- package/src/business/__traces__/worker/update-unit-registrations/update-params-and-image-simultaneously.md +0 -432
- package/src/business/__traces__/worker/update-unit-registrations/worker-with-multiple-registrations-not-deleted-when-one-removed.md +0 -220
- package/src/business/backend-unlock.ts +0 -10
- package/src/common/clock.ts +0 -18
- package/src/common/performance.ts +0 -44
- package/src/common/random.ts +0 -68
- package/src/common/test/index.ts +0 -2
- package/src/common/test/render.ts +0 -98
- package/src/common/test/tracer.ts +0 -359
- package/src/hotstate/abstractions.ts +0 -48
- package/src/hotstate/factory.ts +0 -17
- package/src/hotstate/index.ts +0 -3
- package/src/hotstate/manager.ts +0 -192
- package/src/hotstate/memory.ts +0 -100
- package/src/hotstate/validation.ts +0 -100
- package/src/lock/test.ts +0 -108
- package/src/project/abstractions.ts +0 -78
- package/src/project/evaluation.ts +0 -248
- package/src/project/factory.ts +0 -11
- package/src/project/index.ts +0 -3
- package/src/project/local.ts +0 -417
- package/src/pubsub/local.ts +0 -36
- package/src/pubsub/validation.ts +0 -33
- package/src/shared/utils/args.ts +0 -25
- package/src/state/abstractions.ts +0 -289
- package/src/state/encryption.ts +0 -98
- package/src/state/factory.ts +0 -20
- package/src/state/index.ts +0 -7
- package/src/state/local/backend.ts +0 -106
- package/src/state/local/collection.ts +0 -361
- package/src/state/local/index.ts +0 -2
- package/src/state/manager.ts +0 -890
- package/src/state/memory/backend.ts +0 -70
- package/src/state/memory/collection.ts +0 -270
- package/src/state/memory/index.ts +0 -2
- package/src/state/repository/index.ts +0 -2
- package/src/state/repository/repository.index.ts +0 -193
- package/src/state/repository/repository.ts +0 -507
- package/src/state/test.ts +0 -457
- /package/src/{state → database/local}/keyring.ts +0 -0
package/src/business/secret.ts
CHANGED
|
@@ -1,281 +1,250 @@
|
|
|
1
1
|
import type { Logger } from "pino"
|
|
2
|
+
import type { DatabaseManager, ProjectTransaction } from "../database"
|
|
2
3
|
import type { LibraryBackend } from "../library"
|
|
3
|
-
import type {
|
|
4
|
-
import
|
|
5
|
-
import type
|
|
4
|
+
import type { PubSubManager } from "../pubsub"
|
|
5
|
+
import { randomBytes } from "node:crypto"
|
|
6
|
+
import { isUnitModel, parseInstanceId, type CommonObjectMeta } from "@highstate/contract"
|
|
6
7
|
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
} from "
|
|
12
|
-
import { isNonNullish } from "remeda"
|
|
13
|
-
import { formatSecretDescriptor, type Project, type Secret, type SecretDescriptor } from "../shared"
|
|
8
|
+
InstanceStateNotFoundError,
|
|
9
|
+
InvalidInstanceKindError,
|
|
10
|
+
ProjectNotFoundError,
|
|
11
|
+
SystemSecretNames,
|
|
12
|
+
} from "../shared"
|
|
14
13
|
|
|
15
14
|
export class SecretService {
|
|
16
15
|
constructor(
|
|
17
|
-
private readonly
|
|
16
|
+
private readonly database: DatabaseManager,
|
|
17
|
+
private readonly pubsubManager: PubSubManager,
|
|
18
18
|
private readonly libraryBackend: LibraryBackend,
|
|
19
|
-
private readonly instanceStateService: InstanceStateService,
|
|
20
|
-
private readonly random: RandomProvider,
|
|
21
19
|
private readonly logger: Logger,
|
|
22
20
|
) {}
|
|
23
21
|
|
|
24
22
|
/**
|
|
25
|
-
* Updates secrets for a specific instance
|
|
26
|
-
*
|
|
23
|
+
* Updates the secrets for a specific instance within an existing transaction.
|
|
24
|
+
* Only works with unit instances.
|
|
27
25
|
*
|
|
28
|
-
* @param
|
|
29
|
-
* @param
|
|
30
|
-
* @param
|
|
31
|
-
* @param
|
|
32
|
-
* @
|
|
26
|
+
* @param tx The database transaction to use.
|
|
27
|
+
* @param libraryId The ID of the library containing the component.
|
|
28
|
+
* @param stateId The ID of the instance state.
|
|
29
|
+
* @param secretValues The secrets to create or update. Missing secrets will be deleted.
|
|
30
|
+
* @returns The list of secret names that were updated or created.
|
|
33
31
|
*/
|
|
34
|
-
async
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const
|
|
32
|
+
async updateInstanceSecretsCore(
|
|
33
|
+
tx: ProjectTransaction,
|
|
34
|
+
libraryId: string,
|
|
35
|
+
stateId: string,
|
|
36
|
+
secretValues: Record<string, unknown>,
|
|
37
|
+
): Promise<string[]> {
|
|
38
|
+
// verify instance exists and is a unit
|
|
39
|
+
const state = await tx.instanceState.findUnique({
|
|
40
|
+
where: { id: stateId },
|
|
41
|
+
select: { kind: true, instanceId: true },
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
if (!state) {
|
|
45
|
+
throw new InstanceStateNotFoundError("", stateId)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (state.kind !== "unit") {
|
|
49
|
+
throw new InvalidInstanceKindError("", stateId, "unit", state.kind)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const library = await this.libraryBackend.loadLibrary(libraryId)
|
|
53
|
+
|
|
54
|
+
const [componentType] = parseInstanceId(state.instanceId)
|
|
55
|
+
const component = library.components[componentType]
|
|
42
56
|
|
|
43
|
-
const [type] = parseInstanceId(instanceId)
|
|
44
|
-
const component = library.components[type]
|
|
45
57
|
if (!component) {
|
|
46
|
-
throw new Error(`Component type ${
|
|
58
|
+
throw new Error(`Component type "${componentType}" not found in library "${libraryId}"`)
|
|
47
59
|
}
|
|
48
60
|
|
|
49
61
|
if (!isUnitModel(component)) {
|
|
50
|
-
throw new Error(`Component type ${
|
|
62
|
+
throw new Error(`Component type "${componentType}" is not a unit model`)
|
|
51
63
|
}
|
|
52
64
|
|
|
53
|
-
//
|
|
54
|
-
for (const secretName of Object.
|
|
55
|
-
|
|
56
|
-
|
|
65
|
+
// upsert provided secrets
|
|
66
|
+
for (const [secretName, value] of Object.entries(secretValues)) {
|
|
67
|
+
const componentSecret = component.secrets[secretName]
|
|
68
|
+
if (!componentSecret) {
|
|
69
|
+
throw new Error(`Secret "${secretName}" not defined in component "${componentType}"`)
|
|
57
70
|
}
|
|
58
|
-
}
|
|
59
71
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
72
|
+
const meta: CommonObjectMeta = {
|
|
73
|
+
...componentSecret.meta,
|
|
74
|
+
|
|
75
|
+
// fallback to component icon if secret icon is not defined
|
|
76
|
+
icon: componentSecret.meta.icon || component.meta.icon,
|
|
77
|
+
iconColor: componentSecret.meta.iconColor || component.meta.iconColor,
|
|
64
78
|
}
|
|
65
|
-
}
|
|
66
79
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
// process changed secrets
|
|
75
|
-
for (const [secretName, value] of Object.entries(changedSecretValues)) {
|
|
76
|
-
const descriptor: SecretDescriptor = { type: "instance", instanceId, secretName }
|
|
77
|
-
const indexKey = formatSecretDescriptor(descriptor)
|
|
78
|
-
|
|
79
|
-
// check if secret already exists
|
|
80
|
-
const existingSecret = await indexRepo.get(indexKey)
|
|
81
|
-
|
|
82
|
-
// create or update secret info
|
|
83
|
-
const secret: Secret = {
|
|
84
|
-
id: existingSecret?.id ?? this.random.uuidv7(),
|
|
85
|
-
descriptor: descriptor,
|
|
86
|
-
meta: {
|
|
87
|
-
...existingSecret?.meta,
|
|
88
|
-
...component.secrets[secretName].meta,
|
|
89
|
-
icon: component.secrets[secretName].meta.icon ?? component.meta.icon,
|
|
80
|
+
await tx.secret.upsert({
|
|
81
|
+
where: {
|
|
82
|
+
stateId_name: {
|
|
83
|
+
stateId,
|
|
84
|
+
name: secretName,
|
|
85
|
+
},
|
|
90
86
|
},
|
|
91
|
-
|
|
87
|
+
update: {
|
|
88
|
+
meta,
|
|
89
|
+
content: value,
|
|
90
|
+
},
|
|
91
|
+
create: {
|
|
92
|
+
stateId,
|
|
93
|
+
name: secretName,
|
|
94
|
+
meta,
|
|
95
|
+
content: value,
|
|
96
|
+
},
|
|
97
|
+
})
|
|
98
|
+
}
|
|
92
99
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
100
|
+
// delete secrets that are no longer provided
|
|
101
|
+
const providedSecretNames = Object.keys(secretValues)
|
|
102
|
+
await tx.secret.deleteMany({
|
|
103
|
+
where: {
|
|
104
|
+
stateId,
|
|
105
|
+
name: { notIn: providedSecretNames },
|
|
106
|
+
},
|
|
107
|
+
})
|
|
96
108
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
109
|
+
return Object.keys(secretValues)
|
|
110
|
+
}
|
|
100
111
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
112
|
+
/**
|
|
113
|
+
* Updates secrets for a specific instance, handling both creation/updates and deletions.
|
|
114
|
+
* Only works with unit instances.
|
|
115
|
+
*
|
|
116
|
+
* @param projectId The project ID containing the instance.
|
|
117
|
+
* @param stateId The ID of the instance state.
|
|
118
|
+
* @param secretValues The secrets to create or update. Missing secrets will be deleted.
|
|
119
|
+
*/
|
|
120
|
+
async updateInstanceSecrets(
|
|
121
|
+
projectId: string,
|
|
122
|
+
stateId: string,
|
|
123
|
+
secretValues: Record<string, unknown>,
|
|
124
|
+
): Promise<void> {
|
|
125
|
+
const database = await this.database.forProject(projectId)
|
|
126
|
+
|
|
127
|
+
const project = await this.database.backend.project.findUnique({
|
|
128
|
+
where: { id: projectId },
|
|
129
|
+
select: { libraryId: true },
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
if (!project) {
|
|
133
|
+
throw new ProjectNotFoundError(projectId)
|
|
113
134
|
}
|
|
114
135
|
|
|
115
|
-
|
|
116
|
-
|
|
136
|
+
const statePatch = await database.$transaction(async tx => {
|
|
137
|
+
await this.updateInstanceSecretsCore(tx, project.libraryId, stateId, secretValues)
|
|
117
138
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
139
|
+
// invalidate instance state
|
|
140
|
+
const state = await tx.instanceState.update({
|
|
141
|
+
where: { id: stateId },
|
|
142
|
+
data: { inputHashNonce: randomBytes(4).readInt32LE() },
|
|
143
|
+
select: { inputHashNonce: true },
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
return { ...state, secretNames: Object.keys(secretValues) }
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
this.pubsubManager.publish(["instance-state", projectId], {
|
|
150
|
+
type: "patched",
|
|
151
|
+
stateId,
|
|
152
|
+
patch: statePatch,
|
|
153
|
+
})
|
|
126
154
|
|
|
127
155
|
this.logger.info(
|
|
128
156
|
{
|
|
129
|
-
projectId
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
deletedCount: deletedSecretNames.length,
|
|
157
|
+
projectId,
|
|
158
|
+
stateId,
|
|
159
|
+
secretCount: Object.keys(secretValues).length,
|
|
133
160
|
},
|
|
134
|
-
|
|
135
|
-
instanceId,
|
|
161
|
+
"updated instance secrets",
|
|
136
162
|
)
|
|
137
163
|
}
|
|
138
164
|
|
|
139
165
|
/**
|
|
140
166
|
* Gets the values of all secrets for a specific instance.
|
|
167
|
+
* Only works with unit instances.
|
|
141
168
|
*
|
|
142
|
-
* @param
|
|
143
|
-
* @param
|
|
169
|
+
* @param projectId The project ID containing the instance.
|
|
170
|
+
* @param stateId The ID of the instance state.
|
|
144
171
|
* @returns A record of secret key-value pairs.
|
|
145
172
|
*/
|
|
146
173
|
async getInstanceSecretValues(
|
|
147
|
-
|
|
148
|
-
|
|
174
|
+
projectId: string,
|
|
175
|
+
stateId: string,
|
|
149
176
|
): Promise<Record<string, unknown>> {
|
|
150
|
-
const
|
|
151
|
-
project,
|
|
152
|
-
instanceId,
|
|
153
|
-
)
|
|
177
|
+
const database = await this.database.forProject(projectId)
|
|
154
178
|
|
|
155
|
-
//
|
|
156
|
-
const
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
continue
|
|
161
|
-
}
|
|
179
|
+
// verify instance exists and is a unit
|
|
180
|
+
const state = await database.instanceState.findUnique({
|
|
181
|
+
where: { id: stateId },
|
|
182
|
+
select: { kind: true },
|
|
183
|
+
})
|
|
162
184
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
values[descriptor] = content
|
|
166
|
-
}
|
|
185
|
+
if (!state) {
|
|
186
|
+
throw new InstanceStateNotFoundError(projectId, stateId)
|
|
167
187
|
}
|
|
168
188
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* Gets the secrets for a specific instance, including metadata.
|
|
174
|
-
* Will create missing secrets with empty values.
|
|
175
|
-
*
|
|
176
|
-
* @param project The project to which the instance belongs.
|
|
177
|
-
* @param instanceId The instance ID.
|
|
178
|
-
* @return A record of secret key-value pairs with metadata.
|
|
179
|
-
*/
|
|
180
|
-
async getUnitSecrets(
|
|
181
|
-
project: Project,
|
|
182
|
-
instanceId: string,
|
|
183
|
-
): Promise<Record<string, UnitSecretModel>> {
|
|
184
|
-
const { descriptors, component, secrets, secretContentMap } = await this.getInstanceSecretData(
|
|
185
|
-
project,
|
|
186
|
-
instanceId,
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
const missingDescriptors: SecretDescriptor[] = []
|
|
190
|
-
const result: Record<string, UnitSecretModel> = {}
|
|
191
|
-
|
|
192
|
-
for (const descriptor of descriptors) {
|
|
193
|
-
const secret = secrets[formatSecretDescriptor(descriptor)]
|
|
194
|
-
|
|
195
|
-
if (secret) {
|
|
196
|
-
result[descriptor.secretName] = {
|
|
197
|
-
[HighstateSignature.Secret]: true,
|
|
198
|
-
id: secret.id,
|
|
199
|
-
value: secretContentMap[secret.id],
|
|
200
|
-
}
|
|
201
|
-
} else {
|
|
202
|
-
missingDescriptors.push(descriptor)
|
|
203
|
-
}
|
|
189
|
+
if (state.kind !== "unit") {
|
|
190
|
+
throw new InvalidInstanceKindError(projectId, stateId, "unit", state.kind)
|
|
204
191
|
}
|
|
205
192
|
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
meta: {
|
|
213
|
-
...component.secrets[descriptor.secretName].meta,
|
|
214
|
-
icon: component.secrets[descriptor.secretName].meta.icon ?? component.meta.icon,
|
|
215
|
-
},
|
|
216
|
-
descriptor,
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const rawDescriptor = formatSecretDescriptor(descriptor)
|
|
220
|
-
|
|
221
|
-
await this.stateManager.getSecretRepository(project.id).putItem(secret, batch)
|
|
222
|
-
await this.stateManager.getSecretContentRepository(project.id).put(rawDescriptor, null, batch)
|
|
193
|
+
const secrets = await database.secret.findMany({
|
|
194
|
+
where: {
|
|
195
|
+
stateId,
|
|
196
|
+
name: { not: null },
|
|
197
|
+
},
|
|
198
|
+
})
|
|
223
199
|
|
|
224
|
-
|
|
225
|
-
.getSecretIndexRepository(project.id)
|
|
226
|
-
.indexRepository.put(rawDescriptor, secret.id, batch)
|
|
200
|
+
const values: Record<string, unknown> = {}
|
|
227
201
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
value: null,
|
|
202
|
+
for (const secret of secrets) {
|
|
203
|
+
if (secret.name) {
|
|
204
|
+
values[secret.name] = secret.content
|
|
232
205
|
}
|
|
233
206
|
}
|
|
234
207
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
return result
|
|
208
|
+
return values
|
|
238
209
|
}
|
|
239
210
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
if (!isUnitModel(component)) {
|
|
250
|
-
throw new Error(`Component type ${type} is not a unit model`)
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
const descriptors = Object.keys(component.secrets).map(secretName => ({
|
|
254
|
-
type: "instance" as const,
|
|
255
|
-
instanceId,
|
|
256
|
-
secretName,
|
|
257
|
-
}))
|
|
258
|
-
|
|
259
|
-
const indexKeys = descriptors.map(formatSecretDescriptor)
|
|
211
|
+
/**
|
|
212
|
+
* Gets or creates the Pulumi password secret for the given project.
|
|
213
|
+
* Uses the new direct systemName field approach.
|
|
214
|
+
*
|
|
215
|
+
* @param projectId The ID of the project for which to get or create the Pulumi password.
|
|
216
|
+
* @returns The Pulumi password.
|
|
217
|
+
*/
|
|
218
|
+
async getPulumiPassword(projectId: string): Promise<string> {
|
|
219
|
+
const database = await this.database.forProject(projectId)
|
|
260
220
|
|
|
261
|
-
|
|
262
|
-
.
|
|
263
|
-
|
|
221
|
+
return await database.$transaction(async tx => {
|
|
222
|
+
const existingSecret = await tx.secret.findUnique({
|
|
223
|
+
where: {
|
|
224
|
+
systemName: SystemSecretNames.PulumiPassword,
|
|
225
|
+
},
|
|
226
|
+
})
|
|
264
227
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
228
|
+
if (existingSecret) {
|
|
229
|
+
return existingSecret.content as string
|
|
230
|
+
}
|
|
268
231
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
.
|
|
232
|
+
const newPassword = randomBytes(32).toString("hex")
|
|
233
|
+
|
|
234
|
+
await tx.secret.create({
|
|
235
|
+
data: {
|
|
236
|
+
systemName: SystemSecretNames.PulumiPassword,
|
|
237
|
+
meta: {
|
|
238
|
+
title: "Pulumi Password",
|
|
239
|
+
description: "The password used to encrypt the Pulumi state.",
|
|
240
|
+
icon: "devicon:pulumi",
|
|
241
|
+
},
|
|
242
|
+
content: newPassword,
|
|
243
|
+
},
|
|
244
|
+
})
|
|
272
245
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
component,
|
|
277
|
-
secrets,
|
|
278
|
-
secretContentMap,
|
|
279
|
-
}
|
|
246
|
+
this.logger.info({ projectId }, "created new Pulumi password")
|
|
247
|
+
return newPassword
|
|
248
|
+
})
|
|
280
249
|
}
|
|
281
250
|
}
|