@mark1russell7/kind 0.8.2 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/build/index.d.ts +43 -5
- package/build/index.js +124 -7
- package/build/index.js.map +1 -1
- package/build/{judge-gpC49mVw.d.ts → judge-BD4UVQfy.d.ts} +4 -2
- package/build/{judge-B6W_gFv0.js → judge-BbLWVTYj.js} +3 -2
- package/build/{judge-B6W_gFv0.js.map → judge-BbLWVTYj.js.map} +1 -1
- package/build/judge.d.ts +1 -1
- package/build/judge.js +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -184,6 +184,7 @@ The lab image (`image/`) holds the service of a cell on `@mark1russell7/service`
|
|
|
184
184
|
| `authorization-policy` | `kubectl apply` of a DENY AuthorizationPolicy on the server pods for the principal of an account (`account`, the account `default` of the clients when not given), then `kubectl delete` after the hold |
|
|
185
185
|
| `idle` | SIGUSR1 to the gRPC client of each client pod, and SIGUSR2 after the hold: a gap of the calls (the target `clients`). The restore sends SIGUSR2 again. With `middlebox`, a stateful middlebox in each replica from before the gap to the restore. With `close`, a new channel at the fault for 5 s: SIGHUP before the fault, then SIGUSR2, a wait and SIGHUP |
|
|
186
186
|
| `ztunnel-restart` | `kubectl delete pod` of the ztunnel pod of each node, with its grace (`ZTUNNEL_PODS`). The flow of each client crosses the ztunnel of its own node. The restore waits for the rollout of the DaemonSet |
|
|
187
|
+
| `certificate-expiry` | No act on a connection: the calls of each client go on for the hold. At the fault and at the heal, istioctl reads the leaf certificates of the ztunnel pod of each node (`ztunnelCertificates`). A line `certificates` keeps their validity, the evidence of their lifetime |
|
|
187
188
|
|
|
188
189
|
A cgroup path that is not the scope of one container is refused. A write to the root of the node throttles or freezes each pod of the node.
|
|
189
190
|
|
|
@@ -201,6 +202,7 @@ The plan's `event:clock-jump` has no trigger. A step of CLOCK_REALTIME in the VM
|
|
|
201
202
|
`predict.ts` gives each band from the declaration, the pod settings and the calibration of the propagation:
|
|
202
203
|
|
|
203
204
|
- **A deletion.** The listener of a leaving pod stays open for its preStop sleep and the hold of `fail readiness`. A connection fails when the rules of its node select the pod after that. `rules.ts` gives O04 with the hold as data, and `lint()` decides it.
|
|
205
|
+
- **The way that a plan stops a pod.** `stopOf(cell)` reads it from the trigger: a deletion, a liveness restart, a crash, or null when the plan stops no pod. `lintCell()` gives each cell only the drain rules that guard its way (`lintStop()` of the service). A plan that stops no pod gets each drain rule. A crash gets no drain rule, and its finding of `stop` depends.
|
|
204
206
|
- **A pause of kube-proxy** keeps the rules of one node for its hold. The window on that node ends one propagation after the pause. A SYN_SENT entry of an earlier run lives up to 122 s, thus the window also opens up to 122 s before the intake. `predictionText` writes each end of a window with its band, for example `the intake + [-122, 4.605] s`.
|
|
205
207
|
- **A reset from a leaving pod** leaves the conntrack entry of its flow in CLOSE for 10 s, with the NAT to that pod. From 0.1.6, a window can give that life (`afterReset`). Then a request outside the window can fail with the outcome of the rule (`reusesReset`). The condition is a reset of the same client on the same port, up to that life before the request. The catalog gives it to a deletion without a hold, in the modes with the NAT in conntrack.
|
|
206
208
|
- **A fault of a shared dependency** trips the readiness latch of each replica (`failSpan`). Then the kubelet needs its threshold of probes, and the rules need one propagation.
|
|
@@ -252,6 +254,8 @@ From 0.8.0, a prediction `ends` can be the end of the tunnel of each client (`of
|
|
|
252
254
|
- The first request of each client after the heal must be `ok`, on a new tunnel. The main value is the middle of the ends, in `s`.
|
|
253
255
|
- From 0.8.1, `ends` has the optional band `answer`. A change to CLOSE_WAIT in that band ± δ also agrees: the peer answers the close of the client, and its FIN comes first. Before the band, the peer closed first.
|
|
254
256
|
|
|
257
|
+
A new member of the union `TriggerKind`, `certificate-expiry`, and a new member of the union `Step`, `certificates`, break a reader that switches on them. `KindLab` also has a new method, `record`. Each is a breaking change before 1.0.0, thus the version is 0.9.0. The record format stays `/2`: the lines `certificates` are new lines of a run.
|
|
258
|
+
|
|
255
259
|
In 0.8.1, the middlebox uses the match recent, not the sysctls of conntrack, and `ends` has the optional field `answer`. `SYSCTL` and `NETNS_DEFAULTS` keep only `tcp_retries2`. These fields came in 0.8.0, which was not published. The fix and the optional field are a patch, thus the version is 0.8.1.
|
|
256
260
|
|
|
257
261
|
New members of the union `Step` (`sysctl` and `middlebox`) and of the signals of a step (`SIGHUP`) break a reader that switches on them. `KindLab` also has a new method, `netns`. Each is a breaking change before 1.0.0, thus the version is 0.8.0. The record format stays `/2`. A trigger has the optional fields `middlebox`, `retries`, `quiet` and `close`, and `ends` has the optional field `of`. The lines `kernel.state` are new lines of a run.
|
package/build/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { $ as updatesOf, $t as Declaration, A as TriggerV1, An as scenario, At as rulesOf, B as RunCheck, Bt as ztunnelPodsOf, C as KindCellResult, Cn as NodeImage, Ct as outcomesOf, D as PredictionV1, Dn as kindConfig, Dt as requestsOf, E as LoadSample, En as goDuration, Et as recordsOf, F as KIND_NOISE, Ft as slicesOf, G as judgeKind, Gt as PORT, H as checkRun, Ht as CLIENT, I as KindDecision, It as socketsOf, J as propagationOf, Jt as bandOf, K as observationAfter, Kt as REDIS, L as KindVerdict, Lt as stoppingOf, M as upgrade, Mt as signalsOf, N as upgradeCell, Nt as sliceDropOf, O as RunCheckV1, On as kubeProxyPatch, Ot as restartOf, P as Deleted, Pt as sliceEmptyOf, Q as unitOf, Qt as Band, R as LAST_SLACK, Rt as transitionOf, S as KindCellRecordV1, Sn as NODE_IMAGES, St as kernelCounts, T as KindVerdictV1, Tn as cidrRange, Tt as podsOf, U as deletionsOf, Ut as HEALTH_PORT, V as RunFacts, Vt as ztunnelReplaced, W as factsOf, Wt as LOG_LABEL, X as referenceOf, Xt as secondsOf, Y as propagationSource, Yt as seconds, Z as reusesReset, Zt as showBand, _ as ClusterManifest, _n as Workload, _t as dropOf, a as STAGES, an as MeshMode, at as RecordLine, b as FORMAT_V1, bn as KindScenario, bt as intakeOf, c as readRecord, cn as RedisDeclaration, ct as SliceLine, d as calibrationOf, dn as ResetReuse, dt as TunnelLine, en as KindCell, et as Endpoint, f as cellsTable, fn as Stack, ft as ZtunnelPodLine, g as BandV1, gn as WindowPrediction, gt as deletionOf, h as timeSpread, hn as TriggerKind, ht as byNode, i as quantileOf, in as MeshFlavor, it as PropagationSource, j as judge, jn as scenarioProblems, jt as signalOf, k as RunFactsV1, kn as nodeNames, kt as restartsAt, l as Judged, ln as Reference, lt as SocketLine, m as predictionText, mn as Trigger, mt as byClients, n as medianInterval, nn as KubeletProbe, nt as Line, o as kindCellRecordSchema, on as PodSettings, ot as Request, p as medianText, pn as Template, pt as backendsAt, q as observationEnd, qt as SERVER, r as middle, rn as Mesh, rt as PodLine, s as kindCellRecordV1Schema, sn as Prediction, st as RulesLine, t as RELATIVE, tn as KindRun, tt as HBONE_PORT, u as TimeSpread, un as Replica, ut as TCP_STATE, v as EnvironmentManifest, vn as KUBE_PROXY_MODES, vt as emptyOf, w as KindCellV1, wn as cidrOverlap, wt as podsAt, x as KindCellRecord, xn as KubeProxyMode, xt as isTunnelState, y as FORMAT, yn as KindConfig, yt as failuresOf, z as Propagated, zt as tunnelsOf } from "./judge-
|
|
1
|
+
import { $ as updatesOf, $t as Declaration, A as TriggerV1, An as scenario, At as rulesOf, B as RunCheck, Bt as ztunnelPodsOf, C as KindCellResult, Cn as NodeImage, Ct as outcomesOf, D as PredictionV1, Dn as kindConfig, Dt as requestsOf, E as LoadSample, En as goDuration, Et as recordsOf, F as KIND_NOISE, Ft as slicesOf, G as judgeKind, Gt as PORT, H as checkRun, Ht as CLIENT, I as KindDecision, It as socketsOf, J as propagationOf, Jt as bandOf, K as observationAfter, Kt as REDIS, L as KindVerdict, Lt as stoppingOf, M as upgrade, Mt as signalsOf, N as upgradeCell, Nt as sliceDropOf, O as RunCheckV1, On as kubeProxyPatch, Ot as restartOf, P as Deleted, Pt as sliceEmptyOf, Q as unitOf, Qt as Band, R as LAST_SLACK, Rt as transitionOf, S as KindCellRecordV1, Sn as NODE_IMAGES, St as kernelCounts, T as KindVerdictV1, Tn as cidrRange, Tt as podsOf, U as deletionsOf, Ut as HEALTH_PORT, V as RunFacts, Vt as ztunnelReplaced, W as factsOf, Wt as LOG_LABEL, X as referenceOf, Xt as secondsOf, Y as propagationSource, Yt as seconds, Z as reusesReset, Zt as showBand, _ as ClusterManifest, _n as Workload, _t as dropOf, a as STAGES, an as MeshMode, at as RecordLine, b as FORMAT_V1, bn as KindScenario, bt as intakeOf, c as readRecord, cn as RedisDeclaration, ct as SliceLine, d as calibrationOf, dn as ResetReuse, dt as TunnelLine, en as KindCell, et as Endpoint, f as cellsTable, fn as Stack, ft as ZtunnelPodLine, g as BandV1, gn as WindowPrediction, gt as deletionOf, h as timeSpread, hn as TriggerKind, ht as byNode, i as quantileOf, in as MeshFlavor, it as PropagationSource, j as judge, jn as scenarioProblems, jt as signalOf, k as RunFactsV1, kn as nodeNames, kt as restartsAt, l as Judged, ln as Reference, lt as SocketLine, m as predictionText, mn as Trigger, mt as byClients, n as medianInterval, nn as KubeletProbe, nt as Line, o as kindCellRecordSchema, on as PodSettings, ot as Request, p as medianText, pn as Template, pt as backendsAt, q as observationEnd, qt as SERVER, r as middle, rn as Mesh, rt as PodLine, s as kindCellRecordV1Schema, sn as Prediction, st as RulesLine, t as RELATIVE, tn as KindRun, tt as HBONE_PORT, u as TimeSpread, un as Replica, ut as TCP_STATE, v as EnvironmentManifest, vn as KUBE_PROXY_MODES, vt as emptyOf, w as KindCellV1, wn as cidrOverlap, wt as podsAt, x as KindCellRecord, xn as KubeProxyMode, xt as isTunnelState, y as FORMAT, yn as KindConfig, yt as failuresOf, z as Propagated, zt as tunnelsOf } from "./judge-BD4UVQfy.js";
|
|
2
2
|
import { Quantity } from "@mark1russell7/quantity";
|
|
3
|
-
import { CheckFn, Finding, HealthServer, Poll, Rule, Scenario, ServiceBuilder, ServiceDescription, Stage, Timing, TransportImpl, Verdict } from "@mark1russell7/service";
|
|
3
|
+
import { CheckFn, Finding, HealthServer, Poll, Rule, Scenario, ServiceBuilder, ServiceDescription, Stage, StopWay, Timing, TransportImpl, Verdict } from "@mark1russell7/service";
|
|
4
4
|
import { RedisClient } from "@mark1russell7/service/redis";
|
|
5
5
|
//#region src/backends.d.ts
|
|
6
6
|
/** A service rule names the Service whose backends the agent reads: its namespace, its name, and its ClusterIP and port for IPVS. */
|
|
@@ -164,6 +164,8 @@ type Step = {
|
|
|
164
164
|
readonly target: Target;
|
|
165
165
|
readonly idle: Quantity | null;
|
|
166
166
|
readonly port: number;
|
|
167
|
+
} | {
|
|
168
|
+
readonly do: "certificates";
|
|
167
169
|
};
|
|
168
170
|
/**
|
|
169
171
|
* A fault plan is the steps of a run:
|
|
@@ -362,6 +364,28 @@ export declare const ztunnelEnvArgs: (env: Readonly<Record<string, string>>, und
|
|
|
362
364
|
export declare const setZtunnelEnv: (cluster: Cluster, env: Readonly<Record<string, string>>, undo: boolean) => Promise<void>;
|
|
363
365
|
/** This function tells if the lab polls the LDS updates of the server sidecars of a cell: a policy in a sidecar mesh. */
|
|
364
366
|
export declare const pollsListeners: (cell: Pick<KindCell, "mesh" | "trigger">) => boolean;
|
|
367
|
+
/** This is the validity of one leaf certificate of ztunnel, as istioctl gives it: RFC 3339 times. */
|
|
368
|
+
interface LeafCertificate {
|
|
369
|
+
readonly pod: string;
|
|
370
|
+
readonly identity: string;
|
|
371
|
+
readonly state: string;
|
|
372
|
+
readonly from: string | null;
|
|
373
|
+
readonly to: string | null;
|
|
374
|
+
}
|
|
375
|
+
/** This function gives the arguments of istioctl that read the certificates of one ztunnel pod as JSON. */
|
|
376
|
+
export declare const certificateArgs: (pod: string, kubeconfig: string) => string[];
|
|
377
|
+
/**
|
|
378
|
+
* This function gives the leaf of each identity in the JSON of `istioctl ztunnel-config certificate`.
|
|
379
|
+
* The leaf is the first certificate of the chain (certificates.go of istioctl 1.31.3, lines 68–71).
|
|
380
|
+
* An identity with no chain yet has no times.
|
|
381
|
+
*/
|
|
382
|
+
export declare const leafCertificates: (pod: string, json: string) => LeafCertificate[];
|
|
383
|
+
/**
|
|
384
|
+
* This function reads the leaf certificates of each ztunnel pod that is not going, with istioctl.
|
|
385
|
+
* The CLI reads the admin port of ztunnel through a port-forward. Each ztunnel binds that port to
|
|
386
|
+
* localhost only (config.rs of ztunnel 1.31.3, lines 831–835).
|
|
387
|
+
*/
|
|
388
|
+
export declare const ztunnelCertificates: (cluster: Cluster) => Promise<LeafCertificate[]>;
|
|
365
389
|
//#endregion
|
|
366
390
|
//#region src/lab.d.ts
|
|
367
391
|
/** A stamp brackets an act on CLOCK_MONOTONIC, in milliseconds. */
|
|
@@ -410,6 +434,8 @@ interface KindLab {
|
|
|
410
434
|
take(): Line[];
|
|
411
435
|
/** This method adds a listener of each line, and gives the function that removes it. */
|
|
412
436
|
listen(listener: (line: Line) => void): () => void;
|
|
437
|
+
/** This method adds a line of the runner to the lines: for example, evidence that the runner reads with a tool. */
|
|
438
|
+
record(line: Line): void;
|
|
413
439
|
/**
|
|
414
440
|
* This method starts the watcher of the API on the namespaces. With `ztunnel`, it also follows the
|
|
415
441
|
* log of each ztunnel in istio-system: lines `ztunnel-pod` and `ztunnel`, which no tracker of the
|
|
@@ -623,7 +649,7 @@ export declare const O09: Rule;
|
|
|
623
649
|
export declare const O10: Rule;
|
|
624
650
|
/** O16: the cooperative window is shorter than the drain, which is shorter than the grace less the preStop sleep. */
|
|
625
651
|
export declare const O16: Rule;
|
|
626
|
-
/** These are the rules of the drain
|
|
652
|
+
/** These are the rules of the drain. A kind cell gets the rules that guard the way that its plan stops a pod. */
|
|
627
653
|
export declare const DRAIN_RULES: readonly Rule[];
|
|
628
654
|
/**
|
|
629
655
|
* This function gives the scenario of a cell for `lint()`: the preStop sleep, the grace, the probe
|
|
@@ -632,7 +658,19 @@ export declare const DRAIN_RULES: readonly Rule[];
|
|
|
632
658
|
export declare const scenarioOf: (cell: KindCell, propagation: Propagation) => Scenario;
|
|
633
659
|
/** A verdict set is the verdict of each drain rule for one declaration, by the identifier of the rule. */
|
|
634
660
|
type Verdicts = Readonly<Record<string, Verdict>>;
|
|
635
|
-
/**
|
|
661
|
+
/**
|
|
662
|
+
* This function gives the way that the fault plan of a cell stops a pod, or null when the plan stops no pod.
|
|
663
|
+
* - A deletion, a rolling update, a node drain, a scale-in and a rollout delete a pod with its grace.
|
|
664
|
+
* - In T07 a pause of kube-proxy comes before a deletion. In T18 the pause is on Redis.
|
|
665
|
+
* - The crash of the lab is SIGKILL from the node. Like a crash, it has no preStop hook and no drain.
|
|
666
|
+
* - The other faults are on a link, on Redis or on the process. The kubelet can restart a pod after them.
|
|
667
|
+
*/
|
|
668
|
+
export declare const stopOf: (cell: KindCell) => StopWay | null;
|
|
669
|
+
/**
|
|
670
|
+
* This function applies the drain rules to the description of a cell, and gives each finding. A cell
|
|
671
|
+
* whose plan stops a pod gets the rules of that way (`lintStop()`). A plan that stops no pod gets each
|
|
672
|
+
* drain rule, because a restart by the kubelet or a later deletion can follow its fault.
|
|
673
|
+
*/
|
|
636
674
|
export declare const lintCell: (description: ServiceDescription, cell: KindCell, propagation: Propagation) => Finding[];
|
|
637
675
|
/** This function gives the verdict of each drain rule, by its identifier. */
|
|
638
676
|
export declare const verdictsOf: (findings: readonly Finding[]) => Verdicts;
|
|
@@ -732,5 +770,5 @@ export declare const toolPath: (tool: Tool, key?: string, cache?: string) => str
|
|
|
732
770
|
*/
|
|
733
771
|
export declare const ensureTool: (tool: Tool, key?: string, cache?: string) => Promise<string>;
|
|
734
772
|
//#endregion
|
|
735
|
-
export { type Band, type BandV1, CLIENT, type Cluster, type ClusterHosts, type ClusterManifest, type Credentials, type Declaration, type Deleted, type DeletionWindow, type EdsSpec, Endpoint, type EnvironmentManifest, FORMAT, FORMAT_V1, type FaultPlan, HBONE_PORT, HEALTH_PORT, type Judged, KIND_NOISE, KUBE_PROXY_MODES, type KindCell, type KindCellRecord, type KindCellRecordV1, type KindCellResult, type KindCellV1, type KindConfig, type KindDecision, type KindLab, type KindRun, type KindScenario, type KindVerdict, type KindVerdictV1, type KubeProxyMode, type KubeletProbe, LAST_SLACK, LOG_LABEL, type LdsSpec, Line, type ListenerCounts, type LoadSample, type Mesh, type MeshFlavor, type MeshImages, type MeshMode, NODE_IMAGES, type NodeImage, PORT, type Parts, PodLine, type PodSettings, type Prediction, type PredictionV1, type Propagated, type Propagation, PropagationSource, REDIS, RELATIVE, RecordLine, type RedisDeclaration, type Reference, type Replica, Request, type ResetReuse, RulesLine, type RunCheck, type RunCheckV1, type RunFacts, type RunFactsV1, type RunOptions, SERVER, STAGES, type ServiceRule, SliceLine, SocketLine, type Stack, type Stamp, type Step, TCP_STATE, type Target, type Template, type TimeSpread, type Tool, type Trigger, type TriggerKind, type TriggerV1, TunnelLine, type Verdicts, type WindowPrediction, type Workload, ZtunnelPodLine, backendsAt, bandOf, byClients, byNode, calibrationOf, cellsTable, checkRun, cidrOverlap, cidrRange, deletionOf, deletionsOf, dropOf, emptyOf, factsOf, failuresOf, goDuration, intakeOf, isTunnelState, judge, judgeKind, kernelCounts, kindCellRecordSchema, kindCellRecordV1Schema, kindConfig, kubeProxyPatch, medianInterval, medianText, middle, nodeNames, observationAfter, observationEnd, outcomesOf, podsAt, podsOf, predictionText, propagationOf, propagationSource, quantileOf, readRecord, recordsOf, referenceOf, requestsOf, restartOf, restartsAt, reusesReset, rulesOf, scenario, scenarioProblems, seconds, secondsOf, showBand, signalOf, signalsOf, sliceDropOf, sliceEmptyOf, slicesOf, socketsOf, stoppingOf, timeSpread, transitionOf, tunnelsOf, unitOf, updatesOf, upgrade, upgradeCell, ztunnelPodsOf, ztunnelReplaced };
|
|
773
|
+
export { type Band, type BandV1, CLIENT, type Cluster, type ClusterHosts, type ClusterManifest, type Credentials, type Declaration, type Deleted, type DeletionWindow, type EdsSpec, Endpoint, type EnvironmentManifest, FORMAT, FORMAT_V1, type FaultPlan, HBONE_PORT, HEALTH_PORT, type Judged, KIND_NOISE, KUBE_PROXY_MODES, type KindCell, type KindCellRecord, type KindCellRecordV1, type KindCellResult, type KindCellV1, type KindConfig, type KindDecision, type KindLab, type KindRun, type KindScenario, type KindVerdict, type KindVerdictV1, type KubeProxyMode, type KubeletProbe, LAST_SLACK, LOG_LABEL, type LdsSpec, type LeafCertificate, Line, type ListenerCounts, type LoadSample, type Mesh, type MeshFlavor, type MeshImages, type MeshMode, NODE_IMAGES, type NodeImage, PORT, type Parts, PodLine, type PodSettings, type Prediction, type PredictionV1, type Propagated, type Propagation, PropagationSource, REDIS, RELATIVE, RecordLine, type RedisDeclaration, type Reference, type Replica, Request, type ResetReuse, RulesLine, type RunCheck, type RunCheckV1, type RunFacts, type RunFactsV1, type RunOptions, SERVER, STAGES, type ServiceRule, SliceLine, SocketLine, type Stack, type Stamp, type Step, TCP_STATE, type Target, type Template, type TimeSpread, type Tool, type Trigger, type TriggerKind, type TriggerV1, TunnelLine, type Verdicts, type WindowPrediction, type Workload, ZtunnelPodLine, backendsAt, bandOf, byClients, byNode, calibrationOf, cellsTable, checkRun, cidrOverlap, cidrRange, deletionOf, deletionsOf, dropOf, emptyOf, factsOf, failuresOf, goDuration, intakeOf, isTunnelState, judge, judgeKind, kernelCounts, kindCellRecordSchema, kindCellRecordV1Schema, kindConfig, kubeProxyPatch, medianInterval, medianText, middle, nodeNames, observationAfter, observationEnd, outcomesOf, podsAt, podsOf, predictionText, propagationOf, propagationSource, quantileOf, readRecord, recordsOf, referenceOf, requestsOf, restartOf, restartsAt, reusesReset, rulesOf, scenario, scenarioProblems, seconds, secondsOf, showBand, signalOf, signalsOf, sliceDropOf, sliceEmptyOf, slicesOf, socketsOf, stoppingOf, timeSpread, transitionOf, tunnelsOf, unitOf, updatesOf, upgrade, upgradeCell, ztunnelPodsOf, ztunnelReplaced };
|
|
736
774
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as signalOf, A as medianInterval, B as emptyOf, C as propagationOf, D as unitOf, E as reusesReset, F as backendsAt, G as outcomesOf, H as intakeOf, I as byClients, J as recordsOf, K as podsAt, L as byNode, M as quantileOf, N as HBONE_PORT, O as updatesOf, P as TCP_STATE, Q as rulesOf, R as deletionOf, S as observationEnd, T as referenceOf, U as isTunnelState, V as failuresOf, W as kernelCounts, X as restartOf, Y as requestsOf, Z as restartsAt, _ as checkRun, _t as seconds, a as calibrationOf, at as stoppingOf, b as judgeKind, c as predictionText, ct as ztunnelPodsOf, d as FORMAT_V1, dt as HEALTH_PORT, et as signalsOf, f as judge, ft as LOG_LABEL, g as LAST_SLACK, gt as bandOf, h as KIND_NOISE, ht as SERVER, i as readRecord, it as socketsOf, j as middle, k as RELATIVE, l as timeSpread, lt as ztunnelReplaced, m as upgradeCell, mt as REDIS, n as kindCellRecordSchema, nt as sliceEmptyOf, o as cellsTable, ot as transitionOf, p as upgrade, pt as PORT, q as podsOf, r as kindCellRecordV1Schema, rt as slicesOf, s as medianText, st as tunnelsOf, t as STAGES, tt as sliceDropOf, u as FORMAT, ut as CLIENT, v as deletionsOf, vt as secondsOf, w as propagationSource, x as observationAfter, y as factsOf, yt as showBand, z as dropOf } from "./judge-
|
|
1
|
+
import { $ as signalOf, A as medianInterval, B as emptyOf, C as propagationOf, D as unitOf, E as reusesReset, F as backendsAt, G as outcomesOf, H as intakeOf, I as byClients, J as recordsOf, K as podsAt, L as byNode, M as quantileOf, N as HBONE_PORT, O as updatesOf, P as TCP_STATE, Q as rulesOf, R as deletionOf, S as observationEnd, T as referenceOf, U as isTunnelState, V as failuresOf, W as kernelCounts, X as restartOf, Y as requestsOf, Z as restartsAt, _ as checkRun, _t as seconds, a as calibrationOf, at as stoppingOf, b as judgeKind, c as predictionText, ct as ztunnelPodsOf, d as FORMAT_V1, dt as HEALTH_PORT, et as signalsOf, f as judge, ft as LOG_LABEL, g as LAST_SLACK, gt as bandOf, h as KIND_NOISE, ht as SERVER, i as readRecord, it as socketsOf, j as middle, k as RELATIVE, l as timeSpread, lt as ztunnelReplaced, m as upgradeCell, mt as REDIS, n as kindCellRecordSchema, nt as sliceEmptyOf, o as cellsTable, ot as transitionOf, p as upgrade, pt as PORT, q as podsOf, r as kindCellRecordV1Schema, rt as slicesOf, s as medianText, st as tunnelsOf, t as STAGES, tt as sliceDropOf, u as FORMAT, ut as CLIENT, v as deletionsOf, vt as secondsOf, w as propagationSource, x as observationAfter, y as factsOf, yt as showBand, z as dropOf } from "./judge-BbLWVTYj.js";
|
|
2
2
|
import { valueIn } from "@mark1russell7/quantity";
|
|
3
3
|
import { execFile, execFileSync } from "node:child_process";
|
|
4
4
|
import { chmodSync, copyFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
@@ -7,7 +7,7 @@ import { promisify } from "node:util";
|
|
|
7
7
|
import { createHash } from "node:crypto";
|
|
8
8
|
import { fileURLToPath } from "node:url";
|
|
9
9
|
import { gunzipSync } from "node:zlib";
|
|
10
|
-
import { failSpan, lint, service } from "@mark1russell7/service";
|
|
10
|
+
import { failSpan, lint, lintStop, service } from "@mark1russell7/service";
|
|
11
11
|
import { createRequire } from "node:module";
|
|
12
12
|
import { tmpdir } from "node:os";
|
|
13
13
|
import { harnessImage, imageOf } from "@mark1russell7/harness";
|
|
@@ -1242,6 +1242,12 @@ const planOf = (cell) => {
|
|
|
1242
1242
|
]
|
|
1243
1243
|
}]
|
|
1244
1244
|
};
|
|
1245
|
+
case "certificate-expiry": return {
|
|
1246
|
+
inject: [{ do: "certificates" }],
|
|
1247
|
+
hold: needs(trigger.hold, "a hold, the time past the lifetime of the certificates"),
|
|
1248
|
+
heal: [{ do: "certificates" }],
|
|
1249
|
+
restore: []
|
|
1250
|
+
};
|
|
1245
1251
|
}
|
|
1246
1252
|
};
|
|
1247
1253
|
/** This function tells if a trigger stops a pod of the service with its grace: a deletion, an eviction, a scale-in or a rollout. */
|
|
@@ -1621,6 +1627,57 @@ const setZtunnelEnv = async (cluster, env, undo) => {
|
|
|
1621
1627
|
};
|
|
1622
1628
|
/** This function tells if the lab polls the LDS updates of the server sidecars of a cell: a policy in a sidecar mesh. */
|
|
1623
1629
|
const pollsListeners = (cell) => cell.mesh?.mode === "sidecar" && cell.trigger.kind === "authorization-policy";
|
|
1630
|
+
/** This function gives the arguments of istioctl that read the certificates of one ztunnel pod as JSON. */
|
|
1631
|
+
const certificateArgs = (pod, kubeconfig) => [
|
|
1632
|
+
"ztunnel-config",
|
|
1633
|
+
"certificate",
|
|
1634
|
+
`${pod}.istio-system`,
|
|
1635
|
+
"--kubeconfig",
|
|
1636
|
+
kubeconfig,
|
|
1637
|
+
"-o",
|
|
1638
|
+
"json"
|
|
1639
|
+
];
|
|
1640
|
+
/**
|
|
1641
|
+
* This function gives the leaf of each identity in the JSON of `istioctl ztunnel-config certificate`.
|
|
1642
|
+
* The leaf is the first certificate of the chain (certificates.go of istioctl 1.31.3, lines 68–71).
|
|
1643
|
+
* An identity with no chain yet has no times.
|
|
1644
|
+
*/
|
|
1645
|
+
const leafCertificates = (pod, json) => {
|
|
1646
|
+
return JSON.parse(json).map((each) => {
|
|
1647
|
+
const leaf = each.certChain?.[0];
|
|
1648
|
+
return {
|
|
1649
|
+
pod,
|
|
1650
|
+
identity: each.identity ?? "",
|
|
1651
|
+
state: each.state ?? "",
|
|
1652
|
+
from: leaf?.validFrom || null,
|
|
1653
|
+
to: leaf?.expirationTime || null
|
|
1654
|
+
};
|
|
1655
|
+
});
|
|
1656
|
+
};
|
|
1657
|
+
/**
|
|
1658
|
+
* This function reads the leaf certificates of each ztunnel pod that is not going, with istioctl.
|
|
1659
|
+
* The CLI reads the admin port of ztunnel through a port-forward. Each ztunnel binds that port to
|
|
1660
|
+
* localhost only (config.rs of ztunnel 1.31.3, lines 831–835).
|
|
1661
|
+
*/
|
|
1662
|
+
const ztunnelCertificates = async (cluster) => {
|
|
1663
|
+
const istioctl = await ensureTool(ISTIOCTL);
|
|
1664
|
+
const listed = JSON.parse(await cluster.kubectl([
|
|
1665
|
+
"-n",
|
|
1666
|
+
"istio-system",
|
|
1667
|
+
"get",
|
|
1668
|
+
"pods",
|
|
1669
|
+
"-l",
|
|
1670
|
+
ZTUNNEL_PODS,
|
|
1671
|
+
"-o",
|
|
1672
|
+
"json"
|
|
1673
|
+
]));
|
|
1674
|
+
const out = [];
|
|
1675
|
+
for (const item of listed.items.filter((each) => each.metadata.deletionTimestamp === void 0)) {
|
|
1676
|
+
const json = await command(istioctl, certificateArgs(item.metadata.name, cluster.kubeconfig), { timeout: 6e4 });
|
|
1677
|
+
out.push(...leafCertificates(item.metadata.name, json));
|
|
1678
|
+
}
|
|
1679
|
+
return out;
|
|
1680
|
+
};
|
|
1624
1681
|
//#endregion
|
|
1625
1682
|
//#region src/lds.ts
|
|
1626
1683
|
/**
|
|
@@ -1808,6 +1865,9 @@ const openKindLab = async (cluster, image) => {
|
|
|
1808
1865
|
lines = [];
|
|
1809
1866
|
return out;
|
|
1810
1867
|
},
|
|
1868
|
+
record(line) {
|
|
1869
|
+
push(line);
|
|
1870
|
+
},
|
|
1811
1871
|
listen(listener) {
|
|
1812
1872
|
listeners.add(listener);
|
|
1813
1873
|
return () => listeners.delete(listener);
|
|
@@ -2597,7 +2657,7 @@ const O16 = {
|
|
|
2597
2657
|
}] }
|
|
2598
2658
|
}]
|
|
2599
2659
|
};
|
|
2600
|
-
/** These are the rules of the drain
|
|
2660
|
+
/** These are the rules of the drain. A kind cell gets the rules that guard the way that its plan stops a pod. */
|
|
2601
2661
|
const DRAIN_RULES = [
|
|
2602
2662
|
O04,
|
|
2603
2663
|
O09,
|
|
@@ -2625,8 +2685,44 @@ const scenarioOf = (cell, propagation) => ({
|
|
|
2625
2685
|
liveness: s(seconds$1(cell.pod.liveness.period) * cell.pod.liveness.threshold)
|
|
2626
2686
|
}
|
|
2627
2687
|
});
|
|
2628
|
-
/**
|
|
2629
|
-
|
|
2688
|
+
/**
|
|
2689
|
+
* This function gives the way that the fault plan of a cell stops a pod, or null when the plan stops no pod.
|
|
2690
|
+
* - A deletion, a rolling update, a node drain, a scale-in and a rollout delete a pod with its grace.
|
|
2691
|
+
* - In T07 a pause of kube-proxy comes before a deletion. In T18 the pause is on Redis.
|
|
2692
|
+
* - The crash of the lab is SIGKILL from the node. Like a crash, it has no preStop hook and no drain.
|
|
2693
|
+
* - The other faults are on a link, on Redis or on the process. The kubelet can restart a pod after them.
|
|
2694
|
+
*/
|
|
2695
|
+
const stopOf = (cell) => {
|
|
2696
|
+
switch (cell.trigger.kind) {
|
|
2697
|
+
case "pod-deletion":
|
|
2698
|
+
case "rolling-update":
|
|
2699
|
+
case "node-drain":
|
|
2700
|
+
case "scale-in":
|
|
2701
|
+
case "rollout": return "deletion";
|
|
2702
|
+
case "freeze-process": return cell.template === "T07" ? "deletion" : null;
|
|
2703
|
+
case "crash": return "crash";
|
|
2704
|
+
case "liveness-restart": return "liveness-restart";
|
|
2705
|
+
case "rst":
|
|
2706
|
+
case "blackhole":
|
|
2707
|
+
case "peer-gone-without-close":
|
|
2708
|
+
case "app-stall":
|
|
2709
|
+
case "cpu-throttle":
|
|
2710
|
+
case "authorization-policy":
|
|
2711
|
+
case "idle":
|
|
2712
|
+
case "ztunnel-restart":
|
|
2713
|
+
case "certificate-expiry": return null;
|
|
2714
|
+
}
|
|
2715
|
+
};
|
|
2716
|
+
/**
|
|
2717
|
+
* This function applies the drain rules to the description of a cell, and gives each finding. A cell
|
|
2718
|
+
* whose plan stops a pod gets the rules of that way (`lintStop()`). A plan that stops no pod gets each
|
|
2719
|
+
* drain rule, because a restart by the kubelet or a later deletion can follow its fault.
|
|
2720
|
+
*/
|
|
2721
|
+
const lintCell = (description, cell, propagation) => {
|
|
2722
|
+
const way = stopOf(cell);
|
|
2723
|
+
const scenario = scenarioOf(cell, propagation);
|
|
2724
|
+
return way === null ? lint(description, scenario, DRAIN_RULES) : lintStop(description, scenario, DRAIN_RULES, way);
|
|
2725
|
+
};
|
|
2630
2726
|
/** This function gives the verdict of each drain rule, by its identifier. */
|
|
2631
2727
|
const verdictsOf = (findings) => Object.fromEntries(findings.map((finding) => [finding.rule, finding.verdict]));
|
|
2632
2728
|
/** This function gives the description of the service of a cell, as the app of the image composes it. Nothing connects. */
|
|
@@ -3176,6 +3272,26 @@ const doStep = async (ctx, step, replicas, background) => {
|
|
|
3176
3272
|
t1: await lab.now()
|
|
3177
3273
|
};
|
|
3178
3274
|
}
|
|
3275
|
+
case "certificates": {
|
|
3276
|
+
const t0 = await lab.now();
|
|
3277
|
+
const certificates = await ztunnelCertificates(cluster).catch((error) => String(error).slice(0, 400));
|
|
3278
|
+
const t1 = await lab.now();
|
|
3279
|
+
lab.record(typeof certificates === "string" ? {
|
|
3280
|
+
ev: "certificates",
|
|
3281
|
+
t: t0,
|
|
3282
|
+
t1,
|
|
3283
|
+
error: certificates
|
|
3284
|
+
} : {
|
|
3285
|
+
ev: "certificates",
|
|
3286
|
+
t: t0,
|
|
3287
|
+
t1,
|
|
3288
|
+
certificates
|
|
3289
|
+
});
|
|
3290
|
+
return {
|
|
3291
|
+
t0,
|
|
3292
|
+
t1
|
|
3293
|
+
};
|
|
3294
|
+
}
|
|
3179
3295
|
case "middlebox":
|
|
3180
3296
|
if (step.target !== "servers") throw new Error(`a middlebox takes the target servers, not ${step.target}`);
|
|
3181
3297
|
return middleboxServers(ctx, step.idle, step.port, replicas);
|
|
@@ -3568,7 +3684,8 @@ const estimate = (cell, environments = 2) => {
|
|
|
3568
3684
|
rollout: hold + 50,
|
|
3569
3685
|
"authorization-policy": hold + 20,
|
|
3570
3686
|
idle: hold + 5,
|
|
3571
|
-
"ztunnel-restart": 40
|
|
3687
|
+
"ztunnel-restart": 40,
|
|
3688
|
+
"certificate-expiry": hold + 20
|
|
3572
3689
|
};
|
|
3573
3690
|
const after = observationAfter(cell);
|
|
3574
3691
|
const observed = after === null ? 0 : hold + valueIn(after, "s");
|
|
@@ -3606,6 +3723,6 @@ const shardOf = (cells, index, count) => {
|
|
|
3606
3723
|
return out;
|
|
3607
3724
|
};
|
|
3608
3725
|
//#endregion
|
|
3609
|
-
export { ACCESS_LOG_FORMAT, CHANNEL_USE, CLIENT, CLIENT_ACCOUNT, CLOSE_LEAD, CONTROLLER, DOCUMENTED, DRAIN_RULES, EDS_EVERY, FLAG_CHECK, FORMAT, FORMAT_V1, HBONE_PORT, HEALTH_PORT, ISTIOCTL, ISTIO_IMAGES, ISTIO_VERSION, KEPT_KERNEL, KIND, KIND_NOISE, KUBECTL, KUBE_PROXY_MODES, LAST_SLACK, LDS_EVERY, LDS_FILTER, LOG_LABEL, MESH_IMAGES, MESH_WORKLOADS, MIDDLEBOX, NETNS_DEFAULTS, NODE_IMAGES, O04, O09, O10, O16, POLICY, PORT, QUIET_LEAD, REDIS, REDIS_IMAGE, RELATIVE, ROUTE, RULES_EVERY, SERVER, STAGES, SYSCTL, TCP_STATE, WATCHDOG, ZTUNNEL_PODS, backendsAt, backendsOf, bandOf, byClients, byNode, cacheFolder, calibrationOf, capOf, cellsTable, checkRun, cidrOverlap, cidrRange, clientObjects, clusterFilter, compose, createCluster, deletes, deletionOf, deletionWindow, deletionsOf, describeCell, dropOf, emptyOf, ensureTool, estimatedTime, factsOf, failuresOf, followsZtunnel, goDuration, hostsOf, installMesh, intakeAfter, intakeOf, isTunnelState, istioOperator, judge, judgeKind, keptKernel, kernelCounts, kindCellRecordSchema, kindCellRecordV1Schema, kindConfig, kubeProxyPatch, kubeletBand, labImage, latchBand, lintCell, listenerCountsOf, localPin, medianInterval, medianText, meshKey, middle, middleboxCommands, namespaceObject, namespaceOf, nodeNames, observationAfter, observationEnd, openKindLab, outboundCluster, outcomesOf, pausedWindow, planOf, platformKey, podsAt, podsOf, policyObject, pollsListeners, predictionText, probeOf, propagationOf, propagationSource, quantileOf, readRecord, recordsOf, redisObjects, referenceOf, removalBand, requestsOf, restartBand, restartOf, restartsAt, reusesReset, rulesOf, runKindCells, scenario, scenarioOf, scenarioProblems, seconds, secondsOf, serverCluster, serverObjects, setZtunnelEnv, sha256, shardOf, showBand, signalOf, signalsOf, sliceDropOf, sliceEmptyOf, slicesOf, socketsOf, stackOf, stageLabImage, stallRemovalBand, stoppingOf, sysctlCommand, tarEntry, timeSpread, toolPath, transitionOf, tunnelsOf, unitOf, updatesOf, upgrade, upgradeCell, verdictsOf, writeResult, ztunnelEnvArgs, ztunnelPodsOf, ztunnelReplaced };
|
|
3726
|
+
export { ACCESS_LOG_FORMAT, CHANNEL_USE, CLIENT, CLIENT_ACCOUNT, CLOSE_LEAD, CONTROLLER, DOCUMENTED, DRAIN_RULES, EDS_EVERY, FLAG_CHECK, FORMAT, FORMAT_V1, HBONE_PORT, HEALTH_PORT, ISTIOCTL, ISTIO_IMAGES, ISTIO_VERSION, KEPT_KERNEL, KIND, KIND_NOISE, KUBECTL, KUBE_PROXY_MODES, LAST_SLACK, LDS_EVERY, LDS_FILTER, LOG_LABEL, MESH_IMAGES, MESH_WORKLOADS, MIDDLEBOX, NETNS_DEFAULTS, NODE_IMAGES, O04, O09, O10, O16, POLICY, PORT, QUIET_LEAD, REDIS, REDIS_IMAGE, RELATIVE, ROUTE, RULES_EVERY, SERVER, STAGES, SYSCTL, TCP_STATE, WATCHDOG, ZTUNNEL_PODS, backendsAt, backendsOf, bandOf, byClients, byNode, cacheFolder, calibrationOf, capOf, cellsTable, certificateArgs, checkRun, cidrOverlap, cidrRange, clientObjects, clusterFilter, compose, createCluster, deletes, deletionOf, deletionWindow, deletionsOf, describeCell, dropOf, emptyOf, ensureTool, estimatedTime, factsOf, failuresOf, followsZtunnel, goDuration, hostsOf, installMesh, intakeAfter, intakeOf, isTunnelState, istioOperator, judge, judgeKind, keptKernel, kernelCounts, kindCellRecordSchema, kindCellRecordV1Schema, kindConfig, kubeProxyPatch, kubeletBand, labImage, latchBand, leafCertificates, lintCell, listenerCountsOf, localPin, medianInterval, medianText, meshKey, middle, middleboxCommands, namespaceObject, namespaceOf, nodeNames, observationAfter, observationEnd, openKindLab, outboundCluster, outcomesOf, pausedWindow, planOf, platformKey, podsAt, podsOf, policyObject, pollsListeners, predictionText, probeOf, propagationOf, propagationSource, quantileOf, readRecord, recordsOf, redisObjects, referenceOf, removalBand, requestsOf, restartBand, restartOf, restartsAt, reusesReset, rulesOf, runKindCells, scenario, scenarioOf, scenarioProblems, seconds, secondsOf, serverCluster, serverObjects, setZtunnelEnv, sha256, shardOf, showBand, signalOf, signalsOf, sliceDropOf, sliceEmptyOf, slicesOf, socketsOf, stackOf, stageLabImage, stallRemovalBand, stopOf, stoppingOf, sysctlCommand, tarEntry, timeSpread, toolPath, transitionOf, tunnelsOf, unitOf, updatesOf, upgrade, upgradeCell, verdictsOf, writeResult, ztunnelCertificates, ztunnelEnvArgs, ztunnelPodsOf, ztunnelReplaced };
|
|
3610
3727
|
|
|
3611
3728
|
//# sourceMappingURL=index.js.map
|