@microagi/alchemy-gcp 0.11.5 → 0.11.7
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.
- package/CHANGELOG.md +22 -0
- package/lib/ArtifactRegistry/Operations.d.ts +2 -1
- package/lib/ArtifactRegistry/Operations.d.ts.map +1 -1
- package/lib/ArtifactRegistry/Operations.js +9 -2
- package/lib/ArtifactRegistry/Operations.js.map +1 -1
- package/lib/ArtifactRegistry/Repository.d.ts.map +1 -1
- package/lib/ArtifactRegistry/Repository.js +6 -1
- package/lib/ArtifactRegistry/Repository.js.map +1 -1
- package/lib/ArtifactRegistry/RepositoryIamMember.d.ts.map +1 -1
- package/lib/ArtifactRegistry/RepositoryIamMember.js +6 -1
- package/lib/ArtifactRegistry/RepositoryIamMember.js.map +1 -1
- package/lib/CloudResourceManager/Project.d.ts.map +1 -1
- package/lib/CloudResourceManager/Project.js +10 -2
- package/lib/CloudResourceManager/Project.js.map +1 -1
- package/lib/Compute/Address.d.ts +1 -1
- package/lib/Compute/Address.d.ts.map +1 -1
- package/lib/Compute/Address.js +5 -2
- package/lib/Compute/Address.js.map +1 -1
- package/lib/Compute/Firewall.d.ts +1 -1
- package/lib/Compute/Firewall.d.ts.map +1 -1
- package/lib/Compute/Firewall.js +5 -2
- package/lib/Compute/Firewall.js.map +1 -1
- package/lib/Compute/ForwardingRule.d.ts +1 -1
- package/lib/Compute/ForwardingRule.d.ts.map +1 -1
- package/lib/Compute/ForwardingRule.js +5 -2
- package/lib/Compute/ForwardingRule.js.map +1 -1
- package/lib/Compute/GlobalAddress.d.ts +1 -1
- package/lib/Compute/GlobalAddress.d.ts.map +1 -1
- package/lib/Compute/GlobalAddress.js +5 -2
- package/lib/Compute/GlobalAddress.js.map +1 -1
- package/lib/Compute/Network.d.ts +1 -1
- package/lib/Compute/Network.d.ts.map +1 -1
- package/lib/Compute/Network.js +5 -2
- package/lib/Compute/Network.js.map +1 -1
- package/lib/Compute/Operations.d.ts +7 -2
- package/lib/Compute/Operations.d.ts.map +1 -1
- package/lib/Compute/Operations.js +10 -5
- package/lib/Compute/Operations.js.map +1 -1
- package/lib/Compute/ProjectDefaultNetworkTier.d.ts +1 -1
- package/lib/Compute/ProjectDefaultNetworkTier.d.ts.map +1 -1
- package/lib/Compute/ProjectDefaultNetworkTier.js +2 -0
- package/lib/Compute/ProjectDefaultNetworkTier.js.map +1 -1
- package/lib/Compute/SharedVpcHost.d.ts +1 -1
- package/lib/Compute/SharedVpcHost.d.ts.map +1 -1
- package/lib/Compute/SharedVpcHost.js +7 -2
- package/lib/Compute/SharedVpcHost.js.map +1 -1
- package/lib/Compute/SharedVpcServiceProject.d.ts +1 -1
- package/lib/Compute/SharedVpcServiceProject.d.ts.map +1 -1
- package/lib/Compute/SharedVpcServiceProject.js +5 -2
- package/lib/Compute/SharedVpcServiceProject.js.map +1 -1
- package/lib/Compute/Subnetwork.d.ts +1 -1
- package/lib/Compute/Subnetwork.d.ts.map +1 -1
- package/lib/Compute/Subnetwork.js +9 -3
- package/lib/Compute/Subnetwork.js.map +1 -1
- package/lib/Container/Cluster.d.ts.map +1 -1
- package/lib/Container/Cluster.js +6 -2
- package/lib/Container/Cluster.js.map +1 -1
- package/lib/Container/NodePool.d.ts.map +1 -1
- package/lib/Container/NodePool.js +2 -0
- package/lib/Container/NodePool.js.map +1 -1
- package/lib/Container/Operations.d.ts +2 -2
- package/lib/Container/Operations.d.ts.map +1 -1
- package/lib/Container/Operations.js +9 -3
- package/lib/Container/Operations.js.map +1 -1
- package/lib/Iam/Operations.d.ts +42 -0
- package/lib/Iam/Operations.d.ts.map +1 -0
- package/lib/Iam/Operations.js +48 -0
- package/lib/Iam/Operations.js.map +1 -0
- package/lib/Iam/ServiceAccount.d.ts.map +1 -1
- package/lib/Iam/ServiceAccount.js +6 -1
- package/lib/Iam/ServiceAccount.js.map +1 -1
- package/lib/Iam/ServiceAccountKey.d.ts.map +1 -1
- package/lib/Iam/ServiceAccountKey.js +2 -0
- package/lib/Iam/ServiceAccountKey.js.map +1 -1
- package/lib/Iam/WorkloadIdentityPool.d.ts +100 -0
- package/lib/Iam/WorkloadIdentityPool.d.ts.map +1 -0
- package/lib/Iam/WorkloadIdentityPool.js +175 -0
- package/lib/Iam/WorkloadIdentityPool.js.map +1 -0
- package/lib/Iam/WorkloadIdentityPoolProvider.d.ts +124 -0
- package/lib/Iam/WorkloadIdentityPoolProvider.d.ts.map +1 -0
- package/lib/Iam/WorkloadIdentityPoolProvider.js +222 -0
- package/lib/Iam/WorkloadIdentityPoolProvider.js.map +1 -0
- package/lib/Iam/index.d.ts +4 -0
- package/lib/Iam/index.d.ts.map +1 -1
- package/lib/Iam/index.js +2 -0
- package/lib/Iam/index.js.map +1 -1
- package/lib/Kubernetes/Helm.d.ts.map +1 -1
- package/lib/Kubernetes/Helm.js +2 -0
- package/lib/Kubernetes/Helm.js.map +1 -1
- package/lib/Kubernetes/KubernetesManifest.d.ts.map +1 -1
- package/lib/Kubernetes/KubernetesManifest.js +2 -0
- package/lib/Kubernetes/KubernetesManifest.js.map +1 -1
- package/lib/Kubernetes/Secret.d.ts.map +1 -1
- package/lib/Kubernetes/Secret.js +2 -0
- package/lib/Kubernetes/Secret.js.map +1 -1
- package/lib/ManagedLustre/Instance.d.ts.map +1 -1
- package/lib/ManagedLustre/Instance.js +11 -4
- package/lib/ManagedLustre/Instance.js.map +1 -1
- package/lib/Providers.d.ts +1 -1
- package/lib/Providers.d.ts.map +1 -1
- package/lib/Providers.js +5 -1
- package/lib/Providers.js.map +1 -1
- package/lib/Run/IamSync.d.ts.map +1 -1
- package/lib/Run/IamSync.js +4 -1
- package/lib/Run/IamSync.js.map +1 -1
- package/lib/Run/Job.d.ts.map +1 -1
- package/lib/Run/Job.js +6 -1
- package/lib/Run/Job.js.map +1 -1
- package/lib/Run/Operations.d.ts +2 -2
- package/lib/Run/Operations.d.ts.map +1 -1
- package/lib/Run/Operations.js +9 -3
- package/lib/Run/Operations.js.map +1 -1
- package/lib/Run/Service.d.ts.map +1 -1
- package/lib/Run/Service.js +6 -1
- package/lib/Run/Service.js.map +1 -1
- package/lib/ServiceNetworking/PsaConnection.d.ts.map +1 -1
- package/lib/ServiceNetworking/PsaConnection.js +11 -4
- package/lib/ServiceNetworking/PsaConnection.js.map +1 -1
- package/lib/ServiceUsage/ApiEnable.d.ts.map +1 -1
- package/lib/ServiceUsage/ApiEnable.js +9 -1
- package/lib/ServiceUsage/ApiEnable.js.map +1 -1
- package/lib/Sqladmin/Database.d.ts.map +1 -1
- package/lib/Sqladmin/Database.js +2 -0
- package/lib/Sqladmin/Database.js.map +1 -1
- package/lib/Sqladmin/Instance.d.ts.map +1 -1
- package/lib/Sqladmin/Instance.js +6 -1
- package/lib/Sqladmin/Instance.js.map +1 -1
- package/lib/Sqladmin/Operations.d.ts.map +1 -1
- package/lib/Sqladmin/Operations.js +7 -1
- package/lib/Sqladmin/Operations.js.map +1 -1
- package/lib/Sqladmin/User.d.ts.map +1 -1
- package/lib/Sqladmin/User.js +2 -0
- package/lib/Sqladmin/User.js.map +1 -1
- package/lib/Storage/Bucket.d.ts.map +1 -1
- package/lib/Storage/Bucket.js +6 -1
- package/lib/Storage/Bucket.js.map +1 -1
- package/lib/Storage/StorageBucketIamMember.d.ts.map +1 -1
- package/lib/Storage/StorageBucketIamMember.js +6 -1
- package/lib/Storage/StorageBucketIamMember.js.map +1 -1
- package/package.json +7 -7
- package/src/ArtifactRegistry/Operations.ts +10 -5
- package/src/ArtifactRegistry/Repository.ts +7 -3
- package/src/ArtifactRegistry/RepositoryIamMember.ts +6 -3
- package/src/CloudResourceManager/Project.ts +11 -6
- package/src/Compute/Address.ts +5 -1
- package/src/Compute/Firewall.ts +5 -1
- package/src/Compute/ForwardingRule.ts +5 -1
- package/src/Compute/GlobalAddress.ts +5 -1
- package/src/Compute/Network.ts +5 -1
- package/src/Compute/Operations.ts +8 -4
- package/src/Compute/ProjectDefaultNetworkTier.ts +2 -0
- package/src/Compute/SharedVpcHost.ts +7 -1
- package/src/Compute/SharedVpcServiceProject.ts +5 -1
- package/src/Compute/Subnetwork.ts +9 -4
- package/src/Container/Cluster.ts +7 -3
- package/src/Container/NodePool.ts +2 -0
- package/src/Container/Operations.ts +10 -6
- package/src/Iam/Operations.ts +81 -0
- package/src/Iam/ServiceAccount.ts +6 -3
- package/src/Iam/ServiceAccountKey.ts +2 -0
- package/src/Iam/WorkloadIdentityPool.ts +309 -0
- package/src/Iam/WorkloadIdentityPoolProvider.ts +425 -0
- package/src/Iam/index.ts +10 -0
- package/src/Kubernetes/Helm.ts +2 -0
- package/src/Kubernetes/KubernetesManifest.ts +2 -0
- package/src/Kubernetes/Secret.ts +2 -0
- package/src/ManagedLustre/Instance.ts +10 -4
- package/src/Providers.ts +12 -0
- package/src/Run/IamSync.ts +4 -3
- package/src/Run/Job.ts +7 -3
- package/src/Run/Operations.ts +10 -6
- package/src/Run/Service.ts +7 -3
- package/src/ServiceNetworking/PsaConnection.ts +10 -4
- package/src/ServiceUsage/ApiEnable.ts +10 -4
- package/src/Sqladmin/Database.ts +2 -0
- package/src/Sqladmin/Instance.ts +7 -3
- package/src/Sqladmin/Operations.ts +8 -4
- package/src/Sqladmin/User.ts +2 -0
- package/src/Storage/Bucket.ts +6 -3
- package/src/Storage/StorageBucketIamMember.ts +6 -3
|
@@ -76,9 +76,10 @@ export const ArtifactRegistryRepositoryIamMemberProvider = () =>
|
|
|
76
76
|
effect.pipe(
|
|
77
77
|
Effect.retry({
|
|
78
78
|
while: (error) => (error as { _tag?: string })?._tag === "Conflict",
|
|
79
|
-
schedule: Schedule.
|
|
80
|
-
Schedule.
|
|
81
|
-
|
|
79
|
+
schedule: Schedule.max([
|
|
80
|
+
Schedule.exponential(Duration.millis(250)),
|
|
81
|
+
Schedule.recurs(8),
|
|
82
|
+
]),
|
|
82
83
|
}),
|
|
83
84
|
);
|
|
84
85
|
|
|
@@ -89,6 +90,8 @@ export const ArtifactRegistryRepositoryIamMemberProvider = () =>
|
|
|
89
90
|
});
|
|
90
91
|
|
|
91
92
|
return {
|
|
93
|
+
nuke: { skip: true },
|
|
94
|
+
list: () => Effect.succeed([]),
|
|
92
95
|
stables: ["repository", "role", "member"],
|
|
93
96
|
diff: Effect.fn(function* ({ news, olds = {}, output }) {
|
|
94
97
|
if (!isResolved(news)) return undefined;
|
|
@@ -242,9 +242,11 @@ export const ProjectProvider = () =>
|
|
|
242
242
|
),
|
|
243
243
|
Effect.retry({
|
|
244
244
|
while: (e: { _tag?: string }) => e?._tag === "OperationPending",
|
|
245
|
-
schedule: Schedule.
|
|
246
|
-
Schedule.
|
|
247
|
-
Schedule.
|
|
245
|
+
schedule: Schedule.max([
|
|
246
|
+
Schedule.exponential(Duration.seconds(1), 1.5),
|
|
247
|
+
Schedule.recurs(60),
|
|
248
|
+
]).pipe(
|
|
249
|
+
Schedule.tap(() =>
|
|
248
250
|
session.note(`Waiting for GCP operation ${operationName}…`),
|
|
249
251
|
),
|
|
250
252
|
),
|
|
@@ -467,13 +469,16 @@ export const ProjectProvider = () =>
|
|
|
467
469
|
});
|
|
468
470
|
}).pipe(
|
|
469
471
|
Effect.retry({
|
|
470
|
-
schedule: Schedule.
|
|
471
|
-
Schedule.
|
|
472
|
-
|
|
472
|
+
schedule: Schedule.max([
|
|
473
|
+
Schedule.exponential(Duration.seconds(2)),
|
|
474
|
+
Schedule.recurs(8),
|
|
475
|
+
]),
|
|
473
476
|
}),
|
|
474
477
|
);
|
|
475
478
|
|
|
476
479
|
return {
|
|
480
|
+
nuke: { skip: true },
|
|
481
|
+
list: () => Effect.succeed([]),
|
|
477
482
|
stables: ["projectId", "projectNumber", "name"],
|
|
478
483
|
diff: Effect.fn(function* ({ id, news, olds = {}, output }) {
|
|
479
484
|
if (!isResolved(news)) return undefined;
|
package/src/Compute/Address.ts
CHANGED
|
@@ -172,6 +172,8 @@ export const AddressProvider = () =>
|
|
|
172
172
|
});
|
|
173
173
|
|
|
174
174
|
return {
|
|
175
|
+
nuke: { skip: true },
|
|
176
|
+
list: () => Effect.succeed([]),
|
|
175
177
|
stables: ["name", "project", "region", "selfLink", "id", "address"],
|
|
176
178
|
diff: Effect.fn(function* ({ news, olds = {} }) {
|
|
177
179
|
if (!isResolved(news)) return undefined;
|
|
@@ -250,7 +252,7 @@ export const AddressProvider = () =>
|
|
|
250
252
|
});
|
|
251
253
|
}),
|
|
252
254
|
delete: Effect.fn(function* ({ output, session }) {
|
|
253
|
-
|
|
255
|
+
const deletion = deleteAddresses({
|
|
254
256
|
project: output.project,
|
|
255
257
|
region: output.region,
|
|
256
258
|
address: output.name,
|
|
@@ -260,6 +262,8 @@ export const AddressProvider = () =>
|
|
|
260
262
|
? awaitOp(output.project, output.region, op.name, session)
|
|
261
263
|
: Effect.succeed(op),
|
|
262
264
|
),
|
|
265
|
+
);
|
|
266
|
+
yield* deletion.pipe(
|
|
263
267
|
Effect.catchTag("NotFound", () => Effect.void),
|
|
264
268
|
// 400 "is being used by ..." comes back while a forwarding
|
|
265
269
|
// rule still references the address. The rule must be
|
package/src/Compute/Firewall.ts
CHANGED
|
@@ -199,6 +199,8 @@ export const FirewallProvider = () =>
|
|
|
199
199
|
);
|
|
200
200
|
|
|
201
201
|
return {
|
|
202
|
+
nuke: { skip: true },
|
|
203
|
+
list: () => Effect.succeed([]),
|
|
202
204
|
stables: ["name", "project", "selfLink", "id", "network"],
|
|
203
205
|
diff: Effect.fn(function* ({ news, olds = {} }) {
|
|
204
206
|
if (!isResolved(news)) return undefined;
|
|
@@ -297,7 +299,7 @@ export const FirewallProvider = () =>
|
|
|
297
299
|
return toFirewallAttributes(final, { project: news.project });
|
|
298
300
|
}),
|
|
299
301
|
delete: Effect.fn(function* ({ output, session }) {
|
|
300
|
-
|
|
302
|
+
const deletion = deleteFirewalls({
|
|
301
303
|
project: output.project,
|
|
302
304
|
firewall: output.name,
|
|
303
305
|
}).pipe(
|
|
@@ -306,6 +308,8 @@ export const FirewallProvider = () =>
|
|
|
306
308
|
? awaitOp(output.project, op.name, session)
|
|
307
309
|
: Effect.succeed(op),
|
|
308
310
|
),
|
|
311
|
+
);
|
|
312
|
+
yield* deletion.pipe(
|
|
309
313
|
Effect.catchTag("NotFound", () => Effect.void),
|
|
310
314
|
);
|
|
311
315
|
}),
|
|
@@ -182,6 +182,8 @@ export const ForwardingRuleProvider = () =>
|
|
|
182
182
|
});
|
|
183
183
|
|
|
184
184
|
return {
|
|
185
|
+
nuke: { skip: true },
|
|
186
|
+
list: () => Effect.succeed([]),
|
|
185
187
|
stables: ["name", "project", "region", "selfLink", "id"],
|
|
186
188
|
diff: Effect.fn(function* ({ news, olds = {} }) {
|
|
187
189
|
if (!isResolved(news)) return undefined;
|
|
@@ -265,7 +267,7 @@ export const ForwardingRuleProvider = () =>
|
|
|
265
267
|
});
|
|
266
268
|
}),
|
|
267
269
|
delete: Effect.fn(function* ({ output, session }) {
|
|
268
|
-
|
|
270
|
+
const deletion = deleteForwardingRules({
|
|
269
271
|
project: output.project,
|
|
270
272
|
region: output.region,
|
|
271
273
|
forwardingRule: output.name,
|
|
@@ -275,6 +277,8 @@ export const ForwardingRuleProvider = () =>
|
|
|
275
277
|
? awaitOp(output.project, output.region, op.name, session)
|
|
276
278
|
: Effect.succeed(op),
|
|
277
279
|
),
|
|
280
|
+
);
|
|
281
|
+
yield* deletion.pipe(
|
|
278
282
|
Effect.catchTag("NotFound", () => Effect.void),
|
|
279
283
|
);
|
|
280
284
|
}),
|
|
@@ -176,6 +176,8 @@ export const GlobalAddressProvider = () =>
|
|
|
176
176
|
});
|
|
177
177
|
|
|
178
178
|
return {
|
|
179
|
+
nuke: { skip: true },
|
|
180
|
+
list: () => Effect.succeed([]),
|
|
179
181
|
stables: ["name", "project", "selfLink", "id", "address"],
|
|
180
182
|
diff: Effect.fn(function* ({ news, olds = {} }) {
|
|
181
183
|
if (!isResolved(news)) return undefined;
|
|
@@ -248,7 +250,7 @@ export const GlobalAddressProvider = () =>
|
|
|
248
250
|
return toGlobalAddressAttributes(final, { project: news.project });
|
|
249
251
|
}),
|
|
250
252
|
delete: Effect.fn(function* ({ output, session }) {
|
|
251
|
-
|
|
253
|
+
const deletion = deleteGlobalAddresses({
|
|
252
254
|
project: output.project,
|
|
253
255
|
address: output.name,
|
|
254
256
|
}).pipe(
|
|
@@ -257,6 +259,8 @@ export const GlobalAddressProvider = () =>
|
|
|
257
259
|
? awaitOp(output.project, op.name, session)
|
|
258
260
|
: Effect.succeed(op),
|
|
259
261
|
),
|
|
262
|
+
);
|
|
263
|
+
yield* deletion.pipe(
|
|
260
264
|
Effect.catchTag("NotFound", () => Effect.void),
|
|
261
265
|
// 400 with "is being used by ..." comes back when a PSA
|
|
262
266
|
// connection still references the range. The user has to
|
package/src/Compute/Network.ts
CHANGED
|
@@ -252,6 +252,8 @@ export const NetworkProvider = () =>
|
|
|
252
252
|
});
|
|
253
253
|
|
|
254
254
|
return {
|
|
255
|
+
nuke: { skip: true },
|
|
256
|
+
list: () => Effect.succeed([]),
|
|
255
257
|
stables: ["name", "project", "selfLink", "id"],
|
|
256
258
|
diff: Effect.fn(function* ({ news, olds = {} }) {
|
|
257
259
|
if (!isResolved(news)) return undefined;
|
|
@@ -326,7 +328,7 @@ export const NetworkProvider = () =>
|
|
|
326
328
|
return toNetworkAttributes(final, { project: news.project });
|
|
327
329
|
}),
|
|
328
330
|
delete: Effect.fn(function* ({ output, session }) {
|
|
329
|
-
|
|
331
|
+
const deletion = deleteNetworks({
|
|
330
332
|
project: output.project,
|
|
331
333
|
network: output.name,
|
|
332
334
|
}).pipe(
|
|
@@ -335,6 +337,8 @@ export const NetworkProvider = () =>
|
|
|
335
337
|
? awaitOp(output.project, op.name, session)
|
|
336
338
|
: Effect.succeed(op),
|
|
337
339
|
),
|
|
340
|
+
);
|
|
341
|
+
yield* deletion.pipe(
|
|
338
342
|
Effect.catchTag("NotFound", () => Effect.void),
|
|
339
343
|
);
|
|
340
344
|
}),
|
|
@@ -30,13 +30,17 @@ const formatOperationError = (op: compute.Operation): string => {
|
|
|
30
30
|
const isDone = (op: compute.Operation): boolean => op.status === "DONE";
|
|
31
31
|
|
|
32
32
|
const pollSchedule = (label: string, session: ScopedPlanStatusSession) =>
|
|
33
|
-
Schedule.
|
|
34
|
-
Schedule.
|
|
33
|
+
Schedule.max([
|
|
34
|
+
Schedule.min([
|
|
35
|
+
Schedule.exponential(Duration.seconds(2), 1.5),
|
|
36
|
+
Schedule.spaced(Duration.seconds(15)),
|
|
37
|
+
]),
|
|
35
38
|
// 80 × ≤15s ≈ 20 min — long enough for a network create (~1 min),
|
|
36
39
|
// a parallelstore-adjacent global op, or a 10-minute parallelstore
|
|
37
40
|
// delete (longest LRO observed in this provider's surface).
|
|
38
|
-
Schedule.
|
|
39
|
-
|
|
41
|
+
Schedule.recurs(80),
|
|
42
|
+
]).pipe(
|
|
43
|
+
Schedule.tap(() =>
|
|
40
44
|
session.note(`Waiting for Compute operation ${label}…`),
|
|
41
45
|
),
|
|
42
46
|
);
|
|
@@ -55,6 +55,8 @@ export const ProjectDefaultNetworkTierProvider = () =>
|
|
|
55
55
|
);
|
|
56
56
|
|
|
57
57
|
return {
|
|
58
|
+
nuke: { singleton: true },
|
|
59
|
+
list: () => Effect.succeed([]),
|
|
58
60
|
stables: ["project"],
|
|
59
61
|
diff: Effect.fn(function* ({ news, olds = {} }) {
|
|
60
62
|
if (!isResolved(news)) return undefined;
|
|
@@ -75,6 +75,8 @@ export const SharedVpcHostProvider = () =>
|
|
|
75
75
|
);
|
|
76
76
|
|
|
77
77
|
return {
|
|
78
|
+
nuke: { singleton: true },
|
|
79
|
+
list: () => Effect.succeed([]),
|
|
78
80
|
stables: ["project"],
|
|
79
81
|
diff: Effect.fn(function* ({ news, olds = {} }) {
|
|
80
82
|
if (!isResolved(news)) return undefined;
|
|
@@ -104,12 +106,16 @@ export const SharedVpcHostProvider = () =>
|
|
|
104
106
|
return { project: news.project, xpnProjectStatus: "HOST" };
|
|
105
107
|
}),
|
|
106
108
|
delete: Effect.fn(function* ({ output, session }) {
|
|
107
|
-
|
|
109
|
+
const disabling = disableXpnHostProjects({
|
|
110
|
+
project: output.project,
|
|
111
|
+
}).pipe(
|
|
108
112
|
Effect.flatMap((op) =>
|
|
109
113
|
op.name
|
|
110
114
|
? awaitOp(output.project, op.name, session)
|
|
111
115
|
: Effect.succeed(op),
|
|
112
116
|
),
|
|
117
|
+
);
|
|
118
|
+
yield* disabling.pipe(
|
|
113
119
|
Effect.catchTag("NotFound", () => Effect.void),
|
|
114
120
|
// `BadRequest` is returned when:
|
|
115
121
|
// 1. The project isn't a host (idempotent disable — fine).
|
|
@@ -125,6 +125,8 @@ export const SharedVpcServiceProjectProvider = () =>
|
|
|
125
125
|
});
|
|
126
126
|
|
|
127
127
|
return {
|
|
128
|
+
nuke: { skip: true },
|
|
129
|
+
list: () => Effect.succeed([]),
|
|
128
130
|
stables: ["hostProject", "serviceProject"],
|
|
129
131
|
diff: Effect.fn(function* ({ news, olds = {} }) {
|
|
130
132
|
if (!isResolved(news)) return undefined;
|
|
@@ -153,7 +155,7 @@ export const SharedVpcServiceProjectProvider = () =>
|
|
|
153
155
|
};
|
|
154
156
|
}),
|
|
155
157
|
delete: Effect.fn(function* ({ output, session }) {
|
|
156
|
-
|
|
158
|
+
const disabling = disableXpnResource({
|
|
157
159
|
project: output.hostProject,
|
|
158
160
|
body: {
|
|
159
161
|
xpnResource: { type: "PROJECT", id: output.serviceProject },
|
|
@@ -164,6 +166,8 @@ export const SharedVpcServiceProjectProvider = () =>
|
|
|
164
166
|
? awaitOp(output.hostProject, op.name, session)
|
|
165
167
|
: Effect.succeed(op),
|
|
166
168
|
),
|
|
169
|
+
);
|
|
170
|
+
yield* disabling.pipe(
|
|
167
171
|
Effect.catchTag("NotFound", () => Effect.void),
|
|
168
172
|
// `BadRequest` covers "not attached to this host" (idempotent
|
|
169
173
|
// detach); other 400s (resources still using shared subnets)
|
|
@@ -254,9 +254,10 @@ export const SubnetworkProvider = () =>
|
|
|
254
254
|
// multiple bindings in parallel, races are common. Cap at
|
|
255
255
|
// ~1.5 min total to surface real failures.
|
|
256
256
|
Effect.retry({
|
|
257
|
-
schedule: Schedule.
|
|
258
|
-
Schedule.
|
|
259
|
-
|
|
257
|
+
schedule: Schedule.max([
|
|
258
|
+
Schedule.exponential(Duration.seconds(2)),
|
|
259
|
+
Schedule.recurs(8),
|
|
260
|
+
]),
|
|
260
261
|
}),
|
|
261
262
|
);
|
|
262
263
|
|
|
@@ -344,6 +345,8 @@ export const SubnetworkProvider = () =>
|
|
|
344
345
|
});
|
|
345
346
|
|
|
346
347
|
return {
|
|
348
|
+
nuke: { skip: true },
|
|
349
|
+
list: () => Effect.succeed([]),
|
|
347
350
|
stables: ["name", "project", "region", "selfLink", "id"],
|
|
348
351
|
diff: Effect.fn(function* ({ news, olds = {} }) {
|
|
349
352
|
if (!isResolved(news)) return undefined;
|
|
@@ -445,7 +448,7 @@ export const SubnetworkProvider = () =>
|
|
|
445
448
|
});
|
|
446
449
|
}),
|
|
447
450
|
delete: Effect.fn(function* ({ output, session }) {
|
|
448
|
-
|
|
451
|
+
const deletion = deleteSubnetworks({
|
|
449
452
|
project: output.project,
|
|
450
453
|
region: output.region,
|
|
451
454
|
subnetwork: output.name,
|
|
@@ -455,6 +458,8 @@ export const SubnetworkProvider = () =>
|
|
|
455
458
|
? awaitOp(output.project, output.region, op.name, session)
|
|
456
459
|
: Effect.succeed(op),
|
|
457
460
|
),
|
|
461
|
+
);
|
|
462
|
+
yield* deletion.pipe(
|
|
458
463
|
Effect.catchTag("NotFound", () => Effect.void),
|
|
459
464
|
);
|
|
460
465
|
}),
|
package/src/Container/Cluster.ts
CHANGED
|
@@ -505,6 +505,8 @@ export const ClusterProvider = () =>
|
|
|
505
505
|
});
|
|
506
506
|
|
|
507
507
|
return {
|
|
508
|
+
nuke: { skip: true },
|
|
509
|
+
list: () => Effect.succeed([]),
|
|
508
510
|
stables: [
|
|
509
511
|
"name",
|
|
510
512
|
"selfLink",
|
|
@@ -595,9 +597,11 @@ export const ClusterProvider = () =>
|
|
|
595
597
|
while: (e: { _tag?: string; message?: string }) =>
|
|
596
598
|
e?._tag === "Forbidden" &&
|
|
597
599
|
/enabled this API recently|has not been used/i.test(e.message ?? ""),
|
|
598
|
-
schedule: Schedule.
|
|
599
|
-
Schedule.
|
|
600
|
-
Schedule.
|
|
600
|
+
schedule: Schedule.max([
|
|
601
|
+
Schedule.spaced(Duration.seconds(15)),
|
|
602
|
+
Schedule.recurs(20), // 20 × 15s ≈ 5 min
|
|
603
|
+
]).pipe(
|
|
604
|
+
Schedule.tap(() =>
|
|
601
605
|
session.note(
|
|
602
606
|
"Waiting for Container API enablement to propagate…",
|
|
603
607
|
),
|
|
@@ -546,6 +546,8 @@ export const NodePoolProvider = () =>
|
|
|
546
546
|
});
|
|
547
547
|
|
|
548
548
|
return {
|
|
549
|
+
nuke: { skip: true },
|
|
550
|
+
list: () => Effect.succeed([]),
|
|
549
551
|
stables: ["name", "selfLink", "project", "location", "clusterName"],
|
|
550
552
|
diff: Effect.fn(function* ({ news, olds = {} }) {
|
|
551
553
|
if (!isResolved(news)) return undefined;
|
|
@@ -46,8 +46,8 @@ type GetOperations = Effect.Success<typeof cont.getProjectsLocationsOperations>;
|
|
|
46
46
|
* The doneness predicate compares `.status === "DONE"` accordingly.
|
|
47
47
|
*
|
|
48
48
|
* Schedule: exponential 2s → 1.5× growth, capped per-poll at 15s via
|
|
49
|
-
* `Schedule.
|
|
50
|
-
* `Schedule.
|
|
49
|
+
* `Schedule.min`, then a hard count cap of 80 retries via
|
|
50
|
+
* `Schedule.max` → ~20 min wall ceiling, well
|
|
51
51
|
* above the worst observed GKE op time (cluster create runs 5–10 min).
|
|
52
52
|
*
|
|
53
53
|
* The helper is a factory — the caller resolves
|
|
@@ -68,10 +68,14 @@ export const makeAwaitOperation = (getOperations: GetOperations) =>
|
|
|
68
68
|
),
|
|
69
69
|
Effect.retry({
|
|
70
70
|
while: (e: { _tag?: string }) => e?._tag === "OperationPending",
|
|
71
|
-
schedule: Schedule.
|
|
72
|
-
Schedule.
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
schedule: Schedule.max([
|
|
72
|
+
Schedule.min([
|
|
73
|
+
Schedule.exponential(Duration.seconds(2), 1.5),
|
|
74
|
+
Schedule.spaced(Duration.seconds(15)),
|
|
75
|
+
]),
|
|
76
|
+
Schedule.recurs(80),
|
|
77
|
+
]).pipe(
|
|
78
|
+
Schedule.tap(() =>
|
|
75
79
|
session.note(`Waiting for GKE operation ${operationName}…`),
|
|
76
80
|
),
|
|
77
81
|
),
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { ConfigError } from "@distilled.cloud/gcp";
|
|
2
|
+
import type * as iam from "@distilled.cloud/gcp/unstable/iam-v1";
|
|
3
|
+
import type { ScopedPlanStatusSession } from "alchemy/Cli/Cli";
|
|
4
|
+
import * as Duration from "effect/Duration";
|
|
5
|
+
import * as Effect from "effect/Effect";
|
|
6
|
+
import * as Schedule from "effect/Schedule";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Resolved callable signature of an `iam-v1` operations getter.
|
|
10
|
+
*
|
|
11
|
+
* Workload Identity pools and providers each have their own operations
|
|
12
|
+
* collection (`…WorkloadIdentityPoolsOperations`,
|
|
13
|
+
* `…WorkloadIdentityPoolsProvidersOperations`) rather than one shared
|
|
14
|
+
* endpoint, so this is generic over the getter and each resource passes its
|
|
15
|
+
* own — the same factory shape `ArtifactRegistry/Operations.ts` uses.
|
|
16
|
+
*/
|
|
17
|
+
type GetOperations = Effect.Success<
|
|
18
|
+
typeof iam.getProjectsLocationsWorkloadIdentityPoolsOperations
|
|
19
|
+
>;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Build the IAM long-running-operation polling helper.
|
|
23
|
+
*
|
|
24
|
+
* `iam-v1` operations use the standard `google.longrunning.Operation` shape —
|
|
25
|
+
* doneness is `.done === true` and failure is a populated `.error` (NOT
|
|
26
|
+
* Container's `.status === "DONE"`, and NOT Sqladmin's tri-state `.status`).
|
|
27
|
+
* Verified against the `Operation` interface in
|
|
28
|
+
* `vendor/distilled/packages/gcp/src/unstable-services/iam-v1.ts`.
|
|
29
|
+
*
|
|
30
|
+
* Operation names returned by pool/provider create and delete are already
|
|
31
|
+
* fully qualified (`projects/{p}/locations/global/workloadIdentityPools/{id}/operations/{op}`),
|
|
32
|
+
* so callers pass them straight through — no qualify dance.
|
|
33
|
+
*
|
|
34
|
+
* Schedule: exponential 1s → 1.5× growth, capped per-poll at 10s via
|
|
35
|
+
* `Schedule.min`, then a hard count cap of 60 retries via `Schedule.max`
|
|
36
|
+
* → ~10 min wall ceiling. Pool and provider CRUD normally settles in
|
|
37
|
+
* seconds; the ceiling exists so a stuck operation surfaces as an error
|
|
38
|
+
* rather than hanging a deploy indefinitely.
|
|
39
|
+
*
|
|
40
|
+
* The helper is a factory — the caller resolves the operations getter once at
|
|
41
|
+
* provider construction and passes the resulting callable here, so we never
|
|
42
|
+
* re-resolve services on each await.
|
|
43
|
+
*/
|
|
44
|
+
export const makeAwaitOperation = (
|
|
45
|
+
getOperations: GetOperations,
|
|
46
|
+
label: string,
|
|
47
|
+
) =>
|
|
48
|
+
Effect.fn(function* (
|
|
49
|
+
operationName: string,
|
|
50
|
+
session: ScopedPlanStatusSession,
|
|
51
|
+
) {
|
|
52
|
+
const op = yield* getOperations({ name: operationName }).pipe(
|
|
53
|
+
Effect.flatMap((current) =>
|
|
54
|
+
current.done === true
|
|
55
|
+
? Effect.succeed(current)
|
|
56
|
+
: Effect.fail({ _tag: "OperationPending" as const }),
|
|
57
|
+
),
|
|
58
|
+
Effect.retry({
|
|
59
|
+
while: (e: { _tag?: string }) => e?._tag === "OperationPending",
|
|
60
|
+
schedule: Schedule.max([
|
|
61
|
+
Schedule.min([
|
|
62
|
+
Schedule.exponential(Duration.seconds(1), 1.5),
|
|
63
|
+
Schedule.spaced(Duration.seconds(10)),
|
|
64
|
+
]),
|
|
65
|
+
Schedule.recurs(60),
|
|
66
|
+
]).pipe(
|
|
67
|
+
Schedule.tap(() =>
|
|
68
|
+
session.note(`Waiting for ${label} operation ${operationName}…`),
|
|
69
|
+
),
|
|
70
|
+
),
|
|
71
|
+
}),
|
|
72
|
+
);
|
|
73
|
+
if (op.error) {
|
|
74
|
+
return yield* new ConfigError({
|
|
75
|
+
message: `${label} operation ${operationName} failed: ${
|
|
76
|
+
op.error.message ?? JSON.stringify(op.error)
|
|
77
|
+
}`,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return op;
|
|
81
|
+
});
|
|
@@ -330,9 +330,10 @@ export const ServiceAccountProvider = () =>
|
|
|
330
330
|
});
|
|
331
331
|
}).pipe(
|
|
332
332
|
Effect.retry({
|
|
333
|
-
schedule: Schedule.
|
|
334
|
-
Schedule.
|
|
335
|
-
|
|
333
|
+
schedule: Schedule.max([
|
|
334
|
+
Schedule.exponential(Duration.seconds(2)),
|
|
335
|
+
Schedule.recurs(8),
|
|
336
|
+
]),
|
|
336
337
|
}),
|
|
337
338
|
);
|
|
338
339
|
|
|
@@ -340,6 +341,8 @@ export const ServiceAccountProvider = () =>
|
|
|
340
341
|
// Stable identity: accountId + project; both immutable; either
|
|
341
342
|
// change → replace. The server-assigned uniqueId is also stable
|
|
342
343
|
// for the lifetime of the GSA (re-create gets a different one).
|
|
344
|
+
nuke: { skip: true },
|
|
345
|
+
list: () => Effect.succeed([]),
|
|
343
346
|
stables: ["accountId", "projectId", "uniqueId", "name", "email"],
|
|
344
347
|
diff: Effect.fn(function* ({ id, news, olds = {}, output }) {
|
|
345
348
|
if (!isResolved(news)) return undefined;
|
|
@@ -153,6 +153,8 @@ export const ServiceAccountKeyProvider = () =>
|
|
|
153
153
|
// privateKeyData is stable: it's set on create and never
|
|
154
154
|
// changes. The engine preserves it across reconciles and
|
|
155
155
|
// does not use it for drift detection.
|
|
156
|
+
nuke: { skip: true },
|
|
157
|
+
list: () => Effect.succeed([]),
|
|
156
158
|
stables: ["name", "privateKeyData", "keyAlgorithm", "keyType"],
|
|
157
159
|
diff: Effect.fn(function* ({ news, olds = {} }) {
|
|
158
160
|
if (!isResolved(news)) return undefined;
|