@nexusgpu/repterm-plugin-kubectl 0.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 +277 -0
- package/dist/index.d.ts +314 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +544 -0
- package/dist/matchers.d.ts +113 -0
- package/dist/matchers.d.ts.map +1 -0
- package/dist/matchers.js +527 -0
- package/dist/plugin-kubectl/examples/00-simple-demo.d.ts +10 -0
- package/dist/plugin-kubectl/examples/00-simple-demo.d.ts.map +1 -0
- package/dist/plugin-kubectl/examples/00-simple-demo.js +51 -0
- package/dist/plugin-kubectl/examples/01-basic-kubectl.d.ts +13 -0
- package/dist/plugin-kubectl/examples/01-basic-kubectl.d.ts.map +1 -0
- package/dist/plugin-kubectl/examples/01-basic-kubectl.js +86 -0
- package/dist/plugin-kubectl/examples/02-debugging.d.ts +13 -0
- package/dist/plugin-kubectl/examples/02-debugging.d.ts.map +1 -0
- package/dist/plugin-kubectl/examples/02-debugging.js +80 -0
- package/dist/plugin-kubectl/examples/03-resource-management.d.ts +13 -0
- package/dist/plugin-kubectl/examples/03-resource-management.d.ts.map +1 -0
- package/dist/plugin-kubectl/examples/03-resource-management.js +134 -0
- package/dist/plugin-kubectl/examples/04-rollout.d.ts +13 -0
- package/dist/plugin-kubectl/examples/04-rollout.d.ts.map +1 -0
- package/dist/plugin-kubectl/examples/04-rollout.js +122 -0
- package/dist/plugin-kubectl/examples/05-matchers.d.ts +15 -0
- package/dist/plugin-kubectl/examples/05-matchers.d.ts.map +1 -0
- package/dist/plugin-kubectl/examples/05-matchers.js +138 -0
- package/dist/plugin-kubectl/examples/06-advanced.d.ts +14 -0
- package/dist/plugin-kubectl/examples/06-advanced.d.ts.map +1 -0
- package/dist/plugin-kubectl/examples/06-advanced.js +140 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/00-prerequisites.d.ts +14 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/00-prerequisites.d.ts.map +1 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/00-prerequisites.js +66 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/01-workload-allocation.d.ts +14 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/01-workload-allocation.d.ts.map +1 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/01-workload-allocation.js +145 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/02-annotation-mode.d.ts +13 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/02-annotation-mode.d.ts.map +1 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/02-annotation-mode.js +123 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/03-insufficient.d.ts +17 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/03-insufficient.d.ts.map +1 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/03-insufficient.js +96 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/04-release.d.ts +13 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/04-release.d.ts.map +1 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/04-release.js +117 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/05-multi-workload-shared-gpu.d.ts +14 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/05-multi-workload-shared-gpu.d.ts.map +1 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/05-multi-workload-shared-gpu.js +145 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/06-workload-resource-resize.d.ts +14 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/06-workload-resource-resize.d.ts.map +1 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/06-workload-resource-resize.js +235 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/07-workload-worker-pod-generation.d.ts +15 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/07-workload-worker-pod-generation.d.ts.map +1 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/07-workload-worker-pod-generation.js +146 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/08-workload-replicas-scale.d.ts +13 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/08-workload-replicas-scale.d.ts.map +1 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/08-workload-replicas-scale.js +141 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/09-gpu-remote-invocation.d.ts +15 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/09-gpu-remote-invocation.d.ts.map +1 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/09-gpu-remote-invocation.js +256 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/_config.d.ts +71 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/_config.d.ts.map +1 -0
- package/dist/plugin-kubectl/examples/tensor-fusion/_config.js +159 -0
- package/dist/plugin-kubectl/src/index.d.ts +314 -0
- package/dist/plugin-kubectl/src/index.d.ts.map +1 -0
- package/dist/plugin-kubectl/src/index.js +545 -0
- package/dist/plugin-kubectl/src/matchers.d.ts +113 -0
- package/dist/plugin-kubectl/src/matchers.d.ts.map +1 -0
- package/dist/plugin-kubectl/src/matchers.js +527 -0
- package/dist/plugin-kubectl/src/result.d.ts +80 -0
- package/dist/plugin-kubectl/src/result.d.ts.map +1 -0
- package/dist/plugin-kubectl/src/result.js +134 -0
- package/dist/repterm/src/api/describe.d.ts +18 -0
- package/dist/repterm/src/api/describe.d.ts.map +1 -0
- package/dist/repterm/src/api/describe.js +32 -0
- package/dist/repterm/src/api/expect.d.ts +43 -0
- package/dist/repterm/src/api/expect.d.ts.map +1 -0
- package/dist/repterm/src/api/expect.js +166 -0
- package/dist/repterm/src/api/hooks.d.ts +178 -0
- package/dist/repterm/src/api/hooks.d.ts.map +1 -0
- package/dist/repterm/src/api/hooks.js +230 -0
- package/dist/repterm/src/api/steps.d.ts +45 -0
- package/dist/repterm/src/api/steps.d.ts.map +1 -0
- package/dist/repterm/src/api/steps.js +105 -0
- package/dist/repterm/src/api/test.d.ts +101 -0
- package/dist/repterm/src/api/test.d.ts.map +1 -0
- package/dist/repterm/src/api/test.js +206 -0
- package/dist/repterm/src/index.d.ts +15 -0
- package/dist/repterm/src/index.d.ts.map +1 -0
- package/dist/repterm/src/index.js +23 -0
- package/dist/repterm/src/plugin/index.d.ts +47 -0
- package/dist/repterm/src/plugin/index.d.ts.map +1 -0
- package/dist/repterm/src/plugin/index.js +85 -0
- package/dist/repterm/src/plugin/withPlugins.d.ts +71 -0
- package/dist/repterm/src/plugin/withPlugins.d.ts.map +1 -0
- package/dist/repterm/src/plugin/withPlugins.js +100 -0
- package/dist/repterm/src/runner/models.d.ts +261 -0
- package/dist/repterm/src/runner/models.d.ts.map +1 -0
- package/dist/repterm/src/runner/models.js +4 -0
- package/dist/result.d.ts +80 -0
- package/dist/result.d.ts.map +1 -0
- package/dist/result.js +134 -0
- package/package.json +38 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 示例 2: 日志与调试
|
|
3
|
+
*
|
|
4
|
+
* 演示 kubectl 插件的调试 API:logs, exec, describe
|
|
5
|
+
*
|
|
6
|
+
* 运行方式:
|
|
7
|
+
* bun run repterm packages/plugin-kubectl/examples/02-debugging.ts
|
|
8
|
+
*
|
|
9
|
+
* 前置条件:
|
|
10
|
+
* - 已配置 kubectl 并连接到 Kubernetes 集群
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=02-debugging.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"02-debugging.d.ts","sourceRoot":"","sources":["../../../examples/02-debugging.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 示例 2: 日志与调试
|
|
3
|
+
*
|
|
4
|
+
* 演示 kubectl 插件的调试 API:logs, exec, describe
|
|
5
|
+
*
|
|
6
|
+
* 运行方式:
|
|
7
|
+
* bun run repterm packages/plugin-kubectl/examples/02-debugging.ts
|
|
8
|
+
*
|
|
9
|
+
* 前置条件:
|
|
10
|
+
* - 已配置 kubectl 并连接到 Kubernetes 集群
|
|
11
|
+
*/
|
|
12
|
+
import { describe, defineConfig, createTestWithPlugins, } from '../../repterm/src/index.js';
|
|
13
|
+
import { kubectlPlugin } from '../src/index.js';
|
|
14
|
+
// 配置插件
|
|
15
|
+
const config = defineConfig({
|
|
16
|
+
plugins: [kubectlPlugin({ namespace: 'default' })],
|
|
17
|
+
});
|
|
18
|
+
const test = createTestWithPlugins(config);
|
|
19
|
+
// 测试用 Pod
|
|
20
|
+
const debugPodYaml = `
|
|
21
|
+
apiVersion: v1
|
|
22
|
+
kind: Pod
|
|
23
|
+
metadata:
|
|
24
|
+
name: debug-pod
|
|
25
|
+
labels:
|
|
26
|
+
app: debug
|
|
27
|
+
spec:
|
|
28
|
+
containers:
|
|
29
|
+
- name: main
|
|
30
|
+
image: busybox
|
|
31
|
+
command: ['sh', '-c', 'echo "Container started"; while true; do echo "heartbeat $(date)"; sleep 5; done']
|
|
32
|
+
`;
|
|
33
|
+
describe('日志与调试 API', () => {
|
|
34
|
+
// 准备测试环境
|
|
35
|
+
test('准备: 创建测试 Pod', async (ctx) => {
|
|
36
|
+
const { kubectl } = ctx.plugins;
|
|
37
|
+
await kubectl.apply(debugPodYaml);
|
|
38
|
+
await kubectl.waitForPod('debug-pod', 'Running', 60000);
|
|
39
|
+
});
|
|
40
|
+
// ===== logs - 获取 Pod 日志 =====
|
|
41
|
+
test('logs - 获取 Pod 日志', async (ctx) => {
|
|
42
|
+
const { kubectl } = ctx.plugins;
|
|
43
|
+
// 基础日志获取
|
|
44
|
+
const logs = await kubectl.logs('debug-pod');
|
|
45
|
+
});
|
|
46
|
+
test('logs - 带选项获取日志', async (ctx) => {
|
|
47
|
+
const { kubectl } = ctx.plugins;
|
|
48
|
+
// 使用 tail 选项限制行数
|
|
49
|
+
await kubectl.logs('debug-pod', { tail: 5 });
|
|
50
|
+
// 使用 since 选项按时间过滤
|
|
51
|
+
await kubectl.logs('debug-pod', { since: '1m' });
|
|
52
|
+
});
|
|
53
|
+
// ===== exec - 在 Pod 中执行命令 =====
|
|
54
|
+
test('exec - 执行简单命令', async (ctx) => {
|
|
55
|
+
const { kubectl } = ctx.plugins;
|
|
56
|
+
// 执行单个命令
|
|
57
|
+
await kubectl.exec('debug-pod', 'hostname');
|
|
58
|
+
});
|
|
59
|
+
test('exec - 执行复杂命令', async (ctx) => {
|
|
60
|
+
const { kubectl } = ctx.plugins;
|
|
61
|
+
// 执行 shell 命令
|
|
62
|
+
await kubectl.exec('debug-pod', ['sh', '-c', 'ls -la / && echo "done"']);
|
|
63
|
+
});
|
|
64
|
+
// ===== describe - 获取资源描述 =====
|
|
65
|
+
test('describe - 获取 Pod 描述', async (ctx) => {
|
|
66
|
+
const { kubectl } = ctx.plugins;
|
|
67
|
+
// 获取详细描述
|
|
68
|
+
const description = await kubectl.describe('pod', 'debug-pod');
|
|
69
|
+
});
|
|
70
|
+
test('describe - 获取所有 Pods 描述', async (ctx) => {
|
|
71
|
+
const { kubectl } = ctx.plugins;
|
|
72
|
+
// 不指定名称,获取所有资源的描述
|
|
73
|
+
await kubectl.describe('pods');
|
|
74
|
+
});
|
|
75
|
+
// 清理
|
|
76
|
+
test('清理: 删除测试 Pod', async (ctx) => {
|
|
77
|
+
const { kubectl } = ctx.plugins;
|
|
78
|
+
await kubectl.delete('pod', 'debug-pod', { force: true });
|
|
79
|
+
});
|
|
80
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 示例 3: 资源管理
|
|
3
|
+
*
|
|
4
|
+
* 演示 kubectl 插件的资源管理 API:scale, patch, label, annotate, wait, waitForReplicas
|
|
5
|
+
*
|
|
6
|
+
* 运行方式:
|
|
7
|
+
* bun run repterm packages/plugin-kubectl/examples/03-resource-management.ts
|
|
8
|
+
*
|
|
9
|
+
* 前置条件:
|
|
10
|
+
* - 已配置 kubectl 并连接到 Kubernetes 集群
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=03-resource-management.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"03-resource-management.d.ts","sourceRoot":"","sources":["../../../examples/03-resource-management.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 示例 3: 资源管理
|
|
3
|
+
*
|
|
4
|
+
* 演示 kubectl 插件的资源管理 API:scale, patch, label, annotate, wait, waitForReplicas
|
|
5
|
+
*
|
|
6
|
+
* 运行方式:
|
|
7
|
+
* bun run repterm packages/plugin-kubectl/examples/03-resource-management.ts
|
|
8
|
+
*
|
|
9
|
+
* 前置条件:
|
|
10
|
+
* - 已配置 kubectl 并连接到 Kubernetes 集群
|
|
11
|
+
*/
|
|
12
|
+
import { describe, defineConfig, createTestWithPlugins, } from '../../repterm/src/index.js';
|
|
13
|
+
import { kubectlPlugin } from '../src/index.js';
|
|
14
|
+
// 配置插件
|
|
15
|
+
const config = defineConfig({
|
|
16
|
+
plugins: [kubectlPlugin({ namespace: 'default' })],
|
|
17
|
+
});
|
|
18
|
+
const test = createTestWithPlugins(config);
|
|
19
|
+
// 测试用 Deployment
|
|
20
|
+
const nginxDeploymentYaml = `
|
|
21
|
+
apiVersion: apps/v1
|
|
22
|
+
kind: Deployment
|
|
23
|
+
metadata:
|
|
24
|
+
name: nginx-deploy
|
|
25
|
+
labels:
|
|
26
|
+
app: nginx
|
|
27
|
+
spec:
|
|
28
|
+
replicas: 2
|
|
29
|
+
selector:
|
|
30
|
+
matchLabels:
|
|
31
|
+
app: nginx
|
|
32
|
+
template:
|
|
33
|
+
metadata:
|
|
34
|
+
labels:
|
|
35
|
+
app: nginx
|
|
36
|
+
spec:
|
|
37
|
+
containers:
|
|
38
|
+
- name: nginx
|
|
39
|
+
image: nginx:1.21-alpine
|
|
40
|
+
ports:
|
|
41
|
+
- containerPort: 80
|
|
42
|
+
`;
|
|
43
|
+
describe('资源管理 API', () => {
|
|
44
|
+
// 准备测试环境
|
|
45
|
+
test('准备: 创建测试 Deployment', async (ctx) => {
|
|
46
|
+
const { kubectl } = ctx.plugins;
|
|
47
|
+
await kubectl.apply(nginxDeploymentYaml);
|
|
48
|
+
// 等待 Deployment 就绪
|
|
49
|
+
await kubectl.wait('deployment', 'nginx-deploy', 'Available', { timeout: 120000 });
|
|
50
|
+
});
|
|
51
|
+
// ===== scale - 扩缩容 =====
|
|
52
|
+
test('scale - 扩展副本数', async (ctx) => {
|
|
53
|
+
const { kubectl } = ctx.plugins;
|
|
54
|
+
// 使用 scale API 扩展到 3 个副本
|
|
55
|
+
await kubectl.scale('deployment', 'nginx-deploy', 3);
|
|
56
|
+
// 等待副本就绪
|
|
57
|
+
await kubectl.waitForReplicas('deployment', 'nginx-deploy', 3, 60000);
|
|
58
|
+
});
|
|
59
|
+
test('scale - 缩减副本数', async (ctx) => {
|
|
60
|
+
const { kubectl } = ctx.plugins;
|
|
61
|
+
await kubectl.scale('deployment', 'nginx-deploy', 1);
|
|
62
|
+
});
|
|
63
|
+
// ===== label - 管理标签 =====
|
|
64
|
+
test('label - 添加标签', async (ctx) => {
|
|
65
|
+
const { kubectl } = ctx.plugins;
|
|
66
|
+
// 使用 label API 添加标签
|
|
67
|
+
await kubectl.label('deployment', 'nginx-deploy', {
|
|
68
|
+
env: 'production',
|
|
69
|
+
team: 'platform',
|
|
70
|
+
});
|
|
71
|
+
// 验证
|
|
72
|
+
const deploy = await kubectl.get('deployment', 'nginx-deploy');
|
|
73
|
+
if (deploy.metadata.labels.env !== 'production') {
|
|
74
|
+
throw new Error('Label env not set correctly');
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
test('label - 删除标签', async (ctx) => {
|
|
78
|
+
const { kubectl } = ctx.plugins;
|
|
79
|
+
// 使用 null 值删除标签
|
|
80
|
+
await kubectl.label('deployment', 'nginx-deploy', {
|
|
81
|
+
team: null, // 删除 team 标签
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
// ===== annotate - 管理注解 =====
|
|
85
|
+
test('annotate - 添加注解', async (ctx) => {
|
|
86
|
+
const { kubectl } = ctx.plugins;
|
|
87
|
+
await kubectl.annotate('deployment', 'nginx-deploy', {
|
|
88
|
+
'description': 'Test deployment for kubectl plugin',
|
|
89
|
+
'owner': 'test-team',
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
test('annotate - 删除注解', async (ctx) => {
|
|
93
|
+
const { kubectl } = ctx.plugins;
|
|
94
|
+
await kubectl.annotate('deployment', 'nginx-deploy', {
|
|
95
|
+
'owner': null, // 删除 owner 注解
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
// ===== patch - 补丁更新 =====
|
|
99
|
+
test('patch - Strategic Merge Patch', async (ctx) => {
|
|
100
|
+
const { kubectl } = ctx.plugins;
|
|
101
|
+
// 使用对象形式的 patch
|
|
102
|
+
await kubectl.patch('deployment', 'nginx-deploy', {
|
|
103
|
+
spec: {
|
|
104
|
+
template: {
|
|
105
|
+
spec: {
|
|
106
|
+
containers: [{
|
|
107
|
+
name: 'nginx',
|
|
108
|
+
resources: {
|
|
109
|
+
limits: { memory: '128Mi' },
|
|
110
|
+
},
|
|
111
|
+
}],
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
}, 'strategic');
|
|
116
|
+
});
|
|
117
|
+
test('patch - JSON Patch', async (ctx) => {
|
|
118
|
+
const { kubectl } = ctx.plugins;
|
|
119
|
+
// 使用 JSON Patch 格式
|
|
120
|
+
await kubectl.patch('deployment', 'nginx-deploy', [
|
|
121
|
+
{ op: 'replace', path: '/spec/replicas', value: 2 },
|
|
122
|
+
], 'json');
|
|
123
|
+
});
|
|
124
|
+
// ===== wait - 等待条件 =====
|
|
125
|
+
test('wait - 等待 Deployment Available', async (ctx) => {
|
|
126
|
+
const { kubectl } = ctx.plugins;
|
|
127
|
+
await kubectl.wait('deployment', 'nginx-deploy', 'Available', { timeout: 60000 });
|
|
128
|
+
});
|
|
129
|
+
// 清理
|
|
130
|
+
test('清理: 删除测试 Deployment', async (ctx) => {
|
|
131
|
+
const { kubectl } = ctx.plugins;
|
|
132
|
+
await kubectl.delete('deployment', 'nginx-deploy', { force: true });
|
|
133
|
+
});
|
|
134
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 示例 4: 发布管理 (Rollout)
|
|
3
|
+
*
|
|
4
|
+
* 演示 kubectl 插件的 rollout API:status, history, restart, undo, pause, resume
|
|
5
|
+
*
|
|
6
|
+
* 运行方式:
|
|
7
|
+
* bun run repterm packages/plugin-kubectl/examples/04-rollout.ts
|
|
8
|
+
*
|
|
9
|
+
* 前置条件:
|
|
10
|
+
* - 已配置 kubectl 并连接到 Kubernetes 集群
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=04-rollout.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"04-rollout.d.ts","sourceRoot":"","sources":["../../../examples/04-rollout.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 示例 4: 发布管理 (Rollout)
|
|
3
|
+
*
|
|
4
|
+
* 演示 kubectl 插件的 rollout API:status, history, restart, undo, pause, resume
|
|
5
|
+
*
|
|
6
|
+
* 运行方式:
|
|
7
|
+
* bun run repterm packages/plugin-kubectl/examples/04-rollout.ts
|
|
8
|
+
*
|
|
9
|
+
* 前置条件:
|
|
10
|
+
* - 已配置 kubectl 并连接到 Kubernetes 集群
|
|
11
|
+
*/
|
|
12
|
+
import { describe, defineConfig, createTestWithPlugins, } from '../../repterm/src/index.js';
|
|
13
|
+
import { kubectlPlugin } from '../src/index.js';
|
|
14
|
+
// 配置插件
|
|
15
|
+
const config = defineConfig({
|
|
16
|
+
plugins: [kubectlPlugin({ namespace: 'default' })],
|
|
17
|
+
});
|
|
18
|
+
const test = createTestWithPlugins(config);
|
|
19
|
+
// 测试用 Deployment
|
|
20
|
+
const appDeploymentYaml = `
|
|
21
|
+
apiVersion: apps/v1
|
|
22
|
+
kind: Deployment
|
|
23
|
+
metadata:
|
|
24
|
+
name: app-deploy
|
|
25
|
+
annotations:
|
|
26
|
+
kubernetes.io/change-cause: "Initial deployment"
|
|
27
|
+
spec:
|
|
28
|
+
replicas: 2
|
|
29
|
+
selector:
|
|
30
|
+
matchLabels:
|
|
31
|
+
app: myapp
|
|
32
|
+
template:
|
|
33
|
+
metadata:
|
|
34
|
+
labels:
|
|
35
|
+
app: myapp
|
|
36
|
+
spec:
|
|
37
|
+
containers:
|
|
38
|
+
- name: app
|
|
39
|
+
image: nginx:1.20-alpine
|
|
40
|
+
ports:
|
|
41
|
+
- containerPort: 80
|
|
42
|
+
`;
|
|
43
|
+
describe('发布管理 (Rollout) API', () => {
|
|
44
|
+
// 准备测试环境
|
|
45
|
+
test('准备: 创建测试 Deployment', async (ctx) => {
|
|
46
|
+
const { kubectl } = ctx.plugins;
|
|
47
|
+
await kubectl.apply(appDeploymentYaml);
|
|
48
|
+
await kubectl.wait('deployment', 'app-deploy', 'Available', { timeout: 120000 });
|
|
49
|
+
});
|
|
50
|
+
// ===== rollout.status - 获取发布状态 =====
|
|
51
|
+
test('rollout.status - 获取发布状态', async (ctx) => {
|
|
52
|
+
const { kubectl } = ctx.plugins;
|
|
53
|
+
const status = await kubectl.rollout.status('deployment', 'app-deploy');
|
|
54
|
+
});
|
|
55
|
+
// ===== rollout.history - 获取发布历史 =====
|
|
56
|
+
test('rollout.history - 获取发布历史', async (ctx) => {
|
|
57
|
+
const { kubectl } = ctx.plugins;
|
|
58
|
+
const history = await kubectl.rollout.history('deployment', 'app-deploy');
|
|
59
|
+
for (const entry of history) {
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
// ===== rollout.restart - 重启 Deployment =====
|
|
63
|
+
test('rollout.restart - 重启 Deployment', async (ctx) => {
|
|
64
|
+
const { kubectl } = ctx.plugins;
|
|
65
|
+
await kubectl.rollout.restart('deployment', 'app-deploy');
|
|
66
|
+
// 等待重启完成
|
|
67
|
+
await kubectl.wait('deployment', 'app-deploy', 'Available', { timeout: 120000 });
|
|
68
|
+
});
|
|
69
|
+
// ===== rollout.pause / resume - 暂停/恢复发布 =====
|
|
70
|
+
test('rollout.pause - 暂停发布', async (ctx) => {
|
|
71
|
+
const { kubectl } = ctx.plugins;
|
|
72
|
+
await kubectl.rollout.pause('deployment', 'app-deploy');
|
|
73
|
+
});
|
|
74
|
+
test('rollout.resume - 恢复发布', async (ctx) => {
|
|
75
|
+
const { kubectl } = ctx.plugins;
|
|
76
|
+
await kubectl.rollout.resume('deployment', 'app-deploy');
|
|
77
|
+
});
|
|
78
|
+
// 触发新版本以便测试回滚
|
|
79
|
+
test('触发镜像更新', async (ctx) => {
|
|
80
|
+
const { kubectl } = ctx.plugins;
|
|
81
|
+
// 使用 patch 更新镜像
|
|
82
|
+
await kubectl.patch('deployment', 'app-deploy', {
|
|
83
|
+
spec: {
|
|
84
|
+
template: {
|
|
85
|
+
spec: {
|
|
86
|
+
containers: [{
|
|
87
|
+
name: 'app',
|
|
88
|
+
image: 'nginx:1.21-alpine',
|
|
89
|
+
}],
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
// 添加变更原因注解
|
|
95
|
+
await kubectl.annotate('deployment', 'app-deploy', {
|
|
96
|
+
'kubernetes.io/change-cause': 'Update to nginx:1.21',
|
|
97
|
+
});
|
|
98
|
+
await kubectl.wait('deployment', 'app-deploy', 'Available', { timeout: 120000 });
|
|
99
|
+
});
|
|
100
|
+
// ===== rollout.undo - 回滚 =====
|
|
101
|
+
test('rollout.undo - 回滚到上一版本', async (ctx) => {
|
|
102
|
+
const { kubectl } = ctx.plugins;
|
|
103
|
+
await kubectl.rollout.undo('deployment', 'app-deploy');
|
|
104
|
+
await kubectl.wait('deployment', 'app-deploy', 'Available', { timeout: 120000 });
|
|
105
|
+
});
|
|
106
|
+
test('rollout.undo - 回滚到指定版本', async (ctx) => {
|
|
107
|
+
const { kubectl } = ctx.plugins;
|
|
108
|
+
// 获取历史,找到可用的版本
|
|
109
|
+
const history = await kubectl.rollout.history('deployment', 'app-deploy');
|
|
110
|
+
if (history.length > 1) {
|
|
111
|
+
const targetRevision = history[0].revision;
|
|
112
|
+
await kubectl.rollout.undo('deployment', 'app-deploy', targetRevision);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
// 清理
|
|
118
|
+
test('清理: 删除测试 Deployment', async (ctx) => {
|
|
119
|
+
const { kubectl } = ctx.plugins;
|
|
120
|
+
await kubectl.delete('deployment', 'app-deploy', { force: true });
|
|
121
|
+
});
|
|
122
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 示例 5: K8s Matchers
|
|
3
|
+
*
|
|
4
|
+
* 演示 kubectl 插件的 expect matchers:
|
|
5
|
+
* toExistInCluster, toBeRunning, toHavePhase, toHaveReplicas,
|
|
6
|
+
* toHaveAvailableReplicas, toBeAvailable, toHaveLabel, toHaveAnnotation, toHaveCondition
|
|
7
|
+
*
|
|
8
|
+
* 运行方式:
|
|
9
|
+
* bun run repterm packages/plugin-kubectl/examples/05-matchers.ts
|
|
10
|
+
*
|
|
11
|
+
* 前置条件:
|
|
12
|
+
* - 已配置 kubectl 并连接到 Kubernetes 集群
|
|
13
|
+
*/
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=05-matchers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"05-matchers.d.ts","sourceRoot":"","sources":["../../../examples/05-matchers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 示例 5: K8s Matchers
|
|
3
|
+
*
|
|
4
|
+
* 演示 kubectl 插件的 expect matchers:
|
|
5
|
+
* toExistInCluster, toBeRunning, toHavePhase, toHaveReplicas,
|
|
6
|
+
* toHaveAvailableReplicas, toBeAvailable, toHaveLabel, toHaveAnnotation, toHaveCondition
|
|
7
|
+
*
|
|
8
|
+
* 运行方式:
|
|
9
|
+
* bun run repterm packages/plugin-kubectl/examples/05-matchers.ts
|
|
10
|
+
*
|
|
11
|
+
* 前置条件:
|
|
12
|
+
* - 已配置 kubectl 并连接到 Kubernetes 集群
|
|
13
|
+
*/
|
|
14
|
+
import { describe, defineConfig, createTestWithPlugins, expect, } from 'repterm';
|
|
15
|
+
import { kubectlPlugin, pod, deployment, registerK8sMatchers } from '../src/index.js';
|
|
16
|
+
// 注册 K8s matchers
|
|
17
|
+
registerK8sMatchers();
|
|
18
|
+
// 配置插件
|
|
19
|
+
const config = defineConfig({
|
|
20
|
+
plugins: [kubectlPlugin({ namespace: 'default' })],
|
|
21
|
+
});
|
|
22
|
+
const test = createTestWithPlugins(config);
|
|
23
|
+
// 测试资源 YAML
|
|
24
|
+
const testPodYaml = `
|
|
25
|
+
apiVersion: v1
|
|
26
|
+
kind: Pod
|
|
27
|
+
metadata:
|
|
28
|
+
name: matcher-pod
|
|
29
|
+
labels:
|
|
30
|
+
app: matcher-test
|
|
31
|
+
env: test
|
|
32
|
+
annotations:
|
|
33
|
+
description: Test pod for matchers
|
|
34
|
+
spec:
|
|
35
|
+
containers:
|
|
36
|
+
- name: nginx
|
|
37
|
+
image: nginx:alpine
|
|
38
|
+
`;
|
|
39
|
+
const testDeploymentYaml = `
|
|
40
|
+
apiVersion: apps/v1
|
|
41
|
+
kind: Deployment
|
|
42
|
+
metadata:
|
|
43
|
+
name: matcher-deploy
|
|
44
|
+
labels:
|
|
45
|
+
app: matcher-deploy
|
|
46
|
+
spec:
|
|
47
|
+
replicas: 2
|
|
48
|
+
selector:
|
|
49
|
+
matchLabels:
|
|
50
|
+
app: matcher-deploy
|
|
51
|
+
template:
|
|
52
|
+
metadata:
|
|
53
|
+
labels:
|
|
54
|
+
app: matcher-deploy
|
|
55
|
+
spec:
|
|
56
|
+
containers:
|
|
57
|
+
- name: nginx
|
|
58
|
+
image: nginx:alpine
|
|
59
|
+
`;
|
|
60
|
+
describe('K8s Matchers', () => {
|
|
61
|
+
// 准备测试资源
|
|
62
|
+
test('准备: 创建测试资源', async (ctx) => {
|
|
63
|
+
const { kubectl } = ctx.plugins;
|
|
64
|
+
await kubectl.apply(testPodYaml);
|
|
65
|
+
await kubectl.apply(testDeploymentYaml);
|
|
66
|
+
await kubectl.waitForPod('matcher-pod', 'Running', 60000);
|
|
67
|
+
await kubectl.wait('deployment', 'matcher-deploy', 'Available', { timeout: 120000 });
|
|
68
|
+
});
|
|
69
|
+
// ===== toExistInCluster - 验证资源存在 =====
|
|
70
|
+
test('toExistInCluster - 验证 Pod 存在', async (ctx) => {
|
|
71
|
+
const { kubectl } = ctx.plugins;
|
|
72
|
+
// 使用 pod() helper 创建资源包装器
|
|
73
|
+
await expect(pod(kubectl, 'matcher-pod')).toExistInCluster();
|
|
74
|
+
});
|
|
75
|
+
test('toExistInCluster - 验证 Deployment 存在', async (ctx) => {
|
|
76
|
+
const { kubectl } = ctx.plugins;
|
|
77
|
+
await expect(deployment(kubectl, 'matcher-deploy')).toExistInCluster();
|
|
78
|
+
});
|
|
79
|
+
// ===== toBeRunning - 验证 Pod Running =====
|
|
80
|
+
test('toBeRunning - 验证 Pod Running 状态', async (ctx) => {
|
|
81
|
+
const { kubectl } = ctx.plugins;
|
|
82
|
+
await expect(pod(kubectl, 'matcher-pod')).toBeRunning();
|
|
83
|
+
});
|
|
84
|
+
// ===== toHavePhase - 验证 Pod 阶段 =====
|
|
85
|
+
test('toHavePhase - 验证 Pod 阶段', async (ctx) => {
|
|
86
|
+
const { kubectl } = ctx.plugins;
|
|
87
|
+
await expect(pod(kubectl, 'matcher-pod')).toHavePhase('Running');
|
|
88
|
+
});
|
|
89
|
+
// ===== toHaveReplicas - 验证副本数 =====
|
|
90
|
+
test('toHaveReplicas - 验证 Deployment 副本数', async (ctx) => {
|
|
91
|
+
const { kubectl } = ctx.plugins;
|
|
92
|
+
await expect(deployment(kubectl, 'matcher-deploy')).toHaveReplicas(2);
|
|
93
|
+
});
|
|
94
|
+
// ===== toHaveAvailableReplicas - 验证可用副本数 =====
|
|
95
|
+
test('toHaveAvailableReplicas - 验证可用副本数', async (ctx) => {
|
|
96
|
+
const { kubectl } = ctx.plugins;
|
|
97
|
+
await expect(deployment(kubectl, 'matcher-deploy')).toHaveAvailableReplicas(2);
|
|
98
|
+
});
|
|
99
|
+
// ===== toBeAvailable - 验证 Deployment 可用 =====
|
|
100
|
+
test('toBeAvailable - 验证 Deployment 可用', async (ctx) => {
|
|
101
|
+
const { kubectl } = ctx.plugins;
|
|
102
|
+
await expect(deployment(kubectl, 'matcher-deploy')).toBeAvailable();
|
|
103
|
+
});
|
|
104
|
+
// ===== toHaveLabel - 验证标签 =====
|
|
105
|
+
test('toHaveLabel - 验证 Pod 标签存在', async (ctx) => {
|
|
106
|
+
const { kubectl } = ctx.plugins;
|
|
107
|
+
// 只检查标签是否存在
|
|
108
|
+
await expect(pod(kubectl, 'matcher-pod')).toHaveLabel('app');
|
|
109
|
+
});
|
|
110
|
+
test('toHaveLabel - 验证 Pod 标签值', async (ctx) => {
|
|
111
|
+
const { kubectl } = ctx.plugins;
|
|
112
|
+
// 检查标签的具体值
|
|
113
|
+
await expect(pod(kubectl, 'matcher-pod')).toHaveLabel('app', 'matcher-test');
|
|
114
|
+
await expect(pod(kubectl, 'matcher-pod')).toHaveLabel('env', 'test');
|
|
115
|
+
});
|
|
116
|
+
// ===== toHaveAnnotation - 验证注解 =====
|
|
117
|
+
test('toHaveAnnotation - 验证 Pod 注解', async (ctx) => {
|
|
118
|
+
const { kubectl } = ctx.plugins;
|
|
119
|
+
await expect(pod(kubectl, 'matcher-pod')).toHaveAnnotation('description');
|
|
120
|
+
await expect(pod(kubectl, 'matcher-pod')).toHaveAnnotation('description', 'Test pod for matchers');
|
|
121
|
+
});
|
|
122
|
+
// ===== toHaveCondition - 验证条件 =====
|
|
123
|
+
test('toHaveCondition - 验证 Deployment 条件', async (ctx) => {
|
|
124
|
+
const { kubectl } = ctx.plugins;
|
|
125
|
+
await expect(deployment(kubectl, 'matcher-deploy')).toHaveCondition('Available', 'True');
|
|
126
|
+
});
|
|
127
|
+
// ===== not. 否定断言 =====
|
|
128
|
+
test('not.toExistInCluster - 验证资源不存在', async (ctx) => {
|
|
129
|
+
const { kubectl } = ctx.plugins;
|
|
130
|
+
await expect(pod(kubectl, 'non-existent-pod')).not.toExistInCluster();
|
|
131
|
+
});
|
|
132
|
+
// 清理
|
|
133
|
+
test('清理: 删除测试资源', async (ctx) => {
|
|
134
|
+
const { kubectl } = ctx.plugins;
|
|
135
|
+
await kubectl.delete('pod', 'matcher-pod', { force: true });
|
|
136
|
+
await kubectl.delete('deployment', 'matcher-deploy', { force: true });
|
|
137
|
+
});
|
|
138
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 示例 6: 进阶功能
|
|
3
|
+
*
|
|
4
|
+
* 演示 kubectl 插件的进阶 API:
|
|
5
|
+
* portForward, waitForService, getEvents, getNodes, cp
|
|
6
|
+
*
|
|
7
|
+
* 运行方式:
|
|
8
|
+
* bun run repterm packages/plugin-kubectl/examples/06-advanced.ts
|
|
9
|
+
*
|
|
10
|
+
* 前置条件:
|
|
11
|
+
* - 已配置 kubectl 并连接到 Kubernetes 集群
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=06-advanced.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"06-advanced.d.ts","sourceRoot":"","sources":["../../../examples/06-advanced.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
|