1import * as GCP from "@/GCP";
2import * as Test from "@/Test/Alchemy";
3import * as cnr from "@distilled.cloud/gcp/cloudnumberregistry_v1alpha";
4import { expect } from "alchemy-test";
5import * as Effect from "effect/Effect";
6import {
7 location,
8 logLevel,
9 currentProject,
10 entitled,
11 runLifecycle,
12 waitUntilGone,
13} from "./common.ts";
14
15const { test } = Test.make({ providers: GCP.providers() });
16
17const CIDR = "10.250.0.0/22";
18
19test.provider.skipIf(!entitled)(
20 "getProjectsLocationsCustomRanges on a missing range fails with a typed tag",
21 (stack) =>
22 Effect.gen(function* () {
23 const project = yield* currentProject;
24
25 yield* stack.destroy();
26
27 const error = yield* Effect.flip(
28 cnr.getProjectsLocationsCustomRanges({
29 name: `projects/${project}/locations/${location}/customRanges/alchemy-missing-range`,
30 }),
31 );
32 expect(error._tag).toEqual("NotFound");
33
34 yield* stack.destroy();
35 }).pipe(logLevel),
36 {
37 tags: ["provider:gcp", "provider:gcp:cloudnumberregistry", "live"],
38 timeout: 90_000,
39 },
40);
41
42test.provider.skipIf(!runLifecycle)(
43 "create, update, and delete a custom range",
44 (stack) =>
45 Effect.gen(function* () {
46 const project = yield* currentProject;
47
48 yield* stack.destroy();
49
50 const created = yield* stack.deploy(
51 Effect.gen(function* () {
52 const book = yield* GCP.CloudNumberRegistry.RegistryBook(
53 "Inventory",
54 {
55 location,
56 labels: { env: "test" },
57 },
58 );
59 const realm = yield* GCP.CloudNumberRegistry.Realm("Private", {
60 location,
61 registryBook: book.name,
62 trafficType: "PRIVATE",
63 managementType: "USER",
64 ipVersion: "IPV4",
65 labels: { env: "test" },
66 });
67 const range = yield* GCP.CloudNumberRegistry.CustomRange("OnPrem", {
68 location,
69 realm: realm.name,
70 ipv4CidrRange: CIDR,
71 description: "alchemy-test-range",
72 labels: { env: "test" },
73 });
74 return { book, realm, range };
75 }),
76 );
77
78 expect(created.range.customRangeId).toEqual(expect.any(String));
79 expect(created.range.name).toEqual(
80 `projects/${project}/locations/${location}/customRanges/${created.range.customRangeId}`,
81 );
82 expect(created.range.ipv4CidrRange).toEqual(CIDR);
83 expect(created.range.description).toEqual("alchemy-test-range");
84 expect(created.range.labels).toMatchObject({ env: "test" });
85
86 const fetched = yield* cnr.getProjectsLocationsCustomRanges({
87 name: created.range.name,
88 });
89 expect(fetched.name).toEqual(created.range.name);
90 expect(fetched.ipv4CidrRange).toEqual(CIDR);
91 expect(fetched.labels?.env).toEqual("test");
92 expect(
93 Object.keys(fetched.labels ?? {}).some((key) =>
94 key.startsWith("alchemy-"),
95 ),
96 ).toEqual(true);
97
98 const updated = yield* stack.deploy(
99 Effect.gen(function* () {
100 const book = yield* GCP.CloudNumberRegistry.RegistryBook(
101 "Inventory",
102 {
103 registryBookId: created.book.registryBookId,
104 location,
105 labels: { env: "test" },
106 },
107 );
108 const realm = yield* GCP.CloudNumberRegistry.Realm("Private", {
109 realmId: created.realm.realmId,
110 location,
111 registryBook: book.name,
112 trafficType: "PRIVATE",
113 managementType: "USER",
114 ipVersion: "IPV4",
115 labels: { env: "test" },
116 });
117 const range = yield* GCP.CloudNumberRegistry.CustomRange("OnPrem", {
118 customRangeId: created.range.customRangeId,
119 location,
120 realm: realm.name,
121 ipv4CidrRange: CIDR,
122 description: "alchemy-prod-range",
123 attributes: [{ key: "site", value: "campus" }],
124 labels: { env: "prod", role: "range" },
125 });
126 return { book, realm, range };
127 }),
128 );
129
130 expect(updated.range.name).toEqual(created.range.name);
131 expect(updated.range.customRangeId).toEqual(created.range.customRangeId);
132 expect(updated.range.description).toEqual("alchemy-prod-range");
133 expect(updated.range.labels).toMatchObject({
134 env: "prod",
135 role: "range",
136 });
137
138 const refetched = yield* cnr.getProjectsLocationsCustomRanges({
139 name: created.range.name,
140 });
141 expect(refetched.description).toEqual("alchemy-prod-range");
142 expect(refetched.labels?.env).toEqual("prod");
143 expect(refetched.labels?.role).toEqual("range");
144
145 yield* stack.destroy();
146 const gone = yield* waitUntilGone(
147 cnr.getProjectsLocationsCustomRanges({ name: created.range.name }),
148 );
149 expect(gone).toEqual("gone");
150 }).pipe(logLevel),
151 {
152 tags: ["provider:gcp", "provider:gcp:cloudnumberregistry", "live"],
153 timeout: 90_000,
154 },
155);