@intentius/chant-lexicon-gcp 0.124.38 → 0.124.39
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/dist/api/read-client.d.ts +7 -0
- package/dist/api/read-client.d.ts.map +1 -1
- package/dist/api/read-client.js +24 -9
- package/dist/composites/catalog.d.ts.map +1 -1
- package/dist/composites/catalog.js +187 -0
- package/dist/composites/index.d.ts +4 -0
- package/dist/composites/index.d.ts.map +1 -1
- package/dist/composites/index.js +2 -0
- package/dist/composites/private-egress-network.d.ts +42 -0
- package/dist/composites/private-egress-network.d.ts.map +1 -0
- package/dist/composites/private-egress-network.js +48 -0
- package/dist/composites/public-cloud-run.d.ts +85 -0
- package/dist/composites/public-cloud-run.d.ts.map +1 -0
- package/dist/composites/public-cloud-run.js +144 -0
- package/dist/deep-observe.d.ts +5 -0
- package/dist/deep-observe.d.ts.map +1 -1
- package/dist/deep-observe.js +34 -2
- package/dist/health.d.ts +26 -2
- package/dist/health.d.ts.map +1 -1
- package/dist/health.js +85 -6
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/integrity.json +3 -3
- package/dist/manifest.json +1 -1
- package/dist/op/activities/gcp-apply.d.ts +19 -0
- package/dist/op/activities/gcp-apply.d.ts.map +1 -1
- package/dist/op/activities/gcp-apply.js +16 -0
- package/dist/op/activities/gcp-compute.d.ts +9 -0
- package/dist/op/activities/gcp-compute.d.ts.map +1 -1
- package/dist/op/activities/gcp-compute.js +107 -11
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +6 -2
- package/dist/skills/chant-gcp.md +2 -0
- package/package.json +2 -2
- package/src/api/read-client.ts +23 -8
- package/src/composites/catalog.ts +187 -0
- package/src/composites/cloud-run-lb.test.ts +93 -0
- package/src/composites/index.ts +4 -0
- package/src/composites/private-egress-network.ts +82 -0
- package/src/composites/public-cloud-run.ts +245 -0
- package/src/deep-observe.test.ts +46 -0
- package/src/deep-observe.ts +38 -2
- package/src/health.test.ts +65 -1
- package/src/health.ts +88 -11
- package/src/index.ts +2 -1
- package/src/op/activities/gcp-apply.ts +31 -1
- package/src/op/activities/gcp-compute-reconcile.test.ts +150 -0
- package/src/op/activities/gcp-compute.test.ts +4 -2
- package/src/op/activities/gcp-compute.ts +129 -11
- package/src/plugin.ts +6 -2
- package/src/skills/chant-gcp.md +2 -0
|
@@ -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;
|
|
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;IAClB,8FAA8F;IAC9F,OAAO,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,OAAO,CAAA;KAAE,CAAC;CACxC;AAgPD;;;;;;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;AA6BD;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CA0F5G"}
|
package/dist/deep-observe.js
CHANGED
|
@@ -299,8 +299,14 @@ const CNRM_REFINERS = {
|
|
|
299
299
|
delete tree.gatewayAddress;
|
|
300
300
|
delete tree.fingerprint;
|
|
301
301
|
},
|
|
302
|
-
ComputeForwardingRule(tree) {
|
|
302
|
+
ComputeForwardingRule(tree, ctx) {
|
|
303
303
|
computeLocation(tree);
|
|
304
|
+
// Compute returns the IP; CNRM writes `ipAddress: { addressRef }` or `{ ip }`.
|
|
305
|
+
// The IP is the declared address's own when the read found it so (#4238).
|
|
306
|
+
if (typeof tree.IPAddress === "string") {
|
|
307
|
+
tree.ipAddress = ctx.address && ctx.address.ip === tree.IPAddress ? { addressRef: ctx.address.ref } : { ip: tree.IPAddress };
|
|
308
|
+
delete tree.IPAddress;
|
|
309
|
+
}
|
|
304
310
|
if (tree.IPProtocol !== undefined) {
|
|
305
311
|
tree.ipProtocol = tree.IPProtocol;
|
|
306
312
|
delete tree.IPProtocol;
|
|
@@ -352,6 +358,31 @@ export function toCnrmTree(kind, body, ctx) {
|
|
|
352
358
|
CNRM_REFINERS[kind]?.(tree, { ...ctx, restName });
|
|
353
359
|
return tree;
|
|
354
360
|
}
|
|
361
|
+
/**
|
|
362
|
+
* The live IP of the address a forwarding rule declares in
|
|
363
|
+
* `ipAddress.addressRef`, read with the address's own declaration when the
|
|
364
|
+
* manifest holds it, so the rule's `IPAddress` can be matched to the ref
|
|
365
|
+
* rather than read as drift (#4238). Undefined when there is no ref or the
|
|
366
|
+
* read fails; the rule then shows the IP as it is.
|
|
367
|
+
*/
|
|
368
|
+
async function declaredAddressIp(client, props, manifest) {
|
|
369
|
+
const spec = props.spec ?? props;
|
|
370
|
+
const ref = spec.ipAddress?.addressRef;
|
|
371
|
+
if (!ref)
|
|
372
|
+
return undefined;
|
|
373
|
+
const raw = typeof ref.name === "string" ? ref.name : typeof ref.external === "string" ? ref.external : undefined;
|
|
374
|
+
if (!raw)
|
|
375
|
+
return undefined;
|
|
376
|
+
const name = raw.slice(raw.lastIndexOf("/") + 1);
|
|
377
|
+
const declared = manifest.find((r) => r.kind === "ComputeAddress" && r.metadata?.name === name);
|
|
378
|
+
try {
|
|
379
|
+
const body = await getResource(client, "ComputeAddress", name, declared?.spec ?? { location: spec.location });
|
|
380
|
+
return typeof body.address === "string" ? { ip: body.address, ref } : undefined;
|
|
381
|
+
}
|
|
382
|
+
catch {
|
|
383
|
+
return undefined;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
355
386
|
/**
|
|
356
387
|
* Read the live property tree for each declared entity over the applier's
|
|
357
388
|
* REST transport, normalized into the declared CNRM shape (see the module
|
|
@@ -399,6 +430,7 @@ export async function observeResourcesDeepGcp(options) {
|
|
|
399
430
|
try {
|
|
400
431
|
const obj = await getResource(client, gvk.kind, name, props);
|
|
401
432
|
const labels = obj.labels;
|
|
433
|
+
const address = gvk.kind === "ComputeForwardingRule" ? await declaredAddressIp(client, props, manifest) : undefined;
|
|
402
434
|
// owned filter: withhold what does not carry chant's marker. Withheld is
|
|
403
435
|
// not absent (#1089). Where the payload has no labels at all there is
|
|
404
436
|
// nothing to filter on, so the resource passes through — the same
|
|
@@ -414,7 +446,7 @@ export async function observeResourcesDeepGcp(options) {
|
|
|
414
446
|
resources[entityName] = {
|
|
415
447
|
type: entityType,
|
|
416
448
|
physicalId: obj.id ?? obj.selfLink ?? obj.name,
|
|
417
|
-
properties: normalizeDeepProperties(toCnrmTree(gvk.kind, obj, { project: client.project }), {
|
|
449
|
+
properties: normalizeDeepProperties(toCnrmTree(gvk.kind, obj, { project: client.project, ...(address ? { address } : {}) }), {
|
|
418
450
|
entityType,
|
|
419
451
|
side: "live",
|
|
420
452
|
// The static table is the whole prune here — there is no per-resource
|
package/dist/health.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Runtime health for GCP (#4177): Cloud Run services
|
|
2
|
+
* Runtime health for GCP (#4177): Cloud Run services; and (#4239) backend
|
|
3
|
+
* services, from `getHealth` on each backend group, and IAM policy members,
|
|
4
|
+
* healthy when the member holds the role in the target's policy.
|
|
3
5
|
*
|
|
4
6
|
* A Cloud Run v2 service carries its `Ready` condition as `terminalCondition`
|
|
5
7
|
* (`CONDITION_SUCCEEDED`, `CONDITION_FAILED`, pending or reconciling). The v1
|
|
@@ -10,7 +12,7 @@
|
|
|
10
12
|
*/
|
|
11
13
|
import type { HealthEntry, HealthReadOptions, HealthReadResult } from "@intentius/chant/lexicon";
|
|
12
14
|
import { type GcpReadHttp } from "./api/read-client.js";
|
|
13
|
-
export declare const GCP_HEALTH_TYPES: readonly ["GCP::Run::Service"];
|
|
15
|
+
export declare const GCP_HEALTH_TYPES: readonly ["GCP::Run::Service", "GCP::Compute::BackendService", "GCP::Iam::PolicyMember"];
|
|
14
16
|
export interface GcpHealthOptions extends HealthReadOptions {
|
|
15
17
|
http?: GcpReadHttp;
|
|
16
18
|
now?: () => Date;
|
|
@@ -37,6 +39,28 @@ export interface CloudRunServiceState {
|
|
|
37
39
|
}
|
|
38
40
|
/** The `Ready` condition's verdict. No condition at all is `unknown`. */
|
|
39
41
|
export declare function cloudRunEntry(body: CloudRunServiceState, observedAt: string): HealthEntry;
|
|
42
|
+
/** One backend group's `getHealth` answer: `healthStatus[].healthState` per endpoint. */
|
|
43
|
+
export interface BackendGroupHealth {
|
|
44
|
+
group: string;
|
|
45
|
+
healthStatus?: Array<{
|
|
46
|
+
healthState?: string;
|
|
47
|
+
}>;
|
|
48
|
+
/** Set when the call failed; the group then counts as unknown. */
|
|
49
|
+
error?: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* A backend service's verdict from its groups: any endpoint `UNHEALTHY` is
|
|
53
|
+
* unhealthy; every endpoint `HEALTHY`, with at least one, is healthy; anything
|
|
54
|
+
* else (no backends, a group that reports no status, as a serverless NEG
|
|
55
|
+
* does, a failed call) is unknown.
|
|
56
|
+
*/
|
|
57
|
+
export declare function backendServiceEntry(groups: readonly BackendGroupHealth[], observedAt: string): HealthEntry;
|
|
58
|
+
/** A binding the read found in its target's policy. A missing one is `absent`, never here. */
|
|
59
|
+
export declare function policyMemberEntry(binding: {
|
|
60
|
+
role?: string;
|
|
61
|
+
member?: string;
|
|
62
|
+
resource?: string;
|
|
63
|
+
}, observedAt: string): HealthEntry;
|
|
40
64
|
export declare function observeHealthGcp(options: GcpHealthOptions): Promise<HealthReadResult>;
|
|
41
65
|
export {};
|
|
42
66
|
//# sourceMappingURL=health.d.ts.map
|
package/dist/health.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,gBAAgB,EAAoB,MAAM,0BAA0B,CAAC;AACnH,OAAO,EAAkD,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGrG,eAAO,MAAM,gBAAgB,YAAI,mBAAmB,EAAE,8BAA8B,EAAE,wBAAwB,CAAU,CAAC;AAEzH,MAAM,WAAW,gBAAiB,SAAQ,iBAAiB;IACzD,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;CAClB;AAED,UAAU,SAAS;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,gEAAgE;AAChE,MAAM,WAAW,oBAAoB;IACnC,iBAAiB,CAAC,EAAE,SAAS,CAAC;IAC9B,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;IACzB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,SAAS,EAAE,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACrD;AAOD,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,IAAI,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CAqBzF;AAED,yFAAyF;AACzF,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,KAAK,CAAC;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,SAAS,kBAAkB,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CAkB1G;AAED,8FAA8F;AAC9F,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CAOjI;AA6BD,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAqD3F"}
|
package/dist/health.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Runtime health for GCP (#4177): Cloud Run services
|
|
2
|
+
* Runtime health for GCP (#4177): Cloud Run services; and (#4239) backend
|
|
3
|
+
* services, from `getHealth` on each backend group, and IAM policy members,
|
|
4
|
+
* healthy when the member holds the role in the target's policy.
|
|
3
5
|
*
|
|
4
6
|
* A Cloud Run v2 service carries its `Ready` condition as `terminalCondition`
|
|
5
7
|
* (`CONDITION_SUCCEEDED`, `CONDITION_FAILED`, pending or reconciling). The v1
|
|
@@ -8,9 +10,9 @@
|
|
|
8
10
|
* project resolution and endpoint rule as `describe-resources.ts`, so
|
|
9
11
|
* `GCP_ENDPOINT_URL` (floci-gcp) answers.
|
|
10
12
|
*/
|
|
11
|
-
import { getResource, GcpReadError, isNotFound } from "./api/read-client.js";
|
|
12
|
-
import { deriveGVK, manifestProjectAnnotations, readTargets, resolveReadProject } from "./describe-resources.js";
|
|
13
|
-
export const GCP_HEALTH_TYPES = ["GCP::Run::Service"];
|
|
13
|
+
import { getResource, GcpReadError, isNotFound, readUrl } from "./api/read-client.js";
|
|
14
|
+
import { deriveGVK, manifestProjectAnnotations, readManifest, readTargets, resolveReadProject } from "./describe-resources.js";
|
|
15
|
+
export const GCP_HEALTH_TYPES = ["GCP::Run::Service", "GCP::Compute::BackendService", "GCP::Iam::PolicyMember"];
|
|
14
16
|
function readyCondition(body) {
|
|
15
17
|
if (body.terminalCondition && (body.terminalCondition.type ?? "Ready") === "Ready")
|
|
16
18
|
return body.terminalCondition;
|
|
@@ -39,6 +41,72 @@ export function cloudRunEntry(body, observedAt) {
|
|
|
39
41
|
...(ready.lastTransitionTime ? { checkedAt: ready.lastTransitionTime } : {}),
|
|
40
42
|
};
|
|
41
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* A backend service's verdict from its groups: any endpoint `UNHEALTHY` is
|
|
46
|
+
* unhealthy; every endpoint `HEALTHY`, with at least one, is healthy; anything
|
|
47
|
+
* else (no backends, a group that reports no status, as a serverless NEG
|
|
48
|
+
* does, a failed call) is unknown.
|
|
49
|
+
*/
|
|
50
|
+
export function backendServiceEntry(groups, observedAt) {
|
|
51
|
+
const type = "GCP::Compute::BackendService";
|
|
52
|
+
if (groups.length === 0)
|
|
53
|
+
return { type, state: "unknown", detail: "no backends", observedAt };
|
|
54
|
+
let healthy = 0;
|
|
55
|
+
let unhealthy = 0;
|
|
56
|
+
let unknown = 0;
|
|
57
|
+
for (const g of groups) {
|
|
58
|
+
const states = g.error ? [] : (g.healthStatus ?? []).map((h) => (h.healthState ?? "").toUpperCase());
|
|
59
|
+
if (states.length === 0)
|
|
60
|
+
unknown++;
|
|
61
|
+
else if (states.some((st) => st === "UNHEALTHY"))
|
|
62
|
+
unhealthy++;
|
|
63
|
+
else if (states.every((st) => st === "HEALTHY"))
|
|
64
|
+
healthy++;
|
|
65
|
+
else
|
|
66
|
+
unknown++;
|
|
67
|
+
}
|
|
68
|
+
const state = unhealthy > 0 ? "unhealthy" : healthy === groups.length ? "healthy" : "unknown";
|
|
69
|
+
const parts = [`${healthy} of ${groups.length} backend${groups.length === 1 ? "" : "s"} healthy`];
|
|
70
|
+
if (unhealthy)
|
|
71
|
+
parts.push(`${unhealthy} unhealthy`);
|
|
72
|
+
if (unknown)
|
|
73
|
+
parts.push(`${unknown} with no health status`);
|
|
74
|
+
return { type, state, detail: parts.join(", "), observedAt };
|
|
75
|
+
}
|
|
76
|
+
/** A binding the read found in its target's policy. A missing one is `absent`, never here. */
|
|
77
|
+
export function policyMemberEntry(binding, observedAt) {
|
|
78
|
+
return {
|
|
79
|
+
type: "GCP::Iam::PolicyMember",
|
|
80
|
+
state: "healthy",
|
|
81
|
+
detail: `${binding.member ?? "member"} holds ${binding.role ?? "the role"}${binding.resource ? ` on ${binding.resource}` : ""}`,
|
|
82
|
+
observedAt,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const defaultReadHttp = async (method, url, body) => {
|
|
86
|
+
const res = await fetch(url, {
|
|
87
|
+
method,
|
|
88
|
+
...(body === undefined ? {} : { headers: { "content-type": "application/json" }, body: JSON.stringify(body) }),
|
|
89
|
+
});
|
|
90
|
+
return { status: res.status, text: await res.text() };
|
|
91
|
+
};
|
|
92
|
+
/** `getHealth` for each of a backend service's groups, at the service's own read URL. */
|
|
93
|
+
async function backendGroupsHealth(url, body, http) {
|
|
94
|
+
const backends = Array.isArray(body.backends) ? body.backends : [];
|
|
95
|
+
return Promise.all(backends
|
|
96
|
+
.map((b) => b.group)
|
|
97
|
+
.filter((g) => typeof g === "string")
|
|
98
|
+
.map(async (group) => {
|
|
99
|
+
try {
|
|
100
|
+
const res = await http("POST", `${url}/getHealth`, { group });
|
|
101
|
+
if (res.status < 200 || res.status >= 300)
|
|
102
|
+
return { group, error: `getHealth ${res.status}` };
|
|
103
|
+
return { group, ...JSON.parse(res.text) };
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
return { group, error: err instanceof Error ? err.message : String(err) };
|
|
107
|
+
}
|
|
108
|
+
}));
|
|
109
|
+
}
|
|
42
110
|
export async function observeHealthGcp(options) {
|
|
43
111
|
const observedAt = (options.now?.() ?? new Date()).toISOString();
|
|
44
112
|
const endpoint = process.env.GCP_ENDPOINT_URL;
|
|
@@ -47,6 +115,7 @@ export async function observeHealthGcp(options) {
|
|
|
47
115
|
const unobserved = {};
|
|
48
116
|
const absent = [];
|
|
49
117
|
const targets = readTargets(options.entities);
|
|
118
|
+
const manifest = readManifest(options.entities, targets);
|
|
50
119
|
await Promise.all([...options.entities].map(async ([entityName, { entityType }]) => {
|
|
51
120
|
const gvk = deriveGVK(entityType);
|
|
52
121
|
const { name, props } = targets.get(entityName);
|
|
@@ -64,8 +133,18 @@ export async function observeHealthGcp(options) {
|
|
|
64
133
|
return;
|
|
65
134
|
}
|
|
66
135
|
try {
|
|
67
|
-
const
|
|
68
|
-
|
|
136
|
+
const client = { project, ...(endpoint ? { endpoint } : {}), ...(options.http ? { http: options.http } : {}), manifest };
|
|
137
|
+
const body = await getResource(client, gvk.kind, name, props);
|
|
138
|
+
if (gvk.kind === "ComputeBackendService") {
|
|
139
|
+
const groups = await backendGroupsHealth(readUrl(client, gvk.kind, name, props), body, options.http ?? defaultReadHttp);
|
|
140
|
+
entities[entityName] = backendServiceEntry(groups, observedAt);
|
|
141
|
+
}
|
|
142
|
+
else if (gvk.kind === "IAMPolicyMember") {
|
|
143
|
+
entities[entityName] = policyMemberEntry(body, observedAt);
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
entities[entityName] = cloudRunEntry(body, observedAt);
|
|
147
|
+
}
|
|
69
148
|
}
|
|
70
149
|
catch (err) {
|
|
71
150
|
if (isNotFound(err)) {
|
package/dist/index.d.ts
CHANGED
|
@@ -7,8 +7,8 @@ export { GCP, ProjectId, Region, Zone } from "./pseudo.js";
|
|
|
7
7
|
export { GcpAnnotations } from "./variables.js";
|
|
8
8
|
export { LexiconOutput, output, isLexiconOutput } from "@intentius/chant/lexicon-output";
|
|
9
9
|
export * from "./generated/index.js";
|
|
10
|
-
export { GkeCluster, CloudRunServiceComposite, CloudSqlInstance, GcsBucket, VpcNetwork, PubSubPipeline, CloudFunctionWithTrigger, PrivateService, ManagedCertificate, SecureProject, MemorystoreRedis, MultiRegionVpc, GkeCrdbRegion, GpuNodePool, GovernanceFoundation, LocationRestriction, OrganizationAuditConfig, } from "./composites/index.js";
|
|
11
|
-
export type { GkeClusterProps, CloudRunServiceProps, CloudSqlInstanceProps, GcsBucketProps, VpcNetworkProps, VpcSubnet, PubSubPipelineProps, CloudFunctionWithTriggerProps, PrivateServiceProps, ManagedCertificateProps, SecureProjectProps, MemorystoreRedisProps, MultiRegionVpcConfig, MultiRegionVpcRegion, GkeCrdbRegionConfig, GkeCrdbRegionNodeConfig, GpuNodePoolProps, GpuNodePoolTaint, GovernanceFoundationProps, LocationRestrictionProps, OrganizationAuditConfigProps, } from "./composites/index.js";
|
|
10
|
+
export { GkeCluster, CloudRunServiceComposite, CloudSqlInstance, GcsBucket, VpcNetwork, PubSubPipeline, CloudFunctionWithTrigger, PrivateService, ManagedCertificate, SecureProject, MemorystoreRedis, MultiRegionVpc, GkeCrdbRegion, GpuNodePool, PrivateEgressNetwork, PublicCloudRun, GovernanceFoundation, LocationRestriction, OrganizationAuditConfig, } from "./composites/index.js";
|
|
11
|
+
export type { GkeClusterProps, CloudRunServiceProps, CloudSqlInstanceProps, GcsBucketProps, VpcNetworkProps, VpcSubnet, PubSubPipelineProps, CloudFunctionWithTriggerProps, PrivateServiceProps, ManagedCertificateProps, SecureProjectProps, MemorystoreRedisProps, MultiRegionVpcConfig, MultiRegionVpcRegion, GkeCrdbRegionConfig, GkeCrdbRegionNodeConfig, GpuNodePoolProps, GpuNodePoolTaint, PrivateEgressNetworkProps, PublicCloudRunProps, GovernanceFoundationProps, LocationRestrictionProps, OrganizationAuditConfigProps, } from "./composites/index.js";
|
|
12
12
|
export { landingZoneConfig, resourceLocationRestriction, DISABLE_SA_KEY_CREATION, SKIP_DEFAULT_NETWORK, AUDIT_ALL_SERVICES, FOUNDATION_FOLDERS, } from "./governance.js";
|
|
13
13
|
export type { GcpGovernanceConfig, LandingZoneConfigProps, FolderConfig, OrgPolicyConfig, ProjectConfig } from "./governance.js";
|
|
14
14
|
export { StorageRoles, ComputeRoles, ContainerRoles, IAMRoles, SQLRoles, RunRoles, PubSubRoles } from "./actions/index.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAG9E,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7C,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAGrC,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC5G,OAAO,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAGrF,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAGxD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAIzF,cAAc,mBAAmB,CAAC;AAGlC,OAAO,EACL,UAAU,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,SAAS,EAAE,UAAU,EAC7E,cAAc,EAAE,wBAAwB,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAC3F,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAG9E,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG7C,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAGrC,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC5G,OAAO,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAGrF,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAGxD,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAIzF,cAAc,mBAAmB,CAAC;AAGlC,OAAO,EACL,UAAU,EAAE,wBAAwB,EAAE,gBAAgB,EAAE,SAAS,EAAE,UAAU,EAC7E,cAAc,EAAE,wBAAwB,EAAE,cAAc,EAAE,kBAAkB,EAAE,aAAa,EAC3F,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,oBAAoB,EAAE,cAAc,EAClG,oBAAoB,EAAE,mBAAmB,EAAE,uBAAuB,GACnE,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,cAAc,EACd,eAAe,EAAE,SAAS,EAC1B,mBAAmB,EACnB,6BAA6B,EAC7B,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,qBAAqB,EACrB,oBAAoB,EAAE,oBAAoB,EAC1C,mBAAmB,EAAE,uBAAuB,EAC5C,gBAAgB,EAAE,gBAAgB,EAClC,yBAAyB,EAAE,mBAAmB,EAC9C,yBAAyB,EAAE,wBAAwB,EAAE,4BAA4B,GAClF,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EACL,iBAAiB,EAAE,2BAA2B,EAC9C,uBAAuB,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,kBAAkB,GACtF,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAG9H,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGxH,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACrF,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAC1G,YAAY,EAAE,cAAc,EAAE,cAAc,EAAE,cAAc,EAAE,kBAAkB,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGrI,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAGvE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -21,7 +21,7 @@ export { LexiconOutput, output, isLexiconOutput } from "@intentius/chant/lexicon
|
|
|
21
21
|
// After running `npm run generate`, this re-exports all Config Connector resource classes
|
|
22
22
|
export * from "./generated/index.js";
|
|
23
23
|
// Composites
|
|
24
|
-
export { GkeCluster, CloudRunServiceComposite, CloudSqlInstance, GcsBucket, VpcNetwork, PubSubPipeline, CloudFunctionWithTrigger, PrivateService, ManagedCertificate, SecureProject, MemorystoreRedis, MultiRegionVpc, GkeCrdbRegion, GpuNodePool, GovernanceFoundation, LocationRestriction, OrganizationAuditConfig, } from "./composites/index.js";
|
|
24
|
+
export { GkeCluster, CloudRunServiceComposite, CloudSqlInstance, GcsBucket, VpcNetwork, PubSubPipeline, CloudFunctionWithTrigger, PrivateService, ManagedCertificate, SecureProject, MemorystoreRedis, MultiRegionVpc, GkeCrdbRegion, GpuNodePool, PrivateEgressNetwork, PublicCloudRun, GovernanceFoundation, LocationRestriction, OrganizationAuditConfig, } from "./composites/index.js";
|
|
25
25
|
// GCP governance authoring: the desired-state config an external governance
|
|
26
26
|
// reconciler applies, and the typed landing-zone authoring layer.
|
|
27
27
|
export { landingZoneConfig, resourceLocationRestriction, DISABLE_SA_KEY_CREATION, SKIP_DEFAULT_NETWORK, AUDIT_ALL_SERVICES, FOUNDATION_FOLDERS, } from "./governance.js";
|
package/dist/integrity.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"algorithm": "sha256",
|
|
3
3
|
"artifacts": {
|
|
4
|
-
"manifest.json": "
|
|
4
|
+
"manifest.json": "f3591792043dc8b5c86d1c30c694b09225546ef08cd7a2c9856718ea094d6259",
|
|
5
5
|
"meta.json": "75643660010c044c6f465bef2688a864ab30cc96fd9b68111969749748ac64ca",
|
|
6
6
|
"types/index.d.ts": "da1ebc6bcf83e1a018a773b59714194aeeb74ae1d5c1252b737b7e730ca98bd5",
|
|
7
7
|
"rules/hardcoded-project.ts": "6d5ae9efa74d73800eebe1a0a0d43c619ee0fdebe3347195df93fcbe63b34f0d",
|
|
@@ -35,10 +35,10 @@
|
|
|
35
35
|
"rules/wgc501.ts": "bf99d8dc97537687fdfe9a8d5eb420172bf3279a4147311037f9c1d1f5fd4c85",
|
|
36
36
|
"rules/wgc502.ts": "6460a028f73ef31a66653954e67142079130112b70fa01a79f80464968a1b9f6",
|
|
37
37
|
"rules/wgc503.ts": "44dc51efbf9f9384b61a4e19b173b4c182557143cb59fbaf4da087e70a38f916",
|
|
38
|
-
"skills/chant-gcp.md": "
|
|
38
|
+
"skills/chant-gcp.md": "da90cf5982451652bd0f0ad51563c248379824a77bd49c9ecbadbb37a82a29e1",
|
|
39
39
|
"skills/chant-gcp-security.md": "39a1c97b7425ed43b081257132449d11ce9d12f2d4755fc30d8b14bbc38f60bd",
|
|
40
40
|
"skills/chant-gcp-patterns.md": "4c6809fc7c37fa1879379ad4c0e2d114dec9497bc6eb9d1bca4e79fddea4f509",
|
|
41
41
|
"skills/chant-gcp-gke.md": "be277019da9a722c851e47cd2dfb9c9536668948c3535fb20db7697e934c4e2b"
|
|
42
42
|
},
|
|
43
|
-
"composite": "
|
|
43
|
+
"composite": "73e7ca62da8ef9beafa48e58b549248bd5b24abd37f1a4bb180de513b7319acc"
|
|
44
44
|
}
|
package/dist/manifest.json
CHANGED
|
@@ -86,7 +86,25 @@ export interface ApplyPlan {
|
|
|
86
86
|
url: string;
|
|
87
87
|
body: unknown;
|
|
88
88
|
};
|
|
89
|
+
/**
|
|
90
|
+
* In place of `update`, for a resource whose update depends on the live body
|
|
91
|
+
* (#4238): compute updates carry the live `fingerprint`, and some fields only
|
|
92
|
+
* change through a setter (`setTarget`, `setLabels`). Returns the requests to
|
|
93
|
+
* send, none when the live resource already matches, or `replace` naming what
|
|
94
|
+
* differs on a field that can't change in place.
|
|
95
|
+
*/
|
|
96
|
+
reconcile?(live: unknown, http: GcpHttp, signal?: AbortSignal): Promise<ReconcileStep>;
|
|
89
97
|
}
|
|
98
|
+
/** What {@link ApplyPlan.reconcile} decided for an existing resource. */
|
|
99
|
+
export type ReconcileStep = {
|
|
100
|
+
requests: Array<{
|
|
101
|
+
method: "POST" | "PATCH" | "PUT";
|
|
102
|
+
url: string;
|
|
103
|
+
body: unknown;
|
|
104
|
+
}>;
|
|
105
|
+
} | {
|
|
106
|
+
replace: string;
|
|
107
|
+
};
|
|
90
108
|
/**
|
|
91
109
|
* Handles an async create whose response is a long-running operation. Present
|
|
92
110
|
* only on mappers for resources that provision asynchronously (Cloud Run, GKE,
|
|
@@ -280,6 +298,7 @@ export declare function applyResource(mapper: ResourceMapper, resource: GcpResou
|
|
|
280
298
|
name: string;
|
|
281
299
|
created: boolean;
|
|
282
300
|
updated: boolean;
|
|
301
|
+
replaceRequired?: string;
|
|
283
302
|
}>;
|
|
284
303
|
/**
|
|
285
304
|
* Poll a long-running operation until it reports done (or errors / times out).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gcp-apply.d.ts","sourceRoot":"","sources":["../../../src/op/activities/gcp-apply.ts"],"names":[],"mappings":"AAgBA,OAAO,EAEL,KAAK,WAAW,EAGjB,MAAM,wBAAwB,CAAC;AAIhC;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAE7D;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAEvF;AAQD,+EAA+E;AAC/E,MAAM,WAAW,WAAW;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAChC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACtC,CAAC;IACF,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED,8DAA8D;AAC9D,MAAM,WAAW,iBAAkB,SAAQ,WAAW;IACpD,IAAI,CAAC,EAAE;QACL,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,wBAAwB,CAAC,EAAE,OAAO,CAAC;QACnC,UAAU,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE,OAAO,CAAA;SAAE,CAAC;QACnC,aAAa,CAAC,EAAE,KAAK,CAAC;YAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;SAAE,CAAC,CAAC;KAClG,CAAC;CACH;AAED,gEAAgE;AAChE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gBAAgB,CAAC,EAAE;QAAE,wBAAwB,EAAE;YAAE,OAAO,EAAE,OAAO,CAAA;SAAE,CAAA;KAAE,CAAC;IACtE,UAAU,CAAC,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAClC,SAAS,CAAC,EAAE;QAAE,IAAI,EAAE,KAAK,CAAC;YAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;SAAE,CAAC,CAAA;KAAE,CAAC;CACvG;AAED,4CAA4C;AAC5C,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,wBAAwB,CAAC,EAAE,MAAM,CAAC;CACnC;AAID;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC;IAC/D,MAAM,CAAC,EAAE;QAAE,MAAM,EAAE,OAAO,GAAG,KAAK,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"gcp-apply.d.ts","sourceRoot":"","sources":["../../../src/op/activities/gcp-apply.ts"],"names":[],"mappings":"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"}
|
|
@@ -485,6 +485,22 @@ export async function applyResource(mapper, resource, ctx, http = defaultHttp, s
|
|
|
485
485
|
}
|
|
486
486
|
const plan = mapper.plan(resource, ctx);
|
|
487
487
|
const get = await http("GET", plan.getUrl, undefined, signal);
|
|
488
|
+
if (get.status === 200 && plan.reconcile) {
|
|
489
|
+
const step = await plan.reconcile(parseJson(get.text), http, signal);
|
|
490
|
+
if ("replace" in step) {
|
|
491
|
+
// Reported, not attempted: replacing deletes the resource, which apply never does on its own.
|
|
492
|
+
console.log(`replace required: ${mapper.kind}/${name}: ${step.replace}`);
|
|
493
|
+
return { kind: mapper.kind, name, created: false, updated: false, replaceRequired: step.replace };
|
|
494
|
+
}
|
|
495
|
+
for (const req of step.requests) {
|
|
496
|
+
const res = await http(req.method, req.url, req.body, signal);
|
|
497
|
+
if (res.status >= 300) {
|
|
498
|
+
throw new Error(`${mapper.kind} ${name} update failed (${res.status}): ${res.text}`);
|
|
499
|
+
}
|
|
500
|
+
await pollIfAsync(mapper, res.text, ctx, http, signal);
|
|
501
|
+
}
|
|
502
|
+
return { kind: mapper.kind, name, created: false, updated: step.requests.length > 0 };
|
|
503
|
+
}
|
|
488
504
|
if (get.status === 200) {
|
|
489
505
|
// Exists. Reconcile to desired if the mapper supports it; otherwise leave it.
|
|
490
506
|
if (!plan.update) {
|
|
@@ -54,6 +54,15 @@ export declare function forwardingRuleBody(resource: GcpResource, ctx: ComputeCt
|
|
|
54
54
|
* resource itself has nothing to poll.
|
|
55
55
|
*/
|
|
56
56
|
export declare const computeOperation: OperationSpec;
|
|
57
|
+
/**
|
|
58
|
+
* True when the live value holds the desired one: every desired key is set
|
|
59
|
+
* live to an equal value, arrays element by element, and a compute URL
|
|
60
|
+
* equals its partial form. Fields only the live side has (defaults, server
|
|
61
|
+
* ids) don't count. Pure.
|
|
62
|
+
*/
|
|
63
|
+
export declare function holds(desired: unknown, live: unknown): boolean;
|
|
64
|
+
/** The desired body's top-level fields the live resource doesn't hold, `name` aside. Pure. */
|
|
65
|
+
export declare function changedFields(desired: Obj, live: Obj): string[];
|
|
57
66
|
export declare const computeAddressMapper: ResourceMapper;
|
|
58
67
|
export declare const regionNetworkEndpointGroupMapper: ResourceMapper;
|
|
59
68
|
export declare const backendServiceMapper: ResourceMapper;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gcp-compute.d.ts","sourceRoot":"","sources":["../../../src/op/activities/gcp-compute.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"gcp-compute.d.ts","sourceRoot":"","sources":["../../../src/op/activities/gcp-compute.ts"],"names":[],"mappings":"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"}
|
|
@@ -14,9 +14,16 @@
|
|
|
14
14
|
* backend service can point at a regional NEG.
|
|
15
15
|
*
|
|
16
16
|
* Inserts return a compute `Operation`, polled at its `selfLink` (rebased onto
|
|
17
|
-
* the endpoint override, so floci-gcp answers).
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* the endpoint override, so floci-gcp answers).
|
|
18
|
+
*
|
|
19
|
+
* An existing load balancer resource is compared with its desired body and
|
|
20
|
+
* updated in place where compute allows it (#4238): a backend service or URL
|
|
21
|
+
* map by PATCH with the live `fingerprint`, a proxy's URL map by `setUrlMap`,
|
|
22
|
+
* a forwarding rule's target by `setTarget`, labels by `setLabels` with the
|
|
23
|
+
* live `labelFingerprint`. A difference on a field compute can't change in
|
|
24
|
+
* place (anything on a serverless NEG, an address's IP) is reported as
|
|
25
|
+
* "replace required" and left alone. A network and a subnetwork still
|
|
26
|
+
* reconcile by existence only.
|
|
20
27
|
*/
|
|
21
28
|
import { GCP_RESOURCE_OWNERSHIP_KEYS } from "../../ownership.js";
|
|
22
29
|
import { OWNERSHIP_MANAGED_BY_VALUE } from "@intentius/chant/ownership";
|
|
@@ -326,7 +333,83 @@ export const computeOperation = {
|
|
|
326
333
|
return errors?.length ? errors.map((e) => e.message ?? e.code ?? "error").join("; ") : undefined;
|
|
327
334
|
},
|
|
328
335
|
};
|
|
329
|
-
|
|
336
|
+
/** A compute reference with everything before `projects/` dropped, so a full URL and a partial one compare equal. */
|
|
337
|
+
function refTail(v) {
|
|
338
|
+
const at = v.indexOf("projects/");
|
|
339
|
+
return at >= 0 ? v.slice(at) : v;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* True when the live value holds the desired one: every desired key is set
|
|
343
|
+
* live to an equal value, arrays element by element, and a compute URL
|
|
344
|
+
* equals its partial form. Fields only the live side has (defaults, server
|
|
345
|
+
* ids) don't count. Pure.
|
|
346
|
+
*/
|
|
347
|
+
export function holds(desired, live) {
|
|
348
|
+
if (typeof desired === "string" && typeof live === "string") {
|
|
349
|
+
return desired === live || (desired.includes("projects/") && refTail(desired) === refTail(live));
|
|
350
|
+
}
|
|
351
|
+
if (Array.isArray(desired)) {
|
|
352
|
+
return Array.isArray(live) && desired.length === live.length && desired.every((d, i) => holds(d, live[i]));
|
|
353
|
+
}
|
|
354
|
+
if (isObj(desired)) {
|
|
355
|
+
return isObj(live) && Object.entries(desired).every(([k, v]) => holds(v, live[k]));
|
|
356
|
+
}
|
|
357
|
+
return desired === live;
|
|
358
|
+
}
|
|
359
|
+
/** The desired body's top-level fields the live resource doesn't hold, `name` aside. Pure. */
|
|
360
|
+
export function changedFields(desired, live) {
|
|
361
|
+
return Object.keys(desired).filter((k) => k !== "name" && !holds(desired[k], live[k]));
|
|
362
|
+
}
|
|
363
|
+
const replace = (kind, fields) => ({
|
|
364
|
+
replace: `${fields.join(", ")} differ${fields.length === 1 ? "s" : ""}, and compute can't change ${fields.length === 1 ? "it" : "them"} on a ${kind} in place`,
|
|
365
|
+
});
|
|
366
|
+
/** `labels` by `setLabels` with the live `labelFingerprint`; anything else changed is a replace. */
|
|
367
|
+
function labelsOnly(kind) {
|
|
368
|
+
return async ({ url, desired, live, changed }) => {
|
|
369
|
+
const other = changed.filter((f) => f !== "labels");
|
|
370
|
+
if (other.length)
|
|
371
|
+
return replace(kind, other);
|
|
372
|
+
if (!changed.length)
|
|
373
|
+
return { requests: [] };
|
|
374
|
+
return { requests: [{ method: "POST", url: `${url}/setLabels`, body: { labels: desired.labels, labelFingerprint: live.labelFingerprint } }] };
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
/** Every changed field by one PATCH carrying the live `fingerprint` (backend services, URL maps). */
|
|
378
|
+
const patchWithFingerprint = async ({ url, desired, live, changed }) => changed.length ? { requests: [{ method: "PATCH", url, body: { ...desired, fingerprint: live.fingerprint } }] } : { requests: [] };
|
|
379
|
+
const reconcileProxy = async ({ url, desired, changed }) => {
|
|
380
|
+
const other = changed.filter((f) => f !== "urlMap");
|
|
381
|
+
if (other.length)
|
|
382
|
+
return replace("ComputeTargetHTTPProxy", other);
|
|
383
|
+
return changed.length ? { requests: [{ method: "POST", url: `${url}/setUrlMap`, body: { urlMap: desired.urlMap } }] } : { requests: [] };
|
|
384
|
+
};
|
|
385
|
+
/**
|
|
386
|
+
* A forwarding rule's `IPAddress` is a declared address's partial URL, where
|
|
387
|
+
* the live rule holds the IP itself, so the address is read and its IP
|
|
388
|
+
* compared. The target changes by `setTarget`, labels by `setLabels`; any
|
|
389
|
+
* other field is a replace.
|
|
390
|
+
*/
|
|
391
|
+
const reconcileForwardingRule = async ({ url, desired, live, changed, ctx, http, signal }) => {
|
|
392
|
+
let fields = changed;
|
|
393
|
+
const ip = desired.IPAddress;
|
|
394
|
+
if (fields.includes("IPAddress") && typeof ip === "string" && ip.includes("/addresses/")) {
|
|
395
|
+
const res = await http("GET", `${ctx.base}/compute/v1/${refTail(ip)}`, undefined, signal);
|
|
396
|
+
const address = res.status === 200 ? JSON.parse(res.text).address : undefined;
|
|
397
|
+
if (address !== undefined && address === live.IPAddress)
|
|
398
|
+
fields = fields.filter((f) => f !== "IPAddress");
|
|
399
|
+
}
|
|
400
|
+
const other = fields.filter((f) => f !== "target" && f !== "labels");
|
|
401
|
+
if (other.length)
|
|
402
|
+
return replace("ComputeForwardingRule", other);
|
|
403
|
+
const requests = [];
|
|
404
|
+
if (fields.includes("target"))
|
|
405
|
+
requests.push({ method: "POST", url: `${url}/setTarget`, body: { target: desired.target } });
|
|
406
|
+
if (fields.includes("labels")) {
|
|
407
|
+
requests.push({ method: "POST", url: `${url}/setLabels`, body: { labels: desired.labels, labelFingerprint: live.labelFingerprint } });
|
|
408
|
+
}
|
|
409
|
+
return { requests };
|
|
410
|
+
};
|
|
411
|
+
const replaceOnAnyChange = (kind) => async ({ changed }) => (changed.length ? replace(kind, changed) : { requests: [] });
|
|
412
|
+
function computeMapper(kind, collection, build, regionalCollection = collection, scopeFor = (spec) => scopeOf(spec), reconcile) {
|
|
330
413
|
return {
|
|
331
414
|
kind,
|
|
332
415
|
defaultHost: COMPUTE_HOST,
|
|
@@ -335,15 +418,28 @@ function computeMapper(kind, collection, build, regionalCollection = collection,
|
|
|
335
418
|
const scope = scopeFor(resource.spec);
|
|
336
419
|
const coll = `${ctx.base}/compute/v1/${scopePath(ctx.project, scope)}/${scope === "global" ? collection : regionalCollection}`;
|
|
337
420
|
const name = computeName(resource);
|
|
338
|
-
|
|
421
|
+
const url = `${coll}/${enc(name)}`;
|
|
422
|
+
const desired = build(resource, ctx);
|
|
423
|
+
return {
|
|
424
|
+
getUrl: url,
|
|
425
|
+
create: { method: "POST", url: coll, body: desired },
|
|
426
|
+
...(reconcile
|
|
427
|
+
? {
|
|
428
|
+
reconcile: (live, http, signal) => {
|
|
429
|
+
const l = isObj(live) ? live : {};
|
|
430
|
+
return reconcile({ url, desired, live: l, changed: changedFields(desired, l), ctx, http, signal });
|
|
431
|
+
},
|
|
432
|
+
}
|
|
433
|
+
: {}),
|
|
434
|
+
};
|
|
339
435
|
},
|
|
340
436
|
};
|
|
341
437
|
}
|
|
342
|
-
export const computeAddressMapper = computeMapper("ComputeAddress", "addresses", addressBody);
|
|
343
|
-
export const regionNetworkEndpointGroupMapper = computeMapper("ComputeRegionNetworkEndpointGroup", "networkEndpointGroups", negBody);
|
|
344
|
-
export const backendServiceMapper = computeMapper("ComputeBackendService", "backendServices", backendServiceBody);
|
|
345
|
-
export const urlMapMapper = computeMapper("ComputeURLMap", "urlMaps", urlMapBody);
|
|
346
|
-
export const targetHttpProxyMapper = computeMapper("ComputeTargetHTTPProxy", "targetHttpProxies", targetHttpProxyBody);
|
|
347
|
-
export const forwardingRuleMapper = computeMapper("ComputeForwardingRule", "forwardingRules", forwardingRuleBody);
|
|
438
|
+
export const computeAddressMapper = computeMapper("ComputeAddress", "addresses", addressBody, undefined, undefined, labelsOnly("ComputeAddress"));
|
|
439
|
+
export const regionNetworkEndpointGroupMapper = computeMapper("ComputeRegionNetworkEndpointGroup", "networkEndpointGroups", negBody, undefined, undefined, replaceOnAnyChange("ComputeRegionNetworkEndpointGroup"));
|
|
440
|
+
export const backendServiceMapper = computeMapper("ComputeBackendService", "backendServices", backendServiceBody, undefined, undefined, patchWithFingerprint);
|
|
441
|
+
export const urlMapMapper = computeMapper("ComputeURLMap", "urlMaps", urlMapBody, undefined, undefined, patchWithFingerprint);
|
|
442
|
+
export const targetHttpProxyMapper = computeMapper("ComputeTargetHTTPProxy", "targetHttpProxies", targetHttpProxyBody, undefined, undefined, reconcileProxy);
|
|
443
|
+
export const forwardingRuleMapper = computeMapper("ComputeForwardingRule", "forwardingRules", forwardingRuleBody, undefined, undefined, reconcileForwardingRule);
|
|
348
444
|
export const networkMapper = computeMapper("ComputeNetwork", "networks", networkBody, "networks", () => "global");
|
|
349
445
|
export const subnetworkMapper = computeMapper("ComputeSubnetwork", "subnetworks", subnetworkBody);
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAqC,MAAM,0BAA0B,CAAC;AAuBjG,eAAO,MAAM,SAAS,EAAE,
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAqC,MAAM,0BAA0B,CAAC;AAuBjG,eAAO,MAAM,SAAS,EAAE,aAyYvB,CAAC"}
|
package/dist/plugin.js
CHANGED
|
@@ -368,8 +368,12 @@ export const bucket = new StorageBucket({
|
|
|
368
368
|
return observeResourcesDeepGcp(options);
|
|
369
369
|
},
|
|
370
370
|
deepNormalizationHooks: gcpDeepNormalizationHooks,
|
|
371
|
-
/**
|
|
372
|
-
|
|
371
|
+
/**
|
|
372
|
+
* Runtime health (#4177, #4239): Cloud Run services, backend services and IAM
|
|
373
|
+
* policy members. Implementation in ./health.ts, whose GCP_HEALTH_TYPES this
|
|
374
|
+
* list matches; written out so the build never imports the reader.
|
|
375
|
+
*/
|
|
376
|
+
healthTypes: ["GCP::Run::Service", "GCP::Compute::BackendService", "GCP::Iam::PolicyMember"],
|
|
373
377
|
async observeHealth(options) {
|
|
374
378
|
const { observeHealthGcp } = await import("./health.js");
|
|
375
379
|
return observeHealthGcp(options);
|
package/dist/skills/chant-gcp.md
CHANGED
|
@@ -202,6 +202,8 @@ Composites group related Config Connector resources with secure defaults. Each r
|
|
|
202
202
|
| `ManagedCertificate` | ComputeManagedSslCertificate | Auto-renewal via Google-managed cert |
|
|
203
203
|
| `SecureProject` | Project + IAMAuditConfig + essential Service resources | Audit logging, required APIs enabled, org policy constraints |
|
|
204
204
|
| `GpuNodePool` | ContainerNodePool with GPU accelerators | Scale-to-zero, nvidia.com/gpu taint, GKE metadata workload identity |
|
|
205
|
+
| `PrivateEgressNetwork` | ComputeNetwork + ComputeSubnetwork | Custom mode, regional routing, Private Google Access |
|
|
206
|
+
| `PublicCloudRun` | IAMServiceAccount + RunService + serverless NEG + global external Application Load Balancer | Own service account, Direct VPC egress for private ranges, optional managed certificate with HTTP to HTTPS redirect, optional Cloud Armor policy |
|
|
205
207
|
|
|
206
208
|
### Example: GKE cluster with secure defaults
|
|
207
209
|
|