@microagi/alchemy-gcp 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +88 -0
  3. package/lib/Auth/AuthProvider.d.ts +48 -0
  4. package/lib/Auth/AuthProvider.d.ts.map +1 -0
  5. package/lib/Auth/AuthProvider.js +84 -0
  6. package/lib/Auth/AuthProvider.js.map +1 -0
  7. package/lib/Auth/Credentials.d.ts +28 -0
  8. package/lib/Auth/Credentials.d.ts.map +1 -0
  9. package/lib/Auth/Credentials.js +41 -0
  10. package/lib/Auth/Credentials.js.map +1 -0
  11. package/lib/CloudResourceManager/Project.d.ts +143 -0
  12. package/lib/CloudResourceManager/Project.d.ts.map +1 -0
  13. package/lib/CloudResourceManager/Project.js +272 -0
  14. package/lib/CloudResourceManager/Project.js.map +1 -0
  15. package/lib/CloudResourceManager/index.d.ts +3 -0
  16. package/lib/CloudResourceManager/index.d.ts.map +1 -0
  17. package/lib/CloudResourceManager/index.js +2 -0
  18. package/lib/CloudResourceManager/index.js.map +1 -0
  19. package/lib/Compute/GlobalAddress.d.ts +101 -0
  20. package/lib/Compute/GlobalAddress.d.ts.map +1 -0
  21. package/lib/Compute/GlobalAddress.js +134 -0
  22. package/lib/Compute/GlobalAddress.js.map +1 -0
  23. package/lib/Compute/Network.d.ts +114 -0
  24. package/lib/Compute/Network.d.ts.map +1 -0
  25. package/lib/Compute/Network.js +145 -0
  26. package/lib/Compute/Network.js.map +1 -0
  27. package/lib/Compute/Operations.d.ts +34 -0
  28. package/lib/Compute/Operations.d.ts.map +1 -0
  29. package/lib/Compute/Operations.js +62 -0
  30. package/lib/Compute/Operations.js.map +1 -0
  31. package/lib/Compute/SharedVpcHost.d.ts +44 -0
  32. package/lib/Compute/SharedVpcHost.d.ts.map +1 -0
  33. package/lib/Compute/SharedVpcHost.js +71 -0
  34. package/lib/Compute/SharedVpcHost.js.map +1 -0
  35. package/lib/Compute/SharedVpcServiceProject.d.ts +46 -0
  36. package/lib/Compute/SharedVpcServiceProject.d.ts.map +1 -0
  37. package/lib/Compute/SharedVpcServiceProject.js +96 -0
  38. package/lib/Compute/SharedVpcServiceProject.js.map +1 -0
  39. package/lib/Compute/Subnetwork.d.ts +108 -0
  40. package/lib/Compute/Subnetwork.d.ts.map +1 -0
  41. package/lib/Compute/Subnetwork.js +201 -0
  42. package/lib/Compute/Subnetwork.js.map +1 -0
  43. package/lib/Compute/index.d.ts +6 -0
  44. package/lib/Compute/index.d.ts.map +1 -0
  45. package/lib/Compute/index.js +6 -0
  46. package/lib/Compute/index.js.map +1 -0
  47. package/lib/Container/Cluster.d.ts +216 -0
  48. package/lib/Container/Cluster.d.ts.map +1 -0
  49. package/lib/Container/Cluster.js +326 -0
  50. package/lib/Container/Cluster.js.map +1 -0
  51. package/lib/Container/NodePool.d.ts +214 -0
  52. package/lib/Container/NodePool.d.ts.map +1 -0
  53. package/lib/Container/NodePool.js +344 -0
  54. package/lib/Container/NodePool.js.map +1 -0
  55. package/lib/Container/Operations.d.ts +50 -0
  56. package/lib/Container/Operations.d.ts.map +1 -0
  57. package/lib/Container/Operations.js +51 -0
  58. package/lib/Container/Operations.js.map +1 -0
  59. package/lib/Container/index.d.ts +5 -0
  60. package/lib/Container/index.d.ts.map +1 -0
  61. package/lib/Container/index.js +3 -0
  62. package/lib/Container/index.js.map +1 -0
  63. package/lib/Parallelstore/Instance.d.ts +119 -0
  64. package/lib/Parallelstore/Instance.d.ts.map +1 -0
  65. package/lib/Parallelstore/Instance.js +180 -0
  66. package/lib/Parallelstore/Instance.js.map +1 -0
  67. package/lib/Parallelstore/index.d.ts +2 -0
  68. package/lib/Parallelstore/index.d.ts.map +1 -0
  69. package/lib/Parallelstore/index.js +2 -0
  70. package/lib/Parallelstore/index.js.map +1 -0
  71. package/lib/Providers.d.ts +24 -0
  72. package/lib/Providers.d.ts.map +1 -0
  73. package/lib/Providers.js +51 -0
  74. package/lib/Providers.js.map +1 -0
  75. package/lib/ServiceNetworking/PsaConnection.d.ts +84 -0
  76. package/lib/ServiceNetworking/PsaConnection.d.ts.map +1 -0
  77. package/lib/ServiceNetworking/PsaConnection.js +130 -0
  78. package/lib/ServiceNetworking/PsaConnection.js.map +1 -0
  79. package/lib/ServiceNetworking/index.d.ts +2 -0
  80. package/lib/ServiceNetworking/index.d.ts.map +1 -0
  81. package/lib/ServiceNetworking/index.js +2 -0
  82. package/lib/ServiceNetworking/index.js.map +1 -0
  83. package/lib/ServiceUsage/ApiEnable.d.ts +78 -0
  84. package/lib/ServiceUsage/ApiEnable.d.ts.map +1 -0
  85. package/lib/ServiceUsage/ApiEnable.js +132 -0
  86. package/lib/ServiceUsage/ApiEnable.js.map +1 -0
  87. package/lib/ServiceUsage/index.d.ts +3 -0
  88. package/lib/ServiceUsage/index.d.ts.map +1 -0
  89. package/lib/ServiceUsage/index.js +2 -0
  90. package/lib/ServiceUsage/index.js.map +1 -0
  91. package/lib/Tags.d.ts +57 -0
  92. package/lib/Tags.d.ts.map +1 -0
  93. package/lib/Tags.js +106 -0
  94. package/lib/Tags.js.map +1 -0
  95. package/lib/index.d.ts +11 -0
  96. package/lib/index.d.ts.map +1 -0
  97. package/lib/index.js +10 -0
  98. package/lib/index.js.map +1 -0
  99. package/package.json +70 -0
  100. package/src/Auth/AuthProvider.ts +180 -0
  101. package/src/Auth/Credentials.ts +69 -0
  102. package/src/CloudResourceManager/Project.ts +517 -0
  103. package/src/CloudResourceManager/index.ts +2 -0
  104. package/src/Compute/GlobalAddress.ts +283 -0
  105. package/src/Compute/Network.ts +306 -0
  106. package/src/Compute/Operations.ts +108 -0
  107. package/src/Compute/SharedVpcHost.ts +141 -0
  108. package/src/Compute/SharedVpcServiceProject.ts +185 -0
  109. package/src/Compute/Subnetwork.ts +375 -0
  110. package/src/Compute/index.ts +5 -0
  111. package/src/Container/Cluster.ts +599 -0
  112. package/src/Container/NodePool.ts +620 -0
  113. package/src/Container/Operations.ts +88 -0
  114. package/src/Container/index.ts +8 -0
  115. package/src/Parallelstore/Instance.ts +371 -0
  116. package/src/Parallelstore/index.ts +1 -0
  117. package/src/Providers.ts +84 -0
  118. package/src/ServiceNetworking/PsaConnection.ts +269 -0
  119. package/src/ServiceNetworking/index.ts +1 -0
  120. package/src/ServiceUsage/ApiEnable.ts +267 -0
  121. package/src/ServiceUsage/index.ts +2 -0
  122. package/src/Tags.ts +130 -0
  123. package/src/index.ts +16 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Project.d.ts","sourceRoot":"","sources":["../../src/CloudResourceManager/Project.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAKnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAM7C,OAAO,KAAK,KAAK,GAAG,MAAM,iBAAiB,CAAC;AAE5C;;GAEG;AACH,MAAM,MAAM,aAAa,GACrB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEzC,MAAM,MAAM,YAAY,GAAG;IACzB;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;OAEG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;OAKG;IACH,MAAM,EAAE,aAAa,CAAC;IACtB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,cAAc,CAAC,EAAE,kBAAkB,CAAC;CACrC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAAG,mBAAmB,MAAM,EAAE,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,MAAM,OAAO,GAAG,QAAQ,CAC5B,aAAa,EACb,YAAY,EACZ;IACE,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,aAAa,EAAE,GAAG,MAAM,EAAE,CAAC;IAC3B,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,MAAM,EAAE,MAAM,CAAC;IACf,yCAAyC;IACzC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,4EAA4E;IAC5E,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B;;;;OAIG;IACH,cAAc,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAC/C;;;;;OAKG;IACH,cAAc,EAAE,OAAO,CAAC;CACzB,EACD,KAAK,EACL,GAAG,CAAC,SAAS,CACd,CAAC;AAEF,eAAO,MAAM,OAAO,0CAAmC,CAAC;AAwCxD,eAAO,MAAM,eAAe,8NA6TzB,CAAC"}
