1import * as GCP from "@/GCP";
2import * as Effect from "effect/Effect";
3import { serveProbes } from "../../bindingHost.ts";
4
5/** Cluster → config → workstation, on the project's `default` network. */
6export const Dev = Effect.gen(function* () {
7 const cluster = yield* GCP.Workstations.WorkstationCluster("Dev", {
8 location: "us-central1",
9 network: "default",
10 subnetwork: "default",
11 labels: { env: "test" },
12 });
13 const config = yield* GCP.Workstations.WorkstationClustersWorkstationConfig(
14 "Code",
15 {
16 workstationCluster: cluster.name,
17 host: {
18 gceInstance: {
19 machineType: "e2-standard-2",
20 poolSize: 0,
21 bootDiskSizeGb: 30,
22 },
23 },
24 labels: { env: "test" },
25 },
26 );
27 const workstation =
28 yield* GCP.Workstations.WorkstationClustersWorkstationConfigsWorkstation(
29 "Mine",
30 { workstationConfig: config.name, labels: { env: "test" } },
31 );
32 return { cluster, config, workstation };
33});
34
35/**
36 * Effect-native Cloud Run service exercising every Cloud Workstations
37 * binding as its own runtime service account. Deployed from
38 * {@link ../Bindings.test.ts}.
39 */
40export default class WorkstationsBindingsHost extends GCP.Function<WorkstationsBindingsHost>()(
41 "WorkstationsBindingsHost",
42 { main: import.meta.url, invokerIamDisabled: true },
43 Effect.gen(function* () {
44 const { cluster, config, workstation } = yield* Dev;
45 const getCluster = yield* GCP.Workstations.GetWorkstationCluster(cluster);
46 const getConfig = yield* GCP.Workstations.GetWorkstationConfig(config);
47 const getWorkstation = yield* GCP.Workstations.GetWorkstation(workstation);
48 const generateAccessToken =
49 yield* GCP.Workstations.GenerateAccessToken(workstation);
50 const start = yield* GCP.Workstations.StartWorkstation(workstation);
51 const stop = yield* GCP.Workstations.StopWorkstation(workstation);
52
53 return {
54 fetch: serveProbes({
55 getWorkstationCluster: getCluster().pipe(
56 Effect.map((live) => ({ name: live.name, network: live.network })),
57 ),
58 getWorkstationConfig: getConfig().pipe(
59 Effect.map((live) => ({
60 name: live.name,
61 machineType: live.host?.gceInstance?.machineType,
62 })),
63 ),
64 getWorkstation: getWorkstation().pipe(
65 Effect.map((live) => ({ name: live.name, state: live.state })),
66 ),
67 generateAccessToken: generateAccessToken({
68 body: { ttl: "600s" },
69 }).pipe(
70 Effect.map((token) => ({
71 hasToken: (token.accessToken ?? "").length > 0,
72 expireTime: token.expireTime,
73 })),
74 ),
75 startWorkstation: start().pipe(
76 Effect.map((operation) => ({ name: operation.name })),
77 ),
78 stopWorkstation: stop().pipe(
79 Effect.map((operation) => ({ name: operation.name })),
80 ),
81 }),
82 };
83 }).pipe(
84 Effect.provide(GCP.Workstations.GetWorkstationClusterHttp),
85 Effect.provide(GCP.Workstations.GetWorkstationConfigHttp),
86 Effect.provide(GCP.Workstations.GetWorkstationHttp),
87 Effect.provide(GCP.Workstations.GenerateAccessTokenHttp),
88 Effect.provide(GCP.Workstations.StartWorkstationHttp),
89 Effect.provide(GCP.Workstations.StopWorkstationHttp),
90 ),
91) {}