@vibesdotdev/integrations-kubernetes 0.0.0-stage → 1.0.0-rc.1
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/LICENSE +18 -0
- package/README.md +19 -2
- package/dist/helm-chart.d.ts +13 -0
- package/dist/helm-chart.d.ts.map +1 -0
- package/dist/helm-chart.js +508 -0
- package/dist/helm-chart.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/k8s-configmap.d.ts +25 -0
- package/dist/k8s-configmap.d.ts.map +1 -0
- package/dist/k8s-configmap.js +168 -0
- package/dist/k8s-configmap.js.map +1 -0
- package/dist/k8s-gpu-operator.d.ts +3 -0
- package/dist/k8s-gpu-operator.d.ts.map +1 -0
- package/dist/k8s-gpu-operator.js +53 -0
- package/dist/k8s-gpu-operator.js.map +1 -0
- package/dist/k8s-namespace.d.ts +51 -0
- package/dist/k8s-namespace.d.ts.map +1 -0
- package/dist/k8s-namespace.js +280 -0
- package/dist/k8s-namespace.js.map +1 -0
- package/dist/k8s-pod-health.d.ts +60 -0
- package/dist/k8s-pod-health.d.ts.map +1 -0
- package/dist/k8s-pod-health.js +376 -0
- package/dist/k8s-pod-health.js.map +1 -0
- package/dist/k8s-secret.d.ts +55 -0
- package/dist/k8s-secret.d.ts.map +1 -0
- package/dist/k8s-secret.js +391 -0
- package/dist/k8s-secret.js.map +1 -0
- package/dist/kind-cluster.d.ts +84 -0
- package/dist/kind-cluster.d.ts.map +1 -0
- package/dist/kind-cluster.js +694 -0
- package/dist/kind-cluster.js.map +1 -0
- package/dist/kubectl-budget.client.d.ts +13 -0
- package/dist/kubectl-budget.client.d.ts.map +1 -0
- package/dist/kubectl-budget.client.js +38 -0
- package/dist/kubectl-budget.client.js.map +1 -0
- package/dist/kubectl.d.ts +59 -0
- package/dist/kubectl.d.ts.map +1 -0
- package/dist/kubectl.js +121 -0
- package/dist/kubectl.js.map +1 -0
- package/dist/port-forward-command.d.ts +6 -0
- package/dist/port-forward-command.d.ts.map +1 -0
- package/dist/port-forward-command.js +24 -0
- package/dist/port-forward-command.js.map +1 -0
- package/dist/port-forward-compat.d.ts +11 -0
- package/dist/port-forward-compat.d.ts.map +1 -0
- package/dist/port-forward-compat.js +21 -0
- package/dist/port-forward-compat.js.map +1 -0
- package/dist/port-forward-identity.d.ts +23 -0
- package/dist/port-forward-identity.d.ts.map +1 -0
- package/dist/port-forward-identity.js +72 -0
- package/dist/port-forward-identity.js.map +1 -0
- package/dist/port-forward.consumer.plugin.d.ts +3 -0
- package/dist/port-forward.consumer.plugin.d.ts.map +1 -0
- package/dist/port-forward.consumer.plugin.js +10 -0
- package/dist/port-forward.consumer.plugin.js.map +1 -0
- package/dist/port-forward.d.ts +18 -0
- package/dist/port-forward.d.ts.map +1 -0
- package/dist/port-forward.descriptor.d.ts +7 -0
- package/dist/port-forward.descriptor.d.ts.map +1 -0
- package/dist/port-forward.descriptor.js +3 -0
- package/dist/port-forward.descriptor.js.map +1 -0
- package/dist/port-forward.impl.consumer.d.ts +22 -0
- package/dist/port-forward.impl.consumer.d.ts.map +1 -0
- package/dist/port-forward.impl.consumer.js +32 -0
- package/dist/port-forward.impl.consumer.js.map +1 -0
- package/dist/port-forward.js +26 -0
- package/dist/port-forward.js.map +1 -0
- package/dist/port-forward.kind.d.ts +13 -0
- package/dist/port-forward.kind.d.ts.map +1 -0
- package/dist/port-forward.kind.js +12 -0
- package/dist/port-forward.kind.js.map +1 -0
- package/dist/resource-providers.consumer.plugin.d.ts +3 -0
- package/dist/resource-providers.consumer.plugin.d.ts.map +1 -0
- package/dist/resource-providers.consumer.plugin.js +56 -0
- package/dist/resource-providers.consumer.plugin.js.map +1 -0
- package/dist/schemas/helm-chart.d.ts +14 -0
- package/dist/schemas/helm-chart.d.ts.map +1 -0
- package/dist/schemas/helm-chart.js +12 -0
- package/dist/schemas/helm-chart.js.map +1 -0
- package/dist/schemas/k8s-pod-health.d.ts +17 -0
- package/dist/schemas/k8s-pod-health.d.ts.map +1 -0
- package/dist/schemas/k8s-pod-health.js +21 -0
- package/dist/schemas/k8s-pod-health.js.map +1 -0
- package/dist/schemas/port-forward.d.ts +62 -0
- package/dist/schemas/port-forward.d.ts.map +1 -0
- package/dist/schemas/port-forward.js +24 -0
- package/dist/schemas/port-forward.js.map +1 -0
- package/dist/tool-env.d.ts +19 -0
- package/dist/tool-env.d.ts.map +1 -0
- package/dist/tool-env.js +32 -0
- package/dist/tool-env.js.map +1 -0
- package/package.json +80 -4
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kubernetes Pod Health Resource Provider
|
|
3
|
+
* Monitors specific pods by label selector and reports health status
|
|
4
|
+
*
|
|
5
|
+
* Use this to create dependencies between port-forwards and their backend pods.
|
|
6
|
+
* When the pod becomes unhealthy, dependent processes can be restarted.
|
|
7
|
+
*
|
|
8
|
+
* Example:
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const postgresPod = defineResource('k8s/pod-health', 'postgres-pod')
|
|
11
|
+
* .set('labelSelector', 'app=postgres')
|
|
12
|
+
* .set('namespace', 'vibes-local')
|
|
13
|
+
* .set('context', 'kind-vibes-local')
|
|
14
|
+
* .build();
|
|
15
|
+
*
|
|
16
|
+
* // Port-forward depends on pod being healthy
|
|
17
|
+
* const postgresForward = defineProcess('postgres-forward')
|
|
18
|
+
* .dependsOn('postgres-pod')
|
|
19
|
+
* .build();
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
import { type RuntimeRef } from '@vibesdotdev/kernel';
|
|
23
|
+
import type { ResourceProvider } from '@vibesdotdev/pm/resources/provider';
|
|
24
|
+
import { type K8sPodHealthConfig, type KubectlSemaphore } from './schemas/k8s-pod-health.ts';
|
|
25
|
+
/** The kubectl semaphore of `runtime`'s root, resolved through the `runtime/client` the resource-providers plugin registers (exported for the two-views test). */
|
|
26
|
+
export declare function kubectlSemaphore(runtime: RuntimeRef): Promise<KubectlSemaphore>;
|
|
27
|
+
/** Run `fn` when one of the root's kubectl slots opens; refuse typed when none opens within `timeoutMs` (exported for the budget test). */
|
|
28
|
+
export declare function withKubectlSemaphore<T>(runtime: RuntimeRef, fn: () => Promise<T>, timeoutMs?: number): Promise<T>;
|
|
29
|
+
interface PodStatus {
|
|
30
|
+
name: string;
|
|
31
|
+
ready: boolean;
|
|
32
|
+
phase: string;
|
|
33
|
+
conditions: Array<{
|
|
34
|
+
type: string;
|
|
35
|
+
status: string;
|
|
36
|
+
}>;
|
|
37
|
+
containerStatuses: Array<{
|
|
38
|
+
name: string;
|
|
39
|
+
ready: boolean;
|
|
40
|
+
restartCount: number;
|
|
41
|
+
state?: {
|
|
42
|
+
waiting?: {
|
|
43
|
+
reason?: string;
|
|
44
|
+
message?: string;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
}>;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get pod status from kubectl (exported for the typed-refusal test: the
|
|
51
|
+
* providers report a refusal as text, so the reason is read here).
|
|
52
|
+
*/
|
|
53
|
+
export declare function getPodStatus(runtime: RuntimeRef, config: K8sPodHealthConfig): Promise<PodStatus[]>;
|
|
54
|
+
/**
|
|
55
|
+
* Kubernetes Pod Health Provider
|
|
56
|
+
* Monitors pod health by label selector
|
|
57
|
+
*/
|
|
58
|
+
export declare const k8sPodHealthProvider: ResourceProvider<K8sPodHealthConfig>;
|
|
59
|
+
export {};
|
|
60
|
+
//# sourceMappingURL=k8s-pod-health.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"k8s-pod-health.d.ts","sourceRoot":"","sources":["../src/k8s-pod-health.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAmB,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGvE,OAAO,KAAK,EACX,gBAAgB,EAKhB,MAAM,oCAAoC,CAAC;AAI5C,OAAO,EAA4B,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAavH,kKAAkK;AAClK,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAGrF;AAED,2IAA2I;AAC3I,wBAAsB,oBAAoB,CAAC,CAAC,EAAE,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,SAAS,SAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CA+CtH;AAMD,UAAU,SAAS;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD,iBAAiB,EAAE,KAAK,CAAC;QACxB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,OAAO,CAAC;QACf,YAAY,EAAE,MAAM,CAAC;QACrB,KAAK,CAAC,EAAE;YAAE,OAAO,CAAC,EAAE;gBAAE,MAAM,CAAC,EAAE,MAAM,CAAC;gBAAC,OAAO,CAAC,EAAE,MAAM,CAAA;aAAE,CAAA;SAAE,CAAC;KAC5D,CAAC,CAAC;CACH;AAqCD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAyDlG;AA4HD;;;GAGG;AACH,eAAO,MAAM,oBAAoB,EAAE,gBAAgB,CAAC,kBAAkB,CA2GrE,CAAC"}
|
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kubernetes Pod Health Resource Provider
|
|
3
|
+
* Monitors specific pods by label selector and reports health status
|
|
4
|
+
*
|
|
5
|
+
* Use this to create dependencies between port-forwards and their backend pods.
|
|
6
|
+
* When the pod becomes unhealthy, dependent processes can be restarted.
|
|
7
|
+
*
|
|
8
|
+
* Example:
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const postgresPod = defineResource('k8s/pod-health', 'postgres-pod')
|
|
11
|
+
* .set('labelSelector', 'app=postgres')
|
|
12
|
+
* .set('namespace', 'vibes-local')
|
|
13
|
+
* .set('context', 'kind-vibes-local')
|
|
14
|
+
* .build();
|
|
15
|
+
*
|
|
16
|
+
* // Port-forward depends on pod being healthy
|
|
17
|
+
* const postgresForward = defineProcess('postgres-forward')
|
|
18
|
+
* .dependsOn('postgres-pod')
|
|
19
|
+
* .build();
|
|
20
|
+
* ```
|
|
21
|
+
*/
|
|
22
|
+
import { CapabilityError } from '@vibesdotdev/kernel';
|
|
23
|
+
import { getVibesClient } from '@vibesdotdev/kernel/client';
|
|
24
|
+
import * as z from 'zod/v4';
|
|
25
|
+
import { providerFailureText, setupErrorResult, toolFailure } from '@vibesdotdev/pm/resources/tool-env';
|
|
26
|
+
import { runKubeCapture } from "./tool-env.js";
|
|
27
|
+
import { KUBECTL_BUDGET_CLIENT_ID, requireRootIdentity } from "./kubectl-budget.client.js";
|
|
28
|
+
import { K8sPodHealthConfigSchema } from "./schemas/k8s-pod-health.js";
|
|
29
|
+
import { attempt, attemptSync } from '@vibesdotdev/pm/utils/attempt';
|
|
30
|
+
// FD Safety: a semaphore for kubectl spawns, to prevent FD exhaustion. It is
|
|
31
|
+
// the handed runtime's ROOT's (`rootIdentityOf`): a plugin view or a reload
|
|
32
|
+
// generation of the same root shares one budget instead of doubling kubectl
|
|
33
|
+
// concurrency, and it is never a module-wide counter shared by every root in
|
|
34
|
+
// the process. A runtime the kernel did not construct names no root and is
|
|
35
|
+
// refused typed.
|
|
36
|
+
const KUBECTL_SEMAPHORE_MAX = 3;
|
|
37
|
+
const KUBECTL_REQUEST_TIMEOUT = '5s';
|
|
38
|
+
/** The kubectl semaphore of `runtime`'s root, resolved through the `runtime/client` the resource-providers plugin registers (exported for the two-views test). */
|
|
39
|
+
export async function kubectlSemaphore(runtime) {
|
|
40
|
+
requireRootIdentity(runtime);
|
|
41
|
+
return (await getVibesClient(KUBECTL_BUDGET_CLIENT_ID, runtime)).semaphore;
|
|
42
|
+
}
|
|
43
|
+
/** Run `fn` when one of the root's kubectl slots opens; refuse typed when none opens within `timeoutMs` (exported for the budget test). */
|
|
44
|
+
export async function withKubectlSemaphore(runtime, fn, timeoutMs = 10000) {
|
|
45
|
+
const semaphore = await kubectlSemaphore(runtime);
|
|
46
|
+
return new Promise((resolve, reject) => {
|
|
47
|
+
let started = false;
|
|
48
|
+
let queueEntry = null;
|
|
49
|
+
// The queue deadline is a lifecycle one-shot (RC07), cancelled when the slot opens.
|
|
50
|
+
const cancelTimeout = runtime.lifecycle.timeout(() => {
|
|
51
|
+
if (started)
|
|
52
|
+
return;
|
|
53
|
+
if (queueEntry) {
|
|
54
|
+
const index = semaphore.queue.indexOf(queueEntry);
|
|
55
|
+
if (index >= 0) {
|
|
56
|
+
semaphore.queue.splice(index, 1);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
reject(new CapabilityError(`kubectl spawn timeout after ${timeoutMs}ms`, 'TIMEOUT', {
|
|
60
|
+
reason: 'pm-kubectl-slot-timeout',
|
|
61
|
+
retryable: true,
|
|
62
|
+
details: { timeoutMs }
|
|
63
|
+
}));
|
|
64
|
+
}, timeoutMs);
|
|
65
|
+
const run = async () => {
|
|
66
|
+
if (started)
|
|
67
|
+
return;
|
|
68
|
+
started = true;
|
|
69
|
+
cancelTimeout();
|
|
70
|
+
semaphore.active++;
|
|
71
|
+
try {
|
|
72
|
+
const result = await fn();
|
|
73
|
+
resolve(result);
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
reject(err);
|
|
77
|
+
}
|
|
78
|
+
finally {
|
|
79
|
+
semaphore.active--;
|
|
80
|
+
const next = semaphore.queue.shift();
|
|
81
|
+
if (next)
|
|
82
|
+
next();
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
if (semaphore.active < KUBECTL_SEMAPHORE_MAX) {
|
|
86
|
+
void run();
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
queueEntry = () => void run();
|
|
90
|
+
semaphore.queue.push(queueEntry);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function validateConfig(config) {
|
|
95
|
+
return K8sPodHealthConfigSchema.parse(config);
|
|
96
|
+
}
|
|
97
|
+
/** The parts of `kubectl get pods -o json` this provider reads; a pod missing a part reads as its defaults. */
|
|
98
|
+
const KubernetesPodListSchema = z.object({
|
|
99
|
+
items: z
|
|
100
|
+
.array(z.object({
|
|
101
|
+
metadata: z.object({ name: z.string().optional() }).nullish(),
|
|
102
|
+
status: z
|
|
103
|
+
.object({
|
|
104
|
+
phase: z.string().optional(),
|
|
105
|
+
conditions: z
|
|
106
|
+
.array(z.object({ type: z.string().optional(), status: z.string().optional() }))
|
|
107
|
+
.nullish(),
|
|
108
|
+
containerStatuses: z
|
|
109
|
+
.array(z.object({
|
|
110
|
+
name: z.string().optional(),
|
|
111
|
+
ready: z.boolean().optional(),
|
|
112
|
+
restartCount: z.number().optional(),
|
|
113
|
+
state: z
|
|
114
|
+
.object({
|
|
115
|
+
waiting: z
|
|
116
|
+
.object({ reason: z.string().optional(), message: z.string().optional() })
|
|
117
|
+
.optional()
|
|
118
|
+
})
|
|
119
|
+
.optional()
|
|
120
|
+
}))
|
|
121
|
+
.nullish()
|
|
122
|
+
})
|
|
123
|
+
.nullish()
|
|
124
|
+
}))
|
|
125
|
+
.catch([])
|
|
126
|
+
});
|
|
127
|
+
/**
|
|
128
|
+
* Get pod status from kubectl (exported for the typed-refusal test: the
|
|
129
|
+
* providers report a refusal as text, so the reason is read here).
|
|
130
|
+
*/
|
|
131
|
+
export function getPodStatus(runtime, config) {
|
|
132
|
+
return withKubectlSemaphore(runtime, async () => {
|
|
133
|
+
const cmd = [
|
|
134
|
+
'kubectl',
|
|
135
|
+
'get',
|
|
136
|
+
'pods',
|
|
137
|
+
'--selector',
|
|
138
|
+
config.labelSelector,
|
|
139
|
+
'--namespace',
|
|
140
|
+
config.namespace,
|
|
141
|
+
'--request-timeout',
|
|
142
|
+
KUBECTL_REQUEST_TIMEOUT,
|
|
143
|
+
'--output',
|
|
144
|
+
'json'
|
|
145
|
+
];
|
|
146
|
+
if (config.context) {
|
|
147
|
+
cmd.push('--context', config.context);
|
|
148
|
+
}
|
|
149
|
+
const { exitCode, stdout: output, stderr } = await runKubeCapture(runtime, cmd[0], cmd.slice(1));
|
|
150
|
+
if (exitCode !== 0) {
|
|
151
|
+
throw toolFailure({ tool: 'kubectl', action: 'get pods', outcome: { exitCode, stderr } });
|
|
152
|
+
}
|
|
153
|
+
const parsed = attemptSync(() => KubernetesPodListSchema.parse(JSON.parse(output)));
|
|
154
|
+
if (!parsed.ok) {
|
|
155
|
+
throw new CapabilityError('kubectl get pods answered an unreadable pod list', 'UNAVAILABLE', {
|
|
156
|
+
reason: 'pm-kubectl-pods-unreadable',
|
|
157
|
+
retryable: true,
|
|
158
|
+
cause: parsed.failure
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
return parsed.value.items.map((pod) => {
|
|
162
|
+
const conditions = pod.status?.conditions ?? [];
|
|
163
|
+
const readyCondition = conditions.find((c) => c.type === 'Ready');
|
|
164
|
+
const containerStatuses = pod.status?.containerStatuses ?? [];
|
|
165
|
+
return {
|
|
166
|
+
name: pod.metadata?.name || 'unknown',
|
|
167
|
+
ready: readyCondition?.status === 'True',
|
|
168
|
+
phase: pod.status?.phase || 'Unknown',
|
|
169
|
+
conditions: conditions.map((c) => ({
|
|
170
|
+
type: c.type ?? 'Unknown',
|
|
171
|
+
status: c.status ?? 'Unknown'
|
|
172
|
+
})),
|
|
173
|
+
containerStatuses: containerStatuses.map((cs) => ({
|
|
174
|
+
name: cs.name ?? 'unknown',
|
|
175
|
+
ready: cs.ready ?? false,
|
|
176
|
+
restartCount: cs.restartCount || 0,
|
|
177
|
+
state: cs.state
|
|
178
|
+
}))
|
|
179
|
+
};
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Get recent logs from a failing pod to help diagnose issues
|
|
185
|
+
*/
|
|
186
|
+
function getPodLogs(runtime, podName, namespace, context, tailLines = 10) {
|
|
187
|
+
return withKubectlSemaphore(runtime, async () => {
|
|
188
|
+
const cmd = [
|
|
189
|
+
'kubectl',
|
|
190
|
+
'logs',
|
|
191
|
+
podName,
|
|
192
|
+
'--namespace',
|
|
193
|
+
namespace,
|
|
194
|
+
'--request-timeout',
|
|
195
|
+
KUBECTL_REQUEST_TIMEOUT,
|
|
196
|
+
'--tail',
|
|
197
|
+
String(tailLines)
|
|
198
|
+
];
|
|
199
|
+
if (context) {
|
|
200
|
+
cmd.push('--context', context);
|
|
201
|
+
}
|
|
202
|
+
const run = await runKubeCapture(runtime, cmd[0], cmd.slice(1));
|
|
203
|
+
const output = run.stdout;
|
|
204
|
+
if (run.exitCode !== 0) {
|
|
205
|
+
const prevCmd = [...cmd, '--previous'];
|
|
206
|
+
const prevRun = await runKubeCapture(runtime, prevCmd[0], prevCmd.slice(1));
|
|
207
|
+
if (prevRun.exitCode === 0 && prevRun.stdout.trim()) {
|
|
208
|
+
return prevRun.stdout.trim();
|
|
209
|
+
}
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
return output.trim() || null;
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Extract ERROR lines from logs for concise display
|
|
217
|
+
*/
|
|
218
|
+
function extractErrorLines(logs) {
|
|
219
|
+
const lines = logs.split('\n');
|
|
220
|
+
const errorLines = lines.filter((line) => line.includes('ERROR') ||
|
|
221
|
+
line.includes('Error') ||
|
|
222
|
+
line.includes('error:') ||
|
|
223
|
+
line.includes('FATAL') ||
|
|
224
|
+
line.includes('panic'));
|
|
225
|
+
return errorLines.length > 0 ? errorLines.slice(-3).join(' | ') : null;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Check if pods are healthy based on config requirements
|
|
229
|
+
*/
|
|
230
|
+
function checkPodsHealthy(pods, config) {
|
|
231
|
+
if (pods.length === 0) {
|
|
232
|
+
return {
|
|
233
|
+
healthy: false,
|
|
234
|
+
message: `No pods found matching selector '${config.labelSelector}'`,
|
|
235
|
+
readyCount: 0
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
let readyCount = 0;
|
|
239
|
+
const unhealthyPods = [];
|
|
240
|
+
for (const pod of pods) {
|
|
241
|
+
let podHealthy = pod.ready && pod.phase === 'Running';
|
|
242
|
+
// Check container readiness if required
|
|
243
|
+
if (podHealthy && config.requireAllContainersReady && pod.containerStatuses.length > 0) {
|
|
244
|
+
const allContainersReady = pod.containerStatuses.every((cs) => cs.ready);
|
|
245
|
+
if (!allContainersReady) {
|
|
246
|
+
podHealthy = false;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
if (podHealthy) {
|
|
250
|
+
readyCount++;
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
const containerInfo = pod.containerStatuses
|
|
254
|
+
.filter((cs) => !cs.ready)
|
|
255
|
+
.map((cs) => {
|
|
256
|
+
const waitReason = cs.state?.waiting?.reason;
|
|
257
|
+
const waitMsg = cs.state?.waiting?.message;
|
|
258
|
+
let info = `${cs.name}(restarts:${cs.restartCount}`;
|
|
259
|
+
if (waitReason)
|
|
260
|
+
info += `, ${waitReason}`;
|
|
261
|
+
if (waitMsg)
|
|
262
|
+
info += `: ${waitMsg.substring(0, 100)}`;
|
|
263
|
+
return `${info})`;
|
|
264
|
+
})
|
|
265
|
+
.join(', ');
|
|
266
|
+
unhealthyPods.push(`${pod.name}: phase=${pod.phase}, ready=${pod.ready}${containerInfo ? `, containers=[${containerInfo}]` : ''}`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
const minReady = config.minReady || 1;
|
|
270
|
+
const healthy = readyCount >= minReady;
|
|
271
|
+
const message = healthy
|
|
272
|
+
? `${readyCount}/${pods.length} pod(s) ready (min: ${minReady})`
|
|
273
|
+
: `Only ${readyCount}/${pods.length} pod(s) ready (need ${minReady}). Unhealthy: ${unhealthyPods.join('; ')}`;
|
|
274
|
+
return { healthy, message, readyCount };
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Kubernetes Pod Health Provider
|
|
278
|
+
* Monitors pod health by label selector
|
|
279
|
+
*/
|
|
280
|
+
export const k8sPodHealthProvider = {
|
|
281
|
+
type: 'k8s/pod-health',
|
|
282
|
+
async setup(config, { runtime }) {
|
|
283
|
+
const podConfig = validateConfig(config.config);
|
|
284
|
+
const checked = await attempt(async () => {
|
|
285
|
+
const pods = await getPodStatus(runtime, podConfig);
|
|
286
|
+
return { pods, healthCheck: checkPodsHealthy(pods, podConfig) };
|
|
287
|
+
});
|
|
288
|
+
if (!checked.ok)
|
|
289
|
+
return setupErrorResult(config, checked.failure);
|
|
290
|
+
const { pods, healthCheck } = checked.value;
|
|
291
|
+
return {
|
|
292
|
+
state: {
|
|
293
|
+
id: config.id,
|
|
294
|
+
type: config.type,
|
|
295
|
+
status: healthCheck.healthy ? 'ready' : 'creating',
|
|
296
|
+
createdAt: new Date(),
|
|
297
|
+
lastChecked: new Date(),
|
|
298
|
+
metadata: {
|
|
299
|
+
labelSelector: podConfig.labelSelector,
|
|
300
|
+
namespace: podConfig.namespace,
|
|
301
|
+
podCount: pods.length,
|
|
302
|
+
readyCount: healthCheck.readyCount,
|
|
303
|
+
healthMessage: healthCheck.message
|
|
304
|
+
}
|
|
305
|
+
},
|
|
306
|
+
metadata: { output: healthCheck.message }
|
|
307
|
+
};
|
|
308
|
+
},
|
|
309
|
+
async teardown(_id, _state) {
|
|
310
|
+
},
|
|
311
|
+
async status(id, { runtime, config: providerConfig }) {
|
|
312
|
+
const config = providerConfig;
|
|
313
|
+
if (!config) {
|
|
314
|
+
return { status: 'missing' };
|
|
315
|
+
}
|
|
316
|
+
const podConfig = validateConfig(config.config);
|
|
317
|
+
const checked = await attempt(async () => {
|
|
318
|
+
const pods = await getPodStatus(runtime, podConfig);
|
|
319
|
+
return { pods, healthCheck: checkPodsHealthy(pods, podConfig) };
|
|
320
|
+
});
|
|
321
|
+
if (!checked.ok)
|
|
322
|
+
return { status: 'error', error: providerFailureText(checked.failure) };
|
|
323
|
+
const { pods, healthCheck } = checked.value;
|
|
324
|
+
return {
|
|
325
|
+
status: healthCheck.healthy ? 'ready' : 'error',
|
|
326
|
+
metadata: {
|
|
327
|
+
podCount: pods.length,
|
|
328
|
+
readyCount: healthCheck.readyCount,
|
|
329
|
+
message: healthCheck.message,
|
|
330
|
+
pods: pods.map((p) => ({ name: p.name, ready: p.ready, phase: p.phase }))
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
},
|
|
334
|
+
async checkReady(config, _state, { runtime }) {
|
|
335
|
+
const podConfig = validateConfig(config.config);
|
|
336
|
+
const checked = await attempt(async () => {
|
|
337
|
+
const pods = await getPodStatus(runtime, podConfig);
|
|
338
|
+
return { pods, healthCheck: checkPodsHealthy(pods, podConfig) };
|
|
339
|
+
});
|
|
340
|
+
if (!checked.ok) {
|
|
341
|
+
return { ready: false, reason: providerFailureText(checked.failure), retryAfter: 5000 };
|
|
342
|
+
}
|
|
343
|
+
const { pods, healthCheck } = checked.value;
|
|
344
|
+
if (healthCheck.healthy) {
|
|
345
|
+
return { ready: true };
|
|
346
|
+
}
|
|
347
|
+
// For failing pods, try to get logs to show the actual error
|
|
348
|
+
let reason = healthCheck.message;
|
|
349
|
+
const failingPods = pods.filter((p) => !p.ready || p.phase !== 'Running');
|
|
350
|
+
for (const pod of failingPods.slice(0, 2)) {
|
|
351
|
+
// Limit to first 2 pods
|
|
352
|
+
// Logs enrich the failure reason; logs that cannot be read are said
|
|
353
|
+
// in the reason (a reported outcome), never dropped.
|
|
354
|
+
const fetched = await attempt(() => getPodLogs(runtime, pod.name, podConfig.namespace, podConfig.context, 15));
|
|
355
|
+
if (!fetched.ok) {
|
|
356
|
+
reason += ` | ${pod.name} logs unavailable: ${providerFailureText(fetched.failure)}`;
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
if (fetched.value) {
|
|
360
|
+
const errorLines = extractErrorLines(fetched.value);
|
|
361
|
+
if (errorLines) {
|
|
362
|
+
reason += ` | ${pod.name} logs: ${errorLines}`;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
return {
|
|
367
|
+
ready: false,
|
|
368
|
+
reason,
|
|
369
|
+
retryAfter: podConfig.healthCheckInterval || 10000
|
|
370
|
+
};
|
|
371
|
+
},
|
|
372
|
+
validateConfig(config) {
|
|
373
|
+
return validateConfig(config);
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
//# sourceMappingURL=k8s-pod-health.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"k8s-pod-health.js","sourceRoot":"","sources":["../src/k8s-pod-health.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAAE,eAAe,EAAmB,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAQ5B,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACxG,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,wBAAwB,EAAE,mBAAmB,EAA4B,MAAM,4BAA4B,CAAC;AACrH,OAAO,EAAE,wBAAwB,EAAkD,MAAM,6BAA6B,CAAC;AAEvH,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAErE,6EAA6E;AAC7E,4EAA4E;AAC5E,4EAA4E;AAC5E,6EAA6E;AAC7E,2EAA2E;AAC3E,iBAAiB;AACjB,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAChC,MAAM,uBAAuB,GAAG,IAAI,CAAC;AAErC,kKAAkK;AAClK,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAAmB;IACzD,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC7B,OAAO,CAAC,MAAM,cAAc,CAAsB,wBAAwB,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AACjG,CAAC;AAED,2IAA2I;AAC3I,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAI,OAAmB,EAAE,EAAoB,EAAE,SAAS,GAAG,KAAK;IACzG,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAClD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACtC,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,UAAU,GAAwB,IAAI,CAAC;QAC3C,oFAAoF;QACpF,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE;YACpD,IAAI,OAAO;gBAAE,OAAO;YACpB,IAAI,UAAU,EAAE,CAAC;gBAChB,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;gBAClD,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;oBAChB,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;gBAClC,CAAC;YACF,CAAC;YACD,MAAM,CACL,IAAI,eAAe,CAAC,+BAA+B,SAAS,IAAI,EAAE,SAAS,EAAE;gBAC5E,MAAM,EAAE,yBAAyB;gBACjC,SAAS,EAAE,IAAI;gBACf,OAAO,EAAE,EAAE,SAAS,EAAE;aACtB,CAAC,CACF,CAAC;QACH,CAAC,EAAE,SAAS,CAAC,CAAC;QAEd,MAAM,GAAG,GAAG,KAAK,IAAI,EAAE;YACtB,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,aAAa,EAAE,CAAC;YAChB,SAAS,CAAC,MAAM,EAAE,CAAC;YACnB,IAAI,CAAC;gBACJ,MAAM,MAAM,GAAG,MAAM,EAAE,EAAE,CAAC;gBAC1B,OAAO,CAAC,MAAM,CAAC,CAAC;YACjB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,MAAM,CAAC,GAAG,CAAC,CAAC;YACb,CAAC;oBAAS,CAAC;gBACV,SAAS,CAAC,MAAM,EAAE,CAAC;gBACnB,MAAM,IAAI,GAAG,SAAS,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;gBACrC,IAAI,IAAI;oBAAE,IAAI,EAAE,CAAC;YAClB,CAAC;QACF,CAAC,CAAC;QAEF,IAAI,SAAS,CAAC,MAAM,GAAG,qBAAqB,EAAE,CAAC;YAC9C,KAAK,GAAG,EAAE,CAAC;QACZ,CAAC;aAAM,CAAC;YACP,UAAU,GAAG,GAAG,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC;YAC9B,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAClC,CAAC;IACF,CAAC,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,cAAc,CAAC,MAAuB;IAC9C,OAAO,wBAAwB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAC/C,CAAC;AAeD,+GAA+G;AAC/G,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,KAAK,EAAE,CAAC;SACN,KAAK,CACL,CAAC,CAAC,MAAM,CAAC;QACR,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE;QAC7D,MAAM,EAAE,CAAC;aACP,MAAM,CAAC;YACP,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;YAC5B,UAAU,EAAE,CAAC;iBACX,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;iBAC/E,OAAO,EAAE;YACX,iBAAiB,EAAE,CAAC;iBAClB,KAAK,CACL,CAAC,CAAC,MAAM,CAAC;gBACR,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;gBAC3B,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE;gBAC7B,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;gBACnC,KAAK,EAAE,CAAC;qBACN,MAAM,CAAC;oBACP,OAAO,EAAE,CAAC;yBACR,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC;yBACzE,QAAQ,EAAE;iBACZ,CAAC;qBACD,QAAQ,EAAE;aACZ,CAAC,CACF;iBACA,OAAO,EAAE;SACX,CAAC;aACD,OAAO,EAAE;KACX,CAAC,CACF;SACA,KAAK,CAAC,EAAE,CAAC;CACX,CAAC,CAAC;AAEH;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,OAAmB,EAAE,MAA0B;IAC3E,OAAO,oBAAoB,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,GAAG,GAAG;YACX,SAAS;YACT,KAAK;YACL,MAAM;YACN,YAAY;YACZ,MAAM,CAAC,aAAa;YACpB,aAAa;YACb,MAAM,CAAC,SAAS;YAChB,mBAAmB;YACnB,uBAAuB;YACvB,UAAU;YACV,MAAM;SACN,CAAC;QAEF,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC;QAED,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAE,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAElG,IAAI,QAAQ,KAAK,CAAC,EAAE,CAAC;YACpB,MAAM,WAAW,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;QAC3F,CAAC;QAED,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,uBAAuB,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACpF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YAChB,MAAM,IAAI,eAAe,CAAC,kDAAkD,EAAE,aAAa,EAAE;gBAC5F,MAAM,EAAE,4BAA4B;gBACpC,SAAS,EAAE,IAAI;gBACf,KAAK,EAAE,MAAM,CAAC,OAAO;aACrB,CAAC,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAa,EAAE;YAChD,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,IAAI,EAAE,CAAC;YAChD,MAAM,cAAc,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;YAClE,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,EAAE,iBAAiB,IAAI,EAAE,CAAC;YAE9D,OAAO;gBACN,IAAI,EAAE,GAAG,CAAC,QAAQ,EAAE,IAAI,IAAI,SAAS;gBACrC,KAAK,EAAE,cAAc,EAAE,MAAM,KAAK,MAAM;gBACxC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,IAAI,SAAS;gBACrC,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBAClC,IAAI,EAAE,CAAC,CAAC,IAAI,IAAI,SAAS;oBACzB,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,SAAS;iBAC7B,CAAC,CAAC;gBACH,iBAAiB,EAAE,iBAAiB,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;oBACjD,IAAI,EAAE,EAAE,CAAC,IAAI,IAAI,SAAS;oBAC1B,KAAK,EAAE,EAAE,CAAC,KAAK,IAAI,KAAK;oBACxB,YAAY,EAAE,EAAE,CAAC,YAAY,IAAI,CAAC;oBAClC,KAAK,EAAE,EAAE,CAAC,KAAK;iBACf,CAAC,CAAC;aACH,CAAC;QACH,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAClB,OAAmB,EACnB,OAAe,EACf,SAAiB,EACjB,OAAgB,EAChB,YAAoB,EAAE;IAEtB,OAAO,oBAAoB,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,GAAG,GAAG;YACX,SAAS;YACT,MAAM;YACN,OAAO;YACP,aAAa;YACb,SAAS;YACT,mBAAmB;YACnB,uBAAuB;YACvB,QAAQ;YACR,MAAM,CAAC,SAAS,CAAC;SACjB,CAAC;QAEF,IAAI,OAAO,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAChC,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAE,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACjE,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;QAE1B,IAAI,GAAG,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;YACxB,MAAM,OAAO,GAAG,CAAC,GAAG,GAAG,EAAE,YAAY,CAAC,CAAC;YACvC,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAE,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7E,IAAI,OAAO,CAAC,QAAQ,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;gBACrD,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YAC9B,CAAC;YACD,OAAO,IAAI,CAAC;QACb,CAAC;QAED,OAAO,MAAM,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;IAC9B,CAAC,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,IAAY;IACtC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAC9B,CAAC,IAAI,EAAE,EAAE,CACR,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QACtB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QACtB,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QACvB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;QACtB,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CACvB,CAAC;IACF,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACxE,CAAC;AASD;;GAEG;AACH,SAAS,gBAAgB,CAAC,IAAiB,EAAE,MAA0B;IACtE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO;YACN,OAAO,EAAE,KAAK;YACd,OAAO,EAAE,oCAAoC,MAAM,CAAC,aAAa,GAAG;YACpE,UAAU,EAAE,CAAC;SACb,CAAC;IACH,CAAC;IAED,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,MAAM,aAAa,GAAa,EAAE,CAAC;IAEnC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACxB,IAAI,UAAU,GAAG,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC;QAEtD,wCAAwC;QACxC,IAAI,UAAU,IAAI,MAAM,CAAC,yBAAyB,IAAI,GAAG,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxF,MAAM,kBAAkB,GAAG,GAAG,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC;YACzE,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBACzB,UAAU,GAAG,KAAK,CAAC;YACpB,CAAC;QACF,CAAC;QAED,IAAI,UAAU,EAAE,CAAC;YAChB,UAAU,EAAE,CAAC;QACd,CAAC;aAAM,CAAC;YACP,MAAM,aAAa,GAAG,GAAG,CAAC,iBAAiB;iBACzC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;iBACzB,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE;gBACX,MAAM,UAAU,GAAG,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC;gBAC7C,MAAM,OAAO,GAAG,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC;gBAC3C,IAAI,IAAI,GAAG,GAAG,EAAE,CAAC,IAAI,aAAa,EAAE,CAAC,YAAY,EAAE,CAAC;gBACpD,IAAI,UAAU;oBAAE,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC1C,IAAI,OAAO;oBAAE,IAAI,IAAI,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;gBACtD,OAAO,GAAG,IAAI,GAAG,CAAC;YACnB,CAAC,CAAC;iBACD,IAAI,CAAC,IAAI,CAAC,CAAC;YACb,aAAa,CAAC,IAAI,CACjB,GAAG,GAAG,CAAC,IAAI,WAAW,GAAG,CAAC,KAAK,WAAW,GAAG,CAAC,KAAK,GAAG,aAAa,CAAC,CAAC,CAAC,iBAAiB,aAAa,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9G,CAAC;QACH,CAAC;IACF,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,UAAU,IAAI,QAAQ,CAAC;IAEvC,MAAM,OAAO,GAAG,OAAO;QACtB,CAAC,CAAC,GAAG,UAAU,IAAI,IAAI,CAAC,MAAM,uBAAuB,QAAQ,GAAG;QAChE,CAAC,CAAC,QAAQ,UAAU,IAAI,IAAI,CAAC,MAAM,uBAAuB,QAAQ,iBAAiB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAE/G,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC;AACzC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAyC;IACzE,IAAI,EAAE,gBAAgB;IAEtB,KAAK,CAAC,KAAK,CAAC,MAAsB,EAAE,EAAE,OAAO,EAA2B;QACvE,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAEhD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,IAAI,EAAE;YACxC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YACpD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC;QACjE,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,EAAE;YAAE,OAAO,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAClE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC;QAE5C,OAAO;YACN,KAAK,EAAE;gBACN,EAAE,EAAE,MAAM,CAAC,EAAE;gBACb,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU;gBAClD,SAAS,EAAE,IAAI,IAAI,EAAE;gBACrB,WAAW,EAAE,IAAI,IAAI,EAAE;gBACvB,QAAQ,EAAE;oBACT,aAAa,EAAE,SAAS,CAAC,aAAa;oBACtC,SAAS,EAAE,SAAS,CAAC,SAAS;oBAC9B,QAAQ,EAAE,IAAI,CAAC,MAAM;oBACrB,UAAU,EAAE,WAAW,CAAC,UAAU;oBAClC,aAAa,EAAE,WAAW,CAAC,OAAO;iBAClC;aACD;YACD,QAAQ,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,EAAE;SACzC,CAAC;IACH,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,GAAW,EAAE,MAAsB;IAClD,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,cAAc,EAA2B;QACpF,MAAM,MAAM,GAAG,cAAc,CAAC;QAC9B,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;QAC9B,CAAC;QAED,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAEhD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,IAAI,EAAE;YACxC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YACpD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC;QACjE,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,EAAE;YAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACzF,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC;QAE5C,OAAO;YACN,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO;YAC/C,QAAQ,EAAE;gBACT,QAAQ,EAAE,IAAI,CAAC,MAAM;gBACrB,UAAU,EAAE,WAAW,CAAC,UAAU;gBAClC,OAAO,EAAE,WAAW,CAAC,OAAO;gBAC5B,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;aACzE;SACD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAAsB,EAAE,MAAqB,EAAE,EAAE,OAAO,EAA2B;QACnG,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAEhD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,KAAK,IAAI,EAAE;YACxC,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YACpD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,gBAAgB,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,CAAC;QACjE,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;QACzF,CAAC;QACD,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC;QAE5C,IAAI,WAAW,CAAC,OAAO,EAAE,CAAC;YACzB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACxB,CAAC;QAED,6DAA6D;QAC7D,IAAI,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC;QACjC,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;QAC1E,KAAK,MAAM,GAAG,IAAI,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAC3C,wBAAwB;YACxB,oEAAoE;YACpE,qDAAqD;YACrD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,CAAC,SAAS,EAAE,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;YAC/G,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;gBACjB,MAAM,IAAI,MAAM,GAAG,CAAC,IAAI,sBAAsB,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBACrF,SAAS;YACV,CAAC;YACD,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;gBACnB,MAAM,UAAU,GAAG,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;gBACpD,IAAI,UAAU,EAAE,CAAC;oBAChB,MAAM,IAAI,MAAM,GAAG,CAAC,IAAI,UAAU,UAAU,EAAE,CAAC;gBAChD,CAAC;YACF,CAAC;QACF,CAAC;QAED,OAAO;YACN,KAAK,EAAE,KAAK;YACZ,MAAM;YACN,UAAU,EAAE,SAAS,CAAC,mBAAmB,IAAI,KAAK;SAClD,CAAC;IACH,CAAC;IAED,cAAc,CAAC,MAAuB;QACrC,OAAO,cAAc,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;CACD,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kubernetes Secret Resource Providers
|
|
3
|
+
*
|
|
4
|
+
* Three providers in one file (they share kubectl plumbing):
|
|
5
|
+
* - `k8s/secret` — Opaque secret from key/value pairs
|
|
6
|
+
* - `k8s/secret-tls` — kubernetes.io/tls secret from cert+key files
|
|
7
|
+
* - `k8s/secret-docker-registry` — kubernetes.io/dockerconfigjson secret
|
|
8
|
+
*
|
|
9
|
+
* Each replaces a slice of the prior bash-script `k8s/secret-setup` provider,
|
|
10
|
+
* which had a single readiness check ("any secret exists in namespace") that
|
|
11
|
+
* could not detect a silently-skipped TLS secret. These typed providers each
|
|
12
|
+
* verify their own secret by name (and by type, where it matters), so a
|
|
13
|
+
* partial failure surfaces at the resource that owns it.
|
|
14
|
+
*/
|
|
15
|
+
import * as z from 'zod/v4';
|
|
16
|
+
import type { ResourceProvider } from '@vibesdotdev/pm/resources/provider';
|
|
17
|
+
/**
|
|
18
|
+
* A Secret manifest built in-process and handed to `kubectl apply -f -` on
|
|
19
|
+
* stdin. Secret values never go on a command line, where every process on the
|
|
20
|
+
* host can read them (pm.md R2); kubectl's own `create --dry-run` generator
|
|
21
|
+
* takes them only as argv, so it is not used for literal values.
|
|
22
|
+
*/
|
|
23
|
+
export declare function buildSecretManifest(name: string, namespace: string, type: 'Opaque' | 'kubernetes.io/dockerconfigjson', stringData: Record<string, string>): string;
|
|
24
|
+
/** The `.dockerconfigjson` payload `kubectl create secret docker-registry` writes. */
|
|
25
|
+
export declare function dockerConfigJson(server: string, username: string, password: string, email: string): string;
|
|
26
|
+
declare const SecretConfigSchema: z.ZodObject<{
|
|
27
|
+
name: z.ZodString;
|
|
28
|
+
namespace: z.ZodString;
|
|
29
|
+
context: z.ZodOptional<z.ZodString>;
|
|
30
|
+
data: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
31
|
+
}, z.core.$strip>;
|
|
32
|
+
type SecretConfig = z.infer<typeof SecretConfigSchema>;
|
|
33
|
+
export declare const k8sSecretProvider: ResourceProvider<SecretConfig>;
|
|
34
|
+
declare const TlsSecretConfigSchema: z.ZodObject<{
|
|
35
|
+
name: z.ZodString;
|
|
36
|
+
namespace: z.ZodString;
|
|
37
|
+
context: z.ZodOptional<z.ZodString>;
|
|
38
|
+
certPath: z.ZodString;
|
|
39
|
+
keyPath: z.ZodString;
|
|
40
|
+
}, z.core.$strip>;
|
|
41
|
+
type TlsSecretConfig = z.infer<typeof TlsSecretConfigSchema>;
|
|
42
|
+
export declare const k8sSecretTlsProvider: ResourceProvider<TlsSecretConfig>;
|
|
43
|
+
declare const DockerRegistryConfigSchema: z.ZodObject<{
|
|
44
|
+
name: z.ZodString;
|
|
45
|
+
namespace: z.ZodString;
|
|
46
|
+
context: z.ZodOptional<z.ZodString>;
|
|
47
|
+
server: z.ZodString;
|
|
48
|
+
username: z.ZodString;
|
|
49
|
+
password: z.ZodString;
|
|
50
|
+
email: z.ZodString;
|
|
51
|
+
}, z.core.$strip>;
|
|
52
|
+
type DockerRegistryConfig = z.infer<typeof DockerRegistryConfigSchema>;
|
|
53
|
+
export declare const k8sSecretDockerRegistryProvider: ResourceProvider<DockerRegistryConfig>;
|
|
54
|
+
export {};
|
|
55
|
+
//# sourceMappingURL=k8s-secret.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"k8s-secret.d.ts","sourceRoot":"","sources":["../src/k8s-secret.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,CAAC,MAAM,QAAQ,CAAC;AAC5B,OAAO,KAAK,EACX,gBAAgB,EAKhB,MAAM,oCAAoC,CAAC;AAoE5C;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAClC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,QAAQ,GAAG,gCAAgC,EACjD,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,MAAM,CAKR;AAED,sFAAsF;AACtF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAG1G;AA4DD,QAAA,MAAM,kBAAkB;;;;;iBAOtB,CAAC;AAEH,KAAK,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AA8BvD,eAAO,MAAM,iBAAiB,EAAE,gBAAgB,CAAC,YAAY,CAuD5D,CAAC;AAMF,QAAA,MAAM,qBAAqB;;;;;;iBAMzB,CAAC;AAEH,KAAK,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AA0C7D,eAAO,MAAM,oBAAoB,EAAE,gBAAgB,CAAC,eAAe,CAuDlE,CAAC;AAMF,QAAA,MAAM,0BAA0B;;;;;;;;iBAQ9B,CAAC;AAEH,KAAK,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAkCvE,eAAO,MAAM,+BAA+B,EAAE,gBAAgB,CAAC,oBAAoB,CAoDlF,CAAC"}
|