1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import * as compute from "@distilled.cloud/gcp/compute_v1";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import { MinimumLogLevel } from "effect/References";
7import * as Schedule from "effect/Schedule";
8
9const { test } = Test.make({ providers: GCP.providers() });
10
11const logLevel = Effect.provideService(
12 MinimumLogLevel,
13 process.env.DEBUG ? "Debug" : "Info",
14);
15
16const waitUntilGone = (project: string, sslPolicyName: string) =>
17 compute.getSslPolicies({ project, sslPolicy: sslPolicyName }).pipe(
18 Effect.as("found" as const),
19 Effect.catchTag("NotFound", () => Effect.succeed("gone" as const)),
20 Effect.repeat({
21 schedule: Schedule.spaced("1 second"),
22 until: (status) => status === "gone",
23 times: 10,
24 }),
25 );
26
27const CUSTOM_FEATURES = [
28 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
29 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
30];
31
32test.provider(
33 "create, update, and delete an ssl policy",
34 (stack) =>
35 Effect.gen(function* () {
36 yield* stack.destroy();
37
38 const created = yield* stack.deploy(
39 Effect.gen(function* () {
40 return yield* GCP.Compute.SslPolicy("FrontendTls", {
41 description: "frontend tls",
42 profile: "MODERN",
43 minTlsVersion: "TLS_1_2",
44 });
45 }),
46 );
47
48 expect(created.sslPolicyName).toEqual(expect.any(String));
49 expect(created.profile).toEqual("MODERN");
50 expect(created.minTlsVersion).toEqual("TLS_1_2");
51 expect(created.description).toEqual("frontend tls");
52 expect(created.enabledFeatures.length).toBeGreaterThan(0);
53 expect(created.selfLink).toEqual(expect.any(String));
54
55 const fetched = yield* compute.getSslPolicies({
56 project: created.project,
57 sslPolicy: created.sslPolicyName,
58 });
59 expect(fetched.name).toEqual(created.sslPolicyName);
60 expect(fetched.profile).toEqual("MODERN");
61 expect(fetched.minTlsVersion).toEqual("TLS_1_2");
62 expect(fetched.description).toContain("[alchemy ");
63 expect(fetched.description).toContain("frontend tls");
64
65 const listed = yield* compute.listSslPolicies({
66 project: created.project,
67 maxResults: 500,
68 });
69 expect(
70 (listed.items ?? []).some(
71 (policy) => policy.name === created.sslPolicyName,
72 ),
73 ).toEqual(true);
74
75 const updated = yield* stack.deploy(
76 Effect.gen(function* () {
77 return yield* GCP.Compute.SslPolicy("FrontendTls", {
78 sslPolicyName: created.sslPolicyName,
79 description: "strict tls",
80 profile: "RESTRICTED",
81 minTlsVersion: "TLS_1_2",
82 });
83 }),
84 );
85
86 expect(updated.sslPolicyName).toEqual(created.sslPolicyName);
87 expect(updated.profile).toEqual("RESTRICTED");
88 expect(updated.minTlsVersion).toEqual("TLS_1_2");
89 expect(updated.description).toEqual("strict tls");
90
91 const refetched = yield* compute.getSslPolicies({
92 project: updated.project,
93 sslPolicy: updated.sslPolicyName,
94 });
95 expect(refetched.profile).toEqual("RESTRICTED");
96 expect(refetched.minTlsVersion).toEqual("TLS_1_2");
97 expect(refetched.description).toContain("strict tls");
98
99 const customized = yield* stack.deploy(
100 Effect.gen(function* () {
101 return yield* GCP.Compute.SslPolicy("FrontendTls", {
102 sslPolicyName: created.sslPolicyName,
103 description: "custom ciphers",
104 profile: "CUSTOM",
105 minTlsVersion: "TLS_1_2",
106 customFeatures: CUSTOM_FEATURES,
107 });
108 }),
109 );
110
111 expect(customized.sslPolicyName).toEqual(created.sslPolicyName);
112 expect(customized.profile).toEqual("CUSTOM");
113 expect(customized.customFeatures.sort()).toEqual(
114 [...CUSTOM_FEATURES].sort(),
115 );
116 expect(customized.description).toEqual("custom ciphers");
117
118 const afterCustom = yield* compute.getSslPolicies({
119 project: customized.project,
120 sslPolicy: customized.sslPolicyName,
121 });
122 expect(afterCustom.profile).toEqual("CUSTOM");
123 expect([...(afterCustom.customFeatures ?? [])].sort()).toEqual(
124 [...CUSTOM_FEATURES].sort(),
125 );
126
127 yield* stack.destroy();
128
129 const gone = yield* waitUntilGone(created.project, created.sslPolicyName);
130 expect(gone).toEqual("gone");
131 }).pipe(logLevel),
132 { tags: ["provider:gcp", "provider:gcp:compute", "live"], timeout: 90_000 },
133);