1/**
2 * Resolve the Floci emulator's default VPC network (default-for-AZ subnets and
3 * the default security group) for suites that read subnet and security-group
4 * IDs from the environment.
5 */
6import * as Floci from "@alchemy.run/aws/Local/Floci";
7import * as Credentials from "@distilled.cloud/aws/Credentials";
8import * as EC2 from "@distilled.cloud/aws/ec2";
9import * as Endpoint from "@distilled.cloud/aws/Endpoint";
10import { Region } from "@distilled.cloud/aws/Region";
11import * as Config from "effect/Config";
12import * as Effect from "effect/Effect";
13import { FetchHttpClient } from "effect/http";
14import * as Layer from "effect/Layer";
15import * as Redacted from "effect/Redacted";
16
17export interface FlociDefaultNetwork {
18 readonly subnetIds: ReadonlyArray<string>;
19 readonly securityGroupIds: ReadonlyArray<string>;
20}
21
22export const resolveFlociDefaultNetwork = Effect.fn(function* (external: boolean) {
23 const region = yield* Config.String("AWS_REGION").pipe(Config.withDefault("us-east-1"));
24 return yield* Effect.gen(function* () {
25 yield* Floci.ensureFloci({ port: Floci.DEFAULT_FLOCI_PORT, external });
26 const vpcs = yield* EC2.describeVpcs({
27 Filters: [{ Name: "is-default", Values: ["true"] }],
28 });
29 const vpcId = vpcs.Vpcs?.[0]?.VpcId;
30 if (vpcId === undefined) {
31 return yield* Effect.fail(new Error("the emulator has no default VPC"));
32 }
33 const subnets = yield* EC2.describeSubnets({
34 Filters: [
35 { Name: "vpc-id", Values: [vpcId] },
36 { Name: "default-for-az", Values: ["true"] },
37 ],
38 });
39 const groups = yield* EC2.describeSecurityGroups({
40 Filters: [
41 { Name: "vpc-id", Values: [vpcId] },
42 { Name: "group-name", Values: ["default"] },
43 ],
44 });
45 const subnetIds = (subnets.Subnets ?? []).flatMap((subnet) =>
46 subnet.SubnetId === undefined ? [] : [subnet.SubnetId],
47 );
48 const securityGroupIds = (groups.SecurityGroups ?? []).flatMap((group) =>
49 group.GroupId === undefined ? [] : [group.GroupId],
50 );
51 if (subnetIds.length === 0 || securityGroupIds.length === 0) {
52 return yield* Effect.fail(new Error(`default VPC ${vpcId} has no default subnets or group`));
53 }
54 return { subnetIds, securityGroupIds } satisfies FlociDefaultNetwork;
55 }).pipe(
56 Effect.provide(
57 Layer.mergeAll(
58 // The emulator's own account; the caller's shell may hold no AWS
59 // credentials, or real ones that must never reach this lookup.
60 Layer.succeed(
61 Credentials.Credentials,
62 Effect.succeed({
63 accessKeyId: Redacted.make("test"),
64 secretAccessKey: Redacted.make("test"),
65 sessionToken: undefined,
66 region: region as never,
67 }),
68 ),
69 Layer.succeed(Region, Effect.succeed(region as never)),
70 Endpoint.of(`http://localhost:${Floci.DEFAULT_FLOCI_PORT}`),
71 FetchHttpClient.layer,
72 ),
73 ),
74 );
75});