@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.
Files changed (59) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +54 -55
  3. package/commands/apply.d.ts +4 -0
  4. package/commands/apply.js +171 -0
  5. package/commands/cluster-info.d.ts +4 -0
  6. package/commands/cluster-info.js +26 -0
  7. package/commands/config-handler.d.ts +11 -0
  8. package/commands/config-handler.js +81 -0
  9. package/commands/config.d.ts +4 -0
  10. package/commands/config.js +72 -0
  11. package/commands/delete.d.ts +4 -0
  12. package/commands/delete.js +256 -0
  13. package/commands/deploy.d.ts +6 -0
  14. package/commands/deploy.js +209 -0
  15. package/commands/describe.d.ts +4 -0
  16. package/commands/describe.js +216 -0
  17. package/commands/exec.d.ts +4 -0
  18. package/commands/exec.js +145 -0
  19. package/commands/get.d.ts +4 -0
  20. package/commands/get.js +164 -0
  21. package/commands/logs.d.ts +4 -0
  22. package/commands/logs.js +110 -0
  23. package/commands/port-forward.d.ts +4 -0
  24. package/commands/port-forward.js +143 -0
  25. package/commands.d.ts +3 -0
  26. package/commands.js +93 -0
  27. package/config.d.ts +22 -0
  28. package/config.js +113 -0
  29. package/esm/commands/apply.js +133 -0
  30. package/esm/commands/cluster-info.js +21 -0
  31. package/esm/commands/config-handler.js +43 -0
  32. package/esm/commands/config.js +67 -0
  33. package/esm/commands/delete.js +218 -0
  34. package/esm/commands/deploy.js +207 -0
  35. package/esm/commands/describe.js +211 -0
  36. package/esm/commands/exec.js +140 -0
  37. package/esm/commands/get.js +159 -0
  38. package/esm/commands/logs.js +105 -0
  39. package/esm/commands/port-forward.js +138 -0
  40. package/esm/commands.js +86 -0
  41. package/esm/config.js +74 -0
  42. package/esm/index.js +19 -0
  43. package/esm/package.js +26 -0
  44. package/esm/utils.js +49 -0
  45. package/index.d.ts +3 -0
  46. package/index.js +22 -0
  47. package/package.d.ts +1 -0
  48. package/package.js +29 -0
  49. package/package.json +37 -61
  50. package/utils.d.ts +11 -0
  51. package/utils.js +58 -0
  52. package/main/client.js +0 -156
  53. package/main/index.js +0 -2598
  54. package/module/client.js +0 -129
  55. package/module/index.js +0 -2594
  56. package/src/client.ts +0 -156
  57. package/src/index.ts +0 -14187
  58. package/types/client.d.ts +0 -31
  59. 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,6 @@
1
+ import { CLIOptions, Inquirerer } from 'inquirerer';
2
+ import { ParsedArgs } from 'minimist';
3
+ declare const _default: (argv: Partial<ParsedArgs>, prompter: Inquirerer, _options: CLIOptions) => Promise<{
4
+ deploymentType: any;
5
+ }>;
6
+ export default _default;
@@ -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,4 @@
1
+ import { CLIOptions, Inquirerer } from 'inquirerer';
2
+ import { ParsedArgs } from 'minimist';
3
+ declare const _default: (argv: Partial<ParsedArgs>, prompter: Inquirerer, _options: CLIOptions) => Promise<void>;
4
+ export default _default;
@@ -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
+ };