| ... | ... | @@ -40,7 +40,6 @@ import * as Path from "effect/Path"; |
| 40 | 40 | import * as PubSub from "effect/PubSub"; |
| 41 | 41 | import * as Ref from "effect/Ref"; |
| 42 | 42 | import * as Schema from "effect/Schema"; |
| 43 | | import * as SchemaIssue from "effect/SchemaIssue"; |
| 44 | 43 | import * as Semaphore from "effect/Semaphore"; |
| 45 | 44 | import * as Scope from "effect/Scope"; |
| 46 | 45 | import * as Stream from "effect/Stream"; |
| ... | ... | @@ -67,7 +66,7 @@ const normalizeServerSettings = ( |
| 67 | 66 | (cause) => |
| 68 | 67 | new ServerSettingsError({ |
| 69 | 68 | settingsPath: "<memory>", |
| 70 | | detail: `failed to normalize server settings: ${SchemaIssue.makeFormatterDefault()(cause.issue)}`, |
| 69 | operation: "normalize", |
| 71 | 70 | cause, |
| 72 | 71 | }), |
| 73 | 72 | ), |
| ... | ... | @@ -277,7 +276,7 @@ const make = Effect.gen(function* () { |
| 277 | 276 | (cause) => |
| 278 | 277 | new ServerSettingsError({ |
| 279 | 278 | settingsPath, |
| 280 | | detail: "failed to check settings file existence", |
| 279 | operation: "check-exists", |
| 281 | 280 | cause, |
| 282 | 281 | }), |
| 283 | 282 | ), |
| ... | ... | @@ -288,7 +287,7 @@ const make = Effect.gen(function* () { |
| 288 | 287 | (cause) => |
| 289 | 288 | new ServerSettingsError({ |
| 290 | 289 | settingsPath, |
| 291 | | detail: "failed to read settings file", |
| 290 | operation: "read-file", |
| 292 | 291 | cause, |
| 293 | 292 | }), |
| 294 | 293 | ), |
| ... | ... | @@ -305,6 +304,7 @@ const make = Effect.gen(function* () { |
| 305 | 304 | yield* Effect.logWarning("failed to parse settings.json, using defaults", { |
| 306 | 305 | path: settingsPath, |
| 307 | 306 | issues: Cause.pretty(decoded.cause), |
| 307 | cause: decoded.cause, |
| 308 | 308 | }); |
| 309 | 309 | return DEFAULT_SERVER_SETTINGS; |
| 310 | 310 | } |
| ... | ... | @@ -318,13 +318,6 @@ const make = Effect.gen(function* () { |
| 318 | 318 | |
| 319 | 319 | const getSettingsFromCache = Cache.get(settingsCache, cacheKey); |
| 320 | 320 | |
| 321 | | const toSettingsError = (detail: string, cause: unknown) => |
| 322 | | new ServerSettingsError({ |
| 323 | | settingsPath, |
| 324 | | detail, |
| 325 | | cause, |
| 326 | | }); |
| 327 | | |
| 328 | 321 | const materializeProviderEnvironmentSecrets = ( |
| 329 | 322 | settings: ServerSettings, |
| 330 | 323 | ): Effect.Effect<ServerSettings, ServerSettingsError> => |
| ... | ... | @@ -343,11 +336,15 @@ const make = Effect.gen(function* () { |
| 343 | 336 | const secret = yield* secretStore |
| 344 | 337 | .get(providerEnvironmentSecretName({ instanceId, name: variable.name })) |
| 345 | 338 | .pipe( |
| 346 | | Effect.mapError((cause) => |
| 347 | | toSettingsError( |
| 348 | | `failed to read sensitive environment variable ${variable.name}`, |
| 349 | | cause, |
| 350 | | ), |
| 339 | Effect.mapError( |
| 340 | (cause) => |
| 341 | new ServerSettingsError({ |
| 342 | settingsPath, |
| 343 | operation: "read-secret", |
| 344 | providerInstanceId: instanceId, |
| 345 | environmentVariable: variable.name, |
| 346 | cause, |
| 347 | }), |
| 351 | 348 | ), |
| 352 | 349 | ); |
| 353 | 350 | environment.push({ |
| ... | ... | @@ -382,13 +379,18 @@ const make = Effect.gen(function* () { |
| 382 | 379 | for (const variable of instance.environment) { |
| 383 | 380 | const secretName = providerEnvironmentSecretName({ instanceId, name: variable.name }); |
| 384 | 381 | if (!variable.sensitive) { |
| 385 | | yield* secretStore |
| 386 | | .remove(secretName) |
| 387 | | .pipe( |
| 388 | | Effect.mapError((cause) => |
| 389 | | toSettingsError(`failed to remove environment secret ${variable.name}`, cause), |
| 390 | | ), |
| 391 | | ); |
| 382 | yield* secretStore.remove(secretName).pipe( |
| 383 | Effect.mapError( |
| 384 | (cause) => |
| 385 | new ServerSettingsError({ |
| 386 | settingsPath, |
| 387 | operation: "remove-secret", |
| 388 | providerInstanceId: instanceId, |
| 389 | environmentVariable: variable.name, |
| 390 | cause, |
| 391 | }), |
| 392 | ), |
| 393 | ); |
| 392 | 394 | environment.push(redactProviderEnvironmentVariable(variable)); |
| 393 | 395 | continue; |
| 394 | 396 | } |
| ... | ... | @@ -396,22 +398,32 @@ const make = Effect.gen(function* () { |
| 396 | 398 | nextSecretKeys.add(secretName); |
| 397 | 399 | if (!variable.valueRedacted) { |
| 398 | 400 | if (variable.value.length > 0) { |
| 399 | | yield* secretStore |
| 400 | | .set(secretName, textEncoder.encode(variable.value)) |
| 401 | | .pipe( |
| 402 | | Effect.mapError((cause) => |
| 403 | | toSettingsError(`failed to persist environment secret ${variable.name}`, cause), |
| 404 | | ), |
| 405 | | ); |
| 401 | yield* secretStore.set(secretName, textEncoder.encode(variable.value)).pipe( |
| 402 | Effect.mapError( |
| 403 | (cause) => |
| 404 | new ServerSettingsError({ |
| 405 | settingsPath, |
| 406 | operation: "write-secret", |
| 407 | providerInstanceId: instanceId, |
| 408 | environmentVariable: variable.name, |
| 409 | cause, |
| 410 | }), |
| 411 | ), |
| 412 | ); |
| 406 | 413 | environment.push({ ...variable, value: "", valueRedacted: true }); |
| 407 | 414 | } else { |
| 408 | | yield* secretStore |
| 409 | | .remove(secretName) |
| 410 | | .pipe( |
| 411 | | Effect.mapError((cause) => |
| 412 | | toSettingsError(`failed to remove environment secret ${variable.name}`, cause), |
| 413 | | ), |
| 414 | | ); |
| 415 | yield* secretStore.remove(secretName).pipe( |
| 416 | Effect.mapError( |
| 417 | (cause) => |
| 418 | new ServerSettingsError({ |
| 419 | settingsPath, |
| 420 | operation: "remove-secret", |
| 421 | providerInstanceId: instanceId, |
| 422 | environmentVariable: variable.name, |
| 423 | cause, |
| 424 | }), |
| 425 | ), |
| 426 | ); |
| 415 | 427 | const { valueRedacted: _omit, ...rest } = variable; |
| 416 | 428 | environment.push(rest); |
| 417 | 429 | } |
| ... | ... | @@ -431,16 +443,18 @@ const make = Effect.gen(function* () { |
| 431 | 443 | if (!variable.sensitive) continue; |
| 432 | 444 | const secretName = providerEnvironmentSecretName({ instanceId, name: variable.name }); |
| 433 | 445 | if (nextSecretKeys.has(secretName)) continue; |
| 434 | | yield* secretStore |
| 435 | | .remove(secretName) |
| 436 | | .pipe( |
| 437 | | Effect.mapError((cause) => |
| 438 | | toSettingsError( |
| 439 | | `failed to remove stale environment secret ${variable.name}`, |
| 446 | yield* secretStore.remove(secretName).pipe( |
| 447 | Effect.mapError( |
| 448 | (cause) => |
| 449 | new ServerSettingsError({ |
| 450 | settingsPath, |
| 451 | operation: "remove-stale-secret", |
| 452 | providerInstanceId: instanceId, |
| 453 | environmentVariable: variable.name, |
| 440 | 454 | cause, |
| 441 | | ), |
| 442 | | ), |
| 443 | | ); |
| 455 | }), |
| 456 | ), |
| 457 | ); |
| 444 | 458 | } |
| 445 | 459 | } |
| 446 | 460 | |
| ... | ... | @@ -468,7 +482,7 @@ const make = Effect.gen(function* () { |
| 468 | 482 | (cause) => |
| 469 | 483 | new ServerSettingsError({ |
| 470 | 484 | settingsPath, |
| 471 | | detail: "failed to write settings file", |
| 485 | operation: "write-file", |
| 472 | 486 | cause, |
| 473 | 487 | }), |
| 474 | 488 | ), |
| ... | ... | @@ -492,7 +506,7 @@ const make = Effect.gen(function* () { |
| 492 | 506 | (cause) => |
| 493 | 507 | new ServerSettingsError({ |
| 494 | 508 | settingsPath, |
| 495 | | detail: "failed to prepare settings directory", |
| 509 | operation: "prepare-directory", |
| 496 | 510 | cause, |
| 497 | 511 | }), |
| 498 | 512 | ), |
| ... | ... | @@ -571,7 +585,10 @@ const make = Effect.gen(function* () { |
| 571 | 585 | materializeProviderEnvironmentSecrets(settings).pipe( |
| 572 | 586 | Effect.catch((error: ServerSettingsError) => |
| 573 | 587 | Effect.logWarning("failed to materialize provider environment secrets", { |
| 574 | | detail: error.detail, |
| 588 | operation: error.operation, |
| 589 | providerInstanceId: error.providerInstanceId, |
| 590 | environmentVariable: error.environmentVariable, |
| 591 | cause: error.cause, |
| 575 | 592 | }).pipe(Effect.as(settings)), |
| 576 | 593 | ), |
| 577 | 594 | ), |