kubernetes-fluent-client 3.0.3 → 3.0.5
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/.prettierignore +4 -0
- package/README.md +24 -0
- package/e2e/cli.e2e.test.ts +127 -0
- package/e2e/crds/policyreports.default.expected/policyreport-v1alpha1.ts +332 -0
- package/e2e/crds/policyreports.default.expected/policyreport-v1alpha2.ts +360 -0
- package/e2e/crds/policyreports.default.expected/policyreport-v1beta1.ts +360 -0
- package/e2e/crds/policyreports.no.post.expected/policyreport-v1alpha1.ts +331 -0
- package/e2e/crds/policyreports.no.post.expected/policyreport-v1alpha2.ts +360 -0
- package/e2e/crds/policyreports.no.post.expected/policyreport-v1beta1.ts +360 -0
- package/e2e/crds/test.yaml/policyreports.test.yaml +1008 -0
- package/e2e/crds/test.yaml/uds-podmonitors.test.yaml +1245 -0
- package/e2e/crds/uds-podmonitors.default.expected/podmonitor-v1.ts +1333 -0
- package/e2e/crds/uds-podmonitors.no.post.expected/podmonitor-v1.ts +1360 -0
- package/package.json +8 -7
- package/src/cli.ts +25 -1
- package/src/fileSystem.test.ts +67 -0
- package/src/fileSystem.ts +25 -0
- package/src/generate.test.ts +368 -358
- package/src/generate.ts +173 -154
- package/src/postProcessing.test.ts +742 -0
- package/src/postProcessing.ts +568 -0
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -48
- package/dist/fetch.d.ts +0 -22
- package/dist/fetch.d.ts.map +0 -1
- package/dist/fetch.js +0 -82
- package/dist/fetch.test.d.ts +0 -2
- package/dist/fetch.test.d.ts.map +0 -1
- package/dist/fetch.test.js +0 -97
- package/dist/fluent/index.d.ts +0 -12
- package/dist/fluent/index.d.ts.map +0 -1
- package/dist/fluent/index.js +0 -228
- package/dist/fluent/index.test.d.ts +0 -2
- package/dist/fluent/index.test.d.ts.map +0 -1
- package/dist/fluent/index.test.js +0 -193
- package/dist/fluent/types.d.ts +0 -187
- package/dist/fluent/types.d.ts.map +0 -1
- package/dist/fluent/types.js +0 -16
- package/dist/fluent/utils.d.ts +0 -41
- package/dist/fluent/utils.d.ts.map +0 -1
- package/dist/fluent/utils.js +0 -153
- package/dist/fluent/utils.test.d.ts +0 -2
- package/dist/fluent/utils.test.d.ts.map +0 -1
- package/dist/fluent/utils.test.js +0 -215
- package/dist/fluent/watch.d.ts +0 -86
- package/dist/fluent/watch.d.ts.map +0 -1
- package/dist/fluent/watch.js +0 -425
- package/dist/fluent/watch.spec.d.ts +0 -2
- package/dist/fluent/watch.spec.d.ts.map +0 -1
- package/dist/fluent/watch.spec.js +0 -261
- package/dist/generate.d.ts +0 -24
- package/dist/generate.d.ts.map +0 -1
- package/dist/generate.js +0 -195
- package/dist/generate.test.d.ts +0 -2
- package/dist/generate.test.d.ts.map +0 -1
- package/dist/generate.test.js +0 -373
- package/dist/helpers.d.ts +0 -33
- package/dist/helpers.d.ts.map +0 -1
- package/dist/helpers.js +0 -103
- package/dist/helpers.test.d.ts +0 -2
- package/dist/helpers.test.d.ts.map +0 -1
- package/dist/helpers.test.js +0 -37
- package/dist/index.d.ts +0 -14
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -60
- package/dist/kinds.d.ts +0 -16
- package/dist/kinds.d.ts.map +0 -1
- package/dist/kinds.js +0 -570
- package/dist/kinds.test.d.ts +0 -2
- package/dist/kinds.test.d.ts.map +0 -1
- package/dist/kinds.test.js +0 -155
- package/dist/patch.d.ts +0 -7
- package/dist/patch.d.ts.map +0 -1
- package/dist/patch.js +0 -2
- package/dist/types.d.ts +0 -32
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -16
- package/dist/upstream.d.ts +0 -4
- package/dist/upstream.d.ts.map +0 -1
- package/dist/upstream.js +0 -56
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
-
};
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
const globals_1 = require("@jest/globals");
|
|
8
|
-
const nock_1 = __importDefault(require("nock"));
|
|
9
|
-
const readable_stream_1 = require("readable-stream");
|
|
10
|
-
const _1 = require(".");
|
|
11
|
-
const __1 = require("..");
|
|
12
|
-
const types_1 = require("./types");
|
|
13
|
-
(0, globals_1.describe)("Watcher", () => {
|
|
14
|
-
const evtMock = globals_1.jest.fn();
|
|
15
|
-
const errMock = globals_1.jest.fn();
|
|
16
|
-
const setupAndStartWatcher = (eventType, handler) => {
|
|
17
|
-
watcher.events.on(eventType, handler);
|
|
18
|
-
watcher.start().catch(errMock);
|
|
19
|
-
};
|
|
20
|
-
let watcher;
|
|
21
|
-
(0, globals_1.beforeEach)(() => {
|
|
22
|
-
globals_1.jest.resetAllMocks();
|
|
23
|
-
(0, nock_1.default)("http://jest-test:8080")
|
|
24
|
-
.get("/api/v1/pods")
|
|
25
|
-
.reply(200, {
|
|
26
|
-
kind: "PodList",
|
|
27
|
-
apiVersion: "v1",
|
|
28
|
-
metadata: {
|
|
29
|
-
resourceVersion: "10",
|
|
30
|
-
},
|
|
31
|
-
items: [createMockPod(`pod-0`, `1`)],
|
|
32
|
-
});
|
|
33
|
-
(0, nock_1.default)("http://jest-test:8080")
|
|
34
|
-
.get("/api/v1/pods")
|
|
35
|
-
.query({ watch: "true", resourceVersion: "10" })
|
|
36
|
-
.reply(200, () => {
|
|
37
|
-
const stream = new readable_stream_1.PassThrough();
|
|
38
|
-
const resources = [
|
|
39
|
-
{ type: "ADDED", object: createMockPod(`pod-0`, `1`) },
|
|
40
|
-
{ type: "MODIFIED", object: createMockPod(`pod-0`, `2`) },
|
|
41
|
-
];
|
|
42
|
-
resources.forEach(resource => {
|
|
43
|
-
stream.write(JSON.stringify(resource) + "\n");
|
|
44
|
-
});
|
|
45
|
-
stream.end();
|
|
46
|
-
return stream;
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
(0, globals_1.afterEach)(() => {
|
|
50
|
-
watcher.close();
|
|
51
|
-
});
|
|
52
|
-
(0, globals_1.it)("should watch named resources", done => {
|
|
53
|
-
nock_1.default.cleanAll();
|
|
54
|
-
(0, nock_1.default)("http://jest-test:8080")
|
|
55
|
-
.get("/api/v1/namespaces/tester/pods")
|
|
56
|
-
.query({ fieldSelector: "metadata.name=demo" })
|
|
57
|
-
.reply(200, createMockPod(`demo`, `15`));
|
|
58
|
-
(0, nock_1.default)("http://jest-test:8080")
|
|
59
|
-
.get("/api/v1/namespaces/tester/pods")
|
|
60
|
-
.query({
|
|
61
|
-
watch: "true",
|
|
62
|
-
fieldSelector: "metadata.name=demo",
|
|
63
|
-
resourceVersion: "15",
|
|
64
|
-
})
|
|
65
|
-
.reply(200);
|
|
66
|
-
watcher = (0, _1.K8s)(__1.kind.Pod, { name: "demo" }).InNamespace("tester").Watch(evtMock);
|
|
67
|
-
setupAndStartWatcher(__1.WatchEvent.CONNECT, () => {
|
|
68
|
-
done();
|
|
69
|
-
});
|
|
70
|
-
});
|
|
71
|
-
(0, globals_1.it)("should handle resource version is too old", done => {
|
|
72
|
-
nock_1.default.cleanAll();
|
|
73
|
-
(0, nock_1.default)("http://jest-test:8080")
|
|
74
|
-
.get("/api/v1/pods")
|
|
75
|
-
.reply(200, {
|
|
76
|
-
kind: "PodList",
|
|
77
|
-
apiVersion: "v1",
|
|
78
|
-
metadata: {
|
|
79
|
-
resourceVersion: "25",
|
|
80
|
-
},
|
|
81
|
-
items: [createMockPod(`pod-0`, `1`)],
|
|
82
|
-
});
|
|
83
|
-
(0, nock_1.default)("http://jest-test:8080")
|
|
84
|
-
.get("/api/v1/pods")
|
|
85
|
-
.query({ watch: "true", resourceVersion: "25" })
|
|
86
|
-
.reply(200, () => {
|
|
87
|
-
const stream = new readable_stream_1.PassThrough();
|
|
88
|
-
stream.write(JSON.stringify({
|
|
89
|
-
type: "ERROR",
|
|
90
|
-
object: {
|
|
91
|
-
kind: "Status",
|
|
92
|
-
apiVersion: "v1",
|
|
93
|
-
metadata: {},
|
|
94
|
-
status: "Failure",
|
|
95
|
-
message: "too old resource version: 123 (391079)",
|
|
96
|
-
reason: "Gone",
|
|
97
|
-
code: 410,
|
|
98
|
-
},
|
|
99
|
-
}) + "\n");
|
|
100
|
-
stream.end();
|
|
101
|
-
return stream;
|
|
102
|
-
});
|
|
103
|
-
watcher = (0, _1.K8s)(__1.kind.Pod).Watch(evtMock);
|
|
104
|
-
setupAndStartWatcher(__1.WatchEvent.OLD_RESOURCE_VERSION, res => {
|
|
105
|
-
(0, globals_1.expect)(res).toEqual("25");
|
|
106
|
-
done();
|
|
107
|
-
});
|
|
108
|
-
});
|
|
109
|
-
(0, globals_1.it)("should call the event handler for each event", done => {
|
|
110
|
-
watcher = (0, _1.K8s)(__1.kind.Pod).Watch((evt, phase) => {
|
|
111
|
-
(0, globals_1.expect)(evt.metadata?.name).toEqual(`pod-0`);
|
|
112
|
-
(0, globals_1.expect)(phase).toEqual(types_1.WatchPhase.Added);
|
|
113
|
-
done();
|
|
114
|
-
});
|
|
115
|
-
watcher.start().catch(errMock);
|
|
116
|
-
});
|
|
117
|
-
(0, globals_1.it)("should return the cache id", () => {
|
|
118
|
-
watcher = (0, _1.K8s)(__1.kind.Pod).Watch(evtMock, {
|
|
119
|
-
resyncDelaySec: 1,
|
|
120
|
-
});
|
|
121
|
-
(0, globals_1.expect)(watcher.getCacheID()).toEqual("d69b75a611");
|
|
122
|
-
});
|
|
123
|
-
(0, globals_1.it)("should handle the CONNECT event", done => {
|
|
124
|
-
watcher = (0, _1.K8s)(__1.kind.Pod).Watch(evtMock, {
|
|
125
|
-
resyncDelaySec: 1,
|
|
126
|
-
});
|
|
127
|
-
setupAndStartWatcher(__1.WatchEvent.CONNECT, () => {
|
|
128
|
-
done();
|
|
129
|
-
});
|
|
130
|
-
});
|
|
131
|
-
(0, globals_1.it)("should handle the DATA event", done => {
|
|
132
|
-
watcher = (0, _1.K8s)(__1.kind.Pod).Watch(evtMock, {
|
|
133
|
-
resyncDelaySec: 1,
|
|
134
|
-
});
|
|
135
|
-
setupAndStartWatcher(__1.WatchEvent.DATA, (pod, phase) => {
|
|
136
|
-
(0, globals_1.expect)(pod.metadata?.name).toEqual(`pod-0`);
|
|
137
|
-
(0, globals_1.expect)(phase).toEqual(types_1.WatchPhase.Added);
|
|
138
|
-
done();
|
|
139
|
-
});
|
|
140
|
-
});
|
|
141
|
-
(0, globals_1.it)("should handle the NETWORK_ERROR event", done => {
|
|
142
|
-
nock_1.default.cleanAll();
|
|
143
|
-
(0, nock_1.default)("http://jest-test:8080")
|
|
144
|
-
.get("/api/v1/pods")
|
|
145
|
-
.reply(200, {
|
|
146
|
-
kind: "PodList",
|
|
147
|
-
apiVersion: "v1",
|
|
148
|
-
metadata: {
|
|
149
|
-
resourceVersion: "45",
|
|
150
|
-
},
|
|
151
|
-
items: [createMockPod(`pod-0`, `1`)],
|
|
152
|
-
});
|
|
153
|
-
(0, nock_1.default)("http://jest-test:8080")
|
|
154
|
-
.get("/api/v1/pods")
|
|
155
|
-
.query({ watch: "true", resourceVersion: "45" })
|
|
156
|
-
.replyWithError("Something bad happened");
|
|
157
|
-
watcher = (0, _1.K8s)(__1.kind.Pod).Watch(evtMock, {
|
|
158
|
-
resyncDelaySec: 1,
|
|
159
|
-
});
|
|
160
|
-
setupAndStartWatcher(__1.WatchEvent.NETWORK_ERROR, error => {
|
|
161
|
-
(0, globals_1.expect)(error.message).toEqual("request to http://jest-test:8080/api/v1/pods?watch=true&resourceVersion=45 failed, reason: Something bad happened");
|
|
162
|
-
done();
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
(0, globals_1.it)("should handle the RECONNECT event on an error", done => {
|
|
166
|
-
nock_1.default.cleanAll();
|
|
167
|
-
(0, nock_1.default)("http://jest-test:8080")
|
|
168
|
-
.get("/api/v1/pods")
|
|
169
|
-
.reply(200, {
|
|
170
|
-
kind: "PodList",
|
|
171
|
-
apiVersion: "v1",
|
|
172
|
-
metadata: {
|
|
173
|
-
resourceVersion: "65",
|
|
174
|
-
},
|
|
175
|
-
items: [createMockPod(`pod-0`, `1`)],
|
|
176
|
-
});
|
|
177
|
-
(0, nock_1.default)("http://jest-test:8080")
|
|
178
|
-
.get("/api/v1/pods")
|
|
179
|
-
.query({ watch: "true", resourceVersion: "65" })
|
|
180
|
-
.replyWithError("Something bad happened");
|
|
181
|
-
watcher = (0, _1.K8s)(__1.kind.Pod).Watch(evtMock, {
|
|
182
|
-
resyncDelaySec: 0.01,
|
|
183
|
-
});
|
|
184
|
-
setupAndStartWatcher(__1.WatchEvent.RECONNECT, count => {
|
|
185
|
-
(0, globals_1.expect)(count).toEqual(1);
|
|
186
|
-
done();
|
|
187
|
-
});
|
|
188
|
-
});
|
|
189
|
-
(0, globals_1.it)("should perform a resync after the resync interval", done => {
|
|
190
|
-
watcher = (0, _1.K8s)(__1.kind.Pod).Watch(evtMock, {
|
|
191
|
-
resyncDelaySec: 0.01,
|
|
192
|
-
lastSeenLimitSeconds: 0.01,
|
|
193
|
-
});
|
|
194
|
-
setupAndStartWatcher(__1.WatchEvent.RECONNECT, count => {
|
|
195
|
-
(0, globals_1.expect)(count).toEqual(1);
|
|
196
|
-
done();
|
|
197
|
-
});
|
|
198
|
-
});
|
|
199
|
-
(0, globals_1.it)("should handle the GIVE_UP event", done => {
|
|
200
|
-
nock_1.default.cleanAll();
|
|
201
|
-
(0, nock_1.default)("http://jest-test:8080")
|
|
202
|
-
.get("/api/v1/pods")
|
|
203
|
-
.reply(200, {
|
|
204
|
-
kind: "PodList",
|
|
205
|
-
apiVersion: "v1",
|
|
206
|
-
metadata: {
|
|
207
|
-
resourceVersion: "75",
|
|
208
|
-
},
|
|
209
|
-
items: [createMockPod(`pod-0`, `1`)],
|
|
210
|
-
});
|
|
211
|
-
(0, nock_1.default)("http://jest-test:8080")
|
|
212
|
-
.get("/api/v1/pods")
|
|
213
|
-
.query({ watch: "true", resourceVersion: "75" })
|
|
214
|
-
.replyWithError("Something bad happened");
|
|
215
|
-
watcher = (0, _1.K8s)(__1.kind.Pod).Watch(evtMock, {
|
|
216
|
-
resyncFailureMax: 1,
|
|
217
|
-
resyncDelaySec: 0.01,
|
|
218
|
-
lastSeenLimitSeconds: 1,
|
|
219
|
-
});
|
|
220
|
-
setupAndStartWatcher(__1.WatchEvent.GIVE_UP, error => {
|
|
221
|
-
(0, globals_1.expect)(error.message).toContain("Retry limit (1) exceeded, giving up");
|
|
222
|
-
done();
|
|
223
|
-
});
|
|
224
|
-
});
|
|
225
|
-
});
|
|
226
|
-
/**
|
|
227
|
-
* Creates a mock pod object
|
|
228
|
-
*
|
|
229
|
-
* @param name The name of the pod
|
|
230
|
-
* @param resourceVersion The resource version of the pod
|
|
231
|
-
* @returns A mock pod object
|
|
232
|
-
*/
|
|
233
|
-
function createMockPod(name, resourceVersion) {
|
|
234
|
-
return {
|
|
235
|
-
kind: "Pod",
|
|
236
|
-
apiVersion: "v1",
|
|
237
|
-
metadata: {
|
|
238
|
-
name: name,
|
|
239
|
-
resourceVersion: resourceVersion,
|
|
240
|
-
uid: Math.random().toString(36).substring(7),
|
|
241
|
-
// ... other metadata fields
|
|
242
|
-
},
|
|
243
|
-
spec: {
|
|
244
|
-
containers: [
|
|
245
|
-
{
|
|
246
|
-
name: "nginx",
|
|
247
|
-
image: "nginx:1.14.2",
|
|
248
|
-
ports: [
|
|
249
|
-
{
|
|
250
|
-
containerPort: 80,
|
|
251
|
-
protocol: "TCP",
|
|
252
|
-
},
|
|
253
|
-
],
|
|
254
|
-
},
|
|
255
|
-
],
|
|
256
|
-
},
|
|
257
|
-
status: {
|
|
258
|
-
// ... pod status
|
|
259
|
-
},
|
|
260
|
-
};
|
|
261
|
-
}
|
package/dist/generate.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import { TargetLanguage } from "quicktype-core";
|
|
2
|
-
import { LogFn } from "./types";
|
|
3
|
-
export interface GenerateOptions {
|
|
4
|
-
/** The source URL, yaml file path or K8s CRD name */
|
|
5
|
-
source: string;
|
|
6
|
-
/** The output directory path */
|
|
7
|
-
directory?: string;
|
|
8
|
-
/** Disable kubernetes-fluent-client wrapping */
|
|
9
|
-
plain?: boolean;
|
|
10
|
-
/** The language to generate types in */
|
|
11
|
-
language?: string | TargetLanguage;
|
|
12
|
-
/** Override the NPM package to import when generating formatted Typescript */
|
|
13
|
-
npmPackage?: string;
|
|
14
|
-
/** Log function callback */
|
|
15
|
-
logFn: LogFn;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Generate TypeScript types from a K8s CRD
|
|
19
|
-
*
|
|
20
|
-
* @param opts The options to use when generating
|
|
21
|
-
* @returns A promise that resolves when the TypeScript types have been generated
|
|
22
|
-
*/
|
|
23
|
-
export declare function generate(opts: GenerateOptions): Promise<Record<string, string[]>>;
|
|
24
|
-
//# sourceMappingURL=generate.d.ts.map
|
package/dist/generate.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AAMA,OAAO,EAIL,cAAc,EAEf,MAAM,gBAAgB,CAAC;AAKxB,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,MAAM,WAAW,eAAe;IAC9B,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gDAAgD;IAChD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,MAAM,GAAG,cAAc,CAAC;IACnC,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,KAAK,EAAE,KAAK,CAAC;CACd;AA0KD;;;;;GAKG;AACH,wBAAsB,QAAQ,CAAC,IAAI,EAAE,eAAe,qCA4BnD"}
|
package/dist/generate.js
DELETED
|
@@ -1,195 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
// SPDX-FileCopyrightText: 2023-Present The Kubernetes Fluent Client Authors
|
|
4
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
5
|
-
if (k2 === undefined) k2 = k;
|
|
6
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
7
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
8
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
9
|
-
}
|
|
10
|
-
Object.defineProperty(o, k2, desc);
|
|
11
|
-
}) : (function(o, m, k, k2) {
|
|
12
|
-
if (k2 === undefined) k2 = k;
|
|
13
|
-
o[k2] = m[k];
|
|
14
|
-
}));
|
|
15
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
16
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
17
|
-
}) : function(o, v) {
|
|
18
|
-
o["default"] = v;
|
|
19
|
-
});
|
|
20
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
21
|
-
if (mod && mod.__esModule) return mod;
|
|
22
|
-
var result = {};
|
|
23
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
24
|
-
__setModuleDefault(result, mod);
|
|
25
|
-
return result;
|
|
26
|
-
};
|
|
27
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
-
exports.generate = generate;
|
|
29
|
-
const client_node_1 = require("@kubernetes/client-node");
|
|
30
|
-
const fs = __importStar(require("fs"));
|
|
31
|
-
const path = __importStar(require("path"));
|
|
32
|
-
const quicktype_core_1 = require("quicktype-core");
|
|
33
|
-
const fetch_1 = require("./fetch");
|
|
34
|
-
const fluent_1 = require("./fluent");
|
|
35
|
-
const upstream_1 = require("./upstream");
|
|
36
|
-
/**
|
|
37
|
-
* Converts a CustomResourceDefinition to TypeScript types
|
|
38
|
-
*
|
|
39
|
-
* @param crd The CustomResourceDefinition to convert
|
|
40
|
-
* @param opts The options to use when converting
|
|
41
|
-
* @returns A promise that resolves when the CustomResourceDefinition has been converted
|
|
42
|
-
*/
|
|
43
|
-
async function convertCRDtoTS(crd, opts) {
|
|
44
|
-
// Get the name of the kind
|
|
45
|
-
const name = crd.spec.names.kind;
|
|
46
|
-
const results = {};
|
|
47
|
-
for (const match of crd.spec.versions) {
|
|
48
|
-
const version = match.name;
|
|
49
|
-
// Get the schema from the matched version
|
|
50
|
-
const schema = JSON.stringify(match?.schema?.openAPIV3Schema);
|
|
51
|
-
// Create a new JSONSchemaInput
|
|
52
|
-
const schemaInput = new quicktype_core_1.JSONSchemaInput(new quicktype_core_1.FetchingJSONSchemaStore());
|
|
53
|
-
opts.logFn(`- Generating ${crd.spec.group}/${version} types for ${name}`);
|
|
54
|
-
// Add the schema to the input
|
|
55
|
-
await schemaInput.addSource({ name, schema });
|
|
56
|
-
// Create a new InputData object
|
|
57
|
-
const inputData = new quicktype_core_1.InputData();
|
|
58
|
-
inputData.addInput(schemaInput);
|
|
59
|
-
// If the language is not specified, default to TypeScript
|
|
60
|
-
if (!opts.language) {
|
|
61
|
-
opts.language = "ts";
|
|
62
|
-
}
|
|
63
|
-
// Generate the types
|
|
64
|
-
const out = await (0, quicktype_core_1.quicktype)({
|
|
65
|
-
inputData,
|
|
66
|
-
lang: opts.language,
|
|
67
|
-
rendererOptions: { "just-types": "true" },
|
|
68
|
-
});
|
|
69
|
-
let processedLines = out.lines;
|
|
70
|
-
// If using typescript, remove the line containing `[property: string]: any;`
|
|
71
|
-
if (opts.language === "ts" || opts.language === "typescript") {
|
|
72
|
-
processedLines = out.lines.filter(line => !line.includes("[property: string]: any;"));
|
|
73
|
-
}
|
|
74
|
-
// If the language is TypeScript and plain is not specified, wire up the fluent client
|
|
75
|
-
if (opts.language === "ts" && !opts.plain) {
|
|
76
|
-
if (!opts.npmPackage) {
|
|
77
|
-
opts.npmPackage = "kubernetes-fluent-client";
|
|
78
|
-
}
|
|
79
|
-
processedLines.unshift(
|
|
80
|
-
// Add warning that the file is auto-generated
|
|
81
|
-
`// This file is auto-generated by ${opts.npmPackage}, do not edit manually\n`,
|
|
82
|
-
// Add the imports before any other lines
|
|
83
|
-
`import { GenericKind, RegisterKind } from "${opts.npmPackage}";\n`);
|
|
84
|
-
// Replace the interface with a named class that extends GenericKind
|
|
85
|
-
const entryIdx = processedLines.findIndex(line => line.includes(`export interface ${name} {`));
|
|
86
|
-
// Replace the interface with a named class that extends GenericKind
|
|
87
|
-
processedLines[entryIdx] = `export class ${name} extends GenericKind {`;
|
|
88
|
-
// Add the RegisterKind call
|
|
89
|
-
processedLines.push(`RegisterKind(${name}, {`);
|
|
90
|
-
processedLines.push(` group: "${crd.spec.group}",`);
|
|
91
|
-
processedLines.push(` version: "${version}",`);
|
|
92
|
-
processedLines.push(` kind: "${name}",`);
|
|
93
|
-
processedLines.push(` plural: "${crd.spec.names.plural}",`);
|
|
94
|
-
processedLines.push(`});`);
|
|
95
|
-
}
|
|
96
|
-
const finalContents = processedLines.join("\n");
|
|
97
|
-
const fileName = `${name.toLowerCase()}-${version.toLowerCase()}`;
|
|
98
|
-
// If an output file is specified, write the output to the file
|
|
99
|
-
if (opts.directory) {
|
|
100
|
-
// Create the directory if it doesn't exist
|
|
101
|
-
fs.mkdirSync(opts.directory, { recursive: true });
|
|
102
|
-
// Write the file
|
|
103
|
-
const filePath = path.join(opts.directory, `${fileName}.${opts.language}`);
|
|
104
|
-
fs.writeFileSync(filePath, finalContents);
|
|
105
|
-
}
|
|
106
|
-
// Add the results to the array
|
|
107
|
-
results[fileName] = processedLines;
|
|
108
|
-
}
|
|
109
|
-
return results;
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* Reads a CustomResourceDefinition from a file, the cluster or the internet
|
|
113
|
-
*
|
|
114
|
-
* @param opts The options to use when reading
|
|
115
|
-
* @returns A promise that resolves when the CustomResourceDefinition has been read
|
|
116
|
-
*/
|
|
117
|
-
async function readOrFetchCrd(opts) {
|
|
118
|
-
const { source, logFn } = opts;
|
|
119
|
-
let filePath;
|
|
120
|
-
if (source[0] === "/") {
|
|
121
|
-
// If source is an absolute path
|
|
122
|
-
filePath = source;
|
|
123
|
-
}
|
|
124
|
-
else {
|
|
125
|
-
// If source is a relative path
|
|
126
|
-
filePath = path.join(process.cwd(), source);
|
|
127
|
-
}
|
|
128
|
-
// First try to read the source as a file
|
|
129
|
-
try {
|
|
130
|
-
if (fs.existsSync(filePath)) {
|
|
131
|
-
logFn(`Attempting to load ${source} as a local file`);
|
|
132
|
-
const payload = fs.readFileSync(filePath, "utf8");
|
|
133
|
-
return (0, client_node_1.loadAllYaml)(payload);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
catch {
|
|
137
|
-
// Ignore errors
|
|
138
|
-
}
|
|
139
|
-
// Next try to parse the source as a URL
|
|
140
|
-
try {
|
|
141
|
-
const url = new URL(source);
|
|
142
|
-
// If the source is a URL, fetch it
|
|
143
|
-
if (url.protocol === "http:" || url.protocol === "https:") {
|
|
144
|
-
logFn(`Attempting to load ${source} as a URL`);
|
|
145
|
-
const { ok, data } = await (0, fetch_1.fetch)(source);
|
|
146
|
-
// If the request failed, throw an error
|
|
147
|
-
if (!ok) {
|
|
148
|
-
throw new Error(`Failed to fetch ${source}: ${data}`);
|
|
149
|
-
}
|
|
150
|
-
return (0, client_node_1.loadAllYaml)(data);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
catch (e) {
|
|
154
|
-
// If invalid, ignore the error
|
|
155
|
-
if (e.code !== "ERR_INVALID_URL") {
|
|
156
|
-
throw new Error(`Error parsing URL ${source}`);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
// Finally, if the source is not a file or URL, try to read it as a CustomResourceDefinition from the cluster
|
|
160
|
-
try {
|
|
161
|
-
logFn(`Attempting to read ${source} from the current Kubernetes context`);
|
|
162
|
-
return [await (0, fluent_1.K8s)(upstream_1.CustomResourceDefinition).Get(source)];
|
|
163
|
-
}
|
|
164
|
-
catch (e) {
|
|
165
|
-
throw new Error(`Failed to read ${source} as a file, url or K8s CRD: ${e.data?.message || "Cluster not available"}`);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Generate TypeScript types from a K8s CRD
|
|
170
|
-
*
|
|
171
|
-
* @param opts The options to use when generating
|
|
172
|
-
* @returns A promise that resolves when the TypeScript types have been generated
|
|
173
|
-
*/
|
|
174
|
-
async function generate(opts) {
|
|
175
|
-
const crds = (await readOrFetchCrd(opts)).filter(crd => !!crd);
|
|
176
|
-
const results = {};
|
|
177
|
-
opts.logFn("");
|
|
178
|
-
for (const crd of crds) {
|
|
179
|
-
if (crd.kind !== "CustomResourceDefinition" || !crd.spec?.versions?.length) {
|
|
180
|
-
opts.logFn(`Skipping ${crd?.metadata?.name}, it does not appear to be a CRD`);
|
|
181
|
-
// Ignore empty and non-CRD objects
|
|
182
|
-
continue;
|
|
183
|
-
}
|
|
184
|
-
// Add the results to the record
|
|
185
|
-
const out = await convertCRDtoTS(crd, opts);
|
|
186
|
-
for (const key of Object.keys(out)) {
|
|
187
|
-
results[key] = out[key];
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
if (opts.directory) {
|
|
191
|
-
// Notify the user that the files have been generated
|
|
192
|
-
opts.logFn(`\n✅ Generated ${Object.keys(results).length} files in the ${opts.directory} directory`);
|
|
193
|
-
}
|
|
194
|
-
return results;
|
|
195
|
-
}
|
package/dist/generate.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"generate.test.d.ts","sourceRoot":"","sources":["../src/generate.test.ts"],"names":[],"mappings":""}
|