@@ -0,0 +1,272 @@
1
+ import { ConfigError } from "@distilled.cloud/gcp";
2
+ import * as billing from "@distilled.cloud/gcp/cloudbilling-v1";
3
+ import * as crm from "@distilled.cloud/gcp/cloudresourcemanager-v3";
4
+ import { Resource } from "alchemy";
5
+ import { Unowned } from "alchemy/AdoptPolicy";
6
+ import { isResolved } from "alchemy/Diff";
7
+ import { createPhysicalName } from "alchemy/PhysicalName";
8
+ import * as Provider from "alchemy/Provider";
9
+ import { diffTags } from "alchemy/Tags";
10
+ import * as Duration from "effect/Duration";
11
+ import * as Effect from "effect/Effect";
12
+ import * as Schedule from "effect/Schedule";
13
+ import { gcpInternalLabels, hasAlchemyLabels } from "../Tags.js";
14
+ export const Project = Resource("GCP.Project");
15
+ const parentToString = (parent) => parent.type === "folder" ? `folders/${parent.id}` : `organizations/${parent.id}`;
16
+ const createProjectId = (id, override) => Effect.gen(function* () {
17
+ if (override)
18
+ return override;
19
+ // GCP project IDs: 6-30 chars, lowercase letters/digits/hyphens,
20
+ // must start with a letter. `createPhysicalName` already prepends
21
+ // the stack name (which conventionally starts with a letter), so
22
+ // the first-letter rule is satisfied by construction.
23
+ return (yield* createPhysicalName({ id, maxLength: 30 })).toLowerCase();
24
+ });
25
+ const toAttributes = (p, billingInfo) => ({
26
+ projectId: p.projectId,
27
+ // GCP returns the project number as a digit-only string. The cast
28
+ // safely narrows from `string` to `` `${number}` `` — server-side
29
+ // contract guarantees the shape (the empty-string fallback is a
30
+ // belt-and-braces guard for malformed responses; downstream code
31
+ // observes a project state of "ACTIVE" before consuming this).
32
+ projectNumber: (p.name?.replace(/^projects\//, "") ?? "0"),
33
+ name: p.name ?? `projects/${p.projectId}`,
34
+ displayName: p.displayName,
35
+ state: p.state ?? "ACTIVE",
36
+ parent: p.parent ?? "",
37
+ createTime: p.createTime,
38
+ labels: { ...(p.labels ?? {}) },
39
+ // GCP returns `billingAccountName` as a plain string but its format
40
+ // is always `billingAccounts/{id}` — narrow at the boundary.
41
+ billingAccount: (billingInfo?.billingAccountName || undefined),
42
+ billingEnabled: billingInfo?.billingEnabled ?? false,
43
+ });
44
+ export const ProjectProvider = () => Provider.effect(Project, Effect.gen(function* () {
45
+ // Acquire SDK clients ONCE — Credentials and HttpClient are
46
+ // resolved at provider construction, not on every reconcile.
47
+ const getProjects = yield* crm.getProjects;
48
+ const createProjects = yield* crm.createProjects;
49
+ const patchProjects = yield* crm.patchProjects;
50
+ const deleteProjects = yield* crm.deleteProjects;
51
+ const getOperations = yield* crm.getOperations;
52
+ const getBillingInfo = yield* billing.getBillingInfoProjects;
53
+ const updateBillingInfo = yield* billing.updateBillingInfoProjects;
54
+ const awaitOperation = Effect.fn(function* (operationName, session) {
55
+ const op = yield* getOperations({ name: operationName }).pipe(Effect.flatMap((current) => current.done === true
56
+ ? Effect.succeed(current)
57
+ : Effect.fail({ _tag: "OperationPending" })), Effect.retry({
58
+ while: (e) => e?._tag === "OperationPending",
59
+ schedule: Schedule.exponential(Duration.seconds(1), 1.5).pipe(Schedule.both(Schedule.recurs(60)), Schedule.tapOutput(() => session.note(`Waiting for GCP operation ${operationName}…`))),
60
+ }));
61
+ if (op.error) {
62
+ return yield* new ConfigError({
63
+ message: `GCP operation ${operationName} failed: ${op.error.message ?? JSON.stringify(op.error)}`,
64
+ });
65
+ }
66
+ return op;
67
+ });
68
+ const observeProject = (projectId) => getProjects({ name: `projects/${projectId}` }).pipe(
69
+ // GCP returns 403 Forbidden (not 404) when a project ID is
70
+ // unknown or invisible to the caller — a deliberate choice to
71
+ // avoid leaking project-ID existence across tenants. From this
72
+ // provider's perspective both shapes mean "not present", so
73
+ // observation should treat them identically.
74
+ Effect.catchTag("NotFound", () => Effect.succeed(undefined)), Effect.catchTag("Forbidden", () => Effect.succeed(undefined)),
75
+ // A project marked for deletion is still readable but in
76
+ // `DELETE_REQUESTED` state. Treat as missing so the create
77
+ // path runs; if the projectId is still reserved server-side
78
+ // the create will fail with Conflict and surface a real
79
+ // error.
80
+ Effect.map((p) => p && p.state && p.state !== "ACTIVE" ? undefined : p));
81
+ const requireProject = (projectId, context) => observeProject(projectId).pipe(Effect.flatMap((p) => p
82
+ ? Effect.succeed(p)
83
+ : Effect.fail(new ConfigError({
84
+ message: `Project ${projectId} ${context}.`,
85
+ }))));
86
+ // Read current billing association. Returns `undefined` when the
87
+ // project is unknown to billing (NotFound) or invisible to the
88
+ // caller (Forbidden) — same 403→missing collapse as the project
89
+ // observe path.
90
+ const observeBilling = (projectId) => getBillingInfo({ name: `projects/${projectId}` }).pipe(Effect.catchTag("NotFound", () => Effect.succeed(undefined)), Effect.catchTag("Forbidden", () => Effect.succeed(undefined)));
91
+ // Attach / detach a billing account on the project. Pass empty
92
+ // string to detach (GCP's documented contract — see the long
93
+ // disclaimer on `updateBillingInfoProjects` warning that this
94
+ // disables paid services on the project). Synchronous PUT, no
95
+ // LRO involved.
96
+ const syncBilling = Effect.fn(function* (projectId, observed, desired) {
97
+ const observedAccount = observed?.billingAccountName ?? "";
98
+ const desiredAccount = desired ?? "";
99
+ if (observedAccount === desiredAccount) {
100
+ return observed;
101
+ }
102
+ return yield* updateBillingInfo({
103
+ name: `projects/${projectId}`,
104
+ body: { billingAccountName: desiredAccount },
105
+ }).pipe(
106
+ // Surface the most common BadRequest mode — the billing
107
+ // account's per-account project-attach quota — with a
108
+ // remediation pointer. Soft-deleted projects continue to
109
+ // hold quota for 30 days, so the typical fix is a quota
110
+ // increase rather than waiting it out. Other 400s
111
+ // (malformed account name, closed account, permission
112
+ // mismatch) propagate untouched so the underlying API
113
+ // message is preserved.
114
+ // Surface the most common BadRequest mode with a clear
115
+ // remediation pointer, and re-shape every BadRequest into
116
+ // ConfigError so callers see one error class regardless of
117
+ // the underlying GCP-side detail. The two patterns:
118
+ //
119
+ // 1. Billing-account project-attach quota exhausted —
120
+ // every soft-deleted project still holds quota for
121
+ // 30 days. Real fix is a quota increase request.
122
+ // 2. Other 400s (malformed account name, closed
123
+ // account, IAM mismatch on `billing.resourceAssociations.create`)
124
+ // — surface the underlying GCP message.
125
+ Effect.catchTag("BadRequest", (e) => {
126
+ // GCP returns the high-level message in `e.message` and
127
+ // stuffs the structured detail (e.g. `QuotaFailure`) into
128
+ // the response body's `details[]` array — which distilled
129
+ // doesn't surface (only `message` is parsed in
130
+ // `vendor/distilled/packages/gcp/src/client/api.ts:32-35`).
131
+ //
132
+ // The single most common 4xx on `updateBillingInfo` is
133
+ // FAILED_PRECONDITION ("Precondition check failed.") for
134
+ // the billing account's per-account project-attach quota.
135
+ // Each successful attach — including soft-deleted projects
136
+ // within their 30-day retention window — counts toward
137
+ // this quota. There is no way to detect this case with
138
+ // certainty from the surfaced error, so we always include
139
+ // the quota-remediation hint alongside the underlying
140
+ // message; users who hit a different 400 will still see
141
+ // GCP's real reason in the prefix.
142
+ const underlying = e.message ?? "unknown 400 from cloudbilling.updateBillingInfo";
143
+ const isLikelyQuota = /precondition|FAILED_PRECONDITION/i.test(underlying);
144
+ const hint = isLikelyQuota
145
+ ? " This is most often the billing account's project-attach quota — request an increase at https://support.google.com/code/contact/billing_quota_increase, or use a different billing account."
146
+ : "";
147
+ return Effect.fail(new ConfigError({
148
+ message: `Cannot attach billing account ${desiredAccount} to project ${projectId}: ${underlying}.${hint}`,
149
+ }));
150
+ }));
151
+ });
152
+ const syncMutable = Effect.fn(function* (observed, desired, session) {
153
+ const observedLabels = { ...(observed.labels ?? {}) };
154
+ const updateMaskFields = [];
155
+ if (desired.displayName !== observed.displayName) {
156
+ updateMaskFields.push("display_name");
157
+ }
158
+ const labelDiff = diffTags(observedLabels, desired.labels);
159
+ if (labelDiff.removed.length > 0 || labelDiff.upsert.length > 0) {
160
+ updateMaskFields.push("labels");
161
+ }
162
+ if (updateMaskFields.length === 0)
163
+ return observed;
164
+ const op = yield* patchProjects({
165
+ name: observed.name,
166
+ updateMask: updateMaskFields.join(","),
167
+ body: {
168
+ displayName: desired.displayName,
169
+ labels: desired.labels,
170
+ },
171
+ });
172
+ if (op.name)
173
+ yield* awaitOperation(op.name, session);
174
+ return yield* requireProject(observed.projectId, "disappeared after patch");
175
+ });
176
+ return {
177
+ stables: ["projectId", "projectNumber", "name"],
178
+ diff: Effect.fn(function* ({ id, news, olds = {}, output }) {
179
+ if (!isResolved(news))
180
+ return undefined;
181
+ const desiredId = yield* createProjectId(id, news.projectId);
182
+ const currentId = output?.projectId ??
183
+ (yield* createProjectId(id, olds.projectId));
184
+ const desiredParent = parentToString(news.parent);
185
+ const observedParent = output?.parent ??
186
+ (olds.parent ? parentToString(olds.parent) : desiredParent);
187
+ if (desiredId !== currentId || observedParent !== desiredParent) {
188
+ return { action: "replace" };
189
+ }
190
+ }),
191
+ reconcile: Effect.fn(function* ({ id, news, session }) {
192
+ const projectId = yield* createProjectId(id, news.projectId);
193
+ const parent = parentToString(news.parent);
194
+ const internalLabels = yield* gcpInternalLabels(id);
195
+ const desiredLabels = {
196
+ ...(news.labels ?? {}),
197
+ ...internalLabels, // alchemy keys reserved — overwrite user values
198
+ };
199
+ // 1. Observe — cloud state is authoritative; `output`/`olds`
200
+ // are caches and may be stale or missing.
201
+ let observed = yield* observeProject(projectId);
202
+ // 2. Ensure — create if missing. `createProjects` returns an
203
+ // LRO; poll until done. `Conflict` covers two cases: a
204
+ // peer reconciler raced us, or a prior reconcile created
205
+ // the project but state-persistence failed. In both, the
206
+ // project exists — re-observe and converge.
207
+ if (!observed) {
208
+ const operation = yield* createProjects({
209
+ body: {
210
+ projectId,
211
+ parent,
212
+ displayName: news.displayName,
213
+ labels: desiredLabels,
214
+ },
215
+ }).pipe(Effect.catchTag("Conflict", () => Effect.succeed(undefined)));
216
+ if (operation?.name)
217
+ yield* awaitOperation(operation.name, session);
218
+ observed = yield* requireProject(projectId, "did not appear after create");
219
+ }
220
+ // 3. Sync — displayName + labels are mutable. Diff against
221
+ // OBSERVED state (not `olds`) so adoption converges
222
+ // correctly: if a foreign label set is on the project,
223
+ // the patch will replace it with our desired set
224
+ // (including alchemy internals).
225
+ const synced = yield* syncMutable(observed, {
226
+ displayName: news.displayName ?? observed.displayName,
227
+ labels: desiredLabels,
228
+ }, session);
229
+ // 4. Sync billing association. Done after the project patch
230
+ // so the project resource is fully present before we
231
+ // attach billing (CRM project create is the LRO; billing
232
+ // update is synchronous).
233
+ const observedBilling = yield* observeBilling(synced.projectId);
234
+ const finalBilling = yield* syncBilling(synced.projectId, observedBilling, news.billingAccount);
235
+ return toAttributes(synced, finalBilling);
236
+ }),
237
+ delete: Effect.fn(function* ({ output, session }) {
238
+ yield* deleteProjects({ name: `projects/${output.projectId}` }).pipe(Effect.flatMap((op) => op.name ? awaitOperation(op.name, session) : Effect.succeed(op)),
239
+ // Already gone.
240
+ Effect.catchTag("NotFound", () => Effect.void),
241
+ // GCP returns 400 with "Project ... is already in
242
+ // DELETE_REQUESTED" when delete is invoked on an already-
243
+ // soft-deleted project. Treat that as idempotent success.
244
+ // TODO(distilled): tag this state via patch — see finding 12.
245
+ // The GCP `matchError` (vendor/distilled/packages/gcp/src/client/api.ts)
246
+ // currently dispatches purely on HTTP status and ignores the
247
+ // `message.includes` matcher in the patch JSON, so a per-operation
248
+ // patch alone can't disambiguate this case from a real 400 without
249
+ // also extending `matchError` to consult the matchers.
250
+ Effect.catchTag("BadRequest", (e) => /already.*delet|DELETE_REQUESTED/i.test(e.message ?? "")
251
+ ? Effect.void
252
+ : Effect.fail(e)));
253
+ }),
254
+ read: Effect.fn(function* ({ id, output, olds }) {
255
+ const projectId = output?.projectId ??
256
+ (yield* createProjectId(id, olds?.projectId));
257
+ const observed = yield* observeProject(projectId);
258
+ if (!observed)
259
+ return undefined;
260
+ const observedBilling = yield* observeBilling(projectId);
261
+ const attrs = toAttributes(observed, observedBilling);
262
+ // Adoption gate: a project without our internal labels was
263
+ // created outside this stack/stage/id. The engine surfaces
264
+ // `Unowned(attrs)` to the user as "exists but is not ours" —
265
+ // adoption requires `--adopt` (or `adopt(true)`).
266
+ return (yield* hasAlchemyLabels(id, observed.labels))
267
+ ? attrs
268
+ : Unowned(attrs);
269
+ }),
270
+ };
271
+ }));
272
+ //# sourceMappingURL=Project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Project.js","sourceRoot":"","sources":["../../src/CloudResourceManager/Project.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { Project, ProjectProvider } from "./Project.ts";
2
+ export type { ProjectParent, ProjectProps } from "./Project.ts";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/CloudResourceManager/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACxD,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { Project, ProjectProvider } from "./Project.js";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/CloudResourceManager/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,101 @@
1
+ import { Resource } from "alchemy";
2
+ import * as Provider from "alchemy/Provider";
3
+ import type * as GCP from "../Providers.ts";
4
+ /**
5
+ * A global compute Address. The intended use here is **Private Services
6
+ * Access (PSA)** — reserving an internal IP range that
7
+ * `servicenetworking.services.connections.create` consumes to peer
8
+ * Google's service-producer VPC into the host VPC. That requires the
9
+ * specific shape `addressType=INTERNAL`, `purpose=VPC_PEERING`,
10
+ * `network=<vpc selfLink>`, plus an explicit `prefixLength`.
11
+ *
12
+ * Other purposes (`PRIVATE_SERVICE_CONNECT`, `GCE_ENDPOINT`, regional
13
+ * external addresses) are not modelled in this resource — add them in
14
+ * separate resources if/when needed.
15
+ *
16
+ * Adoption uses the labels field (Address carries `labels` +
17
+ * `labelFingerprint`).
18
+ *
19
+ * @section Reserving a PSA range
20
+ * @example /20 reserved for `servicenetworking.googleapis.com`
21
+ * ```typescript
22
+ * const psaRange = yield* GCP.GlobalAddress("PsaRange", {
23
+ * project: hostProject.projectId,
24
+ * network: vpc.selfLink,
25
+ * purpose: "VPC_PEERING",
26
+ * addressType: "INTERNAL",
27
+ * prefixLength: 20,
28
+ * });
29
+ * ```
30
+ */
31
+ export type GlobalAddressProps = {
32
+ /** GCP project ID hosting the address. Immutable — replace if changed. */
33
+ project: string;
34
+ /**
35
+ * Address name. Defaults to `createPhysicalName({ id, lowercase: true,
36
+ * maxLength: 63 })`. Immutable — replace if changed.
37
+ */
38
+ name?: string;
39
+ /** Description (free-form). */
40
+ description?: string;
41
+ /**
42
+ * Internal vs external. Defaults to `INTERNAL` (the only value that
43
+ * makes sense for a PSA reservation). Immutable — replace.
44
+ */
45
+ addressType?: "INTERNAL" | "EXTERNAL";
46
+ /**
47
+ * Address purpose. For PSA use `VPC_PEERING`. Immutable — replace.
48
+ */
49
+ purpose?: "VPC_PEERING" | "GCE_ENDPOINT" | "PRIVATE_SERVICE_CONNECT" | "DNS_RESOLVER";
50
+ /**
51
+ * URL of the VPC the address belongs to (PSA requires this).
52
+ * Immutable — replace.
53
+ */
54
+ network?: string;
55
+ /**
56
+ * Prefix length for a range allocation (PSA always allocates a
57
+ * range, not a single address). Required for `purpose=VPC_PEERING`.
58
+ * Immutable — replace.
59
+ */
60
+ prefixLength?: number;
61
+ /**
62
+ * Explicit address (or first address of the range) to reserve. If
63
+ * omitted, GCP picks one inside the VPC's available space.
64
+ * Immutable — replace.
65
+ */
66
+ address?: string;
67
+ /**
68
+ * Resource labels. Alchemy internal labels (`alchemy_app`,
69
+ * `alchemy_stage`, `alchemy_id`) are merged on top automatically and
70
+ * are reserved. Mutable via `setLabels`.
71
+ */
72
+ labels?: Record<string, string>;
73
+ };
74
+ export type GlobalAddressAttributes = {
75
+ /** Address name. */
76
+ name: string;
77
+ /** GCP project ID, threaded through from props for delete/read. */
78
+ project: string;
79
+ /** Server-defined URL. */
80
+ selfLink: string;
81
+ /** Server-assigned numeric id. */
82
+ id: string;
83
+ /** The reserved IP (or first IP of the range). */
84
+ address: string;
85
+ /** Prefix length, when reserving a range. */
86
+ prefixLength: number | undefined;
87
+ /** Address type. */
88
+ addressType: string | undefined;
89
+ /** Purpose. */
90
+ purpose: string | undefined;
91
+ /** VPC URL. */
92
+ network: string | undefined;
93
+ /** Status: `RESERVING`, `RESERVED`, `IN_USE`. */
94
+ status: string | undefined;
95
+ /** Labels currently set, including the alchemy internals. */
96
+ labels: Record<string, string>;
97
+ };
98
+ export type GlobalAddress = Resource<"GCP.GlobalAddress", GlobalAddressProps, GlobalAddressAttributes, never, GCP.Providers>;
99
+ export declare const GlobalAddress: import("alchemy").ResourceClass<GlobalAddress>;
100
+ export declare const GlobalAddressProvider: () => import("effect/Layer").Layer<Provider.Provider<GlobalAddress>, never, import("effect/unstable/http/HttpClient").HttpClient | import("alchemy").Stage | import("alchemy").Stack | import("@distilled.cloud/gcp").Credentials>;
101
+ //# sourceMappingURL=GlobalAddress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlobalAddress.d.ts","sourceRoot":"","sources":["../../src/Compute/GlobalAddress.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAKnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAG7C,OAAO,KAAK,KAAK,GAAG,MAAM,iBAAiB,CAAC;AAG5C;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,WAAW,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC;IACtC;;OAEG;IACH,OAAO,CAAC,EACJ,aAAa,GACb,cAAc,GACd,yBAAyB,GACzB,cAAc,CAAC;IACnB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,oBAAoB;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAC;IAChB,0BAA0B;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,oBAAoB;IACpB,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,eAAe;IACf,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,eAAe;IACf,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,iDAAiD;IACjD,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG,QAAQ,CAClC,mBAAmB,EACnB,kBAAkB,EAClB,uBAAuB,EACvB,KAAK,EACL,GAAG,CAAC,SAAS,CACd,CAAC;AACF,eAAO,MAAM,aAAa,gDAA+C,CAAC;AAmB1E,eAAO,MAAM,qBAAqB,oOAgJ/B,CAAC"}
@@ -0,0 +1,134 @@
1
+ import * as compute from "@distilled.cloud/gcp/compute-v1";
2
+ import { Resource } from "alchemy";
3
+ import { Unowned } from "alchemy/AdoptPolicy";
4
+ import { deepEqual, isResolved, somePropsAreDifferent } from "alchemy/Diff";
5
+ import { createPhysicalName } from "alchemy/PhysicalName";
6
+ import * as Provider from "alchemy/Provider";
7
+ import * as Effect from "effect/Effect";
8
+ import { gcpInternalLabels, hasAlchemyLabels } from "../Tags.js";
9
+ import { makeAwaitGlobalOperation } from "./Operations.js";
10
+ export const GlobalAddress = Resource("GCP.GlobalAddress");
11
+ const toGlobalAddressAttributes = (a, parent) => ({
12
+ name: a.name ?? "",
13
+ project: parent.project,
14
+ selfLink: a.selfLink ?? "",
15
+ id: a.id ?? "",
16
+ address: a.address ?? "",
17
+ prefixLength: a.prefixLength,
18
+ addressType: a.addressType,
19
+ purpose: a.purpose,
20
+ network: a.network,
21
+ status: a.status,
22
+ labels: { ...(a.labels ?? {}) },
23
+ });
24
+ export const GlobalAddressProvider = () => Provider.effect(GlobalAddress, Effect.gen(function* () {
25
+ const getGlobalAddresses = yield* compute.getGlobalAddresses;
26
+ const insertGlobalAddresses = yield* compute.insertGlobalAddresses;
27
+ const deleteGlobalAddresses = yield* compute.deleteGlobalAddresses;
28
+ const setLabelsGlobalAddresses = yield* compute.setLabelsGlobalAddresses;
29
+ const getGlobalOperations = yield* compute.getGlobalOperations;
30
+ const awaitOp = makeAwaitGlobalOperation(getGlobalOperations);
31
+ const observe = (project, name) => getGlobalAddresses({ project, address: name }).pipe(Effect.catchTag("NotFound", () => Effect.succeed(undefined)), Effect.catchTag("Forbidden", () => Effect.succeed(undefined)));
32
+ const syncLabels = Effect.fn(function* (args) {
33
+ if (deepEqual(args.observed.labels ?? {}, args.desired))
34
+ return;
35
+ const op = yield* setLabelsGlobalAddresses({
36
+ project: args.project,
37
+ resource: args.observed.name ?? "",
38
+ body: {
39
+ labels: args.desired,
40
+ labelFingerprint: args.observed.labelFingerprint,
41
+ },
42
+ });
43
+ if (op.name)
44
+ yield* awaitOp(args.project, op.name, args.session);
45
+ });
46
+ return {
47
+ stables: ["name", "project", "selfLink", "id", "address"],
48
+ diff: Effect.fn(function* ({ news, olds = {} }) {
49
+ if (!isResolved(news))
50
+ return undefined;
51
+ if (somePropsAreDifferent(olds, news, [
52
+ "project",
53
+ "name",
54
+ "addressType",
55
+ "purpose",
56
+ "network",
57
+ "prefixLength",
58
+ "address",
59
+ ])) {
60
+ return { action: "replace" };
61
+ }
62
+ return undefined;
63
+ }),
64
+ reconcile: Effect.fn(function* ({ id, news, session }) {
65
+ const internalLabels = yield* gcpInternalLabels(id);
66
+ const desiredName = news.name ??
67
+ (yield* createPhysicalName({ id, maxLength: 63 })).toLowerCase();
68
+ const desiredLabels = {
69
+ ...(news.labels ?? {}),
70
+ ...internalLabels,
71
+ };
72
+ let observed = yield* observe(news.project, desiredName);
73
+ if (!observed) {
74
+ const body = {
75
+ name: desiredName,
76
+ ...(news.description ? { description: news.description } : {}),
77
+ addressType: news.addressType ?? "INTERNAL",
78
+ ...(news.purpose ? { purpose: news.purpose } : {}),
79
+ ...(news.network ? { network: news.network } : {}),
80
+ ...(news.prefixLength !== undefined
81
+ ? { prefixLength: news.prefixLength }
82
+ : {}),
83
+ ...(news.address ? { address: news.address } : {}),
84
+ labels: desiredLabels,
85
+ };
86
+ const op = yield* insertGlobalAddresses({
87
+ project: news.project,
88
+ body,
89
+ }).pipe(Effect.catchTag("Conflict", () => Effect.succeed(undefined)));
90
+ if (op?.name)
91
+ yield* awaitOp(news.project, op.name, session);
92
+ observed = yield* getGlobalAddresses({
93
+ project: news.project,
94
+ address: desiredName,
95
+ });
96
+ }
97
+ yield* syncLabels({
98
+ project: news.project,
99
+ observed,
100
+ desired: desiredLabels,
101
+ session,
102
+ });
103
+ const final = yield* getGlobalAddresses({
104
+ project: news.project,
105
+ address: desiredName,
106
+ });
107
+ return toGlobalAddressAttributes(final, { project: news.project });
108
+ }),
109
+ delete: Effect.fn(function* ({ output, session }) {
110
+ yield* deleteGlobalAddresses({
111
+ project: output.project,
112
+ address: output.name,
113
+ }).pipe(Effect.flatMap((op) => op.name
114
+ ? awaitOp(output.project, op.name, session)
115
+ : Effect.succeed(op)), Effect.catchTag("NotFound", () => Effect.void));
116
+ }),
117
+ read: Effect.fn(function* ({ id, output, olds }) {
118
+ const project = output?.project ?? olds?.project;
119
+ if (!project)
120
+ return undefined;
121
+ const name = output?.name ??
122
+ olds?.name ??
123
+ (yield* createPhysicalName({ id, maxLength: 63 })).toLowerCase();
124
+ const observed = yield* observe(project, name);
125
+ if (!observed)
126
+ return undefined;
127
+ const attrs = toGlobalAddressAttributes(observed, { project });
128
+ return (yield* hasAlchemyLabels(id, observed.labels))
129
+ ? attrs
130
+ : Unowned(attrs);
131
+ }),
132
+ };
133
+ }));
134
+ //# sourceMappingURL=GlobalAddress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GlobalAddress.js","sourceRoot":"","sources":["../../src/Compute/GlobalAddress.ts"],"names":[],"mappings":"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"}