@kubernetesjs/cli 0.0.3 → 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/LICENSE +1 -1
- package/README.md +54 -55
- package/commands/apply.d.ts +4 -0
- package/commands/apply.js +171 -0
- package/commands/cluster-info.d.ts +4 -0
- package/commands/cluster-info.js +26 -0
- package/commands/config-handler.d.ts +11 -0
- package/commands/config-handler.js +81 -0
- package/commands/config.d.ts +4 -0
- package/commands/config.js +72 -0
- package/commands/delete.d.ts +4 -0
- package/commands/delete.js +256 -0
- package/commands/deploy.d.ts +6 -0
- package/commands/deploy.js +209 -0
- package/commands/describe.d.ts +4 -0
- package/commands/describe.js +216 -0
- package/commands/exec.d.ts +4 -0
- package/commands/exec.js +145 -0
- package/commands/get.d.ts +4 -0
- package/commands/get.js +164 -0
- package/commands/logs.d.ts +4 -0
- package/commands/logs.js +110 -0
- package/commands/port-forward.d.ts +4 -0
- package/commands/port-forward.js +143 -0
- package/commands.d.ts +3 -0
- package/commands.js +93 -0
- package/config.d.ts +22 -0
- package/config.js +113 -0
- package/esm/commands/apply.js +133 -0
- package/esm/commands/cluster-info.js +21 -0
- package/esm/commands/config-handler.js +43 -0
- package/esm/commands/config.js +67 -0
- package/esm/commands/delete.js +218 -0
- package/esm/commands/deploy.js +207 -0
- package/esm/commands/describe.js +211 -0
- package/esm/commands/exec.js +140 -0
- package/esm/commands/get.js +159 -0
- package/esm/commands/logs.js +105 -0
- package/esm/commands/port-forward.js +138 -0
- package/esm/commands.js +86 -0
- package/esm/config.js +74 -0
- package/esm/index.js +19 -0
- package/esm/package.js +26 -0
- package/esm/utils.js +49 -0
- package/index.d.ts +3 -0
- package/index.js +22 -0
- package/package.d.ts +1 -0
- package/package.js +29 -0
- package/package.json +37 -61
- package/utils.d.ts +11 -0
- package/utils.js +58 -0
- package/main/client.js +0 -156
- package/main/index.js +0 -2598
- package/module/client.js +0 -129
- package/module/index.js +0 -2594
- package/src/client.ts +0 -156
- package/src/index.ts +0 -14187
- package/types/client.d.ts +0 -31
- package/types/index.d.ts +0 -11331
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
40
|
+
const kubernetesjs_1 = require("kubernetesjs");
|
|
41
|
+
const config_1 = require("../config");
|
|
42
|
+
const fs = __importStar(require("fs"));
|
|
43
|
+
async function promptResourceType(prompter, argv) {
|
|
44
|
+
const resourceTypes = [
|
|
45
|
+
'pod',
|
|
46
|
+
'service',
|
|
47
|
+
'deployment',
|
|
48
|
+
'replicaset',
|
|
49
|
+
'statefulset',
|
|
50
|
+
'daemonset',
|
|
51
|
+
'configmap',
|
|
52
|
+
'secret'
|
|
53
|
+
];
|
|
54
|
+
const question = {
|
|
55
|
+
type: 'autocomplete',
|
|
56
|
+
name: 'resourceType',
|
|
57
|
+
message: 'Select resource type to delete',
|
|
58
|
+
options: resourceTypes,
|
|
59
|
+
maxDisplayLines: 10,
|
|
60
|
+
required: true
|
|
61
|
+
};
|
|
62
|
+
const { resourceType } = await prompter.prompt(argv, [question]);
|
|
63
|
+
return resourceType;
|
|
64
|
+
}
|
|
65
|
+
async function promptResourceSelection(prompter, argv, resourceType, namespace, client) {
|
|
66
|
+
let resources = [];
|
|
67
|
+
switch (resourceType) {
|
|
68
|
+
case 'pod':
|
|
69
|
+
const pods = await client.listCoreV1NamespacedPod({
|
|
70
|
+
path: { namespace },
|
|
71
|
+
query: { limit: 100 }
|
|
72
|
+
});
|
|
73
|
+
resources = pods.items || [];
|
|
74
|
+
break;
|
|
75
|
+
case 'service':
|
|
76
|
+
const services = await client.listCoreV1NamespacedService({
|
|
77
|
+
path: { namespace },
|
|
78
|
+
query: { limit: 100 }
|
|
79
|
+
});
|
|
80
|
+
resources = services.items || [];
|
|
81
|
+
break;
|
|
82
|
+
case 'deployment':
|
|
83
|
+
const deployments = await client.listAppsV1NamespacedDeployment({
|
|
84
|
+
path: { namespace },
|
|
85
|
+
query: { limit: 100 }
|
|
86
|
+
});
|
|
87
|
+
resources = deployments.items || [];
|
|
88
|
+
break;
|
|
89
|
+
case 'configmap':
|
|
90
|
+
const configmaps = await client.listCoreV1NamespacedConfigMap({
|
|
91
|
+
path: { namespace },
|
|
92
|
+
query: { limit: 100 }
|
|
93
|
+
});
|
|
94
|
+
resources = configmaps.items || [];
|
|
95
|
+
break;
|
|
96
|
+
case 'secret':
|
|
97
|
+
const secrets = await client.listCoreV1NamespacedSecret({
|
|
98
|
+
path: { namespace },
|
|
99
|
+
query: { limit: 100 }
|
|
100
|
+
});
|
|
101
|
+
resources = secrets.items || [];
|
|
102
|
+
break;
|
|
103
|
+
default:
|
|
104
|
+
console.log(chalk_1.default.yellow(`Resource type '${resourceType}' not implemented yet for selection`));
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
if (resources.length === 0) {
|
|
108
|
+
console.log(chalk_1.default.yellow(`No ${resourceType}s found in namespace ${namespace}`));
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
const options = resources.map(r => ({
|
|
112
|
+
name: r.metadata.name,
|
|
113
|
+
value: r.metadata.name
|
|
114
|
+
}));
|
|
115
|
+
const question = {
|
|
116
|
+
type: 'checkbox',
|
|
117
|
+
name: 'selectedResources',
|
|
118
|
+
message: `Select ${resourceType}(s) to delete`,
|
|
119
|
+
options,
|
|
120
|
+
maxDisplayLines: 10,
|
|
121
|
+
required: true
|
|
122
|
+
};
|
|
123
|
+
let selectedResources;
|
|
124
|
+
({ selectedResources } = await prompter.prompt(argv, [question]));
|
|
125
|
+
return selectedResources
|
|
126
|
+
.filter(res => res.selected)
|
|
127
|
+
.map(res => res.value);
|
|
128
|
+
}
|
|
129
|
+
async function deleteResource(client, resourceType, resourceName, namespace) {
|
|
130
|
+
try {
|
|
131
|
+
switch (resourceType) {
|
|
132
|
+
case 'pod':
|
|
133
|
+
await client.deleteCoreV1NamespacedPod({
|
|
134
|
+
path: {
|
|
135
|
+
namespace,
|
|
136
|
+
name: resourceName
|
|
137
|
+
},
|
|
138
|
+
query: {}
|
|
139
|
+
});
|
|
140
|
+
console.log(chalk_1.default.green(`Pod "${resourceName}" deleted successfully`));
|
|
141
|
+
break;
|
|
142
|
+
case 'service':
|
|
143
|
+
await client.deleteCoreV1NamespacedService({
|
|
144
|
+
path: {
|
|
145
|
+
namespace,
|
|
146
|
+
name: resourceName
|
|
147
|
+
},
|
|
148
|
+
query: {}
|
|
149
|
+
});
|
|
150
|
+
console.log(chalk_1.default.green(`Service "${resourceName}" deleted successfully`));
|
|
151
|
+
break;
|
|
152
|
+
case 'deployment':
|
|
153
|
+
await client.deleteAppsV1NamespacedDeployment({
|
|
154
|
+
path: {
|
|
155
|
+
namespace,
|
|
156
|
+
name: resourceName
|
|
157
|
+
},
|
|
158
|
+
query: {}
|
|
159
|
+
});
|
|
160
|
+
console.log(chalk_1.default.green(`Deployment "${resourceName}" deleted successfully`));
|
|
161
|
+
break;
|
|
162
|
+
case 'configmap':
|
|
163
|
+
await client.deleteCoreV1NamespacedConfigMap({
|
|
164
|
+
path: {
|
|
165
|
+
namespace,
|
|
166
|
+
name: resourceName
|
|
167
|
+
},
|
|
168
|
+
query: {}
|
|
169
|
+
});
|
|
170
|
+
console.log(chalk_1.default.green(`ConfigMap "${resourceName}" deleted successfully`));
|
|
171
|
+
break;
|
|
172
|
+
case 'secret':
|
|
173
|
+
await client.deleteCoreV1NamespacedSecret({
|
|
174
|
+
path: {
|
|
175
|
+
namespace,
|
|
176
|
+
name: resourceName
|
|
177
|
+
},
|
|
178
|
+
query: {}
|
|
179
|
+
});
|
|
180
|
+
console.log(chalk_1.default.green(`Secret "${resourceName}" deleted successfully`));
|
|
181
|
+
break;
|
|
182
|
+
default:
|
|
183
|
+
console.log(chalk_1.default.yellow(`Resource type '${resourceType}' not implemented yet for deletion`));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
catch (error) {
|
|
187
|
+
console.error(chalk_1.default.red(`Error deleting ${resourceType} "${resourceName}": ${error}`));
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async function deleteFromYaml(client, filePath, namespace) {
|
|
191
|
+
try {
|
|
192
|
+
const content = (0, config_1.readYamlFile)(filePath);
|
|
193
|
+
const resources = Array.isArray(content) ? content :
|
|
194
|
+
(content.kind === 'List' && Array.isArray(content.items)) ? content.items :
|
|
195
|
+
[content];
|
|
196
|
+
for (const resource of resources) {
|
|
197
|
+
const kind = resource.kind.toLowerCase();
|
|
198
|
+
const name = resource.metadata?.name;
|
|
199
|
+
const ns = resource.metadata?.namespace || namespace;
|
|
200
|
+
if (!name) {
|
|
201
|
+
console.error(chalk_1.default.red('Resource must have a name'));
|
|
202
|
+
continue;
|
|
203
|
+
}
|
|
204
|
+
await deleteResource(client, kind, name, ns);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
console.error(chalk_1.default.red(`Error processing YAML file: ${error}`));
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
exports.default = async (argv, prompter, _options) => {
|
|
212
|
+
try {
|
|
213
|
+
const client = new kubernetesjs_1.KubernetesClient({
|
|
214
|
+
restEndpoint: 'http://localhost:8001' // Default kube-proxy endpoint
|
|
215
|
+
});
|
|
216
|
+
const namespace = argv.n || argv.namespace || (0, config_1.getCurrentNamespace)();
|
|
217
|
+
if (argv.f || argv.filename) {
|
|
218
|
+
const filePath = argv.f || argv.filename;
|
|
219
|
+
if (!fs.existsSync(filePath)) {
|
|
220
|
+
console.error(chalk_1.default.red(`File not found: ${filePath}`));
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
await deleteFromYaml(client, filePath, namespace);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
const resourceType = argv._?.[0] || await promptResourceType(prompter, argv);
|
|
227
|
+
const resourceName = argv._?.[1];
|
|
228
|
+
if (resourceName) {
|
|
229
|
+
await deleteResource(client, resourceType, resourceName, namespace);
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
const selectedResources = await promptResourceSelection(prompter, argv, resourceType, namespace, client);
|
|
233
|
+
if (selectedResources.length === 0) {
|
|
234
|
+
console.log(chalk_1.default.yellow('No resources selected for deletion'));
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
const confirmQuestion = {
|
|
238
|
+
type: 'confirm',
|
|
239
|
+
name: 'confirmDelete',
|
|
240
|
+
message: `Are you sure you want to delete ${selectedResources.length} ${resourceType}(s)?`,
|
|
241
|
+
required: true
|
|
242
|
+
};
|
|
243
|
+
const { confirmDelete } = await prompter.prompt(argv, [confirmQuestion]);
|
|
244
|
+
if (!confirmDelete) {
|
|
245
|
+
console.log(chalk_1.default.yellow('Deletion cancelled'));
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
for (const resource of selectedResources) {
|
|
249
|
+
await deleteResource(client, resourceType, resource, namespace);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
console.error(chalk_1.default.red(`Error: ${error}`));
|
|
255
|
+
}
|
|
256
|
+
};
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const kubernetesjs_1 = require("kubernetesjs");
|
|
4
|
+
const createDeployment = (type) => {
|
|
5
|
+
const commonMetadata = {
|
|
6
|
+
name: `${type}-deployment`,
|
|
7
|
+
labels: {
|
|
8
|
+
app: type
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
const commonSpec = {
|
|
12
|
+
replicas: 1,
|
|
13
|
+
selector: {
|
|
14
|
+
matchLabels: {
|
|
15
|
+
app: type
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
template: {
|
|
19
|
+
metadata: {
|
|
20
|
+
labels: {
|
|
21
|
+
app: type
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
switch (type) {
|
|
27
|
+
case 'minio':
|
|
28
|
+
return {
|
|
29
|
+
apiVersion: 'apps/v1',
|
|
30
|
+
kind: 'Deployment',
|
|
31
|
+
metadata: commonMetadata,
|
|
32
|
+
spec: {
|
|
33
|
+
...commonSpec,
|
|
34
|
+
template: {
|
|
35
|
+
...commonSpec.template,
|
|
36
|
+
spec: {
|
|
37
|
+
containers: [{
|
|
38
|
+
name: 'minio',
|
|
39
|
+
image: 'minio/minio:latest',
|
|
40
|
+
ports: [{ containerPort: 9000, name: 'minio' }],
|
|
41
|
+
env: [
|
|
42
|
+
{ name: 'MINIO_ROOT_USER', value: 'minioadmin' },
|
|
43
|
+
{ name: 'MINIO_ROOT_PASSWORD', value: 'minioadmin' }
|
|
44
|
+
],
|
|
45
|
+
args: ['server', '/data']
|
|
46
|
+
}]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
case 'postgres':
|
|
52
|
+
return {
|
|
53
|
+
apiVersion: 'apps/v1',
|
|
54
|
+
kind: 'Deployment',
|
|
55
|
+
metadata: commonMetadata,
|
|
56
|
+
spec: {
|
|
57
|
+
...commonSpec,
|
|
58
|
+
template: {
|
|
59
|
+
...commonSpec.template,
|
|
60
|
+
spec: {
|
|
61
|
+
containers: [{
|
|
62
|
+
name: 'postgres',
|
|
63
|
+
image: 'pyramation/pgvector:13.3-alpine',
|
|
64
|
+
ports: [{ containerPort: 5432, name: 'postgres' }],
|
|
65
|
+
env: [
|
|
66
|
+
{ name: 'POSTGRES_USER', value: 'postgres' },
|
|
67
|
+
{ name: 'POSTGRES_PASSWORD', value: 'postgres' },
|
|
68
|
+
{ name: 'POSTGRES_DB', value: 'postgres' }
|
|
69
|
+
]
|
|
70
|
+
}]
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
case 'ollama':
|
|
76
|
+
return {
|
|
77
|
+
apiVersion: 'apps/v1',
|
|
78
|
+
kind: 'Deployment',
|
|
79
|
+
metadata: commonMetadata,
|
|
80
|
+
spec: {
|
|
81
|
+
...commonSpec,
|
|
82
|
+
template: {
|
|
83
|
+
...commonSpec.template,
|
|
84
|
+
spec: {
|
|
85
|
+
containers: [{
|
|
86
|
+
name: 'ollama',
|
|
87
|
+
image: 'ollama/ollama:latest',
|
|
88
|
+
ports: [{ containerPort: 11434, name: 'ollama' }]
|
|
89
|
+
}]
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
default:
|
|
95
|
+
throw new Error(`Unsupported deployment type: ${type}`);
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
const createService = (type) => {
|
|
99
|
+
const commonMetadata = {
|
|
100
|
+
name: `${type}-service`,
|
|
101
|
+
labels: {
|
|
102
|
+
app: type
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
const commonSpec = {
|
|
106
|
+
selector: {
|
|
107
|
+
app: type
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
switch (type) {
|
|
111
|
+
case 'minio':
|
|
112
|
+
return {
|
|
113
|
+
apiVersion: 'v1',
|
|
114
|
+
kind: 'Service',
|
|
115
|
+
metadata: commonMetadata,
|
|
116
|
+
spec: {
|
|
117
|
+
...commonSpec,
|
|
118
|
+
ports: [{ port: 9000, targetPort: 'minio' }],
|
|
119
|
+
type: 'ClusterIP'
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
case 'postgres':
|
|
123
|
+
return {
|
|
124
|
+
apiVersion: 'v1',
|
|
125
|
+
kind: 'Service',
|
|
126
|
+
metadata: commonMetadata,
|
|
127
|
+
spec: {
|
|
128
|
+
...commonSpec,
|
|
129
|
+
ports: [{ port: 5432, targetPort: 'postgres' }],
|
|
130
|
+
type: 'ClusterIP'
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
case 'ollama':
|
|
134
|
+
return {
|
|
135
|
+
apiVersion: 'v1',
|
|
136
|
+
kind: 'Service',
|
|
137
|
+
metadata: commonMetadata,
|
|
138
|
+
spec: {
|
|
139
|
+
...commonSpec,
|
|
140
|
+
ports: [{ port: 11434, targetPort: 'ollama' }],
|
|
141
|
+
type: 'ClusterIP'
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
default:
|
|
145
|
+
throw new Error(`Unsupported service type: ${type}`);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
exports.default = async (argv, prompter, _options) => {
|
|
149
|
+
const deploymentOptions = ['minio', 'postgres', 'ollama'];
|
|
150
|
+
const questions = [
|
|
151
|
+
{
|
|
152
|
+
type: 'autocomplete',
|
|
153
|
+
name: 'deploymentType',
|
|
154
|
+
message: 'Select deployment type',
|
|
155
|
+
options: deploymentOptions,
|
|
156
|
+
maxDisplayLines: 5,
|
|
157
|
+
required: true
|
|
158
|
+
}
|
|
159
|
+
];
|
|
160
|
+
const { deploymentType } = await prompter.prompt(argv, questions);
|
|
161
|
+
const confirmQuestion = {
|
|
162
|
+
type: 'confirm',
|
|
163
|
+
name: 'confirmDeployment',
|
|
164
|
+
message: `Are you sure you want to deploy ${deploymentType}?`,
|
|
165
|
+
required: true
|
|
166
|
+
};
|
|
167
|
+
const { confirmDeployment } = await prompter.prompt(argv, [confirmQuestion]);
|
|
168
|
+
if (!confirmDeployment) {
|
|
169
|
+
console.log('Deployment cancelled.');
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
console.log(`Deploying ${deploymentType}...`);
|
|
173
|
+
try {
|
|
174
|
+
// Initialize Kubernetes client
|
|
175
|
+
const client = new kubernetesjs_1.KubernetesClient({
|
|
176
|
+
restEndpoint: argv.clientUrl
|
|
177
|
+
});
|
|
178
|
+
// Create deployment
|
|
179
|
+
const deployment = createDeployment(deploymentType);
|
|
180
|
+
await client.createAppsV1NamespacedDeployment({
|
|
181
|
+
path: {
|
|
182
|
+
namespace: 'default'
|
|
183
|
+
},
|
|
184
|
+
query: {
|
|
185
|
+
pretty: 'true'
|
|
186
|
+
},
|
|
187
|
+
body: deployment
|
|
188
|
+
});
|
|
189
|
+
console.log(`Created deployment: ${deployment.metadata.name}`);
|
|
190
|
+
// Create service
|
|
191
|
+
const service = createService(deploymentType);
|
|
192
|
+
await client.createCoreV1NamespacedService({
|
|
193
|
+
path: {
|
|
194
|
+
namespace: 'default'
|
|
195
|
+
},
|
|
196
|
+
query: {
|
|
197
|
+
pretty: 'true'
|
|
198
|
+
},
|
|
199
|
+
body: service
|
|
200
|
+
});
|
|
201
|
+
console.log(`Created service: ${service.metadata.name}`);
|
|
202
|
+
console.log(`Successfully deployed ${deploymentType}!`);
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
console.error(`Failed to deploy ${deploymentType}:`, error);
|
|
206
|
+
throw error;
|
|
207
|
+
}
|
|
208
|
+
return { deploymentType };
|
|
209
|
+
};
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
7
|
+
const kubernetesjs_1 = require("kubernetesjs");
|
|
8
|
+
const config_1 = require("../config");
|
|
9
|
+
async function promptResourceType(prompter, argv) {
|
|
10
|
+
const resourceTypes = [
|
|
11
|
+
'pod',
|
|
12
|
+
'service',
|
|
13
|
+
'deployment',
|
|
14
|
+
'replicaset',
|
|
15
|
+
'statefulset',
|
|
16
|
+
'daemonset',
|
|
17
|
+
'configmap',
|
|
18
|
+
'secret',
|
|
19
|
+
'namespace'
|
|
20
|
+
];
|
|
21
|
+
const question = {
|
|
22
|
+
type: 'autocomplete',
|
|
23
|
+
name: 'resourceType',
|
|
24
|
+
message: 'Select resource type',
|
|
25
|
+
options: resourceTypes,
|
|
26
|
+
maxDisplayLines: 10,
|
|
27
|
+
required: true
|
|
28
|
+
};
|
|
29
|
+
const { resourceType } = await prompter.prompt(argv, [question]);
|
|
30
|
+
return resourceType;
|
|
31
|
+
}
|
|
32
|
+
async function promptResourceName(prompter, argv, resourceType, namespace, client) {
|
|
33
|
+
let resources = [];
|
|
34
|
+
switch (resourceType) {
|
|
35
|
+
case 'pod':
|
|
36
|
+
const pods = await client.listCoreV1NamespacedPod({
|
|
37
|
+
path: { namespace },
|
|
38
|
+
query: { limit: 100 }
|
|
39
|
+
});
|
|
40
|
+
resources = pods.items || [];
|
|
41
|
+
break;
|
|
42
|
+
case 'service':
|
|
43
|
+
const services = await client.listCoreV1NamespacedService({
|
|
44
|
+
path: { namespace },
|
|
45
|
+
query: { limit: 100 }
|
|
46
|
+
});
|
|
47
|
+
resources = services.items || [];
|
|
48
|
+
break;
|
|
49
|
+
case 'deployment':
|
|
50
|
+
const deployments = await client.listAppsV1NamespacedDeployment({
|
|
51
|
+
path: { namespace },
|
|
52
|
+
query: { limit: 100 }
|
|
53
|
+
});
|
|
54
|
+
resources = deployments.items || [];
|
|
55
|
+
break;
|
|
56
|
+
default:
|
|
57
|
+
console.log(chalk_1.default.yellow(`Resource type '${resourceType}' not implemented yet for selection`));
|
|
58
|
+
return '';
|
|
59
|
+
}
|
|
60
|
+
if (resources.length === 0) {
|
|
61
|
+
console.log(chalk_1.default.yellow(`No ${resourceType}s found in namespace ${namespace}`));
|
|
62
|
+
return '';
|
|
63
|
+
}
|
|
64
|
+
const options = resources.map(r => ({
|
|
65
|
+
name: r.metadata.name,
|
|
66
|
+
value: r.metadata.name
|
|
67
|
+
}));
|
|
68
|
+
const question = {
|
|
69
|
+
type: 'autocomplete',
|
|
70
|
+
name: 'resourceName',
|
|
71
|
+
message: `Select ${resourceType} name`,
|
|
72
|
+
options,
|
|
73
|
+
maxDisplayLines: 10,
|
|
74
|
+
required: true
|
|
75
|
+
};
|
|
76
|
+
const { resourceName } = await prompter.prompt(argv, [question]);
|
|
77
|
+
return resourceName;
|
|
78
|
+
}
|
|
79
|
+
function describePod(pod) {
|
|
80
|
+
console.log(chalk_1.default.bold(`Name: ${pod.metadata.name}`));
|
|
81
|
+
console.log(chalk_1.default.bold(`Namespace: ${pod.metadata.namespace}`));
|
|
82
|
+
console.log(chalk_1.default.bold(`Priority: ${pod.spec.priority || 0}`));
|
|
83
|
+
console.log(chalk_1.default.bold(`Node: ${pod.spec.nodeName || '<none>'}`));
|
|
84
|
+
console.log(chalk_1.default.bold(`Start Time: ${pod.status.startTime || '<unknown>'}`));
|
|
85
|
+
console.log(chalk_1.default.bold('\nLabels:'));
|
|
86
|
+
if (pod.metadata.labels) {
|
|
87
|
+
Object.entries(pod.metadata.labels).forEach(([key, value]) => {
|
|
88
|
+
console.log(` ${key}=${value}`);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
console.log(chalk_1.default.bold('\nStatus: ' + pod.status.phase));
|
|
92
|
+
console.log(chalk_1.default.bold('IP: ' + pod.status.podIP));
|
|
93
|
+
console.log(chalk_1.default.bold('\nContainers:'));
|
|
94
|
+
if (pod.spec.containers) {
|
|
95
|
+
pod.spec.containers.forEach((container) => {
|
|
96
|
+
console.log(chalk_1.default.bold(` ${container.name}:`));
|
|
97
|
+
console.log(` Image: ${container.image}`);
|
|
98
|
+
console.log(` Ports: ${container.ports?.map((p) => p.containerPort).join(', ') || '<none>'}`);
|
|
99
|
+
const status = pod.status.containerStatuses?.find((s) => s.name === container.name);
|
|
100
|
+
if (status) {
|
|
101
|
+
console.log(` Ready: ${status.ready}`);
|
|
102
|
+
console.log(` Restarts: ${status.restartCount}`);
|
|
103
|
+
const stateEntries = Object.entries(status.state || {});
|
|
104
|
+
if (stateEntries.length > 0) {
|
|
105
|
+
const [state, details] = stateEntries[0];
|
|
106
|
+
console.log(` State: ${state}`);
|
|
107
|
+
if (details && typeof details === 'object') {
|
|
108
|
+
Object.entries(details).forEach(([key, value]) => {
|
|
109
|
+
console.log(` ${key}: ${value}`);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
console.log('');
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
console.log(chalk_1.default.bold('Events:'));
|
|
118
|
+
console.log(' <Events not available in this implementation>');
|
|
119
|
+
}
|
|
120
|
+
function describeService(service) {
|
|
121
|
+
console.log(chalk_1.default.bold(`Name: ${service.metadata.name}`));
|
|
122
|
+
console.log(chalk_1.default.bold(`Namespace: ${service.metadata.namespace}`));
|
|
123
|
+
console.log(chalk_1.default.bold(`Labels: ${JSON.stringify(service.metadata.labels || {})}`));
|
|
124
|
+
console.log(chalk_1.default.bold(`Selector: ${JSON.stringify(service.spec.selector || {})}`));
|
|
125
|
+
console.log(chalk_1.default.bold(`Type: ${service.spec.type}`));
|
|
126
|
+
console.log(chalk_1.default.bold(`IP: ${service.spec.clusterIP}`));
|
|
127
|
+
if (service.spec.ports) {
|
|
128
|
+
console.log(chalk_1.default.bold('\nPorts:'));
|
|
129
|
+
service.spec.ports.forEach((port) => {
|
|
130
|
+
console.log(` ${port.name || '<unnamed>'}: ${port.port}/${port.protocol} -> ${port.targetPort}`);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
console.log(chalk_1.default.bold('\nSession Affinity: ' + (service.spec.sessionAffinity || 'None')));
|
|
134
|
+
console.log(chalk_1.default.bold('\nEvents:'));
|
|
135
|
+
console.log(' <Events not available in this implementation>');
|
|
136
|
+
}
|
|
137
|
+
function describeDeployment(deployment) {
|
|
138
|
+
console.log(chalk_1.default.bold(`Name: ${deployment.metadata.name}`));
|
|
139
|
+
console.log(chalk_1.default.bold(`Namespace: ${deployment.metadata.namespace}`));
|
|
140
|
+
console.log(chalk_1.default.bold(`CreationTimestamp: ${deployment.metadata.creationTimestamp}`));
|
|
141
|
+
console.log(chalk_1.default.bold(`Labels: ${JSON.stringify(deployment.metadata.labels || {})}`));
|
|
142
|
+
console.log(chalk_1.default.bold(`Annotations: ${JSON.stringify(deployment.metadata.annotations || {})}`));
|
|
143
|
+
console.log(chalk_1.default.bold(`Selector: ${JSON.stringify(deployment.spec.selector.matchLabels || {})}`));
|
|
144
|
+
console.log(chalk_1.default.bold(`Replicas: ${deployment.status.replicas || 0} desired | ${deployment.status.updatedReplicas || 0} updated | ${deployment.status.readyReplicas || 0} ready | ${deployment.status.availableReplicas || 0} available`));
|
|
145
|
+
console.log(chalk_1.default.bold(`StrategyType: ${deployment.spec.strategy.type}`));
|
|
146
|
+
if (deployment.spec.template && deployment.spec.template.spec.containers) {
|
|
147
|
+
console.log(chalk_1.default.bold('\nContainers:'));
|
|
148
|
+
deployment.spec.template.spec.containers.forEach((container) => {
|
|
149
|
+
console.log(chalk_1.default.bold(` ${container.name}:`));
|
|
150
|
+
console.log(` Image: ${container.image}`);
|
|
151
|
+
console.log(` Ports: ${container.ports?.map((p) => p.containerPort).join(', ') || '<none>'}`);
|
|
152
|
+
console.log(` Environment: ${container.env?.map((e) => `${e.name}=${e.value}`).join(', ') || '<none>'}`);
|
|
153
|
+
console.log('');
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
if (deployment.status.conditions) {
|
|
157
|
+
console.log(chalk_1.default.bold('\nConditions:'));
|
|
158
|
+
console.log(chalk_1.default.bold(' Type Status Reason'));
|
|
159
|
+
deployment.status.conditions.forEach((condition) => {
|
|
160
|
+
console.log(` ${condition.type.padEnd(15)}${condition.status.padEnd(8)}${condition.reason || ''}`);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
console.log(chalk_1.default.bold('\nEvents:'));
|
|
164
|
+
console.log(' <Events not available in this implementation>');
|
|
165
|
+
}
|
|
166
|
+
exports.default = async (argv, prompter, _options) => {
|
|
167
|
+
try {
|
|
168
|
+
const client = new kubernetesjs_1.KubernetesClient({
|
|
169
|
+
restEndpoint: 'http://localhost:8001' // Default kube-proxy endpoint
|
|
170
|
+
});
|
|
171
|
+
const namespace = argv.n || argv.namespace || (0, config_1.getCurrentNamespace)();
|
|
172
|
+
const resourceType = argv._?.[0] || await promptResourceType(prompter, argv);
|
|
173
|
+
const resourceName = argv._?.[1] || await promptResourceName(prompter, argv, resourceType, namespace, client);
|
|
174
|
+
if (!resourceName) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
console.log(chalk_1.default.blue(`Describing ${resourceType} ${resourceName} in namespace ${namespace}...`));
|
|
178
|
+
switch (resourceType) {
|
|
179
|
+
case 'pod':
|
|
180
|
+
const pod = await client.readCoreV1NamespacedPod({
|
|
181
|
+
path: {
|
|
182
|
+
namespace,
|
|
183
|
+
name: resourceName
|
|
184
|
+
},
|
|
185
|
+
query: {}
|
|
186
|
+
});
|
|
187
|
+
describePod(pod);
|
|
188
|
+
break;
|
|
189
|
+
case 'service':
|
|
190
|
+
const service = await client.readCoreV1NamespacedService({
|
|
191
|
+
path: {
|
|
192
|
+
namespace,
|
|
193
|
+
name: resourceName
|
|
194
|
+
},
|
|
195
|
+
query: {}
|
|
196
|
+
});
|
|
197
|
+
describeService(service);
|
|
198
|
+
break;
|
|
199
|
+
case 'deployment':
|
|
200
|
+
const deployment = await client.readAppsV1NamespacedDeployment({
|
|
201
|
+
path: {
|
|
202
|
+
namespace,
|
|
203
|
+
name: resourceName
|
|
204
|
+
},
|
|
205
|
+
query: {}
|
|
206
|
+
});
|
|
207
|
+
describeDeployment(deployment);
|
|
208
|
+
break;
|
|
209
|
+
default:
|
|
210
|
+
console.log(chalk_1.default.yellow(`Resource type '${resourceType}' not implemented yet`));
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
catch (error) {
|
|
214
|
+
console.error(chalk_1.default.red(`Error: ${error}`));
|
|
215
|
+
}
|
|
216
|
+
};
|