1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import * as certificatemanager from "@distilled.cloud/gcp/certificatemanager_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 DOMAIN_A = "a.alchemy-cm.example.com";
17const DOMAIN_B = "b.alchemy-cm.example.com";
18
19const waitUntilGone = (name: string) =>
20 certificatemanager.getProjectsLocationsDnsAuthorizations({ name }).pipe(
21 Effect.as("found" as const),
22 Effect.catchTag("NotFound", () => Effect.succeed("gone" as const)),
23 Effect.repeat({
24 schedule: Schedule.spaced("1 second"),
25 until: (status) => status === "gone",
26 times: 10,
27 }),
28 );
29
30test.provider(
31 "create, update, and delete a dns authorization",
32 (stack) =>
33 Effect.gen(function* () {
34 yield* stack.destroy();
35
36 const created = yield* stack.deploy(
37 Effect.gen(function* () {
38 return yield* GCP.CertificateManager.DnsAuthorization("WwwAuth", {
39 location: "global",
40 description: "dns auth a",
41 domain: DOMAIN_A,
42 labels: { env: "test" },
43 });
44 }),
45 );
46
47 expect(created.name).toContain("/dnsAuthorizations/");
48 expect(created.dnsAuthorizationId).toEqual(expect.any(String));
49 expect(created.location).toEqual("global");
50 expect(created.domain).toEqual(DOMAIN_A);
51 expect(created.type).toEqual("FIXED_RECORD");
52 expect(created.description).toEqual("dns auth a");
53 expect(created.labels).toMatchObject({ env: "test" });
54 expect(created.dnsResourceRecordName).toEqual(expect.any(String));
55 expect(created.dnsResourceRecordType).toEqual("CNAME");
56 expect(created.dnsResourceRecordData).toEqual(expect.any(String));
57
58 const fetched =
59 yield* certificatemanager.getProjectsLocationsDnsAuthorizations({
60 name: created.name,
61 });
62 expect(fetched.name).toEqual(created.name);
63 expect(fetched.domain).toEqual(DOMAIN_A);
64 expect(fetched.description).toEqual("dns auth a");
65 expect(fetched.labels?.env).toEqual("test");
66 expect(fetched.dnsResourceRecord?.type).toEqual("CNAME");
67 expect(fetched.dnsResourceRecord?.data).toEqual(expect.any(String));
68 expect(
69 Object.keys(fetched.labels ?? {}).some((key) =>
70 key.startsWith("alchemy-"),
71 ),
72 ).toEqual(true);
73
74 const updated = yield* stack.deploy(
75 Effect.gen(function* () {
76 return yield* GCP.CertificateManager.DnsAuthorization("WwwAuth", {
77 dnsAuthorizationId: created.dnsAuthorizationId,
78 location: "global",
79 description: "dns auth b",
80 domain: DOMAIN_A,
81 labels: { env: "prod", role: "auth" },
82 });
83 }),
84 );
85
86 expect(updated.name).toEqual(created.name);
87 expect(updated.domain).toEqual(DOMAIN_A);
88 expect(updated.description).toEqual("dns auth b");
89 expect(updated.labels).toMatchObject({ env: "prod", role: "auth" });
90 expect(updated.dnsResourceRecordData).toEqual(
91 created.dnsResourceRecordData,
92 );
93
94 const refetched =
95 yield* certificatemanager.getProjectsLocationsDnsAuthorizations({
96 name: created.name,
97 });
98 expect(refetched.description).toEqual("dns auth b");
99 expect(refetched.labels?.env).toEqual("prod");
100 expect(refetched.labels?.role).toEqual("auth");
101 expect(refetched.domain).toEqual(DOMAIN_A);
102
103 const replaced = yield* stack.deploy(
104 Effect.gen(function* () {
105 return yield* GCP.CertificateManager.DnsAuthorization("WwwAuth", {
106 dnsAuthorizationId: created.dnsAuthorizationId,
107 location: "global",
108 description: "dns auth c",
109 domain: DOMAIN_B,
110 labels: { env: "prod", role: "auth" },
111 });
112 }),
113 );
114
115 expect(replaced.dnsAuthorizationId).toEqual(created.dnsAuthorizationId);
116 expect(replaced.name).toEqual(created.name);
117 expect(replaced.domain).toEqual(DOMAIN_B);
118 expect(replaced.description).toEqual("dns auth c");
119 expect(replaced.dnsResourceRecordName).toEqual(expect.any(String));
120 expect(replaced.dnsResourceRecordData).toEqual(expect.any(String));
121
122 const replacedFetched =
123 yield* certificatemanager.getProjectsLocationsDnsAuthorizations({
124 name: created.name,
125 });
126 expect(replacedFetched.domain).toEqual(DOMAIN_B);
127 expect(replacedFetched.description).toEqual("dns auth c");
128
129 yield* stack.destroy();
130
131 const gone = yield* waitUntilGone(created.name);
132 expect(gone).toEqual("gone");
133 }).pipe(logLevel),
134 {
135 tags: ["provider:gcp", "provider:gcp:certificatemanager", "live"],
136 timeout: 90_000,
137 },
138);