1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import * as binaryauthorization from "@distilled.cloud/gcp/binaryauthorization_v1";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import * as Schedule from "effect/Schedule";
7import { logLevel, currentProject } from "./common.ts";
8
9const { test } = Test.make({ providers: GCP.providers() });
10
11const waitUntilGone = (name: string) =>
12 binaryauthorization.getProjectsPlatformsPolicies({ name }).pipe(
13 Effect.as("found" as const),
14 Effect.catchTag("NotFound", () => Effect.succeed("gone" as const)),
15 Effect.repeat({
16 schedule: Schedule.spaced("1 second"),
17 until: (status) => status === "gone",
18 times: 10,
19 }),
20 );
21
22test.provider(
23 "getProjectsPlatformsPolicies on a missing policy fails with a typed tag",
24 (stack) =>
25 Effect.gen(function* () {
26 const project = yield* currentProject;
27 yield* stack.destroy();
28
29 const error = yield* Effect.flip(
30 binaryauthorization.getProjectsPlatformsPolicies({
31 name: `projects/${project}/platforms/gke/policies/alchemy-missing-policy`,
32 }),
33 );
34 expect(error._tag).toEqual("NotFound");
35
36 yield* stack.destroy();
37 }).pipe(logLevel),
38 {
39 tags: ["provider:gcp", "provider:gcp:binaryauthorization", "live"],
40 timeout: 90_000,
41 },
42);
43
44test.provider(
45 "create, update, and delete a platform policy",
46 (stack) =>
47 Effect.gen(function* () {
48 yield* stack.destroy();
49
50 const created = yield* stack.deploy(
51 Effect.gen(function* () {
52 return yield* GCP.BinaryAuthorization.PlatformsPolicy("Default", {
53 description: "initial",
54 gkePolicy: {
55 imageAllowlist: {
56 allowPattern: ["gcr.io/google-containers/*"],
57 },
58 },
59 });
60 }),
61 );
62
63 expect(created.name).toContain("/platforms/gke/policies/");
64 expect(created.policyId).toEqual(expect.any(String));
65 expect(created.platform).toEqual("gke");
66 expect(created.description).toEqual("initial");
67 expect(created.gkePolicy?.imageAllowlist?.allowPattern).toContain(
68 "gcr.io/google-containers/*",
69 );
70
71 const fetched = yield* binaryauthorization.getProjectsPlatformsPolicies({
72 name: created.name,
73 });
74 expect(fetched.name).toEqual(created.name);
75 expect(fetched.description).toContain("[alchemy ");
76 expect(fetched.description).toContain("initial");
77
78 const updated = yield* stack.deploy(
79 Effect.gen(function* () {
80 return yield* GCP.BinaryAuthorization.PlatformsPolicy("Default", {
81 policyId: created.policyId,
82 platform: "gke",
83 description: "updated",
84 gkePolicy: {
85 imageAllowlist: {
86 allowPattern: [
87 "gcr.io/google-containers/*",
88 "gcr.io/google-containers/**",
89 ],
90 },
91 },
92 });
93 }),
94 );
95
96 expect(updated.name).toEqual(created.name);
97 expect(updated.description).toEqual("updated");
98 expect(updated.gkePolicy?.imageAllowlist?.allowPattern).toEqual([
99 "gcr.io/google-containers/*",
100 "gcr.io/google-containers/**",
101 ]);
102
103 const fetchedUpdate =
104 yield* binaryauthorization.getProjectsPlatformsPolicies({
105 name: updated.name,
106 });
107 expect(fetchedUpdate.description).toContain("updated");
108
109 yield* stack.destroy();
110 const gone = yield* waitUntilGone(created.name);
111 expect(gone).toEqual("gone");
112 }).pipe(logLevel),
113 {
114 tags: ["provider:gcp", "provider:gcp:binaryauthorization", "live"],
115 timeout: 90_000,
116 },
117);