@microagi/alchemy-gcp 0.2.0 → 0.3.0
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 +65 -0
- package/README.md +54 -2
- package/lib/Container/Cluster.d.ts +25 -0
- package/lib/Container/Cluster.d.ts.map +1 -1
- package/lib/Container/Cluster.js.map +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/IamMember.d.ts +70 -0
- package/lib/Run/IamMember.d.ts.map +1 -0
- package/lib/Run/IamMember.js +65 -0
- package/lib/Run/IamMember.js.map +1 -0
- package/lib/Run/IamSync.d.ts +80 -0
- package/lib/Run/IamSync.d.ts.map +1 -0
- package/lib/Run/IamSync.js +73 -0
- package/lib/Run/IamSync.js.map +1 -0
- package/lib/Run/Job.d.ts +167 -0
- package/lib/Run/Job.d.ts.map +1 -0
- package/lib/Run/Job.js +199 -0
- package/lib/Run/Job.js.map +1 -0
- package/lib/Run/Operations.d.ts +47 -0
- package/lib/Run/Operations.d.ts.map +1 -0
- package/lib/Run/Operations.js +46 -0
- package/lib/Run/Operations.js.map +1 -0
- package/lib/Run/Service.d.ts +193 -0
- package/lib/Run/Service.d.ts.map +1 -0
- package/lib/Run/Service.js +247 -0
- package/lib/Run/Service.js.map +1 -0
- package/lib/Run/Validation.d.ts +54 -0
- package/lib/Run/Validation.d.ts.map +1 -0
- package/lib/Run/Validation.js +129 -0
- package/lib/Run/Validation.js.map +1 -0
- package/lib/Run/index.d.ts +51 -0
- package/lib/Run/index.d.ts.map +1 -0
- package/lib/Run/index.js +4 -0
- package/lib/Run/index.js.map +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/package.json +5 -4
- package/src/Container/Cluster.ts +25 -0
- package/src/Providers.ts +6 -0
- package/src/Run/IamMember.ts +79 -0
- package/src/Run/IamSync.ts +134 -0
- package/src/Run/Job.ts +453 -0
- package/src/Run/Operations.ts +77 -0
- package/src/Run/Service.ts +541 -0
- package/src/Run/Validation.ts +153 -0
- package/src/Run/index.ts +52 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Validation.js","sourceRoot":"","sources":["../../src/Run/Validation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type * as run from "@distilled.cloud/gcp/run-v2";
|
|
2
|
+
export { Job, JobProvider } from "./Job.ts";
|
|
3
|
+
export type { JobAttributes, JobProps } from "./Job.ts";
|
|
4
|
+
export { jobIamMember, serviceIamMember } from "./IamMember.ts";
|
|
5
|
+
export type { RunIamBinding, RunIamBindingContract } from "./IamSync.ts";
|
|
6
|
+
export { Service, ServiceProvider } from "./Service.ts";
|
|
7
|
+
export type { ServiceAttributes, ServiceProps } from "./Service.ts";
|
|
8
|
+
/**
|
|
9
|
+
* Clean aliases for the most commonly-used Cloud Run v2 SDK types,
|
|
10
|
+
* re-exported from `@distilled.cloud/gcp/run-v2` so consumers don't
|
|
11
|
+
* need to import from the underlying SDK directly. The aliases are
|
|
12
|
+
* type-only — they share identity with the distilled types, so values
|
|
13
|
+
* are interchangeable.
|
|
14
|
+
*
|
|
15
|
+
* The `GoogleCloudRunV2*` prefix on the SDK types is generated from
|
|
16
|
+
* the GCP Discovery Document and is awkward to consume; these aliases
|
|
17
|
+
* mirror the casing the GCP REST docs use ("RevisionTemplate",
|
|
18
|
+
* "Container", "TrafficTarget"), which is what most users will
|
|
19
|
+
* already have in their heads.
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* import * as GCP from "@microagi/alchemy-gcp";
|
|
24
|
+
*
|
|
25
|
+
* const template: GCP.RevisionTemplate = {
|
|
26
|
+
* containers: [{ image: "..." }],
|
|
27
|
+
* };
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export type RevisionTemplate = run.GoogleCloudRunV2RevisionTemplate;
|
|
31
|
+
export type ExecutionTemplate = run.GoogleCloudRunV2ExecutionTemplate;
|
|
32
|
+
export type TaskTemplate = run.GoogleCloudRunV2TaskTemplate;
|
|
33
|
+
export type Container = run.GoogleCloudRunV2Container;
|
|
34
|
+
export type ContainerPort = run.GoogleCloudRunV2ContainerPort;
|
|
35
|
+
export type EnvVar = run.GoogleCloudRunV2EnvVar;
|
|
36
|
+
export type EnvVarSource = run.GoogleCloudRunV2EnvVarSource;
|
|
37
|
+
export type ResourceRequirements = run.GoogleCloudRunV2ResourceRequirements;
|
|
38
|
+
export type Probe = run.GoogleCloudRunV2Probe;
|
|
39
|
+
export type VpcAccess = run.GoogleCloudRunV2VpcAccess;
|
|
40
|
+
export type NetworkInterface = run.GoogleCloudRunV2NetworkInterface;
|
|
41
|
+
export type NodeSelector = run.GoogleCloudRunV2NodeSelector;
|
|
42
|
+
export type TrafficTarget = run.GoogleCloudRunV2TrafficTarget;
|
|
43
|
+
export type TrafficTargetStatus = run.GoogleCloudRunV2TrafficTargetStatus;
|
|
44
|
+
export type ServiceScaling = run.GoogleCloudRunV2ServiceScaling;
|
|
45
|
+
export type BinaryAuthorization = run.GoogleCloudRunV2BinaryAuthorization;
|
|
46
|
+
export type Volume = run.GoogleCloudRunV2Volume;
|
|
47
|
+
export type VolumeMount = run.GoogleCloudRunV2VolumeMount;
|
|
48
|
+
export type Condition = run.GoogleCloudRunV2Condition;
|
|
49
|
+
export type ExecutionReference = run.GoogleCloudRunV2ExecutionReference;
|
|
50
|
+
export type SecretKeySelector = run.GoogleCloudRunV2SecretKeySelector;
|
|
51
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Run/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,GAAG,MAAM,6BAA6B,CAAC;AAExD,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAChE,YAAY,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACzE,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACxD,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEpE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,gBAAgB,GAAG,GAAG,CAAC,gCAAgC,CAAC;AACpE,MAAM,MAAM,iBAAiB,GAAG,GAAG,CAAC,iCAAiC,CAAC;AACtE,MAAM,MAAM,YAAY,GAAG,GAAG,CAAC,4BAA4B,CAAC;AAC5D,MAAM,MAAM,SAAS,GAAG,GAAG,CAAC,yBAAyB,CAAC;AACtD,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,6BAA6B,CAAC;AAC9D,MAAM,MAAM,MAAM,GAAG,GAAG,CAAC,sBAAsB,CAAC;AAChD,MAAM,MAAM,YAAY,GAAG,GAAG,CAAC,4BAA4B,CAAC;AAC5D,MAAM,MAAM,oBAAoB,GAAG,GAAG,CAAC,oCAAoC,CAAC;AAC5E,MAAM,MAAM,KAAK,GAAG,GAAG,CAAC,qBAAqB,CAAC;AAC9C,MAAM,MAAM,SAAS,GAAG,GAAG,CAAC,yBAAyB,CAAC;AACtD,MAAM,MAAM,gBAAgB,GAAG,GAAG,CAAC,gCAAgC,CAAC;AACpE,MAAM,MAAM,YAAY,GAAG,GAAG,CAAC,4BAA4B,CAAC;AAC5D,MAAM,MAAM,aAAa,GAAG,GAAG,CAAC,6BAA6B,CAAC;AAC9D,MAAM,MAAM,mBAAmB,GAAG,GAAG,CAAC,mCAAmC,CAAC;AAC1E,MAAM,MAAM,cAAc,GAAG,GAAG,CAAC,8BAA8B,CAAC;AAChE,MAAM,MAAM,mBAAmB,GAAG,GAAG,CAAC,mCAAmC,CAAC;AAC1E,MAAM,MAAM,MAAM,GAAG,GAAG,CAAC,sBAAsB,CAAC;AAChD,MAAM,MAAM,WAAW,GAAG,GAAG,CAAC,2BAA2B,CAAC;AAC1D,MAAM,MAAM,SAAS,GAAG,GAAG,CAAC,yBAAyB,CAAC;AACtD,MAAM,MAAM,kBAAkB,GAAG,GAAG,CAAC,kCAAkC,CAAC;AACxE,MAAM,MAAM,iBAAiB,GAAG,GAAG,CAAC,iCAAiC,CAAC"}
|
package/lib/Run/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/Run/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEhE,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
|
package/lib/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export * from "./CloudResourceManager/index.ts";
|
|
|
5
5
|
export * from "./Compute/index.ts";
|
|
6
6
|
export * from "./Container/index.ts";
|
|
7
7
|
export * from "./ManagedLustre/index.ts";
|
|
8
|
+
export * from "./Run/index.ts";
|
|
8
9
|
export * from "./ServiceNetworking/index.ts";
|
|
9
10
|
export * from "./ServiceUsage/index.ts";
|
|
10
11
|
export * from "./Providers.ts";
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EACL,sBAAsB,EACtB,OAAO,GACR,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,aAAa,EACb,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAChC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EACL,sBAAsB,EACtB,OAAO,GACR,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,aAAa,EACb,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAChC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -4,6 +4,7 @@ export * from "./CloudResourceManager/index.js";
|
|
|
4
4
|
export * from "./Compute/index.js";
|
|
5
5
|
export * from "./Container/index.js";
|
|
6
6
|
export * from "./ManagedLustre/index.js";
|
|
7
|
+
export * from "./Run/index.js";
|
|
7
8
|
export * from "./ServiceNetworking/index.js";
|
|
8
9
|
export * from "./ServiceUsage/index.js";
|
|
9
10
|
export * from "./Providers.js";
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EACL,sBAAsB,EACtB,OAAO,GACR,MAAM,wBAAwB,CAAC;AAKhC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,EACL,sBAAsB,EACtB,OAAO,GACR,MAAM,wBAAwB,CAAC;AAKhC,cAAc,iCAAiC,CAAC;AAChD,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,0BAA0B,CAAC;AACzC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,yBAAyB,CAAC;AACxC,cAAc,gBAAgB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@microagi/alchemy-gcp",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "GCP provider for Alchemy v2 (Effect-based IaC). Resources for Project, Cluster, NodePool, Compute, ManagedLustre, ServiceUsage, ServiceNetworking, with ADC-backed credentials and target-side IAM bindings.",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "GCP provider for Alchemy v2 (Effect-based IaC). Resources for Project, Cluster, NodePool, Compute, ManagedLustre, ServiceUsage, ServiceNetworking, Cloud Run (Service + Job + IAM), with ADC-backed credentials and target-side IAM bindings.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"alchemy",
|
|
7
7
|
"alchemy-effect",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"files": [
|
|
32
32
|
"lib",
|
|
33
33
|
"src",
|
|
34
|
+
"CHANGELOG.md",
|
|
34
35
|
"README.md",
|
|
35
36
|
"LICENSE"
|
|
36
37
|
],
|
|
@@ -57,10 +58,10 @@
|
|
|
57
58
|
"effect": ">=4.0.0-beta.60 || >=4.0.0"
|
|
58
59
|
},
|
|
59
60
|
"devDependencies": {
|
|
60
|
-
"@distilled.cloud/gcp": "
|
|
61
|
+
"@distilled.cloud/gcp": "workspace:*",
|
|
61
62
|
"@types/bun": "latest",
|
|
62
63
|
"@types/node": "latest",
|
|
63
|
-
"alchemy": "
|
|
64
|
+
"alchemy": "workspace:*",
|
|
64
65
|
"effect": ">=4.0.0-beta.60 || >=4.0.0",
|
|
65
66
|
"typescript": "^6.0.3"
|
|
66
67
|
},
|
package/src/Container/Cluster.ts
CHANGED
|
@@ -88,6 +88,31 @@ export type ClusterProps = {
|
|
|
88
88
|
networkPolicyConfig?: { disabled?: boolean };
|
|
89
89
|
gcePersistentDiskCsiDriverConfig?: { enabled?: boolean };
|
|
90
90
|
gcsFuseCsiDriverConfig?: { enabled?: boolean };
|
|
91
|
+
/**
|
|
92
|
+
* Managed Lustre CSI driver (mount `GCP.ManagedLustreInstance`
|
|
93
|
+
* volumes as ReadWriteMany PVCs from pods). Driver is installed
|
|
94
|
+
* cluster-wide once enabled; the StorageClass + PV bindings are
|
|
95
|
+
* still authored by the consumer.
|
|
96
|
+
*/
|
|
97
|
+
lustreCsiDriverConfig?: {
|
|
98
|
+
enabled?: boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Workaround for a port conflict between the Lustre CSI driver
|
|
101
|
+
* and `gke-metadata-server`. Required ONLY when the cluster's
|
|
102
|
+
* GKE node version is older than `1.33.2-gke.4655000` AND you
|
|
103
|
+
* are mounting a `ManagedLustreInstance` with
|
|
104
|
+
* `gkeSupportEnabled: true`. Deprecated otherwise — leave
|
|
105
|
+
* unset on modern node versions.
|
|
106
|
+
*/
|
|
107
|
+
enableLegacyLustrePort?: boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Disable the driver's multi-NIC auto-configuration. By
|
|
110
|
+
* default it discovers and binds every suitable NIC on each
|
|
111
|
+
* node for maximum I/O throughput. Set true only if multi-NIC
|
|
112
|
+
* causes a problem in your network topology.
|
|
113
|
+
*/
|
|
114
|
+
disableMultiNic?: boolean;
|
|
115
|
+
};
|
|
91
116
|
gkeBackupAgentConfig?: { enabled?: boolean };
|
|
92
117
|
dnsCacheConfig?: { enabled?: boolean };
|
|
93
118
|
configConnectorConfig?: { enabled?: boolean };
|
package/src/Providers.ts
CHANGED
|
@@ -17,6 +17,8 @@ import {
|
|
|
17
17
|
ManagedLustreInstance,
|
|
18
18
|
ManagedLustreInstanceProvider,
|
|
19
19
|
} from "./ManagedLustre/Instance.ts";
|
|
20
|
+
import { Job, JobProvider } from "./Run/Job.ts";
|
|
21
|
+
import { Service, ServiceProvider } from "./Run/Service.ts";
|
|
20
22
|
import {
|
|
21
23
|
PsaConnection,
|
|
22
24
|
PsaConnectionProvider,
|
|
@@ -57,6 +59,8 @@ export const providers = () =>
|
|
|
57
59
|
SharedVpcServiceProject,
|
|
58
60
|
PsaConnection,
|
|
59
61
|
ManagedLustreInstance,
|
|
62
|
+
Service,
|
|
63
|
+
Job,
|
|
60
64
|
]),
|
|
61
65
|
).pipe(
|
|
62
66
|
Layer.provide(
|
|
@@ -72,6 +76,8 @@ export const providers = () =>
|
|
|
72
76
|
SharedVpcServiceProjectProvider(),
|
|
73
77
|
PsaConnectionProvider(),
|
|
74
78
|
ManagedLustreInstanceProvider(),
|
|
79
|
+
ServiceProvider(),
|
|
80
|
+
JobProvider(),
|
|
75
81
|
),
|
|
76
82
|
),
|
|
77
83
|
Layer.provideMerge(fromAuthProvider()),
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import type { Job } from "./Job.ts";
|
|
3
|
+
import type { Service } from "./Service.ts";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Bind a single `(role, member)` IAM grant onto a Cloud Run
|
|
7
|
+
* {@link Service}.
|
|
8
|
+
*
|
|
9
|
+
* Target-side binding — see
|
|
10
|
+
* {@link import("../Compute/SubnetworkIamMember.ts").subnetworkIamMember}
|
|
11
|
+
* for the pattern, the SID-collision pitfall, and why `key` exists.
|
|
12
|
+
* Service's `reconcile` merges all bindings into a single
|
|
13
|
+
* `setIamPolicy` call against the service, preserving foreign roles
|
|
14
|
+
* and members on the policy. To remove a binding, drop the call and
|
|
15
|
+
* re-deploy — the provider is additive within the bindings we
|
|
16
|
+
* declared, but does NOT prune.
|
|
17
|
+
*
|
|
18
|
+
* The most common usage:
|
|
19
|
+
*
|
|
20
|
+
* - **Public invoker:** `{ role: "roles/run.invoker", member: "allUsers" }`
|
|
21
|
+
* makes the service publicly reachable. Prefer this over
|
|
22
|
+
* `invokerIamDisabled: true` on the {@link Service} props — declarative
|
|
23
|
+
* IAM is auditable in `setIamPolicy` history; `invokerIamDisabled`
|
|
24
|
+
* is a flag with no audit trail.
|
|
25
|
+
* - **Service-to-service:** a downstream service's runtime SA bound
|
|
26
|
+
* to `roles/run.invoker` on the upstream service.
|
|
27
|
+
*
|
|
28
|
+
* @example Public Cloud Run service
|
|
29
|
+
* ```typescript
|
|
30
|
+
* const api = yield* GCP.Service("PublicApi", { ... });
|
|
31
|
+
* yield* GCP.serviceIamMember(api, "PublicInvoker", {
|
|
32
|
+
* role: "roles/run.invoker",
|
|
33
|
+
* member: "allUsers",
|
|
34
|
+
* });
|
|
35
|
+
* ```
|
|
36
|
+
*
|
|
37
|
+
* @example Service-to-service auth
|
|
38
|
+
* ```typescript
|
|
39
|
+
* const upstream = yield* GCP.Service("Upstream", { ... });
|
|
40
|
+
* yield* GCP.serviceIamMember(upstream, "DownstreamCaller", {
|
|
41
|
+
* role: "roles/run.invoker",
|
|
42
|
+
* member: `serviceAccount:${downstreamSa.email}`,
|
|
43
|
+
* });
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
export const serviceIamMember = (
|
|
47
|
+
service: Service,
|
|
48
|
+
key: string,
|
|
49
|
+
args: { role: string; member: string },
|
|
50
|
+
): Effect.Effect<void> =>
|
|
51
|
+
service.bind`IamMember(${service}, ${key})`({
|
|
52
|
+
iamBindings: [{ role: args.role, members: [args.member] }],
|
|
53
|
+
}) as unknown as Effect.Effect<void>;
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Bind a single `(role, member)` IAM grant onto a Cloud Run {@link Job}.
|
|
57
|
+
*
|
|
58
|
+
* Same target-side pattern as {@link serviceIamMember}. The most
|
|
59
|
+
* common Job binding is `roles/run.invoker` on the service account
|
|
60
|
+
* that triggers the job (Cloud Scheduler, Eventarc, Workflows, or a
|
|
61
|
+
* developer's user identity).
|
|
62
|
+
*
|
|
63
|
+
* @example Letting a Cloud Scheduler SA trigger the job
|
|
64
|
+
* ```typescript
|
|
65
|
+
* const nightly = yield* GCP.Job("Nightly", { ... });
|
|
66
|
+
* yield* GCP.jobIamMember(nightly, "SchedulerInvoker", {
|
|
67
|
+
* role: "roles/run.invoker",
|
|
68
|
+
* member: `serviceAccount:${schedulerSa.email}`,
|
|
69
|
+
* });
|
|
70
|
+
* ```
|
|
71
|
+
*/
|
|
72
|
+
export const jobIamMember = (
|
|
73
|
+
job: Job,
|
|
74
|
+
key: string,
|
|
75
|
+
args: { role: string; member: string },
|
|
76
|
+
): Effect.Effect<void> =>
|
|
77
|
+
job.bind`IamMember(${job}, ${key})`({
|
|
78
|
+
iamBindings: [{ role: args.role, members: [args.member] }],
|
|
79
|
+
}) as unknown as Effect.Effect<void>;
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import type * as run from "@distilled.cloud/gcp/run-v2";
|
|
2
|
+
import type { ResourceBinding } from "alchemy/Resource";
|
|
3
|
+
import * as Duration from "effect/Duration";
|
|
4
|
+
import * as Effect from "effect/Effect";
|
|
5
|
+
import * as Schedule from "effect/Schedule";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Common shape of Cloud Run's `getIamPolicy` / `setIamPolicy` request
|
|
9
|
+
* inputs — Service and Job declare nominally distinct request types,
|
|
10
|
+
* but both reduce to `{ resource, body? }` plus the version query for
|
|
11
|
+
* get. We model the operation surface generically so {@link makeSyncIam}
|
|
12
|
+
* can serve both targets without duplication.
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
type GetIamPolicyOp = (input: {
|
|
17
|
+
resource: string;
|
|
18
|
+
"options.requestedPolicyVersion"?: number;
|
|
19
|
+
}) => Effect.Effect<run.GoogleIamV1Policy, unknown, never>;
|
|
20
|
+
|
|
21
|
+
type SetIamPolicyOp = (input: {
|
|
22
|
+
resource: string;
|
|
23
|
+
body?: run.GoogleIamV1SetIamPolicyRequest;
|
|
24
|
+
}) => Effect.Effect<run.GoogleIamV1Policy, unknown, never>;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Single `(role, members)` entry on a Cloud Run target's IAM policy.
|
|
28
|
+
* Identical shape between Service and Job — both Cloud Run resources
|
|
29
|
+
* speak the same `iam.v1.Policy`, so the binding contract is shared.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```typescript
|
|
33
|
+
* yield* GCP.serviceIamMember(svc, "PublicInvoker", {
|
|
34
|
+
* role: "roles/run.invoker",
|
|
35
|
+
* member: "allUsers",
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export type RunIamBinding = {
|
|
40
|
+
/** IAM role, e.g. `"roles/run.invoker"`. */
|
|
41
|
+
role: string;
|
|
42
|
+
/** Principals, e.g. `["allUsers"]` or `["serviceAccount:foo@bar.iam.gserviceaccount.com"]`. */
|
|
43
|
+
members: ReadonlyArray<string>;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Binding contract for a Cloud Run target — services and jobs both
|
|
48
|
+
* accept a list of `iamBindings` records via the alchemy `.bind`
|
|
49
|
+
* mechanism. The reconciler reads `bindings` from its arguments and
|
|
50
|
+
* routes them through {@link makeSyncIam}.
|
|
51
|
+
*/
|
|
52
|
+
export type RunIamBindingContract = {
|
|
53
|
+
iamBindings: ReadonlyArray<RunIamBinding>;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Build a reusable `syncIam` step parametrised by the resolved
|
|
58
|
+
* `getIamPolicy` / `setIamPolicy` callables. Cloud Run's Service and
|
|
59
|
+
* Job IAM endpoints have identical request/response shapes (both
|
|
60
|
+
* `resource: "projects/{p}/locations/{l}/{kind}/{n}"`), so the same
|
|
61
|
+
* helper works for both — the caller just hands in the right pair of
|
|
62
|
+
* callables.
|
|
63
|
+
*
|
|
64
|
+
* Semantics, mirroring `Compute/Subnetwork.ts`:
|
|
65
|
+
*
|
|
66
|
+
* - **Union bindings per role across all `.bind` callers.** Multiple
|
|
67
|
+
* capabilities granting the same role get their members merged into
|
|
68
|
+
* a single binding.
|
|
69
|
+
* - **Preserve foreign roles and members verbatim.** We never displace
|
|
70
|
+
* bindings we didn't author. The provider is additive — to remove a
|
|
71
|
+
* binding, drop the `.bind` call and re-deploy (a future revision
|
|
72
|
+
* could narrow this; for now it matches the existing idiom).
|
|
73
|
+
* - **Etag round-trip.** `getIamPolicy` returns an etag; we pass it
|
|
74
|
+
* through `setIamPolicy` so a concurrent edit racing us surfaces as
|
|
75
|
+
* `Conflict`. We retry exponentially up to ~1.5 min — enough to
|
|
76
|
+
* absorb normal CI/human contention without masking real failures.
|
|
77
|
+
*/
|
|
78
|
+
export const makeSyncIam =
|
|
79
|
+
(api: { getIamPolicy: GetIamPolicyOp; setIamPolicy: SetIamPolicyOp }) =>
|
|
80
|
+
(args: {
|
|
81
|
+
/** Fully-qualified resource name: `projects/{p}/locations/{l}/{kind}/{n}`. */
|
|
82
|
+
resource: string;
|
|
83
|
+
bindings: ReadonlyArray<ResourceBinding<RunIamBindingContract>>;
|
|
84
|
+
}) =>
|
|
85
|
+
Effect.gen(function* () {
|
|
86
|
+
const desiredByRole = new Map<string, Set<string>>();
|
|
87
|
+
for (const b of args.bindings) {
|
|
88
|
+
for (const ib of b.data.iamBindings) {
|
|
89
|
+
const set = desiredByRole.get(ib.role) ?? new Set<string>();
|
|
90
|
+
for (const m of ib.members) set.add(m);
|
|
91
|
+
desiredByRole.set(ib.role, set);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (desiredByRole.size === 0) return;
|
|
95
|
+
|
|
96
|
+
const current = yield* api.getIamPolicy({
|
|
97
|
+
resource: args.resource,
|
|
98
|
+
"options.requestedPolicyVersion": 3,
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
const bindings = (current.bindings ?? []).map((b) => ({
|
|
102
|
+
...b,
|
|
103
|
+
members: [...(b.members ?? [])],
|
|
104
|
+
}));
|
|
105
|
+
let mutated = false;
|
|
106
|
+
for (const [role, members] of desiredByRole) {
|
|
107
|
+
let existing = bindings.find((b) => b.role === role && !b.condition);
|
|
108
|
+
if (!existing) {
|
|
109
|
+
existing = { role, members: [] };
|
|
110
|
+
bindings.push(existing);
|
|
111
|
+
}
|
|
112
|
+
const merged = new Set([...(existing.members ?? []), ...members]);
|
|
113
|
+
if (merged.size !== (existing.members?.length ?? 0)) mutated = true;
|
|
114
|
+
existing.members = [...merged];
|
|
115
|
+
}
|
|
116
|
+
if (!mutated) return;
|
|
117
|
+
|
|
118
|
+
yield* api.setIamPolicy({
|
|
119
|
+
resource: args.resource,
|
|
120
|
+
body: {
|
|
121
|
+
policy: {
|
|
122
|
+
...current,
|
|
123
|
+
bindings,
|
|
124
|
+
version: 3,
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
}).pipe(
|
|
129
|
+
Effect.retry({
|
|
130
|
+
schedule: Schedule.exponential(Duration.seconds(2)).pipe(
|
|
131
|
+
Schedule.both(Schedule.recurs(8)),
|
|
132
|
+
),
|
|
133
|
+
}),
|
|
134
|
+
);
|