mcp-server-kubernetes 1.0.1 → 1.1.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 +5 -10
- package/dist/index.js +30 -0
- package/dist/models/response-schemas.d.ts +132 -0
- package/dist/models/response-schemas.js +21 -0
- package/dist/tools/create_cronjob.d.ts +47 -0
- package/dist/tools/create_cronjob.js +93 -0
- package/dist/tools/describe_cronjob.d.ts +27 -0
- package/dist/tools/describe_cronjob.js +83 -0
- package/dist/tools/get_job_logs.d.ts +40 -0
- package/dist/tools/get_job_logs.js +104 -0
- package/dist/tools/list_cronjobs.d.ts +23 -0
- package/dist/tools/list_cronjobs.js +35 -0
- package/dist/tools/list_jobs.d.ts +29 -0
- package/dist/tools/list_jobs.js +77 -0
- package/dist/tools/scale_deployment.d.ts +30 -0
- package/dist/tools/scale_deployment.js +50 -0
- package/dist/utils/kubernetes-manager.d.ts +2 -0
- package/dist/utils/kubernetes-manager.js +8 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -66,16 +66,10 @@ npx mcp-chat --config "%APPDATA%\Claude\claude_desktop_config.json"
|
|
|
66
66
|
## Features
|
|
67
67
|
|
|
68
68
|
- [x] Connect to a Kubernetes cluster
|
|
69
|
-
- [x] List all pods
|
|
70
|
-
- [x]
|
|
71
|
-
- [x] List all
|
|
72
|
-
- [x]
|
|
73
|
-
- [x] Create a pod
|
|
74
|
-
- [x] Delete a pod
|
|
75
|
-
- [x] Describe a pod
|
|
76
|
-
- [x] List all namespaces
|
|
77
|
-
- [x] Create a namespace
|
|
78
|
-
- [x] Create custom pod & deployment configs
|
|
69
|
+
- [x] List all pods, services, deployments, nodes
|
|
70
|
+
- [x] Create, describe, delete a pod
|
|
71
|
+
- [x] List all namespaces, create a namespace
|
|
72
|
+
- [x] Create custom pod & deployment configs, update deployment replicas
|
|
79
73
|
- [x] Get logs from a pod for debugging (supports pods, deployments, jobs, and label selectors)
|
|
80
74
|
- [x] Support Helm v3 for installing charts
|
|
81
75
|
- Install charts with custom values
|
|
@@ -87,6 +81,7 @@ npx mcp-chat --config "%APPDATA%\Claude\claude_desktop_config.json"
|
|
|
87
81
|
- [x] kubectl explain and kubectl api-resources support
|
|
88
82
|
- [x] Get Kubernetes events from the cluster
|
|
89
83
|
- [x] Port forward to a pod or service
|
|
84
|
+
- [x] Create, list, and decribe cronjobs
|
|
90
85
|
|
|
91
86
|
## Local Development
|
|
92
87
|
|
package/dist/index.js
CHANGED
|
@@ -5,10 +5,15 @@ import { listPods, listPodsSchema } from "./tools/list_pods.js";
|
|
|
5
5
|
import { listNodes, listNodesSchema } from "./tools/list_nodes.js";
|
|
6
6
|
import { listServices, listServicesSchema } from "./tools/list_services.js";
|
|
7
7
|
import { listDeployments, listDeploymentsSchema, } from "./tools/list_deployments.js";
|
|
8
|
+
import { listCronJobs, listCronJobsSchema } from "./tools/list_cronjobs.js";
|
|
9
|
+
import { describeCronJob, describeCronJobSchema } from "./tools/describe_cronjob.js";
|
|
10
|
+
import { listJobs, listJobsSchema } from "./tools/list_jobs.js";
|
|
11
|
+
import { getJobLogs, getJobLogsSchema } from "./tools/get_job_logs.js";
|
|
8
12
|
import { installHelmChart, installHelmChartSchema, upgradeHelmChart, upgradeHelmChartSchema, uninstallHelmChart, uninstallHelmChartSchema, } from "./tools/helm-operations.js";
|
|
9
13
|
import { explainResource, explainResourceSchema, listApiResources, listApiResourcesSchema, } from "./tools/kubectl-operations.js";
|
|
10
14
|
import { createNamespace, createNamespaceSchema, } from "./tools/create_namespace.js";
|
|
11
15
|
import { createPod, createPodSchema } from "./tools/create_pod.js";
|
|
16
|
+
import { createCronJob, createCronJobSchema } from "./tools/create_cronjob.js";
|
|
12
17
|
import { deletePod, deletePodSchema } from "./tools/delete_pod.js";
|
|
13
18
|
import { describePod, describePodSchema } from "./tools/describe_pod.js";
|
|
14
19
|
import { getLogs, getLogsSchema } from "./tools/get_logs.js";
|
|
@@ -24,6 +29,7 @@ import { startSSEServer } from "./utils/sse.js";
|
|
|
24
29
|
import { startPortForward, PortForwardSchema, stopPortForward, StopPortForwardSchema, } from "./tools/port_forward.js";
|
|
25
30
|
import { deleteDeployment } from "./tools/delete_deployment.js";
|
|
26
31
|
import { createDeployment } from "./tools/create_deployment.js";
|
|
32
|
+
import { scaleDeployment, scaleDeploymentSchema } from "./tools/scale_deployment.js";
|
|
27
33
|
import { describeDeployment, describeDeploymentSchema, } from "./tools/describe_deployment.js";
|
|
28
34
|
const k8sManager = new KubernetesManager();
|
|
29
35
|
const server = new Server({
|
|
@@ -38,15 +44,20 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
38
44
|
createDeploymentSchema,
|
|
39
45
|
createNamespaceSchema,
|
|
40
46
|
createPodSchema,
|
|
47
|
+
createCronJobSchema,
|
|
41
48
|
deletePodSchema,
|
|
49
|
+
describeCronJobSchema,
|
|
42
50
|
describePodSchema,
|
|
43
51
|
describeDeploymentSchema,
|
|
44
52
|
explainResourceSchema,
|
|
45
53
|
getEventsSchema,
|
|
54
|
+
getJobLogsSchema,
|
|
46
55
|
getLogsSchema,
|
|
47
56
|
installHelmChartSchema,
|
|
48
57
|
listApiResourcesSchema,
|
|
58
|
+
listCronJobsSchema,
|
|
49
59
|
listDeploymentsSchema,
|
|
60
|
+
listJobsSchema,
|
|
50
61
|
listNamespacesSchema,
|
|
51
62
|
listNodesSchema,
|
|
52
63
|
listPodsSchema,
|
|
@@ -55,6 +66,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
55
66
|
upgradeHelmChartSchema,
|
|
56
67
|
PortForwardSchema,
|
|
57
68
|
StopPortForwardSchema,
|
|
69
|
+
scaleDeploymentSchema,
|
|
58
70
|
],
|
|
59
71
|
};
|
|
60
72
|
});
|
|
@@ -81,6 +93,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
81
93
|
case "create_pod": {
|
|
82
94
|
return await createPod(k8sManager, input);
|
|
83
95
|
}
|
|
96
|
+
case "create_cronjob": {
|
|
97
|
+
return await createCronJob(k8sManager, input);
|
|
98
|
+
}
|
|
84
99
|
case "delete_pod": {
|
|
85
100
|
return await deletePod(k8sManager, input);
|
|
86
101
|
}
|
|
@@ -130,6 +145,18 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
130
145
|
case "list_services": {
|
|
131
146
|
return await listServices(k8sManager, input);
|
|
132
147
|
}
|
|
148
|
+
case "list_cronjobs": {
|
|
149
|
+
return await listCronJobs(k8sManager, input);
|
|
150
|
+
}
|
|
151
|
+
case "describe_cronjob": {
|
|
152
|
+
return await describeCronJob(k8sManager, input);
|
|
153
|
+
}
|
|
154
|
+
case "list_jobs": {
|
|
155
|
+
return await listJobs(k8sManager, input);
|
|
156
|
+
}
|
|
157
|
+
case "get_job_logs": {
|
|
158
|
+
return await getJobLogs(k8sManager, input);
|
|
159
|
+
}
|
|
133
160
|
case "uninstall_helm_chart": {
|
|
134
161
|
return await uninstallHelmChart(input);
|
|
135
162
|
}
|
|
@@ -151,6 +178,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
151
178
|
case "describe_deployment": {
|
|
152
179
|
return await describeDeployment(k8sManager, input);
|
|
153
180
|
}
|
|
181
|
+
case "scale_deployment": {
|
|
182
|
+
return await scaleDeployment(k8sManager, input);
|
|
183
|
+
}
|
|
154
184
|
default:
|
|
155
185
|
throw new McpError(ErrorCode.InvalidRequest, `Unknown tool: ${name}`);
|
|
156
186
|
}
|
|
@@ -285,6 +285,116 @@ export declare const GetEventsResponseSchema: z.ZodObject<{
|
|
|
285
285
|
text: string;
|
|
286
286
|
}[];
|
|
287
287
|
}>;
|
|
288
|
+
export declare const ListCronJobsResponseSchema: z.ZodObject<{
|
|
289
|
+
content: z.ZodArray<z.ZodObject<{
|
|
290
|
+
type: z.ZodLiteral<"text">;
|
|
291
|
+
text: z.ZodString;
|
|
292
|
+
}, "strip", z.ZodTypeAny, {
|
|
293
|
+
type: "text";
|
|
294
|
+
text: string;
|
|
295
|
+
}, {
|
|
296
|
+
type: "text";
|
|
297
|
+
text: string;
|
|
298
|
+
}>, "many">;
|
|
299
|
+
}, "strip", z.ZodTypeAny, {
|
|
300
|
+
content: {
|
|
301
|
+
type: "text";
|
|
302
|
+
text: string;
|
|
303
|
+
}[];
|
|
304
|
+
}, {
|
|
305
|
+
content: {
|
|
306
|
+
type: "text";
|
|
307
|
+
text: string;
|
|
308
|
+
}[];
|
|
309
|
+
}>;
|
|
310
|
+
export declare const CreateCronJobResponseSchema: z.ZodObject<{
|
|
311
|
+
content: z.ZodArray<z.ZodObject<{
|
|
312
|
+
type: z.ZodLiteral<"text">;
|
|
313
|
+
text: z.ZodString;
|
|
314
|
+
}, "strip", z.ZodTypeAny, {
|
|
315
|
+
type: "text";
|
|
316
|
+
text: string;
|
|
317
|
+
}, {
|
|
318
|
+
type: "text";
|
|
319
|
+
text: string;
|
|
320
|
+
}>, "many">;
|
|
321
|
+
}, "strip", z.ZodTypeAny, {
|
|
322
|
+
content: {
|
|
323
|
+
type: "text";
|
|
324
|
+
text: string;
|
|
325
|
+
}[];
|
|
326
|
+
}, {
|
|
327
|
+
content: {
|
|
328
|
+
type: "text";
|
|
329
|
+
text: string;
|
|
330
|
+
}[];
|
|
331
|
+
}>;
|
|
332
|
+
export declare const DescribeCronJobResponseSchema: z.ZodObject<{
|
|
333
|
+
content: z.ZodArray<z.ZodObject<{
|
|
334
|
+
type: z.ZodLiteral<"text">;
|
|
335
|
+
text: z.ZodString;
|
|
336
|
+
}, "strip", z.ZodTypeAny, {
|
|
337
|
+
type: "text";
|
|
338
|
+
text: string;
|
|
339
|
+
}, {
|
|
340
|
+
type: "text";
|
|
341
|
+
text: string;
|
|
342
|
+
}>, "many">;
|
|
343
|
+
}, "strip", z.ZodTypeAny, {
|
|
344
|
+
content: {
|
|
345
|
+
type: "text";
|
|
346
|
+
text: string;
|
|
347
|
+
}[];
|
|
348
|
+
}, {
|
|
349
|
+
content: {
|
|
350
|
+
type: "text";
|
|
351
|
+
text: string;
|
|
352
|
+
}[];
|
|
353
|
+
}>;
|
|
354
|
+
export declare const ListJobsResponseSchema: z.ZodObject<{
|
|
355
|
+
content: z.ZodArray<z.ZodObject<{
|
|
356
|
+
type: z.ZodLiteral<"text">;
|
|
357
|
+
text: z.ZodString;
|
|
358
|
+
}, "strip", z.ZodTypeAny, {
|
|
359
|
+
type: "text";
|
|
360
|
+
text: string;
|
|
361
|
+
}, {
|
|
362
|
+
type: "text";
|
|
363
|
+
text: string;
|
|
364
|
+
}>, "many">;
|
|
365
|
+
}, "strip", z.ZodTypeAny, {
|
|
366
|
+
content: {
|
|
367
|
+
type: "text";
|
|
368
|
+
text: string;
|
|
369
|
+
}[];
|
|
370
|
+
}, {
|
|
371
|
+
content: {
|
|
372
|
+
type: "text";
|
|
373
|
+
text: string;
|
|
374
|
+
}[];
|
|
375
|
+
}>;
|
|
376
|
+
export declare const GetJobLogsResponseSchema: z.ZodObject<{
|
|
377
|
+
content: z.ZodArray<z.ZodObject<{
|
|
378
|
+
type: z.ZodLiteral<"text">;
|
|
379
|
+
text: z.ZodString;
|
|
380
|
+
}, "strip", z.ZodTypeAny, {
|
|
381
|
+
type: "text";
|
|
382
|
+
text: string;
|
|
383
|
+
}, {
|
|
384
|
+
type: "text";
|
|
385
|
+
text: string;
|
|
386
|
+
}>, "many">;
|
|
387
|
+
}, "strip", z.ZodTypeAny, {
|
|
388
|
+
content: {
|
|
389
|
+
type: "text";
|
|
390
|
+
text: string;
|
|
391
|
+
}[];
|
|
392
|
+
}, {
|
|
393
|
+
content: {
|
|
394
|
+
type: "text";
|
|
395
|
+
text: string;
|
|
396
|
+
}[];
|
|
397
|
+
}>;
|
|
288
398
|
export declare const PortForwardResponseSchema: z.ZodObject<{
|
|
289
399
|
content: z.ZodArray<z.ZodObject<{
|
|
290
400
|
success: z.ZodBoolean;
|
|
@@ -307,3 +417,25 @@ export declare const PortForwardResponseSchema: z.ZodObject<{
|
|
|
307
417
|
success: boolean;
|
|
308
418
|
}[];
|
|
309
419
|
}>;
|
|
420
|
+
export declare const ScaleDeploymentResponseSchema: z.ZodObject<{
|
|
421
|
+
content: z.ZodArray<z.ZodObject<{
|
|
422
|
+
success: z.ZodBoolean;
|
|
423
|
+
message: z.ZodString;
|
|
424
|
+
}, "strip", z.ZodTypeAny, {
|
|
425
|
+
message: string;
|
|
426
|
+
success: boolean;
|
|
427
|
+
}, {
|
|
428
|
+
message: string;
|
|
429
|
+
success: boolean;
|
|
430
|
+
}>, "many">;
|
|
431
|
+
}, "strip", z.ZodTypeAny, {
|
|
432
|
+
content: {
|
|
433
|
+
message: string;
|
|
434
|
+
success: boolean;
|
|
435
|
+
}[];
|
|
436
|
+
}, {
|
|
437
|
+
content: {
|
|
438
|
+
message: string;
|
|
439
|
+
success: boolean;
|
|
440
|
+
}[];
|
|
441
|
+
}>;
|
|
@@ -43,9 +43,30 @@ export const GetLogsResponseSchema = z.object({
|
|
|
43
43
|
export const GetEventsResponseSchema = z.object({
|
|
44
44
|
content: z.array(ToolResponseContent),
|
|
45
45
|
});
|
|
46
|
+
export const ListCronJobsResponseSchema = z.object({
|
|
47
|
+
content: z.array(ToolResponseContent),
|
|
48
|
+
});
|
|
49
|
+
export const CreateCronJobResponseSchema = z.object({
|
|
50
|
+
content: z.array(ToolResponseContent),
|
|
51
|
+
});
|
|
52
|
+
export const DescribeCronJobResponseSchema = z.object({
|
|
53
|
+
content: z.array(ToolResponseContent),
|
|
54
|
+
});
|
|
55
|
+
export const ListJobsResponseSchema = z.object({
|
|
56
|
+
content: z.array(ToolResponseContent),
|
|
57
|
+
});
|
|
58
|
+
export const GetJobLogsResponseSchema = z.object({
|
|
59
|
+
content: z.array(ToolResponseContent),
|
|
60
|
+
});
|
|
46
61
|
export const PortForwardResponseSchema = z.object({
|
|
47
62
|
content: z.array(z.object({
|
|
48
63
|
success: z.boolean(),
|
|
49
64
|
message: z.string(),
|
|
50
65
|
})),
|
|
51
66
|
});
|
|
67
|
+
export const ScaleDeploymentResponseSchema = z.object({
|
|
68
|
+
content: z.array(z.object({
|
|
69
|
+
success: z.boolean(),
|
|
70
|
+
message: z.string(),
|
|
71
|
+
})),
|
|
72
|
+
});
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { KubernetesManager } from "../types.js";
|
|
2
|
+
export declare const createCronJobSchema: {
|
|
3
|
+
readonly name: "create_cronjob";
|
|
4
|
+
readonly description: "Create a new Kubernetes CronJob";
|
|
5
|
+
readonly inputSchema: {
|
|
6
|
+
readonly type: "object";
|
|
7
|
+
readonly properties: {
|
|
8
|
+
readonly name: {
|
|
9
|
+
readonly type: "string";
|
|
10
|
+
};
|
|
11
|
+
readonly namespace: {
|
|
12
|
+
readonly type: "string";
|
|
13
|
+
};
|
|
14
|
+
readonly schedule: {
|
|
15
|
+
readonly type: "string";
|
|
16
|
+
};
|
|
17
|
+
readonly image: {
|
|
18
|
+
readonly type: "string";
|
|
19
|
+
};
|
|
20
|
+
readonly command: {
|
|
21
|
+
readonly type: "array";
|
|
22
|
+
readonly items: {
|
|
23
|
+
readonly type: "string";
|
|
24
|
+
};
|
|
25
|
+
readonly optional: true;
|
|
26
|
+
};
|
|
27
|
+
readonly suspend: {
|
|
28
|
+
readonly type: "boolean";
|
|
29
|
+
readonly optional: true;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
readonly required: readonly ["name", "namespace", "schedule", "image"];
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
export declare function createCronJob(k8sManager: KubernetesManager, input: {
|
|
36
|
+
name: string;
|
|
37
|
+
namespace: string;
|
|
38
|
+
schedule: string;
|
|
39
|
+
image: string;
|
|
40
|
+
command?: string[];
|
|
41
|
+
suspend?: boolean;
|
|
42
|
+
}): Promise<{
|
|
43
|
+
content: {
|
|
44
|
+
type: string;
|
|
45
|
+
text: string;
|
|
46
|
+
}[];
|
|
47
|
+
}>;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
export const createCronJobSchema = {
|
|
2
|
+
name: "create_cronjob",
|
|
3
|
+
description: "Create a new Kubernetes CronJob",
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object",
|
|
6
|
+
properties: {
|
|
7
|
+
name: { type: "string" },
|
|
8
|
+
namespace: { type: "string" },
|
|
9
|
+
schedule: { type: "string" },
|
|
10
|
+
image: { type: "string" },
|
|
11
|
+
command: {
|
|
12
|
+
type: "array",
|
|
13
|
+
items: { type: "string" },
|
|
14
|
+
optional: true,
|
|
15
|
+
},
|
|
16
|
+
suspend: {
|
|
17
|
+
type: "boolean",
|
|
18
|
+
optional: true,
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
required: ["name", "namespace", "schedule", "image"],
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
export async function createCronJob(k8sManager, input) {
|
|
25
|
+
try {
|
|
26
|
+
const cronJob = {
|
|
27
|
+
apiVersion: "batch/v1",
|
|
28
|
+
kind: "CronJob",
|
|
29
|
+
metadata: {
|
|
30
|
+
name: input.name,
|
|
31
|
+
namespace: input.namespace,
|
|
32
|
+
labels: {
|
|
33
|
+
"mcp-managed": "true",
|
|
34
|
+
app: input.name,
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
spec: {
|
|
38
|
+
schedule: input.schedule,
|
|
39
|
+
suspend: input.suspend || false,
|
|
40
|
+
jobTemplate: {
|
|
41
|
+
spec: {
|
|
42
|
+
template: {
|
|
43
|
+
spec: {
|
|
44
|
+
containers: [
|
|
45
|
+
{
|
|
46
|
+
name: input.name,
|
|
47
|
+
image: input.image,
|
|
48
|
+
...(input.command && {
|
|
49
|
+
command: input.command,
|
|
50
|
+
}),
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
restartPolicy: "OnFailure",
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
const response = await k8sManager
|
|
61
|
+
.getBatchApi()
|
|
62
|
+
.createNamespacedCronJob(input.namespace, cronJob)
|
|
63
|
+
.catch((error) => {
|
|
64
|
+
console.error("CronJob creation error:", {
|
|
65
|
+
status: error.response?.statusCode,
|
|
66
|
+
message: error.response?.body?.message || error.message,
|
|
67
|
+
details: error.response?.body,
|
|
68
|
+
});
|
|
69
|
+
throw error;
|
|
70
|
+
});
|
|
71
|
+
k8sManager.trackResource("CronJob", input.name, input.namespace);
|
|
72
|
+
return {
|
|
73
|
+
content: [
|
|
74
|
+
{
|
|
75
|
+
type: "text",
|
|
76
|
+
text: JSON.stringify({
|
|
77
|
+
cronJobName: response.body.metadata.name,
|
|
78
|
+
schedule: response.body.spec.schedule,
|
|
79
|
+
status: "created",
|
|
80
|
+
}, null, 2),
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
console.error("CronJob creation error:", {
|
|
87
|
+
status: error.response?.statusCode,
|
|
88
|
+
message: error.response?.body?.message || error.message,
|
|
89
|
+
details: error.response?.body,
|
|
90
|
+
});
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { KubernetesManager } from "../types.js";
|
|
2
|
+
export declare const describeCronJobSchema: {
|
|
3
|
+
readonly name: "describe_cronjob";
|
|
4
|
+
readonly description: "Get detailed information about a Kubernetes CronJob including recent job history";
|
|
5
|
+
readonly inputSchema: {
|
|
6
|
+
readonly type: "object";
|
|
7
|
+
readonly properties: {
|
|
8
|
+
readonly name: {
|
|
9
|
+
readonly type: "string";
|
|
10
|
+
};
|
|
11
|
+
readonly namespace: {
|
|
12
|
+
readonly type: "string";
|
|
13
|
+
readonly default: "default";
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
readonly required: readonly ["name", "namespace"];
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
export declare function describeCronJob(k8sManager: KubernetesManager, input: {
|
|
20
|
+
name: string;
|
|
21
|
+
namespace: string;
|
|
22
|
+
}): Promise<{
|
|
23
|
+
content: {
|
|
24
|
+
type: string;
|
|
25
|
+
text: string;
|
|
26
|
+
}[];
|
|
27
|
+
}>;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
export const describeCronJobSchema = {
|
|
2
|
+
name: "describe_cronjob",
|
|
3
|
+
description: "Get detailed information about a Kubernetes CronJob including recent job history",
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object",
|
|
6
|
+
properties: {
|
|
7
|
+
name: { type: "string" },
|
|
8
|
+
namespace: { type: "string", default: "default" },
|
|
9
|
+
},
|
|
10
|
+
required: ["name", "namespace"],
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
export async function describeCronJob(k8sManager, input) {
|
|
14
|
+
try {
|
|
15
|
+
// Get the CronJob details
|
|
16
|
+
const batchV1Api = k8sManager.getBatchApi();
|
|
17
|
+
const cronJobResponse = await batchV1Api.readNamespacedCronJob(input.name, input.namespace);
|
|
18
|
+
const cronJob = cronJobResponse.body;
|
|
19
|
+
// Get recent Jobs associated with this CronJob
|
|
20
|
+
const labelSelector = `app=${input.name},cronjob-name=${input.name}`;
|
|
21
|
+
const jobsResponse = await batchV1Api.listNamespacedJob(input.namespace, undefined, // pretty
|
|
22
|
+
undefined, // allowWatchBookmarks
|
|
23
|
+
undefined, // _continue
|
|
24
|
+
undefined, // fieldSelector
|
|
25
|
+
labelSelector);
|
|
26
|
+
// Sort jobs by creation time (newest first)
|
|
27
|
+
const jobs = jobsResponse.body.items.sort((a, b) => {
|
|
28
|
+
const aTime = a.metadata?.creationTimestamp
|
|
29
|
+
? new Date(a.metadata.creationTimestamp)
|
|
30
|
+
: new Date(0);
|
|
31
|
+
const bTime = b.metadata?.creationTimestamp
|
|
32
|
+
? new Date(b.metadata.creationTimestamp)
|
|
33
|
+
: new Date(0);
|
|
34
|
+
return bTime.getTime() - aTime.getTime();
|
|
35
|
+
});
|
|
36
|
+
// Limit to 5 most recent jobs
|
|
37
|
+
const recentJobs = jobs.slice(0, 5).map((job) => ({
|
|
38
|
+
name: job.metadata?.name || "",
|
|
39
|
+
creationTime: job.metadata?.creationTimestamp || "",
|
|
40
|
+
status: {
|
|
41
|
+
active: job.status?.active || 0,
|
|
42
|
+
succeeded: job.status?.succeeded || 0,
|
|
43
|
+
failed: job.status?.failed || 0,
|
|
44
|
+
completionTime: job.status?.completionTime || null,
|
|
45
|
+
},
|
|
46
|
+
}));
|
|
47
|
+
// Format the response with CronJob details and recent jobs
|
|
48
|
+
const cronJobDetails = {
|
|
49
|
+
name: cronJob.metadata?.name || "",
|
|
50
|
+
namespace: cronJob.metadata?.namespace || "",
|
|
51
|
+
schedule: cronJob.spec?.schedule || "",
|
|
52
|
+
suspend: cronJob.spec?.suspend || false,
|
|
53
|
+
concurrencyPolicy: cronJob.spec?.concurrencyPolicy || "Allow",
|
|
54
|
+
lastScheduleTime: cronJob.status?.lastScheduleTime || null,
|
|
55
|
+
lastSuccessfulTime: cronJob.status?.lastSuccessfulTime || null,
|
|
56
|
+
creationTimestamp: cronJob.metadata?.creationTimestamp || "",
|
|
57
|
+
recentJobs: recentJobs,
|
|
58
|
+
jobTemplate: {
|
|
59
|
+
image: cronJob.spec?.jobTemplate?.spec?.template?.spec?.containers?.[0]
|
|
60
|
+
?.image || "",
|
|
61
|
+
command: cronJob.spec?.jobTemplate?.spec?.template?.spec?.containers?.[0]
|
|
62
|
+
?.command || [],
|
|
63
|
+
restartPolicy: cronJob.spec?.jobTemplate?.spec?.template?.spec?.restartPolicy || "",
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
return {
|
|
67
|
+
content: [
|
|
68
|
+
{
|
|
69
|
+
type: "text",
|
|
70
|
+
text: JSON.stringify(cronJobDetails, null, 2),
|
|
71
|
+
},
|
|
72
|
+
],
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
console.error("Error describing CronJob:", {
|
|
77
|
+
status: error.response?.statusCode,
|
|
78
|
+
message: error.response?.body?.message || error.message,
|
|
79
|
+
details: error.response?.body,
|
|
80
|
+
});
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { KubernetesManager } from "../types.js";
|
|
2
|
+
export declare const getJobLogsSchema: {
|
|
3
|
+
readonly name: "get_job_logs";
|
|
4
|
+
readonly description: "Get logs from Pods created by a specific Job";
|
|
5
|
+
readonly inputSchema: {
|
|
6
|
+
readonly type: "object";
|
|
7
|
+
readonly properties: {
|
|
8
|
+
readonly name: {
|
|
9
|
+
readonly type: "string";
|
|
10
|
+
readonly description: "Name of the Job to get logs from";
|
|
11
|
+
};
|
|
12
|
+
readonly namespace: {
|
|
13
|
+
readonly type: "string";
|
|
14
|
+
readonly default: "default";
|
|
15
|
+
};
|
|
16
|
+
readonly tail: {
|
|
17
|
+
readonly type: "number";
|
|
18
|
+
readonly description: "Number of lines to return from the end of the logs";
|
|
19
|
+
readonly optional: true;
|
|
20
|
+
};
|
|
21
|
+
readonly timestamps: {
|
|
22
|
+
readonly type: "boolean";
|
|
23
|
+
readonly description: "Include timestamps in the logs";
|
|
24
|
+
readonly optional: true;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
readonly required: readonly ["name", "namespace"];
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export declare function getJobLogs(k8sManager: KubernetesManager, input: {
|
|
31
|
+
name: string;
|
|
32
|
+
namespace: string;
|
|
33
|
+
tail?: number;
|
|
34
|
+
timestamps?: boolean;
|
|
35
|
+
}): Promise<{
|
|
36
|
+
content: {
|
|
37
|
+
type: string;
|
|
38
|
+
text: string;
|
|
39
|
+
}[];
|
|
40
|
+
}>;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
export const getJobLogsSchema = {
|
|
2
|
+
name: "get_job_logs",
|
|
3
|
+
description: "Get logs from Pods created by a specific Job",
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object",
|
|
6
|
+
properties: {
|
|
7
|
+
name: {
|
|
8
|
+
type: "string",
|
|
9
|
+
description: "Name of the Job to get logs from",
|
|
10
|
+
},
|
|
11
|
+
namespace: {
|
|
12
|
+
type: "string",
|
|
13
|
+
default: "default",
|
|
14
|
+
},
|
|
15
|
+
tail: {
|
|
16
|
+
type: "number",
|
|
17
|
+
description: "Number of lines to return from the end of the logs",
|
|
18
|
+
optional: true,
|
|
19
|
+
},
|
|
20
|
+
timestamps: {
|
|
21
|
+
type: "boolean",
|
|
22
|
+
description: "Include timestamps in the logs",
|
|
23
|
+
optional: true,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
required: ["name", "namespace"],
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
export async function getJobLogs(k8sManager, input) {
|
|
30
|
+
try {
|
|
31
|
+
const coreApi = k8sManager.getCoreApi();
|
|
32
|
+
// First, get the job to check if it exists
|
|
33
|
+
const batchApi = k8sManager.getBatchApi();
|
|
34
|
+
await batchApi.readNamespacedJob(input.name, input.namespace);
|
|
35
|
+
// Find pods associated with this job
|
|
36
|
+
const labelSelector = `job-name=${input.name}`;
|
|
37
|
+
const { body: podList } = await coreApi.listNamespacedPod(input.namespace, undefined, // pretty
|
|
38
|
+
undefined, // allowWatchBookmarks
|
|
39
|
+
undefined, // _continue
|
|
40
|
+
undefined, // fieldSelector
|
|
41
|
+
labelSelector // labelSelector
|
|
42
|
+
);
|
|
43
|
+
if (podList.items.length === 0) {
|
|
44
|
+
return {
|
|
45
|
+
content: [
|
|
46
|
+
{
|
|
47
|
+
type: "text",
|
|
48
|
+
text: JSON.stringify({
|
|
49
|
+
message: `No pods found for job ${input.name}`,
|
|
50
|
+
}, null, 2),
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
// Get logs from all pods belonging to this job
|
|
56
|
+
const podLogs = await Promise.all(podList.items.map(async (pod) => {
|
|
57
|
+
const podName = pod.metadata?.name || "";
|
|
58
|
+
try {
|
|
59
|
+
const logResponse = await coreApi.readNamespacedPodLog(podName, input.namespace, undefined, // container
|
|
60
|
+
undefined, // follow
|
|
61
|
+
input.timestamps || false, // timestamps
|
|
62
|
+
undefined, // sinceSeconds
|
|
63
|
+
undefined, // sinceTime
|
|
64
|
+
(input.tail != undefined ? true : true) || undefined, // tailLines
|
|
65
|
+
undefined // pretty
|
|
66
|
+
);
|
|
67
|
+
return {
|
|
68
|
+
podName,
|
|
69
|
+
logs: logResponse.body,
|
|
70
|
+
status: pod.status?.phase || "Unknown",
|
|
71
|
+
startTime: pod.status?.startTime || null,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
return {
|
|
76
|
+
podName,
|
|
77
|
+
logs: `Error retrieving logs: ${error.message || "Unknown error"}`,
|
|
78
|
+
status: pod.status?.phase || "Unknown",
|
|
79
|
+
startTime: pod.status?.startTime || null,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}));
|
|
83
|
+
return {
|
|
84
|
+
content: [
|
|
85
|
+
{
|
|
86
|
+
type: "text",
|
|
87
|
+
text: JSON.stringify({
|
|
88
|
+
job: input.name,
|
|
89
|
+
namespace: input.namespace,
|
|
90
|
+
pods: podLogs,
|
|
91
|
+
}, null, 2),
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
console.error("Error getting Job logs:", {
|
|
98
|
+
status: error.response?.statusCode,
|
|
99
|
+
message: error.response?.body?.message || error.message,
|
|
100
|
+
details: error.response?.body,
|
|
101
|
+
});
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { KubernetesManager } from "../types.js";
|
|
2
|
+
export declare const listCronJobsSchema: {
|
|
3
|
+
readonly name: "list_cronjobs";
|
|
4
|
+
readonly description: "List CronJobs in a namespace";
|
|
5
|
+
readonly inputSchema: {
|
|
6
|
+
readonly type: "object";
|
|
7
|
+
readonly properties: {
|
|
8
|
+
readonly namespace: {
|
|
9
|
+
readonly type: "string";
|
|
10
|
+
readonly default: "default";
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
readonly required: readonly ["namespace"];
|
|
14
|
+
};
|
|
15
|
+
};
|
|
16
|
+
export declare function listCronJobs(k8sManager: KubernetesManager, input: {
|
|
17
|
+
namespace?: string;
|
|
18
|
+
}): Promise<{
|
|
19
|
+
content: {
|
|
20
|
+
type: string;
|
|
21
|
+
text: string;
|
|
22
|
+
}[];
|
|
23
|
+
}>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export const listCronJobsSchema = {
|
|
2
|
+
name: "list_cronjobs",
|
|
3
|
+
description: "List CronJobs in a namespace",
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object",
|
|
6
|
+
properties: {
|
|
7
|
+
namespace: { type: "string", default: "default" },
|
|
8
|
+
},
|
|
9
|
+
required: ["namespace"],
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
export async function listCronJobs(k8sManager, input) {
|
|
13
|
+
const namespace = input.namespace || "default";
|
|
14
|
+
// Get BatchV1Api from KubernetesManager
|
|
15
|
+
const batchV1Api = k8sManager.getBatchApi();
|
|
16
|
+
// List cronjobs in the specified namespace
|
|
17
|
+
const { body } = await batchV1Api.listNamespacedCronJob(namespace);
|
|
18
|
+
// Transform cronjob data to a more readable format
|
|
19
|
+
const cronjobs = body.items.map((cronjob) => ({
|
|
20
|
+
name: cronjob.metadata?.name || "",
|
|
21
|
+
namespace: cronjob.metadata?.namespace || "",
|
|
22
|
+
schedule: cronjob.spec?.schedule || "",
|
|
23
|
+
suspend: cronjob.spec?.suspend || false,
|
|
24
|
+
lastScheduleTime: cronjob.status?.lastScheduleTime || null,
|
|
25
|
+
createdAt: cronjob.metadata?.creationTimestamp,
|
|
26
|
+
}));
|
|
27
|
+
return {
|
|
28
|
+
content: [
|
|
29
|
+
{
|
|
30
|
+
type: "text",
|
|
31
|
+
text: JSON.stringify({ cronjobs }, null, 2),
|
|
32
|
+
},
|
|
33
|
+
],
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { KubernetesManager } from "../types.js";
|
|
2
|
+
export declare const listJobsSchema: {
|
|
3
|
+
readonly name: "list_jobs";
|
|
4
|
+
readonly description: "List Jobs in a namespace, optionally filtered by a CronJob parent";
|
|
5
|
+
readonly inputSchema: {
|
|
6
|
+
readonly type: "object";
|
|
7
|
+
readonly properties: {
|
|
8
|
+
readonly namespace: {
|
|
9
|
+
readonly type: "string";
|
|
10
|
+
readonly default: "default";
|
|
11
|
+
};
|
|
12
|
+
readonly cronJobName: {
|
|
13
|
+
readonly type: "string";
|
|
14
|
+
readonly description: "Optional: Filter jobs created by a specific CronJob";
|
|
15
|
+
readonly optional: true;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
readonly required: readonly ["namespace"];
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
export declare function listJobs(k8sManager: KubernetesManager, input: {
|
|
22
|
+
namespace: string;
|
|
23
|
+
cronJobName?: string;
|
|
24
|
+
}): Promise<{
|
|
25
|
+
content: {
|
|
26
|
+
type: string;
|
|
27
|
+
text: string;
|
|
28
|
+
}[];
|
|
29
|
+
}>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
export const listJobsSchema = {
|
|
2
|
+
name: "list_jobs",
|
|
3
|
+
description: "List Jobs in a namespace, optionally filtered by a CronJob parent",
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object",
|
|
6
|
+
properties: {
|
|
7
|
+
namespace: { type: "string", default: "default" },
|
|
8
|
+
cronJobName: {
|
|
9
|
+
type: "string",
|
|
10
|
+
description: "Optional: Filter jobs created by a specific CronJob",
|
|
11
|
+
optional: true,
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
required: ["namespace"],
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
export async function listJobs(k8sManager, input) {
|
|
18
|
+
try {
|
|
19
|
+
const namespace = input.namespace;
|
|
20
|
+
const batchV1Api = k8sManager.getBatchApi();
|
|
21
|
+
// Set up label selector if cronJobName is provided
|
|
22
|
+
let labelSelector;
|
|
23
|
+
if (input.cronJobName) {
|
|
24
|
+
labelSelector = `cronjob-name=${input.cronJobName}`;
|
|
25
|
+
}
|
|
26
|
+
// Get jobs with optional filtering
|
|
27
|
+
const { body } = await batchV1Api.listNamespacedJob(namespace, undefined, // pretty
|
|
28
|
+
undefined, // allowWatchBookmarks
|
|
29
|
+
undefined, // _continue
|
|
30
|
+
undefined, // fieldSelector
|
|
31
|
+
labelSelector // labelSelector
|
|
32
|
+
);
|
|
33
|
+
// Sort jobs by creation time (newest first)
|
|
34
|
+
const jobs = body.items.sort((a, b) => {
|
|
35
|
+
const aTime = a.metadata?.creationTimestamp
|
|
36
|
+
? new Date(a.metadata.creationTimestamp)
|
|
37
|
+
: new Date(0);
|
|
38
|
+
const bTime = b.metadata?.creationTimestamp
|
|
39
|
+
? new Date(b.metadata.creationTimestamp)
|
|
40
|
+
: new Date(0);
|
|
41
|
+
return bTime.getTime() - aTime.getTime();
|
|
42
|
+
});
|
|
43
|
+
// Transform job data to a more readable format
|
|
44
|
+
const formattedJobs = jobs.map((job) => ({
|
|
45
|
+
name: job.metadata?.name || "",
|
|
46
|
+
namespace: job.metadata?.namespace || "",
|
|
47
|
+
creationTime: job.metadata?.creationTimestamp || "",
|
|
48
|
+
labels: job.metadata?.labels || {},
|
|
49
|
+
completions: job.spec?.completions || 1,
|
|
50
|
+
parallelism: job.spec?.parallelism || 1,
|
|
51
|
+
status: {
|
|
52
|
+
active: job.status?.active || 0,
|
|
53
|
+
succeeded: job.status?.succeeded || 0,
|
|
54
|
+
failed: job.status?.failed || 0,
|
|
55
|
+
completionTime: job.status?.completionTime || null,
|
|
56
|
+
startTime: job.status?.startTime || null,
|
|
57
|
+
conditions: job.status?.conditions || [],
|
|
58
|
+
},
|
|
59
|
+
}));
|
|
60
|
+
return {
|
|
61
|
+
content: [
|
|
62
|
+
{
|
|
63
|
+
type: "text",
|
|
64
|
+
text: JSON.stringify({ jobs: formattedJobs }, null, 2),
|
|
65
|
+
},
|
|
66
|
+
],
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
console.error("Error listing Jobs:", {
|
|
71
|
+
status: error.response?.statusCode,
|
|
72
|
+
message: error.response?.body?.message || error.message,
|
|
73
|
+
details: error.response?.body,
|
|
74
|
+
});
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { KubernetesManager } from "../types.js";
|
|
2
|
+
export declare const scaleDeploymentSchema: {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
inputSchema: {
|
|
6
|
+
type: string;
|
|
7
|
+
properties: {
|
|
8
|
+
name: {
|
|
9
|
+
type: string;
|
|
10
|
+
};
|
|
11
|
+
namespace: {
|
|
12
|
+
type: string;
|
|
13
|
+
};
|
|
14
|
+
replicas: {
|
|
15
|
+
type: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
required: string[];
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
export declare function scaleDeployment(k8sManager: KubernetesManager, input: {
|
|
22
|
+
name: string;
|
|
23
|
+
namespace: string;
|
|
24
|
+
replicas: number;
|
|
25
|
+
}): Promise<{
|
|
26
|
+
content: {
|
|
27
|
+
success: boolean;
|
|
28
|
+
message: string;
|
|
29
|
+
}[];
|
|
30
|
+
}>;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export const scaleDeploymentSchema = {
|
|
2
|
+
name: "scale_deployment",
|
|
3
|
+
description: "Scale a Kubernetes deployment",
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object",
|
|
6
|
+
properties: {
|
|
7
|
+
name: { type: "string" },
|
|
8
|
+
namespace: { type: "string" },
|
|
9
|
+
replicas: { type: "number" }
|
|
10
|
+
},
|
|
11
|
+
required: ["name", "namespace", "replicas"]
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
export async function scaleDeployment(k8sManager, input) {
|
|
15
|
+
try {
|
|
16
|
+
const scale = k8sManager.getAppsApi().readNamespacedDeploymentScale(input.name, input.namespace);
|
|
17
|
+
(await scale).body.spec.replicas = input.replicas;
|
|
18
|
+
const result = await k8sManager.getAppsApi().replaceNamespacedDeploymentScale(input.name, input.namespace, (await scale).body);
|
|
19
|
+
if (result.response?.statusCode !== undefined && result.response.statusCode >= 200 && result.response.statusCode < 300) {
|
|
20
|
+
return {
|
|
21
|
+
content: [
|
|
22
|
+
{
|
|
23
|
+
success: true,
|
|
24
|
+
message: `Scaled deployment ${input.name} to ${input.replicas} replicas`
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
return {
|
|
31
|
+
content: [
|
|
32
|
+
{
|
|
33
|
+
success: false,
|
|
34
|
+
message: `Failed to scale deployment ${input.name} to ${input.replicas} replicas`
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
return {
|
|
42
|
+
content: [
|
|
43
|
+
{
|
|
44
|
+
success: false,
|
|
45
|
+
message: `Failed to scale deployment ${error.message}`
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -7,6 +7,7 @@ export declare class KubernetesManager {
|
|
|
7
7
|
private kc;
|
|
8
8
|
private k8sApi;
|
|
9
9
|
private k8sAppsApi;
|
|
10
|
+
private k8sBatchApi;
|
|
10
11
|
constructor();
|
|
11
12
|
cleanup(): Promise<void>;
|
|
12
13
|
trackResource(kind: string, name: string, namespace: string): void;
|
|
@@ -18,4 +19,5 @@ export declare class KubernetesManager {
|
|
|
18
19
|
getKubeConfig(): k8s.KubeConfig;
|
|
19
20
|
getCoreApi(): k8s.CoreV1Api;
|
|
20
21
|
getAppsApi(): k8s.AppsV1Api;
|
|
22
|
+
getBatchApi(): k8s.BatchV1Api;
|
|
21
23
|
}
|
|
@@ -6,11 +6,13 @@ export class KubernetesManager {
|
|
|
6
6
|
kc;
|
|
7
7
|
k8sApi;
|
|
8
8
|
k8sAppsApi;
|
|
9
|
+
k8sBatchApi;
|
|
9
10
|
constructor() {
|
|
10
11
|
this.kc = new k8s.KubeConfig();
|
|
11
12
|
this.kc.loadFromDefault();
|
|
12
13
|
this.k8sApi = this.kc.makeApiClient(k8s.CoreV1Api);
|
|
13
14
|
this.k8sAppsApi = this.kc.makeApiClient(k8s.AppsV1Api);
|
|
15
|
+
this.k8sBatchApi = this.kc.makeApiClient(k8s.BatchV1Api);
|
|
14
16
|
}
|
|
15
17
|
async cleanup() {
|
|
16
18
|
// Stop watches
|
|
@@ -41,6 +43,9 @@ export class KubernetesManager {
|
|
|
41
43
|
case "service":
|
|
42
44
|
await this.k8sApi.deleteNamespacedService(name, namespace);
|
|
43
45
|
break;
|
|
46
|
+
case "cronjob":
|
|
47
|
+
await this.k8sBatchApi.deleteNamespacedCronJob(name, namespace);
|
|
48
|
+
break;
|
|
44
49
|
}
|
|
45
50
|
this.resources = this.resources.filter((r) => !(r.kind === kind && r.name === name && r.namespace === namespace));
|
|
46
51
|
}
|
|
@@ -65,4 +70,7 @@ export class KubernetesManager {
|
|
|
65
70
|
getAppsApi() {
|
|
66
71
|
return this.k8sAppsApi;
|
|
67
72
|
}
|
|
73
|
+
getBatchApi() {
|
|
74
|
+
return this.k8sBatchApi;
|
|
75
|
+
}
|
|
68
76
|
}
|