1import * as GCP from "@/GCP";
2import * as Output from "@/Output";
3import * as Test from "@/Test/Alchemy";
4import * as networksecurity from "@distilled.cloud/gcp/networksecurity_v1";
5import { expect } from "alchemy-test";
6import * as Effect from "effect/Effect";
7import { MinimumLogLevel } from "effect/References";
8import * as Schedule from "effect/Schedule";
9import { GcpEnvironment } from "@/GCP/Environment";
10
11const { test } = Test.make({ providers: GCP.providers() });
12
13const logLevel = Effect.provideService(
14 MinimumLogLevel,
15 process.env.DEBUG ? "Debug" : "Info",
16);
17
18const runLifecycle = !process.env.FAST;
19
20const waitUntilGone = (name: string) =>
21 networksecurity.getProjectsLocationsTlsInspectionPolicies({ name }).pipe(
22 Effect.as("found" as const),
23 Effect.catchTag("NotFound", () => Effect.succeed("gone" as const)),
24 Effect.repeat({
25 schedule: Schedule.spaced("1 second"),
26 until: (status) => status === "gone",
27 times: 10,
28 }),
29 );
30
31test.provider(
32 "getProjectsLocationsTlsInspectionPolicies on a missing policy fails with a typed tag",
33 (stack) =>
34 Effect.gen(function* () {
35 yield* stack.destroy();
36
37 const { project } = yield* GcpEnvironment.current;
38 const error = yield* Effect.flip(
39 networksecurity.getProjectsLocationsTlsInspectionPolicies({
40 name: `projects/${project}/locations/us-central1/tlsInspectionPolicies/alchemy-missing`,
41 }),
42 );
43 expect(error._tag).toEqual("NotFound");
44
45 yield* stack.destroy();
46 }).pipe(logLevel),
47 {
48 tags: ["provider:gcp", "provider:gcp:networksecurity", "live"],
49 timeout: 90_000,
50 },
51);
52
53test.provider.skipIf(!runLifecycle)(
54 "create, update, and delete a tls inspection policy",
55 (stack) =>
56 Effect.gen(function* () {
57 yield* stack.destroy();
58
59 const created = yield* stack.deploy(
60 Effect.gen(function* () {
61 const pool = yield* GCP.PrivateCA.CaPool("InspectPool", {
62 location: "us-central1",
63 tier: "DEVOPS",
64 labels: { env: "test" },
65 });
66 const ca = yield* GCP.PrivateCA.CertificateAuthority("InspectRoot", {
67 caPool: pool.name,
68 location: "us-central1",
69 type: "SELF_SIGNED",
70 desiredState: "ENABLED",
71 labels: { env: "test" },
72 });
73 return yield* GCP.NetworkSecurity.TlsInspectionPolicy("Inspect", {
74 location: "us-central1",
75 caPool: pool.name,
76 description: Output.interpolate`inspect a ${ca.certificateAuthorityId}`,
77 excludePublicCaSet: true,
78 });
79 }),
80 );
81
82 expect(created.name).toContain("/tlsInspectionPolicies/");
83 expect(created.name).toContain("/locations/us-central1/");
84 expect(created.tlsInspectionPolicyId).toEqual(expect.any(String));
85 expect(created.location).toEqual("us-central1");
86 expect(created.description).toContain("inspect a");
87 expect(created.caPool).toContain("/caPools/");
88 expect(created.excludePublicCaSet).toEqual(true);
89 expect(created.createTime).toEqual(expect.any(String));
90
91 const fetched =
92 yield* networksecurity.getProjectsLocationsTlsInspectionPolicies({
93 name: created.name,
94 });
95 expect(fetched.name).toEqual(created.name);
96 expect(fetched.caPool).toEqual(created.caPool);
97 expect(fetched.excludePublicCaSet).toEqual(true);
98 expect(fetched.description ?? "").toContain("[alchemy ");
99 expect(fetched.description ?? "").toContain("inspect a");
100
101 const updated = yield* stack.deploy(
102 Effect.gen(function* () {
103 const pool = yield* GCP.PrivateCA.CaPool("InspectPool", {
104 location: "us-central1",
105 caPoolId: created.caPool?.split("/").pop(),
106 tier: "DEVOPS",
107 labels: { env: "test" },
108 });
109 const ca = yield* GCP.PrivateCA.CertificateAuthority("InspectRoot", {
110 caPool: pool.name,
111 location: "us-central1",
112 type: "SELF_SIGNED",
113 desiredState: "ENABLED",
114 labels: { env: "test" },
115 });
116 return yield* GCP.NetworkSecurity.TlsInspectionPolicy("Inspect", {
117 tlsInspectionPolicyId: created.tlsInspectionPolicyId,
118 location: "us-central1",
119 caPool: pool.name,
120 description: Output.interpolate`inspect b ${ca.certificateAuthorityId}`,
121 excludePublicCaSet: true,
122 minTlsVersion: "TLS_1_2",
123 });
124 }),
125 );
126
127 expect(updated.name).toEqual(created.name);
128 expect(updated.description).toContain("inspect b");
129 expect(updated.minTlsVersion).toEqual("TLS_1_2");
130
131 const refetched =
132 yield* networksecurity.getProjectsLocationsTlsInspectionPolicies({
133 name: created.name,
134 });
135 expect(refetched.description ?? "").toContain("inspect b");
136 expect(refetched.minTlsVersion).toEqual("TLS_1_2");
137
138 yield* stack.destroy();
139
140 const gone = yield* waitUntilGone(created.name);
141 expect(gone).toEqual("gone");
142 }).pipe(logLevel),
143 {
144 tags: ["provider:gcp", "provider:gcp:networksecurity", "live"],
145 timeout: 180_000,
146 },
147);