@intentius/chant 0.41.12 → 0.41.13
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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/components.ts"],"names":[],"mappings":"AA+CA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,OAAO,KAAK,EAAE,KAAK,EAAa,MAAM,4BAA4B,CAAC;AAGnE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,0BAA0B,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA4ErF;AA4DD;;;;;;;;;;;;;;;GAeG;AACH;;;;;;;;6EAQ6E;AAC7E,wBAAgB,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,EAAE,CAMzD;
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../../../src/cli/handlers/components.ts"],"names":[],"mappings":"AA+CA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,OAAO,KAAK,EAAE,KAAK,EAAa,MAAM,4BAA4B,CAAC;AAGnE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,0BAA0B,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA4ErF;AA4DD;;;;;;;;;;;;;;;GAeG;AACH;;;;;;;;6EAQ6E;AAC7E,wBAAgB,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,EAAE,CAMzD;AAmED,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CA6R9E;AAED,kEAAkE;AAClE,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAM/E"}
|
|
@@ -100,6 +100,17 @@ export interface ComponentStatusRow {
|
|
|
100
100
|
* where it exists.
|
|
101
101
|
*/
|
|
102
102
|
resources?: ComponentResourceRollup;
|
|
103
|
+
/**
|
|
104
|
+
* Set when some but not all of this component's deploy units were observed
|
|
105
|
+
* present (#1528). `live` is `false` — deployed means all of it — but a
|
|
106
|
+
* consumer painting the row can distinguish "half up" from "gone", and the
|
|
107
|
+
* missing unit names are the actionable part.
|
|
108
|
+
*/
|
|
109
|
+
partial?: {
|
|
110
|
+
present: number;
|
|
111
|
+
total: number;
|
|
112
|
+
missing: string[];
|
|
113
|
+
};
|
|
103
114
|
}
|
|
104
115
|
/** A component's owning deploy unit and its provider-native status. */
|
|
105
116
|
export interface LiveStackInfo {
|
|
@@ -143,6 +154,19 @@ export interface LiveComponentEvidence {
|
|
|
143
154
|
/** The owning deploy unit's raw status, when observed (AWS: the component's own
|
|
144
155
|
* CFN stack). Surfaced onto `ComponentStatusRow.stack` for a richer palette. */
|
|
145
156
|
stack?: LiveStackInfo;
|
|
157
|
+
/**
|
|
158
|
+
* Set when some but not all of the component's deploy units were observed
|
|
159
|
+
* present (#1528). `live` is `false` — a component is deployed when all of
|
|
160
|
+
* it is — but "nothing observed live" would be a lie, and it was one: a
|
|
161
|
+
* multi-unit component with a single absent unit reported exactly that
|
|
162
|
+
* while its Helm releases sat deployed and healthy in the same row's
|
|
163
|
+
* `stack` field. Consumers get the split and the names of what is missing.
|
|
164
|
+
*/
|
|
165
|
+
partial?: {
|
|
166
|
+
present: number;
|
|
167
|
+
total: number;
|
|
168
|
+
missing: string[];
|
|
169
|
+
};
|
|
146
170
|
/**
|
|
147
171
|
* How the component's own resources answered, before any merge collapsed
|
|
148
172
|
* them (behold#98). Always present when evidence exists — a component that
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/lifecycle/status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAsB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EAAwB,KAAK,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAE7E,+FAA+F;AAC/F,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,kEAAkE;IAClE,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,+IAA+I;IAC/I,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC;IACnC,gDAAgD;IAChD,cAAc,EAAE,YAAY,GAAG,YAAY,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;IAC9E,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IACf;;;;OAIG;IACH,UAAU,CAAC,EAAE;QAAE,MAAM,EAAE,gBAAgB,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D;;;;;OAKG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,EAAE,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/lifecycle/status.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -286,10 +286,17 @@ async function observeComponentStacks(
|
|
|
286
286
|
// palette than the reconciliation verdict. One cfn-deploy stack per component
|
|
287
287
|
// is the norm; a multi-stack component reports its representative unit.
|
|
288
288
|
const repr = determinate.find((o) => o.present) ?? determinate[0];
|
|
289
|
+
// Some-but-not-all present is its own answer (#1528): `live` stays false —
|
|
290
|
+
// deployed means all of it — but the split and the missing unit names ride
|
|
291
|
+
// along, so the row can say "half up" instead of "nothing observed live"
|
|
292
|
+
// while its own `stack` field shows a healthy unit.
|
|
293
|
+
const presentCount = determinate.filter((o) => o.present).length;
|
|
294
|
+
const missing = determinate.filter((o) => !o.present).map((o) => o.stack);
|
|
289
295
|
evidence.set(name, {
|
|
290
296
|
live: present,
|
|
291
297
|
ownership: present ? "owned" : undefined,
|
|
292
298
|
stack: { name: repr.stack, status: repr.status, healthy: repr.healthy },
|
|
299
|
+
...(presentCount > 0 && !present ? { partial: { present: presentCount, total: determinate.length, missing } } : {}),
|
|
293
300
|
});
|
|
294
301
|
}
|
|
295
302
|
return evidence;
|
|
@@ -549,3 +549,47 @@ describe("status", () => {
|
|
|
549
549
|
});
|
|
550
550
|
});
|
|
551
551
|
});
|
|
552
|
+
|
|
553
|
+
describe("partial unit presence is said, not rounded down to nothing (#1528)", () => {
|
|
554
|
+
// The lie this fixes, verbatim from a real estate: a three-unit component
|
|
555
|
+
// (CRDs by kubectl-apply, two Helm releases) whose one absent unit produced
|
|
556
|
+
// `detail: "no release record and nothing observed live"` in the same row
|
|
557
|
+
// whose `stack` field showed a deployed, healthy release.
|
|
558
|
+
const partial = { present: 2, total: 3, missing: ["kmv-crds"] };
|
|
559
|
+
|
|
560
|
+
test("unrecorded + partial names the split and the missing units", () => {
|
|
561
|
+
const liveEvidence = new Map<string, LiveComponentEvidence>([
|
|
562
|
+
["operator", { live: false, partial, stack: { name: "cert-manager", status: "deployed", healthy: true } }],
|
|
563
|
+
]);
|
|
564
|
+
const rows = reconcileStatus("prod", [], { liveEvidence, allComponents: ["operator"] });
|
|
565
|
+
expect(rows[0].reconciliation).toBe("unrecorded");
|
|
566
|
+
expect(rows[0].detail).toContain("2 of 3 deploy units observed live");
|
|
567
|
+
expect(rows[0].detail).toContain("missing: kmv-crds");
|
|
568
|
+
expect(rows[0].detail).not.toContain("nothing observed live");
|
|
569
|
+
expect(rows[0].partial).toEqual(partial);
|
|
570
|
+
});
|
|
571
|
+
|
|
572
|
+
test("recorded + partial is stale, with the split instead of 'nothing'", () => {
|
|
573
|
+
const liveEvidence = new Map<string, LiveComponentEvidence>([
|
|
574
|
+
["search-service", { live: false, partial }],
|
|
575
|
+
]);
|
|
576
|
+
const rows = reconcileStatus("prod", [record()], { liveEvidence });
|
|
577
|
+
expect(rows[0].reconciliation).toBe("stale");
|
|
578
|
+
expect(rows[0].detail).toContain("only 2 of 3 deploy units observed live now");
|
|
579
|
+
expect(rows[0].detail).toContain("missing: kmv-crds");
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
test("wholly absent still reads as nothing observed live, no split invented", () => {
|
|
583
|
+
const liveEvidence = new Map<string, LiveComponentEvidence>([["gone", { live: false }]]);
|
|
584
|
+
const rows = reconcileStatus("prod", [], { liveEvidence, allComponents: ["gone"] });
|
|
585
|
+
expect(rows[0].detail).toContain("no release record and nothing observed live");
|
|
586
|
+
expect(rows[0].partial).toBeUndefined();
|
|
587
|
+
});
|
|
588
|
+
|
|
589
|
+
test("the split survives mergeLiveEvidence's field-by-field rebuild", () => {
|
|
590
|
+
const base = new Map<string, LiveComponentEvidence>([["operator", { live: false }]]);
|
|
591
|
+
const supplement = new Map<string, LiveComponentEvidence>([["operator", { live: false, partial }]]);
|
|
592
|
+
const merged = mergeLiveEvidence(base, supplement);
|
|
593
|
+
expect(merged.get("operator")!.partial).toEqual(partial);
|
|
594
|
+
});
|
|
595
|
+
});
|
package/src/lifecycle/status.ts
CHANGED
|
@@ -99,6 +99,13 @@ export interface ComponentStatusRow {
|
|
|
99
99
|
* where it exists.
|
|
100
100
|
*/
|
|
101
101
|
resources?: ComponentResourceRollup;
|
|
102
|
+
/**
|
|
103
|
+
* Set when some but not all of this component's deploy units were observed
|
|
104
|
+
* present (#1528). `live` is `false` — deployed means all of it — but a
|
|
105
|
+
* consumer painting the row can distinguish "half up" from "gone", and the
|
|
106
|
+
* missing unit names are the actionable part.
|
|
107
|
+
*/
|
|
108
|
+
partial?: { present: number; total: number; missing: string[] };
|
|
102
109
|
}
|
|
103
110
|
|
|
104
111
|
/** A component's owning deploy unit and its provider-native status. */
|
|
@@ -142,6 +149,15 @@ export interface LiveComponentEvidence {
|
|
|
142
149
|
/** The owning deploy unit's raw status, when observed (AWS: the component's own
|
|
143
150
|
* CFN stack). Surfaced onto `ComponentStatusRow.stack` for a richer palette. */
|
|
144
151
|
stack?: LiveStackInfo;
|
|
152
|
+
/**
|
|
153
|
+
* Set when some but not all of the component's deploy units were observed
|
|
154
|
+
* present (#1528). `live` is `false` — a component is deployed when all of
|
|
155
|
+
* it is — but "nothing observed live" would be a lie, and it was one: a
|
|
156
|
+
* multi-unit component with a single absent unit reported exactly that
|
|
157
|
+
* while its Helm releases sat deployed and healthy in the same row's
|
|
158
|
+
* `stack` field. Consumers get the split and the names of what is missing.
|
|
159
|
+
*/
|
|
160
|
+
partial?: { present: number; total: number; missing: string[] };
|
|
145
161
|
/**
|
|
146
162
|
* How the component's own resources answered, before any merge collapsed
|
|
147
163
|
* them (behold#98). Always present when evidence exists — a component that
|
|
@@ -189,6 +205,9 @@ export function mergeLiveEvidence(
|
|
|
189
205
|
ownership: sup.ownership ?? b?.ownership,
|
|
190
206
|
action: b?.action,
|
|
191
207
|
stack: sup.stack ?? b?.stack,
|
|
208
|
+
// The unit split rides the same direct observation `live` came from —
|
|
209
|
+
// dropping it here would resurrect the lie the field exists to fix.
|
|
210
|
+
...(sup.partial ? { partial: sup.partial } : {}),
|
|
192
211
|
// Base first: the counts come from the change set, and a stack
|
|
193
212
|
// observation has none to offer.
|
|
194
213
|
...(b?.rollup ?? sup.rollup ? { rollup: b?.rollup ?? sup.rollup } : {}),
|
|
@@ -408,10 +427,16 @@ export function reconcileStatus(
|
|
|
408
427
|
detail = `live${evidence.ownership === "owned" ? " and chant-owned" : ""}, but no release record exists — deployed outside the recorded path`;
|
|
409
428
|
} else if (!recorded && !evidence?.live) {
|
|
410
429
|
reconciliation = "unrecorded";
|
|
411
|
-
|
|
430
|
+
// "Nothing observed live" was a lie for a partially-present component
|
|
431
|
+
// (#1528) — say what was seen and name what was not.
|
|
432
|
+
detail = evidence?.partial
|
|
433
|
+
? `no release record; ${evidence.partial.present} of ${evidence.partial.total} deploy units observed live (missing: ${evidence.partial.missing.join(", ")})`
|
|
434
|
+
: "no release record and nothing observed live";
|
|
412
435
|
} else if (recorded && !evidence?.live) {
|
|
413
436
|
reconciliation = "stale";
|
|
414
|
-
detail =
|
|
437
|
+
detail = evidence?.partial
|
|
438
|
+
? `recorded ${recorded.timestamp} (digest ${recorded.digest}), but only ${evidence.partial.present} of ${evidence.partial.total} deploy units observed live now (missing: ${evidence.partial.missing.join(", ")})`
|
|
439
|
+
: `recorded ${recorded.timestamp} (digest ${recorded.digest}), but nothing observed live now`;
|
|
415
440
|
} else if (recorded && evidence?.action === "update") {
|
|
416
441
|
reconciliation = "drifted";
|
|
417
442
|
detail = `recorded ${recorded.timestamp} (digest ${recorded.digest}), but live configuration has drifted since`;
|
|
@@ -435,6 +460,7 @@ export function reconcileStatus(
|
|
|
435
460
|
...(evidence?.unobserved ? { unobserved: evidence.unobserved } : {}),
|
|
436
461
|
...(evidence?.stack ? { stack: evidence.stack } : {}),
|
|
437
462
|
...(evidence?.rollup ? { resources: evidence.rollup } : {}),
|
|
463
|
+
...(evidence?.partial ? { partial: evidence.partial } : {}),
|
|
438
464
|
});
|
|
439
465
|
}
|
|
440
466
|
|