@intentius/chant-lexicon-gcp 0.124.35 → 0.124.36

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.
@@ -24,7 +24,8 @@
24
24
  * PubSubTopic, PubSubSubscription, SecretManagerSecret, IAMServiceAccount,
25
25
  * RunService, IAMPolicyMember and the Cloud Run load balancer kinds
26
26
  * (ComputeAddress, ComputeRegionNetworkEndpointGroup, ComputeBackendService,
27
- * ComputeURLMap, ComputeTargetHTTPProxy, ComputeForwardingRule; #4233). An
27
+ * ComputeURLMap, ComputeTargetHTTPProxy, ComputeForwardingRule; #4233), and
28
+ * ComputeNetwork and ComputeSubnetwork (#4248). An
28
29
  * IAMPolicyMember is read through its target's policy and is present when the
29
30
  * policy grants its member the role. The kubectl path could fetch any CNRM kind the cluster knew
30
31
  * about, so this is narrower on paper. It is not narrower in practice for
@@ -1 +1 @@
1
- {"version":3,"file":"read-client.d.ts","sourceRoot":"","sources":["../../src/api/read-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,OAAO,EAA6B,KAAK,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5F,kCAAkC;AAClC,MAAM,WAAW,oBAAoB;IACnC,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAED,uHAAuH;AACvH,MAAM,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAUrH;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,KAAK;IAGnC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM;IAF1B,YACE,OAAO,EAAE,MAAM,EACN,MAAM,CAAC,EAAE,MAAM,YAAA,EAIzB;CACF;AAED,mFAAmF;AACnF,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAEhD;AAED,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAEtE;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,oBAAoB,EAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAiDlC"}
1
+ {"version":3,"file":"read-client.d.ts","sourceRoot":"","sources":["../../src/api/read-client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,OAAO,EAA6B,KAAK,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAE5F,kCAAkC;AAClC,MAAM,WAAW,oBAAoB;IACnC,+FAA+F;IAC/F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AAED,uHAAuH;AACvH,MAAM,MAAM,WAAW,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAUrH;;;;GAIG;AACH,qBAAa,YAAa,SAAQ,KAAK;IAGnC,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM;IAF1B,YACE,OAAO,EAAE,MAAM,EACN,MAAM,CAAC,EAAE,MAAM,YAAA,EAIzB;CACF;AAED,mFAAmF;AACnF,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAEhD;AAED,4EAA4E;AAC5E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAEtE;AAED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,oBAAoB,EAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAiDlC"}
@@ -24,7 +24,8 @@
24
24
  * PubSubTopic, PubSubSubscription, SecretManagerSecret, IAMServiceAccount,
25
25
  * RunService, IAMPolicyMember and the Cloud Run load balancer kinds
26
26
  * (ComputeAddress, ComputeRegionNetworkEndpointGroup, ComputeBackendService,
27
- * ComputeURLMap, ComputeTargetHTTPProxy, ComputeForwardingRule; #4233). An
27
+ * ComputeURLMap, ComputeTargetHTTPProxy, ComputeForwardingRule; #4233), and
28
+ * ComputeNetwork and ComputeSubnetwork (#4248). An
28
29
  * IAMPolicyMember is read through its target's policy and is present when the
29
30
  * policy grants its member the role. The kubectl path could fetch any CNRM kind the cluster knew
30
31
  * about, so this is narrower on paper. It is not narrower in practice for
@@ -1 +1 @@
1
- {"version":3,"file":"deep-observe.d.ts","sourceRoot":"","sources":["../src/deep-observe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,OAAO,KAAK,EACV,qBAAqB,EAGtB,MAAM,0BAA0B,CAAC;AAKlC,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAajE,OAAO,EAAE,yBAAyB,EAAE,CAAC;AAErC,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAWtF;AAUD;6EAC6E;AAC7E,UAAU,aAAa;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA2LD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASnH;AAED;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA8F5G"}
1
+ {"version":3,"file":"deep-observe.d.ts","sourceRoot":"","sources":["../src/deep-observe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsDG;AAEH,OAAO,KAAK,EACV,qBAAqB,EAGtB,MAAM,0BAA0B,CAAC;AAKlC,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAajE,OAAO,EAAE,yBAAyB,EAAE,CAAC;AAErC,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAWtF;AAUD;6EAC6E;AAC7E,UAAU,aAAa;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AA0OD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASnH;AAED;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA8F5G"}
@@ -166,6 +166,25 @@ const CNRM_REFINERS = {
166
166
  template.serviceAccountRef = email.endsWith(suffix) ? { name: email.slice(0, -suffix.length) } : { external: email };
167
167
  delete template.serviceAccount;
168
168
  }
169
+ // #4249: Direct VPC egress paths back to CNRM's refs, `name` for the
170
+ // project's own network and subnetwork, `external` otherwise.
171
+ const vpcAccess = template?.vpcAccess;
172
+ if (vpcAccess && Array.isArray(vpcAccess.networkInterfaces)) {
173
+ const own = (value, pattern) => {
174
+ if (!value.includes("/"))
175
+ return { name: value };
176
+ const hit = pattern.exec(value);
177
+ return hit && hit[1] === ctx.project ? { name: hit[2] } : { external: value };
178
+ };
179
+ vpcAccess.networkInterfaces = vpcAccess.networkInterfaces.map((i) => {
180
+ const { network, subnetwork, ...rest } = i;
181
+ return {
182
+ ...rest,
183
+ ...(typeof network === "string" ? { networkRef: own(network, /^projects\/([^/]+)\/global\/networks\/([^/]+)$/) } : {}),
184
+ ...(typeof subnetwork === "string" ? { subnetworkRef: own(subnetwork, /^projects\/([^/]+)\/regions\/[^/]+\/subnetworks\/([^/]+)$/) } : {}),
185
+ };
186
+ });
187
+ }
169
188
  },
170
189
  // #4233: the inverse of gcp-compute.ts's body builders. Compute returns refs
171
190
  // as full URLs and a region as a URL; CNRM writes `*Ref: { name }` and a
@@ -247,6 +266,39 @@ const CNRM_REFINERS = {
247
266
  delete tree.urlMap;
248
267
  }
249
268
  },
269
+ // #4248: a network is global and has no location; compute nests the routing
270
+ // mode and lists the subnetworks it holds, which CNRM declares separately.
271
+ ComputeNetwork(tree) {
272
+ const routing = tree.routingConfig;
273
+ if (routing) {
274
+ if (routing.routingMode !== undefined)
275
+ tree.routingMode = routing.routingMode;
276
+ delete tree.routingConfig;
277
+ }
278
+ delete tree.subnetworks;
279
+ delete tree.gatewayIPv4;
280
+ },
281
+ ComputeSubnetwork(tree) {
282
+ if (typeof tree.region === "string")
283
+ tree.region = lastSegment(tree.region);
284
+ if (typeof tree.network === "string") {
285
+ tree.networkRef = { name: lastSegment(tree.network) };
286
+ delete tree.network;
287
+ }
288
+ if (Array.isArray(tree.secondaryIpRanges)) {
289
+ tree.secondaryIpRange = tree.secondaryIpRanges;
290
+ delete tree.secondaryIpRanges;
291
+ }
292
+ const log = tree.logConfig;
293
+ if (log) {
294
+ if (log.enable === false)
295
+ delete tree.logConfig;
296
+ else
297
+ delete log.enable;
298
+ }
299
+ delete tree.gatewayAddress;
300
+ delete tree.fingerprint;
301
+ },
250
302
  ComputeForwardingRule(tree) {
251
303
  computeLocation(tree);
252
304
  if (tree.IPProtocol !== undefined) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "algorithm": "sha256",
3
3
  "artifacts": {
4
- "manifest.json": "1df258f1ce42c92a75d16af8bb02fb96e2b8a35903feafb3991be4162737103f",
4
+ "manifest.json": "9c67ab15a45ae8ce5c5ac3a6e3a83295bd28e78a4acf71b0d00d74040f5d27e0",
5
5
  "meta.json": "75643660010c044c6f465bef2688a864ab30cc96fd9b68111969749748ac64ca",
6
6
  "types/index.d.ts": "da1ebc6bcf83e1a018a773b59714194aeeb74ae1d5c1252b737b7e730ca98bd5",
7
7
  "rules/hardcoded-project.ts": "6d5ae9efa74d73800eebe1a0a0d43c619ee0fdebe3347195df93fcbe63b34f0d",
@@ -40,5 +40,5 @@
40
40
  "skills/chant-gcp-patterns.md": "4c6809fc7c37fa1879379ad4c0e2d114dec9497bc6eb9d1bca4e79fddea4f509",
41
41
  "skills/chant-gcp-gke.md": "be277019da9a722c851e47cd2dfb9c9536668948c3535fb20db7697e934c4e2b"
42
42
  },
43
- "composite": "8f56e528b666ee71c8dde34f63317337bb6183280e11dd1925ac7c1e4117ca89"
43
+ "composite": "f841125ccfbe364d6981cf4a1f444c9edeaa213e3b5d562dce7b12b341d82daf"
44
44
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gcp",
3
- "version": "0.124.35",
3
+ "version": "0.124.36",
4
4
  "chantVersion": ">=0.1.0",
5
5
  "namespace": "GCP",
6
6
  "intrinsics": [],
@@ -189,6 +189,13 @@ export declare const pubSubTopicMapper: ResourceMapper;
189
189
  export declare function cloudRunServiceBody(resource: GcpResource, project?: string): {
190
190
  template?: unknown;
191
191
  };
192
+ /**
193
+ * A CNRM Direct VPC egress interface as Cloud Run v2 takes it (#4249):
194
+ * `networkRef` and `subnetworkRef` become `network` and `subnetwork` paths,
195
+ * `name` in the project (the subnetwork in the service's region) and
196
+ * `external` as given. `tags` and anything else pass through. Pure.
197
+ */
198
+ export declare function networkInterface(iface: unknown, project: string | undefined, region: string): unknown;
192
199
  /**
193
200
  * The email a CNRM `serviceAccountRef` names: `external` as given (an email,
194
201
  * or a `projects/<p>/serviceAccounts/<email>` path), `name` as an account id
@@ -1 +1 @@
1
- {"version":3,"file":"gcp-apply.d.ts","sourceRoot":"","sources":["../../../src/op/activities/gcp-apply.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gcp-apply.d.ts","sourceRoot":"","sources":["../../../src/op/activities/gcp-apply.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,7 @@ import { sleep } from "@intentius/chant/op";
4
4
  import { hasOwnershipMarker, OWNERSHIP_MANAGED_BY_VALUE } from "@intentius/chant/ownership";
5
5
  import { GCP_RESOURCE_OWNERSHIP_KEYS } from "../../ownership.js";
6
6
  import { iamPolicyMemberMapper } from "./gcp-iam.js";
7
- import { backendServiceMapper, computeAddressMapper, forwardingRuleMapper, regionNetworkEndpointGroupMapper, targetHttpProxyMapper, urlMapMapper, } from "./gcp-compute.js";
7
+ import { backendServiceMapper, computeAddressMapper, forwardingRuleMapper, networkMapper, subnetworkMapper, regionNetworkEndpointGroupMapper, targetHttpProxyMapper, urlMapMapper, } from "./gcp-compute.js";
8
8
  import { applyResult, } from "@intentius/chant/apply";
9
9
  const PROJECT_ID_ANNOTATION = "cnrm.cloud.google.com/project-id";
10
10
  /**
@@ -157,9 +157,40 @@ export function cloudRunServiceBody(resource, project) {
157
157
  return body;
158
158
  const { serviceAccountRef, ...template } = spec.template;
159
159
  const email = serviceAccountEmail(serviceAccountRef, project);
160
- body.template = email ? { ...template, serviceAccount: email } : template;
160
+ const out = email ? { ...template, serviceAccount: email } : { ...template };
161
+ const vpcAccess = out.vpcAccess;
162
+ if (vpcAccess && Array.isArray(vpcAccess.networkInterfaces)) {
163
+ const region = (resource.spec ?? {}).location ?? "us-central1";
164
+ out.vpcAccess = { ...vpcAccess, networkInterfaces: vpcAccess.networkInterfaces.map((i) => networkInterface(i, project, region)) };
165
+ }
166
+ body.template = out;
161
167
  return body;
162
168
  }
169
+ /**
170
+ * A CNRM Direct VPC egress interface as Cloud Run v2 takes it (#4249):
171
+ * `networkRef` and `subnetworkRef` become `network` and `subnetwork` paths,
172
+ * `name` in the project (the subnetwork in the service's region) and
173
+ * `external` as given. `tags` and anything else pass through. Pure.
174
+ */
175
+ export function networkInterface(iface, project, region) {
176
+ if (!iface || typeof iface !== "object")
177
+ return iface;
178
+ const { networkRef, subnetworkRef, ...rest } = iface;
179
+ const path = (ref, scoped, key) => {
180
+ if (!ref)
181
+ return undefined;
182
+ if (ref.external)
183
+ return ref.external;
184
+ if (!ref.name)
185
+ return undefined;
186
+ if (!project)
187
+ throw new Error(`${key} { name: "${ref.name}" } needs a project to form its path`);
188
+ return scoped(project, ref.name);
189
+ };
190
+ const network = path(networkRef, (p, n) => `projects/${p}/global/networks/${n}`, "networkRef");
191
+ const subnetwork = path(subnetworkRef, (p, n) => `projects/${p}/regions/${region}/subnetworks/${n}`, "subnetworkRef");
192
+ return { ...rest, ...(network ? { network } : {}), ...(subnetwork ? { subnetwork } : {}) };
193
+ }
163
194
  /**
164
195
  * The email a CNRM `serviceAccountRef` names: `external` as given (an email,
165
196
  * or a `projects/<p>/serviceAccounts/<email>` path), `name` as an account id
@@ -295,6 +326,8 @@ export const MAPPERS = {
295
326
  ComputeURLMap: urlMapMapper,
296
327
  ComputeTargetHTTPProxy: targetHttpProxyMapper,
297
328
  ComputeForwardingRule: forwardingRuleMapper,
329
+ ComputeNetwork: networkMapper,
330
+ ComputeSubnetwork: subnetworkMapper,
298
331
  };
299
332
  /**
300
333
  * Collect the local resource names this resource references via CNRM `*Ref`
@@ -319,6 +352,8 @@ const REF_KINDS = {
319
352
  backendServiceRef: "ComputeBackendService",
320
353
  urlMapRef: "ComputeURLMap",
321
354
  targetHTTPProxyRef: "ComputeTargetHTTPProxy",
355
+ networkRef: "ComputeNetwork",
356
+ subnetworkRef: "ComputeSubnetwork",
322
357
  };
323
358
  /** The local resources this resource references via `*Ref` fields, each with its kind when known. Pure. */
324
359
  export function referencedResources(resource) {
@@ -31,6 +31,14 @@ export declare function computeLabels(labels: Record<string, string> | undefined
31
31
  export declare function addressBody(resource: GcpResource, ctx: ComputeCtx): Obj;
32
32
  /** ComputeRegionNetworkEndpointGroup → regionNetworkEndpointGroups.insert body (serverless NEGs). Pure. */
33
33
  export declare function negBody(resource: GcpResource, ctx: ComputeCtx): Obj;
34
+ /**
35
+ * ComputeNetwork → networks.insert body. A network is global. CNRM's
36
+ * `autoCreateSubnetworks` defaults to false, where compute's default is true,
37
+ * so it is always sent. Pure.
38
+ */
39
+ export declare function networkBody(resource: GcpResource): Obj;
40
+ /** ComputeSubnetwork → subnetworks.insert body. CNRM's `secondaryIpRange` and `logConfig` become compute's `secondaryIpRanges` and an enabled `logConfig`. Pure. */
41
+ export declare function subnetworkBody(resource: GcpResource, ctx: ComputeCtx): Obj;
34
42
  /** ComputeBackendService → backendServices.insert body. Pure. */
35
43
  export declare function backendServiceBody(resource: GcpResource, ctx: ComputeCtx): Obj;
36
44
  /** ComputeURLMap → urlMaps.insert body. Pure. */
@@ -52,5 +60,7 @@ export declare const backendServiceMapper: ResourceMapper;
52
60
  export declare const urlMapMapper: ResourceMapper;
53
61
  export declare const targetHttpProxyMapper: ResourceMapper;
54
62
  export declare const forwardingRuleMapper: ResourceMapper;
63
+ export declare const networkMapper: ResourceMapper;
64
+ export declare const subnetworkMapper: ResourceMapper;
55
65
  export {};
56
66
  //# sourceMappingURL=gcp-compute.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"gcp-compute.d.ts","sourceRoot":"","sources":["../../../src/op/activities/gcp-compute.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE9E,eAAO,MAAM,YAAY,mCAAmC,CAAC;AAI7D,KAAK,GAAG,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/D,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAqBnC,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;CACnC;AAED,wGAAwG;AACxG,wBAAgB,OAAO,CAAC,IAAI,EAAE,GAAG,GAAG,SAAS,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAG3F;AAMD,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CAKzD;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAmB5F;AAkBD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMhG;AAED,oDAAoD;AACpD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,UAAU,GAAG,GAAG,CAWvE;AAED,2GAA2G;AAC3G,wBAAgB,OAAO,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,UAAU,GAAG,GAAG,CA0BnE;AAED,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,UAAU,GAAG,GAAG,CAoC9E;AAED,iDAAiD;AACjD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,UAAU,GAAG,GAAG,CA4BtE;AAED,oEAAoE;AACpE,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,UAAU,GAAG,GAAG,CAK/E;AAED,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,UAAU,GAAG,GAAG,CAoB9E;AAED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,aAe9B,CAAC;AAqBF,eAAO,MAAM,oBAAoB,gBAA4D,CAAC;AAC9F,eAAO,MAAM,gCAAgC,gBAAuF,CAAC;AACrI,eAAO,MAAM,oBAAoB,gBAAgF,CAAC;AAClH,eAAO,MAAM,YAAY,gBAAwD,CAAC;AAClF,eAAO,MAAM,qBAAqB,gBAAoF,CAAC;AACvH,eAAO,MAAM,oBAAoB,gBAAgF,CAAC"}
1
+ {"version":3,"file":"gcp-compute.d.ts","sourceRoot":"","sources":["../../../src/op/activities/gcp-compute.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE9E,eAAO,MAAM,YAAY,mCAAmC,CAAC;AAI7D,KAAK,GAAG,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAC/D,KAAK,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAqBnC,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,SAAS,WAAW,EAAE,CAAC;CACnC;AAED,wGAAwG;AACxG,wBAAgB,OAAO,CAAC,IAAI,EAAE,GAAG,GAAG,SAAS,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAG3F;AAMD,4EAA4E;AAC5E,wBAAgB,WAAW,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CAKzD;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAmB5F;AAkBD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAMhG;AAED,oDAAoD;AACpD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,UAAU,GAAG,GAAG,CAWvE;AAED,2GAA2G;AAC3G,wBAAgB,OAAO,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,UAAU,GAAG,GAAG,CA0BnE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,WAAW,GAAG,GAAG,CAStD;AAED,oKAAoK;AACpK,wBAAgB,cAAc,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,UAAU,GAAG,GAAG,CAW1E;AAED,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,UAAU,GAAG,GAAG,CAoC9E;AAED,iDAAiD;AACjD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,UAAU,GAAG,GAAG,CA4BtE;AAED,oEAAoE;AACpE,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,UAAU,GAAG,GAAG,CAK/E;AAED,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,EAAE,UAAU,GAAG,GAAG,CAoB9E;AAED;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,aAe9B,CAAC;AAsBF,eAAO,MAAM,oBAAoB,gBAA4D,CAAC;AAC9F,eAAO,MAAM,gCAAgC,gBAAuF,CAAC;AACrI,eAAO,MAAM,oBAAoB,gBAAgF,CAAC;AAClH,eAAO,MAAM,YAAY,gBAAwD,CAAC;AAClF,eAAO,MAAM,qBAAqB,gBAAoF,CAAC;AACvH,eAAO,MAAM,oBAAoB,gBAAgF,CAAC;AAClH,eAAO,MAAM,aAAa,gBAAuF,CAAC;AAClH,eAAO,MAAM,gBAAgB,gBAAoE,CAAC"}
@@ -1,7 +1,9 @@
1
1
  /**
2
2
  * Compute Engine mappers for the Cloud Run load balancer (#4233): ComputeAddress,
3
3
  * ComputeRegionNetworkEndpointGroup (serverless NEGs), ComputeBackendService,
4
- * ComputeURLMap, ComputeTargetHTTPProxy and ComputeForwardingRule.
4
+ * ComputeURLMap, ComputeTargetHTTPProxy and ComputeForwardingRule; and for a
5
+ * declared network (#4248): ComputeNetwork (always global) and
6
+ * ComputeSubnetwork (regional, by its CNRM `region`).
5
7
  *
6
8
  * Each maps a CNRM spec onto the compute v1 insert body. A resource is global
7
9
  * or regional by its CNRM `location` (`"global"` or a region; a NEG has
@@ -158,6 +160,38 @@ export function negBody(resource, ctx) {
158
160
  body.subnetwork = refUrl("subnetworkRef", spec.subnetworkRef, ctx, scope);
159
161
  return body;
160
162
  }
163
+ /**
164
+ * ComputeNetwork → networks.insert body. A network is global. CNRM's
165
+ * `autoCreateSubnetworks` defaults to false, where compute's default is true,
166
+ * so it is always sent. Pure.
167
+ */
168
+ export function networkBody(resource) {
169
+ const spec = (resource.spec ?? {});
170
+ const body = {
171
+ name: computeName(resource),
172
+ autoCreateSubnetworks: spec.autoCreateSubnetworks === true,
173
+ ...pick(spec, ["description", "mtu", "networkFirewallPolicyEnforcementOrder"]),
174
+ };
175
+ if (typeof spec.routingMode === "string")
176
+ body.routingConfig = { routingMode: spec.routingMode };
177
+ return body;
178
+ }
179
+ /** ComputeSubnetwork → subnetworks.insert body. CNRM's `secondaryIpRange` and `logConfig` become compute's `secondaryIpRanges` and an enabled `logConfig`. Pure. */
180
+ export function subnetworkBody(resource, ctx) {
181
+ const spec = (resource.spec ?? {});
182
+ const scope = scopeOf(spec);
183
+ const body = {
184
+ name: computeName(resource),
185
+ ...pick(spec, ["ipCidrRange", "description", "privateIpGoogleAccess", "purpose", "role", "stackType"]),
186
+ };
187
+ if (isObj(spec.networkRef))
188
+ body.network = refUrl("networkRef", spec.networkRef, ctx, scope);
189
+ if (Array.isArray(spec.secondaryIpRange))
190
+ body.secondaryIpRanges = spec.secondaryIpRange;
191
+ if (isObj(spec.logConfig))
192
+ body.logConfig = { enable: true, ...spec.logConfig };
193
+ return body;
194
+ }
161
195
  /** ComputeBackendService → backendServices.insert body. Pure. */
162
196
  export function backendServiceBody(resource, ctx) {
163
197
  const spec = (resource.spec ?? {});
@@ -292,13 +326,13 @@ export const computeOperation = {
292
326
  return errors?.length ? errors.map((e) => e.message ?? e.code ?? "error").join("; ") : undefined;
293
327
  },
294
328
  };
295
- function computeMapper(kind, collection, build, regionalCollection = collection) {
329
+ function computeMapper(kind, collection, build, regionalCollection = collection, scopeFor = (spec) => scopeOf(spec)) {
296
330
  return {
297
331
  kind,
298
332
  defaultHost: COMPUTE_HOST,
299
333
  operation: computeOperation,
300
334
  plan(resource, ctx) {
301
- const scope = scopeOf(resource.spec);
335
+ const scope = scopeFor(resource.spec);
302
336
  const coll = `${ctx.base}/compute/v1/${scopePath(ctx.project, scope)}/${scope === "global" ? collection : regionalCollection}`;
303
337
  const name = computeName(resource);
304
338
  return { getUrl: `${coll}/${enc(name)}`, create: { method: "POST", url: coll, body: build(resource, ctx) } };
@@ -311,3 +345,5 @@ export const backendServiceMapper = computeMapper("ComputeBackendService", "back
311
345
  export const urlMapMapper = computeMapper("ComputeURLMap", "urlMaps", urlMapBody);
312
346
  export const targetHttpProxyMapper = computeMapper("ComputeTargetHTTPProxy", "targetHttpProxies", targetHttpProxyBody);
313
347
  export const forwardingRuleMapper = computeMapper("ComputeForwardingRule", "forwardingRules", forwardingRuleBody);
348
+ export const networkMapper = computeMapper("ComputeNetwork", "networks", networkBody, "networks", () => "global");
349
+ export const subnetworkMapper = computeMapper("ComputeSubnetwork", "subnetworks", subnetworkBody);
@@ -4,6 +4,7 @@
4
4
  * Converts Chant declarables to multi-document K8s YAML output
5
5
  * for Config Connector resources with apiVersion, kind, metadata, and spec.
6
6
  */
7
+ import type { Declarable } from "@intentius/chant/declarable";
7
8
  import type { Serializer } from "@intentius/chant/serializer";
8
9
  /**
9
10
  * Resolve entityType to apiVersion and kind.
@@ -17,6 +18,11 @@ export declare function resolveGVK(entityType: string): {
17
18
  apiVersion: string;
18
19
  kind: string;
19
20
  } | null;
21
+ /**
22
+ * The metadata.name a resource is written with: a string `metadata.name` in its
23
+ * props, else its logical id in kebab case.
24
+ */
25
+ export declare function cnrmName(logical: string, entity: Declarable): string;
20
26
  /**
21
27
  * GCP Config Connector YAML serializer implementation.
22
28
  */
@@ -1 +1 @@
1
- {"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAsC,MAAM,6BAA6B,CAAC;AAiClG;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAW1F;AAsED;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,UAiG3B,CAAC"}
1
+ {"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D,OAAO,KAAK,EAAE,UAAU,EAAsC,MAAM,6BAA6B,CAAC;AAiClG;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAW1F;AA+CD;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAIpE;AA4BD;;GAEG;AACH,eAAO,MAAM,aAAa,EAAE,UAiG3B,CAAC"}
@@ -62,15 +62,15 @@ function deriveGVKFromType(entityType) {
62
62
  * GCP visitor for the generic serializer walker.
63
63
  */
64
64
  function gcpVisitor(entityNames) {
65
+ // Config Connector resolves a `*Ref: { name }` by the target's metadata.name,
66
+ // which is its declared name or else the kebab-cased logical id (#4242).
67
+ const cnrmNames = new Map();
68
+ for (const [entity, logical] of entityNames)
69
+ cnrmNames.set(logical, cnrmName(logical, entity));
70
+ const resolve = (logical) => cnrmNames.get(logical) ?? logical;
65
71
  return {
66
- attrRef: (name, _attr) => {
67
- // For Config Connector, references resolve to metadata.name
68
- return name;
69
- },
70
- resourceRef: (name) => {
71
- // Config Connector uses resourceRef pattern: { name: "resource-name" }
72
- return { name };
73
- },
72
+ attrRef: (name, _attr) => resolve(name),
73
+ resourceRef: (name) => ({ name: resolve(name) }),
74
74
  propertyDeclarable: (entity, walk) => {
75
75
  if (!isResourceDeclarable(entity) || typeof entity.props !== "object" || entity.props === null) {
76
76
  return undefined;
@@ -86,6 +86,18 @@ function gcpVisitor(entityNames) {
86
86
  },
87
87
  };
88
88
  }
89
+ /**
90
+ * The metadata.name a resource is written with: a string `metadata.name` in its
91
+ * props, else its logical id in kebab case.
92
+ */
93
+ export function cnrmName(logical, entity) {
94
+ const props = isResourceDeclarable(entity) ? entity.props : undefined;
95
+ const declared = props?.metadata?.name;
96
+ return typeof declared === "string" && declared.length > 0 ? declared : kebabName(logical);
97
+ }
98
+ function kebabName(logical) {
99
+ return logical.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
100
+ }
89
101
  /**
90
102
  * Convert a value to YAML-compatible form using the walker.
91
103
  */
@@ -152,7 +164,7 @@ export const gcpSerializer = {
152
164
  // Build metadata
153
165
  const metadata = props.metadata ?? {};
154
166
  if (!metadata.name) {
155
- metadata.name = name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
167
+ metadata.name = kebabName(name);
156
168
  }
157
169
  // Merge default labels
158
170
  if (Object.keys(defaultLabelEntries).length > 0) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intentius/chant-lexicon-gcp",
3
- "version": "0.124.35",
3
+ "version": "0.124.36",
4
4
  "description": "Google Cloud lexicon for chant — declarative IaC in TypeScript",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://intentius.io/chant",
@@ -76,6 +76,6 @@
76
76
  "typescript": "^5.9.3"
77
77
  },
78
78
  "peerDependencies": {
79
- "@intentius/chant": "^0.124.35"
79
+ "@intentius/chant": "^0.124.36"
80
80
  }
81
81
  }
@@ -24,7 +24,8 @@
24
24
  * PubSubTopic, PubSubSubscription, SecretManagerSecret, IAMServiceAccount,
25
25
  * RunService, IAMPolicyMember and the Cloud Run load balancer kinds
26
26
  * (ComputeAddress, ComputeRegionNetworkEndpointGroup, ComputeBackendService,
27
- * ComputeURLMap, ComputeTargetHTTPProxy, ComputeForwardingRule; #4233). An
27
+ * ComputeURLMap, ComputeTargetHTTPProxy, ComputeForwardingRule; #4233), and
28
+ * ComputeNetwork and ComputeSubnetwork (#4248). An
28
29
  * IAMPolicyMember is read through its target's policy and is present when the
29
30
  * policy grants its member the role. The kubectl path could fetch any CNRM kind the cluster knew
30
31
  * about, so this is narrower on paper. It is not narrower in practice for
@@ -139,6 +139,32 @@ describe("toCnrmTree — each REST shape in the declared vocabulary (#1210)", ()
139
139
  expect(other.template).toEqual({ serviceAccountRef: { external: "x@other.iam.gserviceaccount.com" } });
140
140
  });
141
141
 
142
+ test("run service: vpcAccess network and subnetwork paths map back to refs (#4249)", () => {
143
+ const tree = toCnrmTree(
144
+ "RunService",
145
+ {
146
+ name: "projects/my-project/locations/europe-west1/services/web",
147
+ template: {
148
+ vpcAccess: {
149
+ egress: "PRIVATE_RANGES_ONLY",
150
+ networkInterfaces: [
151
+ { network: "projects/my-project/global/networks/vpc", subnetwork: "projects/my-project/regions/europe-west1/subnetworks/apps" },
152
+ { network: "projects/other/global/networks/shared", subnetwork: "apps" },
153
+ ],
154
+ },
155
+ },
156
+ },
157
+ ctx,
158
+ ) as { template: { vpcAccess: unknown } };
159
+ expect(tree.template.vpcAccess).toEqual({
160
+ egress: "PRIVATE_RANGES_ONLY",
161
+ networkInterfaces: [
162
+ { networkRef: { name: "vpc" }, subnetworkRef: { name: "apps" } },
163
+ { networkRef: { external: "projects/other/global/networks/shared" }, subnetworkRef: { name: "apps" } },
164
+ ],
165
+ });
166
+ });
167
+
142
168
  test("bucket: GCS's iamConfiguration and lifecycle map onto the CNRM field names", () => {
143
169
  const tree = toCnrmTree(
144
170
  "StorageBucket",
@@ -250,7 +276,7 @@ describe("observeResourcesDeepGcp — over REST (#1209)", () => {
250
276
  });
251
277
 
252
278
  test("a kind the applier cannot write is unsupported-kind, and is never queried", async () => {
253
- const out = await observe(entities([["e", "GCP::Compute::Network", { metadata: { name: "n" } }]]));
279
+ const out = await observe(entities([["e", "GCP::Compute::Firewall", { metadata: { name: "n" } }]]));
254
280
  expect(out.unobserved?.e?.reason).toBe("unsupported-kind");
255
281
  expect(fetchMock).not.toHaveBeenCalled();
256
282
  });
@@ -191,6 +191,24 @@ const CNRM_REFINERS: Record<string, (tree: CnrmTree, ctx: RefineContext) => void
191
191
  template.serviceAccountRef = email.endsWith(suffix) ? { name: email.slice(0, -suffix.length) } : { external: email };
192
192
  delete template.serviceAccount;
193
193
  }
194
+ // #4249: Direct VPC egress paths back to CNRM's refs, `name` for the
195
+ // project's own network and subnetwork, `external` otherwise.
196
+ const vpcAccess = template?.vpcAccess as { networkInterfaces?: unknown } | undefined;
197
+ if (vpcAccess && Array.isArray(vpcAccess.networkInterfaces)) {
198
+ const own = (value: string, pattern: RegExp): { name: string } | { external: string } => {
199
+ if (!value.includes("/")) return { name: value };
200
+ const hit = pattern.exec(value);
201
+ return hit && hit[1] === ctx.project ? { name: hit[2] } : { external: value };
202
+ };
203
+ vpcAccess.networkInterfaces = (vpcAccess.networkInterfaces as Array<Record<string, unknown>>).map((i) => {
204
+ const { network, subnetwork, ...rest } = i;
205
+ return {
206
+ ...rest,
207
+ ...(typeof network === "string" ? { networkRef: own(network, /^projects\/([^/]+)\/global\/networks\/([^/]+)$/) } : {}),
208
+ ...(typeof subnetwork === "string" ? { subnetworkRef: own(subnetwork, /^projects\/([^/]+)\/regions\/[^/]+\/subnetworks\/([^/]+)$/) } : {}),
209
+ };
210
+ });
211
+ }
194
212
  },
195
213
  // #4233: the inverse of gcp-compute.ts's body builders. Compute returns refs
196
214
  // as full URLs and a region as a URL; CNRM writes `*Ref: { name }` and a
@@ -269,6 +287,35 @@ const CNRM_REFINERS: Record<string, (tree: CnrmTree, ctx: RefineContext) => void
269
287
  delete tree.urlMap;
270
288
  }
271
289
  },
290
+ // #4248: a network is global and has no location; compute nests the routing
291
+ // mode and lists the subnetworks it holds, which CNRM declares separately.
292
+ ComputeNetwork(tree) {
293
+ const routing = tree.routingConfig as { routingMode?: unknown } | undefined;
294
+ if (routing) {
295
+ if (routing.routingMode !== undefined) tree.routingMode = routing.routingMode;
296
+ delete tree.routingConfig;
297
+ }
298
+ delete tree.subnetworks;
299
+ delete tree.gatewayIPv4;
300
+ },
301
+ ComputeSubnetwork(tree) {
302
+ if (typeof tree.region === "string") tree.region = lastSegment(tree.region);
303
+ if (typeof tree.network === "string") {
304
+ tree.networkRef = { name: lastSegment(tree.network) };
305
+ delete tree.network;
306
+ }
307
+ if (Array.isArray(tree.secondaryIpRanges)) {
308
+ tree.secondaryIpRange = tree.secondaryIpRanges;
309
+ delete tree.secondaryIpRanges;
310
+ }
311
+ const log = tree.logConfig as { enable?: unknown } | undefined;
312
+ if (log) {
313
+ if (log.enable === false) delete tree.logConfig;
314
+ else delete log.enable;
315
+ }
316
+ delete tree.gatewayAddress;
317
+ delete tree.fingerprint;
318
+ },
272
319
  ComputeForwardingRule(tree) {
273
320
  computeLocation(tree);
274
321
  if (tree.IPProtocol !== undefined) {
@@ -80,7 +80,7 @@ describe("gcp describeResources — direct REST (#1209)", () => {
80
80
 
81
81
  test("a kind the applier has no mapper for is unsupported-kind, not absent", async () => {
82
82
  const out = await read(
83
- makeEntities([{ name: "e", entityType: "GCP::Compute::Network", props: { metadata: { name: "net" } } }]),
83
+ makeEntities([{ name: "e", entityType: "GCP::Compute::Firewall", props: { metadata: { name: "net" } } }]),
84
84
  );
85
85
  expect(out.unobserved?.e?.reason).toBe("unsupported-kind");
86
86
  expect(fetchMock).not.toHaveBeenCalled();
@@ -5,6 +5,7 @@ import {
5
5
  bucketInsertBody,
6
6
  pubSubTopicBody,
7
7
  cloudRunServiceBody,
8
+ networkInterface,
8
9
  serviceAccountEmail,
9
10
  resolveGcpProject,
10
11
  resolveGcpEndpoint,
@@ -122,7 +123,9 @@ describe("mappers build correct plans (#706)", () => {
122
123
  "ComputeAddress",
123
124
  "ComputeBackendService",
124
125
  "ComputeForwardingRule",
126
+ "ComputeNetwork",
125
127
  "ComputeRegionNetworkEndpointGroup",
128
+ "ComputeSubnetwork",
126
129
  "ComputeTargetHTTPProxy",
127
130
  "ComputeURLMap",
128
131
  "IAMPolicyMember",
@@ -164,6 +167,41 @@ describe("Cloud Run mapper + LRO (#706)", () => {
164
167
  expect(() => serviceAccountEmail({ name: "run-sa" })).toThrow(/needs a project/);
165
168
  });
166
169
 
170
+ test("cloudRunServiceBody sends vpcAccess refs as network and subnetwork paths (#4249)", () => {
171
+ const resource = {
172
+ ...RUN_SERVICE,
173
+ spec: {
174
+ ...(RUN_SERVICE.spec as object),
175
+ location: "europe-west1",
176
+ template: {
177
+ containers: [{ image: "i" }],
178
+ vpcAccess: {
179
+ egress: "PRIVATE_RANGES_ONLY",
180
+ networkInterfaces: [{ networkRef: { name: "vpc" }, subnetworkRef: { name: "apps" }, tags: ["run"] }],
181
+ },
182
+ },
183
+ },
184
+ };
185
+ expect(cloudRunServiceBody(resource, "p")).toEqual({
186
+ template: {
187
+ containers: [{ image: "i" }],
188
+ vpcAccess: {
189
+ egress: "PRIVATE_RANGES_ONLY",
190
+ networkInterfaces: [
191
+ { tags: ["run"], network: "projects/p/global/networks/vpc", subnetwork: "projects/p/regions/europe-west1/subnetworks/apps" },
192
+ ],
193
+ },
194
+ },
195
+ });
196
+ });
197
+
198
+ test("networkInterface: external as given, name needs a project", () => {
199
+ expect(networkInterface({ networkRef: { external: "projects/o/global/networks/shared" } }, "p", "r")).toEqual({
200
+ network: "projects/o/global/networks/shared",
201
+ });
202
+ expect(() => networkInterface({ subnetworkRef: { name: "apps" } }, undefined, "r")).toThrow(/needs a project/);
203
+ });
204
+
167
205
  test("RunService plan sends the service account email on create and update", () => {
168
206
  const resource = {
169
207
  ...RUN_SERVICE,
@@ -8,6 +8,8 @@ import {
8
8
  backendServiceMapper,
9
9
  computeAddressMapper,
10
10
  forwardingRuleMapper,
11
+ networkMapper,
12
+ subnetworkMapper,
11
13
  regionNetworkEndpointGroupMapper,
12
14
  targetHttpProxyMapper,
13
15
  urlMapMapper,
@@ -292,10 +294,39 @@ export function cloudRunServiceBody(resource: GcpResource, project?: string): {
292
294
  if (!spec.template) return body;
293
295
  const { serviceAccountRef, ...template } = spec.template as { serviceAccountRef?: { name?: string; external?: string } };
294
296
  const email = serviceAccountEmail(serviceAccountRef, project);
295
- body.template = email ? { ...template, serviceAccount: email } : template;
297
+ const out: Record<string, unknown> = email ? { ...template, serviceAccount: email } : { ...template };
298
+ const vpcAccess = out.vpcAccess as { networkInterfaces?: unknown } | undefined;
299
+ if (vpcAccess && Array.isArray(vpcAccess.networkInterfaces)) {
300
+ const region = ((resource.spec ?? {}) as { location?: string }).location ?? "us-central1";
301
+ out.vpcAccess = { ...vpcAccess, networkInterfaces: vpcAccess.networkInterfaces.map((i) => networkInterface(i, project, region)) };
302
+ }
303
+ body.template = out;
296
304
  return body;
297
305
  }
298
306
 
307
+ type NameRef = { name?: string; external?: string };
308
+
309
+ /**
310
+ * A CNRM Direct VPC egress interface as Cloud Run v2 takes it (#4249):
311
+ * `networkRef` and `subnetworkRef` become `network` and `subnetwork` paths,
312
+ * `name` in the project (the subnetwork in the service's region) and
313
+ * `external` as given. `tags` and anything else pass through. Pure.
314
+ */
315
+ export function networkInterface(iface: unknown, project: string | undefined, region: string): unknown {
316
+ if (!iface || typeof iface !== "object") return iface;
317
+ const { networkRef, subnetworkRef, ...rest } = iface as { networkRef?: NameRef; subnetworkRef?: NameRef };
318
+ const path = (ref: NameRef | undefined, scoped: (p: string, n: string) => string, key: string): string | undefined => {
319
+ if (!ref) return undefined;
320
+ if (ref.external) return ref.external;
321
+ if (!ref.name) return undefined;
322
+ if (!project) throw new Error(`${key} { name: "${ref.name}" } needs a project to form its path`);
323
+ return scoped(project, ref.name);
324
+ };
325
+ const network = path(networkRef, (p, n) => `projects/${p}/global/networks/${n}`, "networkRef");
326
+ const subnetwork = path(subnetworkRef, (p, n) => `projects/${p}/regions/${region}/subnetworks/${n}`, "subnetworkRef");
327
+ return { ...rest, ...(network ? { network } : {}), ...(subnetwork ? { subnetwork } : {}) };
328
+ }
329
+
299
330
  /**
300
331
  * The email a CNRM `serviceAccountRef` names: `external` as given (an email,
301
332
  * or a `projects/<p>/serviceAccounts/<email>` path), `name` as an account id
@@ -435,6 +466,8 @@ export const MAPPERS: Record<string, ResourceMapper> = {
435
466
  ComputeURLMap: urlMapMapper,
436
467
  ComputeTargetHTTPProxy: targetHttpProxyMapper,
437
468
  ComputeForwardingRule: forwardingRuleMapper,
469
+ ComputeNetwork: networkMapper,
470
+ ComputeSubnetwork: subnetworkMapper,
438
471
  };
439
472
 
440
473
  /**
@@ -461,6 +494,8 @@ const REF_KINDS: Record<string, string> = {
461
494
  backendServiceRef: "ComputeBackendService",
462
495
  urlMapRef: "ComputeURLMap",
463
496
  targetHTTPProxyRef: "ComputeTargetHTTPProxy",
497
+ networkRef: "ComputeNetwork",
498
+ subnetworkRef: "ComputeSubnetwork",
464
499
  };
465
500
 
466
501
  /** The local resources this resource references via `*Ref` fields, each with its kind when known. Pure. */
@@ -210,3 +210,97 @@ describe("deep observe reads a load balancer back in the declared vocabulary (#4
210
210
  });
211
211
  });
212
212
  });
213
+
214
+ describe("network and subnetwork mappers (#4248)", () => {
215
+ const net: GcpResource[] = [
216
+ {
217
+ kind: "ComputeSubnetwork",
218
+ metadata: { name: "apps" },
219
+ spec: {
220
+ region: "europe-west1",
221
+ ipCidrRange: "10.0.0.0/24",
222
+ networkRef: { name: "vpc" },
223
+ privateIpGoogleAccess: true,
224
+ secondaryIpRange: [{ rangeName: "pods", ipCidrRange: "10.4.0.0/14" }],
225
+ },
226
+ },
227
+ { kind: "ComputeNetwork", metadata: { name: "vpc" }, spec: { routingMode: "REGIONAL" } },
228
+ {
229
+ kind: "RunService",
230
+ metadata: { name: "web" },
231
+ spec: { location: "europe-west1", template: { vpcAccess: { networkInterfaces: [{ networkRef: { name: "vpc" }, subnetworkRef: { name: "apps" } }] } } },
232
+ },
233
+ ];
234
+ const nctx = { base: "https://compute.googleapis.com", project: "p1", manifest: net };
235
+ const find = (kind: string) => net.find((r) => r.kind === kind)!;
236
+
237
+ test("a network is global, with autoCreateSubnetworks false unless declared and the routing mode nested", () => {
238
+ process.env.GCP_REGION = "us-east1";
239
+ const plan = MAPPERS.ComputeNetwork.plan(find("ComputeNetwork"), nctx);
240
+ expect(plan.create.url).toBe("https://compute.googleapis.com/compute/v1/projects/p1/global/networks");
241
+ expect(plan.getUrl).toBe("https://compute.googleapis.com/compute/v1/projects/p1/global/networks/vpc");
242
+ expect(plan.create.body).toEqual({ name: "vpc", autoCreateSubnetworks: false, routingConfig: { routingMode: "REGIONAL" } });
243
+ });
244
+
245
+ test("a subnetwork is regional and names its network by partial URL", () => {
246
+ const plan = MAPPERS.ComputeSubnetwork.plan(find("ComputeSubnetwork"), nctx);
247
+ expect(plan.create.url).toBe("https://compute.googleapis.com/compute/v1/projects/p1/regions/europe-west1/subnetworks");
248
+ expect(plan.create.body).toEqual({
249
+ name: "apps",
250
+ ipCidrRange: "10.0.0.0/24",
251
+ privateIpGoogleAccess: true,
252
+ network: "projects/p1/global/networks/vpc",
253
+ secondaryIpRanges: [{ rangeName: "pods", ipCidrRange: "10.4.0.0/14" }],
254
+ });
255
+ });
256
+
257
+ test("apply order: network, then subnetwork, then the Cloud Run service that egresses into them", () => {
258
+ const order = orderByReferences(net).map((r) => r.kind);
259
+ expect(order.indexOf("ComputeNetwork")).toBeLessThan(order.indexOf("ComputeSubnetwork"));
260
+ expect(order.indexOf("ComputeSubnetwork")).toBeLessThan(order.indexOf("RunService"));
261
+ });
262
+
263
+ test("the reader reads a network at its global URL", async () => {
264
+ const http = async (_m: string, url: string) =>
265
+ url.endsWith("/global/networks/vpc") ? { status: 200, text: JSON.stringify({ name: "vpc" }) } : { status: 404, text: "" };
266
+ expect(await getResource({ project: "p1", http }, "ComputeNetwork", "vpc", {})).toEqual({ name: "vpc" });
267
+ });
268
+
269
+ test("deep observe inverts both body builders", async () => {
270
+ const { toCnrmTree } = await import("../../deep-observe");
271
+ const c = { project: "p1" };
272
+ expect(
273
+ toCnrmTree(
274
+ "ComputeNetwork",
275
+ {
276
+ name: "vpc",
277
+ autoCreateSubnetworks: false,
278
+ routingConfig: { routingMode: "REGIONAL" },
279
+ subnetworks: ["https://compute.googleapis.com/compute/v1/projects/p1/regions/europe-west1/subnetworks/apps"],
280
+ },
281
+ c,
282
+ ),
283
+ ).toEqual({ metadata: { name: "vpc" }, autoCreateSubnetworks: false, routingMode: "REGIONAL" });
284
+ expect(
285
+ toCnrmTree(
286
+ "ComputeSubnetwork",
287
+ {
288
+ name: "apps",
289
+ region: "https://compute.googleapis.com/compute/v1/projects/p1/regions/europe-west1",
290
+ network: "https://compute.googleapis.com/compute/v1/projects/p1/global/networks/vpc",
291
+ ipCidrRange: "10.0.0.0/24",
292
+ gatewayAddress: "10.0.0.1",
293
+ fingerprint: "abc",
294
+ secondaryIpRanges: [{ rangeName: "pods", ipCidrRange: "10.4.0.0/14" }],
295
+ },
296
+ c,
297
+ ),
298
+ ).toEqual({
299
+ metadata: { name: "apps" },
300
+ region: "europe-west1",
301
+ networkRef: { name: "vpc" },
302
+ ipCidrRange: "10.0.0.0/24",
303
+ secondaryIpRange: [{ rangeName: "pods", ipCidrRange: "10.4.0.0/14" }],
304
+ });
305
+ });
306
+ });
@@ -1,7 +1,9 @@
1
1
  /**
2
2
  * Compute Engine mappers for the Cloud Run load balancer (#4233): ComputeAddress,
3
3
  * ComputeRegionNetworkEndpointGroup (serverless NEGs), ComputeBackendService,
4
- * ComputeURLMap, ComputeTargetHTTPProxy and ComputeForwardingRule.
4
+ * ComputeURLMap, ComputeTargetHTTPProxy and ComputeForwardingRule; and for a
5
+ * declared network (#4248): ComputeNetwork (always global) and
6
+ * ComputeSubnetwork (regional, by its CNRM `region`).
5
7
  *
6
8
  * Each maps a CNRM spec onto the compute v1 insert body. A resource is global
7
9
  * or regional by its CNRM `location` (`"global"` or a region; a NEG has
@@ -168,6 +170,36 @@ export function negBody(resource: GcpResource, ctx: ComputeCtx): Obj {
168
170
  return body;
169
171
  }
170
172
 
173
+ /**
174
+ * ComputeNetwork → networks.insert body. A network is global. CNRM's
175
+ * `autoCreateSubnetworks` defaults to false, where compute's default is true,
176
+ * so it is always sent. Pure.
177
+ */
178
+ export function networkBody(resource: GcpResource): Obj {
179
+ const spec = (resource.spec ?? {}) as Obj;
180
+ const body: Obj = {
181
+ name: computeName(resource),
182
+ autoCreateSubnetworks: spec.autoCreateSubnetworks === true,
183
+ ...pick(spec, ["description", "mtu", "networkFirewallPolicyEnforcementOrder"]),
184
+ };
185
+ if (typeof spec.routingMode === "string") body.routingConfig = { routingMode: spec.routingMode };
186
+ return body;
187
+ }
188
+
189
+ /** ComputeSubnetwork → subnetworks.insert body. CNRM's `secondaryIpRange` and `logConfig` become compute's `secondaryIpRanges` and an enabled `logConfig`. Pure. */
190
+ export function subnetworkBody(resource: GcpResource, ctx: ComputeCtx): Obj {
191
+ const spec = (resource.spec ?? {}) as Obj;
192
+ const scope = scopeOf(spec);
193
+ const body: Obj = {
194
+ name: computeName(resource),
195
+ ...pick(spec, ["ipCidrRange", "description", "privateIpGoogleAccess", "purpose", "role", "stackType"]),
196
+ };
197
+ if (isObj(spec.networkRef)) body.network = refUrl("networkRef", spec.networkRef as Ref, ctx, scope);
198
+ if (Array.isArray(spec.secondaryIpRange)) body.secondaryIpRanges = spec.secondaryIpRange;
199
+ if (isObj(spec.logConfig)) body.logConfig = { enable: true, ...spec.logConfig };
200
+ return body;
201
+ }
202
+
171
203
  /** ComputeBackendService → backendServices.insert body. Pure. */
172
204
  export function backendServiceBody(resource: GcpResource, ctx: ComputeCtx): Obj {
173
205
  const spec = (resource.spec ?? {}) as Obj;
@@ -297,13 +329,14 @@ function computeMapper(
297
329
  collection: string,
298
330
  build: (resource: GcpResource, ctx: ComputeCtx) => Obj,
299
331
  regionalCollection = collection,
332
+ scopeFor: (spec: Obj | undefined) => string = (spec) => scopeOf(spec),
300
333
  ): ResourceMapper {
301
334
  return {
302
335
  kind,
303
336
  defaultHost: COMPUTE_HOST,
304
337
  operation: computeOperation,
305
338
  plan(resource, ctx) {
306
- const scope = scopeOf(resource.spec as Obj | undefined);
339
+ const scope = scopeFor(resource.spec as Obj | undefined);
307
340
  const coll = `${ctx.base}/compute/v1/${scopePath(ctx.project, scope)}/${scope === "global" ? collection : regionalCollection}`;
308
341
  const name = computeName(resource);
309
342
  return { getUrl: `${coll}/${enc(name)}`, create: { method: "POST", url: coll, body: build(resource, ctx) } };
@@ -317,3 +350,5 @@ export const backendServiceMapper = computeMapper("ComputeBackendService", "back
317
350
  export const urlMapMapper = computeMapper("ComputeURLMap", "urlMaps", urlMapBody);
318
351
  export const targetHttpProxyMapper = computeMapper("ComputeTargetHTTPProxy", "targetHttpProxies", targetHttpProxyBody);
319
352
  export const forwardingRuleMapper = computeMapper("ComputeForwardingRule", "forwardingRules", forwardingRuleBody);
353
+ export const networkMapper = computeMapper("ComputeNetwork", "networks", networkBody, "networks", () => "global");
354
+ export const subnetworkMapper = computeMapper("ComputeSubnetwork", "subnetworks", subnetworkBody);
@@ -293,3 +293,29 @@ describe("gcpSerializer", () => {
293
293
  expect(result).toContain("ComputeInstance");
294
294
  });
295
295
  });
296
+
297
+ describe("a .name reference serializes as the target's metadata.name (#4242)", () => {
298
+ test("a declared metadata.name wins; without one, the kebab-cased logical id", async () => {
299
+ const { RegionNetworkEndpointGroup, BackendService, CloudRunService } = await import("./generated");
300
+ const web = new CloudRunService({ location: "us-central1", template: { containers: [{ image: "i" }] } } as any);
301
+ (web as any).name._setLogicalName("webService");
302
+ const neg = new RegionNetworkEndpointGroup({
303
+ metadata: { name: "three-cloud-neg" },
304
+ region: "us-central1",
305
+ networkEndpointType: "SERVERLESS",
306
+ cloudRun: { serviceRef: { name: (web as any).name } },
307
+ } as any);
308
+ (neg as any).name._setLogicalName("neg");
309
+ const backend = new BackendService({
310
+ metadata: { name: "three-cloud-backend" },
311
+ location: "global",
312
+ backend: [{ group: { networkEndpointGroupRef: { name: (neg as any).name } } }],
313
+ } as any);
314
+ const entities = new Map<string, any>([["webService", web], ["neg", neg], ["backend", backend]]);
315
+ const yaml = String(gcpSerializer.serialize(entities));
316
+ expect(yaml).toContain("name: three-cloud-neg");
317
+ expect(yaml).not.toMatch(/networkEndpointGroupRef:\s*\n\s*name: neg\b/);
318
+ expect(yaml).toMatch(/serviceRef:\s*\n\s*name: web-service/);
319
+ expect(yaml).toMatch(/networkEndpointGroupRef:\s*\n\s*name: three-cloud-neg/);
320
+ });
321
+ });
package/src/serializer.ts CHANGED
@@ -84,15 +84,14 @@ function deriveGVKFromType(entityType: string): { apiVersion: string; kind: stri
84
84
  * GCP visitor for the generic serializer walker.
85
85
  */
86
86
  function gcpVisitor(entityNames: Map<Declarable, string>): SerializerVisitor {
87
+ // Config Connector resolves a `*Ref: { name }` by the target's metadata.name,
88
+ // which is its declared name or else the kebab-cased logical id (#4242).
89
+ const cnrmNames = new Map<string, string>();
90
+ for (const [entity, logical] of entityNames) cnrmNames.set(logical, cnrmName(logical, entity));
91
+ const resolve = (logical: string) => cnrmNames.get(logical) ?? logical;
87
92
  return {
88
- attrRef: (name, _attr) => {
89
- // For Config Connector, references resolve to metadata.name
90
- return name;
91
- },
92
- resourceRef: (name) => {
93
- // Config Connector uses resourceRef pattern: { name: "resource-name" }
94
- return { name };
95
- },
93
+ attrRef: (name, _attr) => resolve(name),
94
+ resourceRef: (name) => ({ name: resolve(name) }),
96
95
  propertyDeclarable: (entity, walk) => {
97
96
  if (!isResourceDeclarable(entity) || typeof entity.props !== "object" || entity.props === null) {
98
97
  return undefined;
@@ -109,6 +108,20 @@ function gcpVisitor(entityNames: Map<Declarable, string>): SerializerVisitor {
109
108
  };
110
109
  }
111
110
 
111
+ /**
112
+ * The metadata.name a resource is written with: a string `metadata.name` in its
113
+ * props, else its logical id in kebab case.
114
+ */
115
+ export function cnrmName(logical: string, entity: Declarable): string {
116
+ const props = isResourceDeclarable(entity) ? (entity.props as { metadata?: { name?: unknown } } | undefined) : undefined;
117
+ const declared = props?.metadata?.name;
118
+ return typeof declared === "string" && declared.length > 0 ? declared : kebabName(logical);
119
+ }
120
+
121
+ function kebabName(logical: string): string {
122
+ return logical.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
123
+ }
124
+
112
125
  /**
113
126
  * Convert a value to YAML-compatible form using the walker.
114
127
  */
@@ -189,7 +202,7 @@ export const gcpSerializer: Serializer = {
189
202
  // Build metadata
190
203
  const metadata: Record<string, unknown> = props.metadata as Record<string, unknown> ?? {};
191
204
  if (!metadata.name) {
192
- metadata.name = name.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
205
+ metadata.name = kebabName(name);
193
206
  }
194
207
 
195
208
  // Merge default labels