kubernetes-fluent-client 3.1.2 → 3.1.3

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 (57) hide show
  1. package/.husky/pre-commit +1 -0
  2. package/.lintstagedrc.json +5 -0
  3. package/dist/fluent/watch.d.ts.map +1 -1
  4. package/dist/fluent/watch.js +4 -3
  5. package/package.json +8 -5
  6. package/src/fluent/watch.ts +6 -4
  7. package/dist/fetch.test.d.ts +0 -2
  8. package/dist/fetch.test.d.ts.map +0 -1
  9. package/dist/fetch.test.js +0 -97
  10. package/dist/fileSystem.test.d.ts +0 -2
  11. package/dist/fileSystem.test.d.ts.map +0 -1
  12. package/dist/fileSystem.test.js +0 -75
  13. package/dist/fluent/http2-watch.spec.d.ts +0 -2
  14. package/dist/fluent/http2-watch.spec.d.ts.map +0 -1
  15. package/dist/fluent/http2-watch.spec.js +0 -284
  16. package/dist/fluent/index.test.d.ts +0 -2
  17. package/dist/fluent/index.test.d.ts.map +0 -1
  18. package/dist/fluent/index.test.js +0 -193
  19. package/dist/fluent/utils.test.d.ts +0 -2
  20. package/dist/fluent/utils.test.d.ts.map +0 -1
  21. package/dist/fluent/utils.test.js +0 -215
  22. package/dist/fluent/watch.spec.d.ts +0 -2
  23. package/dist/fluent/watch.spec.d.ts.map +0 -1
  24. package/dist/fluent/watch.spec.js +0 -261
  25. package/dist/generate.test.d.ts +0 -2
  26. package/dist/generate.test.d.ts.map +0 -1
  27. package/dist/generate.test.js +0 -320
  28. package/dist/helpers.test.d.ts +0 -2
  29. package/dist/helpers.test.d.ts.map +0 -1
  30. package/dist/helpers.test.js +0 -37
  31. package/dist/kinds.test.d.ts +0 -2
  32. package/dist/kinds.test.d.ts.map +0 -1
  33. package/dist/kinds.test.js +0 -155
  34. package/dist/postProcessing.test.d.ts +0 -2
  35. package/dist/postProcessing.test.d.ts.map +0 -1
  36. package/dist/postProcessing.test.js +0 -550
  37. package/e2e/cli.e2e.test.ts +0 -127
  38. package/e2e/crds/policyreports.default.expected/policyreport-v1alpha1.ts +0 -332
  39. package/e2e/crds/policyreports.default.expected/policyreport-v1alpha2.ts +0 -360
  40. package/e2e/crds/policyreports.default.expected/policyreport-v1beta1.ts +0 -360
  41. package/e2e/crds/policyreports.no.post.expected/policyreport-v1alpha1.ts +0 -331
  42. package/e2e/crds/policyreports.no.post.expected/policyreport-v1alpha2.ts +0 -360
  43. package/e2e/crds/policyreports.no.post.expected/policyreport-v1beta1.ts +0 -360
  44. package/e2e/crds/test.yaml/policyreports.test.yaml +0 -1008
  45. package/e2e/crds/test.yaml/uds-podmonitors.test.yaml +0 -1245
  46. package/e2e/crds/uds-podmonitors.default.expected/podmonitor-v1.ts +0 -1333
  47. package/e2e/crds/uds-podmonitors.no.post.expected/podmonitor-v1.ts +0 -1360
  48. package/src/fetch.test.ts +0 -115
  49. package/src/fileSystem.test.ts +0 -67
  50. package/src/fluent/http2-watch.spec.ts +0 -335
  51. package/src/fluent/index.test.ts +0 -268
  52. package/src/fluent/utils.test.ts +0 -276
  53. package/src/fluent/watch.spec.ts +0 -299
  54. package/src/generate.test.ts +0 -399
  55. package/src/helpers.test.ts +0 -42
  56. package/src/kinds.test.ts +0 -166
  57. package/src/postProcessing.test.ts +0 -742
package/src/fetch.test.ts DELETED
@@ -1,115 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- // SPDX-FileCopyrightText: 2023-Present The Kubernetes Fluent Client Authors
3
-
4
- import { expect, test, beforeEach } from "@jest/globals";
5
-
6
- import { StatusCodes } from "http-status-codes";
7
- import nock from "nock";
8
- import { RequestInit } from "node-fetch";
9
- import { fetch } from "./fetch";
10
-
11
- beforeEach(() => {
12
- nock("https://jsonplaceholder.typicode.com")
13
- .get("/todos/1")
14
- .reply(200, {
15
- userId: 1,
16
- id: 1,
17
- title: "Example title",
18
- completed: false,
19
- })
20
- .post("/todos", {
21
- title: "test todo",
22
- userId: 1,
23
- completed: false,
24
- })
25
- .reply(200, (uri, requestBody) => requestBody)
26
- .get("/todos/empty-null")
27
- .reply(200, undefined)
28
- .get("/todos/empty-string")
29
- .reply(200, "")
30
- .get("/todos/empty-object")
31
- .reply(200, {})
32
- .get("/todos/invalid")
33
- .replyWithError("Something bad happened");
34
- });
35
-
36
- test("fetch: should return without type data", async () => {
37
- const url = "https://jsonplaceholder.typicode.com/todos/1";
38
- const { data, ok } = await fetch<{ title: string }>(url);
39
- expect(ok).toBe(true);
40
- expect(data["title"]).toBe("Example title");
41
- });
42
-
43
- test("fetch: should return parsed JSON response as a specific type", async () => {
44
- interface Todo {
45
- userId: number;
46
- id: number;
47
- title: string;
48
- completed: boolean;
49
- }
50
-
51
- const url = "https://jsonplaceholder.typicode.com/todos/1";
52
- const { data, ok } = await fetch<Todo>(url);
53
- expect(ok).toBe(true);
54
- expect(data.id).toBe(1);
55
- expect(typeof data.title).toBe("string");
56
- expect(typeof data.completed).toBe("boolean");
57
- });
58
-
59
- test("fetch: should handle additional request options", async () => {
60
- const url = "https://jsonplaceholder.typicode.com/todos";
61
- const requestOptions: RequestInit = {
62
- method: "POST",
63
- body: JSON.stringify({
64
- title: "test todo",
65
- userId: 1,
66
- completed: false,
67
- }),
68
- headers: {
69
- "Content-type": "application/json; charset=UTF-8",
70
- },
71
- };
72
-
73
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
74
- const { data, ok } = await fetch<any>(url, requestOptions);
75
- expect(ok).toBe(true);
76
- expect(data["title"]).toBe("test todo");
77
- expect(data["userId"]).toBe(1);
78
- expect(data["completed"]).toBe(false);
79
- });
80
-
81
- test("fetch: should handle empty (null) responses", async () => {
82
- const url = "https://jsonplaceholder.typicode.com/todos/empty-null";
83
- const resp = await fetch(url);
84
-
85
- expect(resp.data).toBe("");
86
- expect(resp.ok).toBe(true);
87
- expect(resp.status).toBe(StatusCodes.OK);
88
- });
89
-
90
- test("fetch: should handle empty (string) responses", async () => {
91
- const url = "https://jsonplaceholder.typicode.com/todos/empty-string";
92
- const resp = await fetch(url);
93
-
94
- expect(resp.data).toBe("");
95
- expect(resp.ok).toBe(true);
96
- expect(resp.status).toBe(StatusCodes.OK);
97
- });
98
-
99
- test("fetch: should handle empty (object) responses", async () => {
100
- const url = "https://jsonplaceholder.typicode.com/todos/empty-object";
101
- const resp = await fetch(url);
102
-
103
- expect(resp.data).toEqual({});
104
- expect(resp.ok).toBe(true);
105
- expect(resp.status).toBe(StatusCodes.OK);
106
- });
107
-
108
- test("fetch: should handle failed requests without throwing an error", async () => {
109
- const url = "https://jsonplaceholder.typicode.com/todos/invalid";
110
- const resp = await fetch(url);
111
-
112
- expect(resp.data).toBe(undefined);
113
- expect(resp.ok).toBe(false);
114
- expect(resp.status).toBe(StatusCodes.BAD_REQUEST);
115
- });
@@ -1,67 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- // SPDX-FileCopyrightText: 2023-Present The Kubernetes Fluent Client Authors
3
-
4
- import * as fs from "fs";
5
- import { NodeFileSystem } from "./fileSystem";
6
- import { beforeEach, describe, expect, jest, test } from "@jest/globals";
7
-
8
- // Mock the fs module
9
- jest.mock("fs");
10
-
11
- describe("NodeFileSystem", () => {
12
- let nodeFileSystem: NodeFileSystem;
13
-
14
- beforeEach(() => {
15
- nodeFileSystem = new NodeFileSystem();
16
- jest.clearAllMocks(); // Clear all mocks before each test
17
- });
18
-
19
- describe("readFile", () => {
20
- test("should call fs.readFileSync with correct arguments", () => {
21
- const mockFilePath = "test-file.txt";
22
- const mockFileContent = "This is a test file";
23
-
24
- // Mock the fs.readFileSync method to return the mock file content
25
- (fs.readFileSync as jest.Mock).mockReturnValue(mockFileContent);
26
-
27
- const result = nodeFileSystem.readFile(mockFilePath);
28
-
29
- // Assert that fs.readFileSync was called with the correct file path and encoding
30
- expect(fs.readFileSync).toHaveBeenCalledWith(mockFilePath, "utf8");
31
-
32
- // Assert that the returned content matches the mock file content
33
- expect(result).toBe(mockFileContent);
34
- });
35
- });
36
-
37
- describe("writeFile", () => {
38
- test("should call fs.writeFileSync with correct arguments", () => {
39
- const mockFilePath = "test-file.txt";
40
- const mockFileContent = "This is a test file";
41
-
42
- // Call the writeFile method
43
- nodeFileSystem.writeFile(mockFilePath, mockFileContent);
44
-
45
- // Assert that fs.writeFileSync was called with the correct arguments
46
- expect(fs.writeFileSync).toHaveBeenCalledWith(mockFilePath, mockFileContent, "utf8");
47
- });
48
- });
49
-
50
- describe("readdirSync", () => {
51
- test("should call fs.readdirSync with correct arguments and return file list", () => {
52
- const mockDirectoryPath = "test-directory";
53
- const mockFileList = ["file1.txt", "file2.txt"];
54
-
55
- // Mock the fs.readdirSync method to return the mock file list
56
- (fs.readdirSync as jest.Mock).mockReturnValue(mockFileList);
57
-
58
- const result = nodeFileSystem.readdirSync(mockDirectoryPath);
59
-
60
- // Assert that fs.readdirSync was called with the correct directory path
61
- expect(fs.readdirSync).toHaveBeenCalledWith(mockDirectoryPath);
62
-
63
- // Assert that the returned file list matches the mock file list
64
- expect(result).toEqual(mockFileList);
65
- });
66
- });
67
- });
@@ -1,335 +0,0 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
- import { afterEach, beforeEach, describe, expect, it, jest } from "@jest/globals";
3
- import http2 from "http2";
4
- import { Watcher } from "./watch";
5
- import { WatchEvent, kind } from "..";
6
- import { WatchPhase } from "./types";
7
- import { K8s } from ".";
8
-
9
- jest.mock("http2");
10
-
11
- describe("Watcher HTTP2", () => {
12
- let watcher: Watcher<typeof kind.Pod>;
13
- let mockClient: jest.Mocked<http2.ClientHttp2Session>;
14
- let mockReq: jest.Mocked<http2.ClientHttp2Stream>;
15
- const evtMock = jest.fn<(update: kind.Pod, phase: WatchPhase) => void>();
16
- const errMock = jest.fn<(err: Error) => void>();
17
-
18
- const setupAndStartWatcher = (eventType: WatchEvent, handler: (...args: any[]) => void) => {
19
- watcher.events.on(eventType, handler);
20
- watcher.start().catch(errMock);
21
- };
22
-
23
- beforeEach(() => {
24
- jest.clearAllMocks();
25
-
26
- // http2.client
27
- mockClient = {
28
- request: jest.fn(),
29
- close: jest.fn(),
30
- on: jest.fn(),
31
- destroy: jest.fn(),
32
- } as unknown as jest.Mocked<http2.ClientHttp2Session>;
33
-
34
- // http2.request stream
35
- mockReq = {
36
- on: jest.fn(),
37
- end: jest.fn(),
38
- setEncoding: jest.fn(),
39
- } as unknown as jest.Mocked<http2.ClientHttp2Stream>;
40
-
41
- // http2.connect function to return the mocked client session
42
- (http2.connect as jest.Mock).mockReturnValue(mockClient);
43
- });
44
-
45
- afterEach(() => {
46
- watcher.close();
47
- });
48
-
49
- it("should watch named resources", done => {
50
- const pod = createMockPod("pod-1", "1");
51
- const response = { type: "ADDED", object: pod };
52
-
53
- watcher = K8s(kind.Pod).Watch(evtMock, {
54
- useHTTP2: true,
55
- });
56
-
57
- mockReq.on.mockImplementation((event, callback) => {
58
- switch (event) {
59
- case "response":
60
- callback(
61
- { ":status": 200 } as http2.IncomingHttpHeaders & http2.IncomingHttpStatusHeader,
62
- 0,
63
- );
64
- break;
65
- case "data":
66
- setTimeout(() => {
67
- (callback as (chunk: Buffer) => void)(Buffer.from(JSON.stringify(response)));
68
- }, 10);
69
- break;
70
- case "end":
71
- setTimeout(() => {
72
- (callback as () => void)();
73
- done();
74
- }, 20);
75
- break;
76
- case "error":
77
- errMock(new Error("HTTP2 connection error"));
78
- break;
79
- }
80
- return mockReq;
81
- });
82
-
83
- mockClient.request.mockReturnValue(mockReq);
84
-
85
- setupAndStartWatcher(WatchEvent.CONNECT, () => {
86
- setupAndStartWatcher(WatchEvent.DATA, (receivedPod, phase) => {
87
- expect(receivedPod.metadata?.name).toBe("pod-1");
88
- expect(receivedPod.metadata?.resourceVersion).toBe("1");
89
- expect(phase).toBe(WatchPhase.Added);
90
- done();
91
- });
92
- });
93
- });
94
-
95
- it("should handle resource version is too old", done => {
96
- const errorResponse = {
97
- type: "ERROR",
98
- object: {
99
- kind: "Status",
100
- apiVersion: "v1",
101
- metadata: {},
102
- status: "Failure",
103
- message: "too old resource version: 123 (391079)",
104
- reason: "Gone",
105
- code: 410,
106
- },
107
- };
108
-
109
- watcher = K8s(kind.Pod).Watch(evtMock, {
110
- useHTTP2: true,
111
- });
112
-
113
- mockReq.on.mockImplementation((event, callback) => {
114
- switch (event) {
115
- case "response":
116
- callback(
117
- { ":status": 200 } as http2.IncomingHttpHeaders & http2.IncomingHttpStatusHeader,
118
- 0,
119
- );
120
- break;
121
- case "data":
122
- setTimeout(() => {
123
- (callback as (chunk: Buffer) => void)(Buffer.from(JSON.stringify(errorResponse)));
124
- }, 10);
125
- break;
126
- case "end":
127
- setTimeout(() => {
128
- (callback as () => void)();
129
- done();
130
- }, 20);
131
- break;
132
- case "error":
133
- errMock(new Error("HTTP2 connection error"));
134
- break;
135
- }
136
- return mockReq;
137
- });
138
-
139
- mockClient.request.mockReturnValue(mockReq);
140
-
141
- setupAndStartWatcher(WatchEvent.OLD_RESOURCE_VERSION, res => {
142
- expect(res).toEqual("123");
143
- done();
144
- });
145
- });
146
-
147
- it("should call the event handler for each event", done => {
148
- const pod = createMockPod("pod-0", "1");
149
- const response = { type: "ADDED", object: pod };
150
-
151
- watcher = K8s(kind.Pod).Watch(
152
- (evt, phase) => {
153
- expect(evt.metadata?.name).toEqual("pod-0");
154
- expect(phase).toEqual(WatchPhase.Added);
155
- },
156
- { useHTTP2: true },
157
- );
158
-
159
- mockReq.on.mockImplementation((event, callback) => {
160
- switch (event) {
161
- case "response":
162
- callback(
163
- { ":status": 200 } as http2.IncomingHttpHeaders & http2.IncomingHttpStatusHeader,
164
- 0,
165
- );
166
- break;
167
- case "data":
168
- setTimeout(() => {
169
- (callback as (chunk: Buffer) => void)(Buffer.from(JSON.stringify(response)));
170
- }, 10);
171
- break;
172
- case "end":
173
- setTimeout(() => {
174
- (callback as () => void)();
175
- }, 20);
176
- break;
177
- case "error":
178
- errMock(new Error("HTTP2 connection error"));
179
- break;
180
- }
181
- return mockReq;
182
- });
183
-
184
- mockClient.request.mockReturnValue(mockReq);
185
-
186
- watcher.start().catch(errMock);
187
- done();
188
- });
189
-
190
- it("should return the cache id", () => {
191
- watcher = K8s(kind.Pod).Watch(evtMock, {
192
- resyncDelaySec: 1,
193
- useHTTP2: true,
194
- });
195
- expect(watcher.getCacheID()).toEqual("d69b75a611");
196
- });
197
-
198
- it("should handle the CONNECT event", done => {
199
- watcher = K8s(kind.Pod).Watch(evtMock, {
200
- resyncDelaySec: 1,
201
- useHTTP2: true,
202
- });
203
- setupAndStartWatcher(WatchEvent.CONNECT, () => {});
204
- done();
205
- });
206
-
207
- it("should handle the DATA event", done => {
208
- watcher = K8s(kind.Pod).Watch(evtMock, {
209
- resyncDelaySec: 1,
210
- useHTTP2: true,
211
- });
212
- setupAndStartWatcher(WatchEvent.DATA, (pod, phase) => {
213
- expect(pod.metadata?.name).toEqual("pod-0");
214
- expect(phase).toEqual(WatchPhase.Added);
215
- });
216
- done();
217
- });
218
-
219
- it("should handle the NETWORK_ERROR event", done => {
220
- const errorMessage = "Something bad happened";
221
- watcher = K8s(kind.Pod).Watch(evtMock, {
222
- useHTTP2: true,
223
- resyncDelaySec: 1,
224
- });
225
-
226
- mockReq.on.mockImplementation((event, callback) => {
227
- if (event === "response") {
228
- callback(
229
- { ":status": 200 } as http2.IncomingHttpHeaders & http2.IncomingHttpStatusHeader,
230
- 0,
231
- );
232
- } else if (event === "error") {
233
- (callback as (err: Error) => void)(new Error(errorMessage));
234
- }
235
- return mockReq;
236
- });
237
-
238
- mockClient.request.mockReturnValue(mockReq);
239
-
240
- setupAndStartWatcher(WatchEvent.NETWORK_ERROR, error => {
241
- expect(error.message).toEqual(errorMessage);
242
- });
243
-
244
- watcher.start().catch(errMock);
245
- done();
246
- });
247
-
248
- it("should handle the RECONNECT event on an error", done => {
249
- const errorMessage = "Something bad happened";
250
-
251
- watcher = K8s(kind.Pod).Watch(evtMock, {
252
- useHTTP2: true,
253
- resyncDelaySec: 0.01,
254
- });
255
-
256
- let reconnectCount = 0;
257
-
258
- mockReq.on.mockImplementation((event, callback) => {
259
- if (event === "response") {
260
- callback(
261
- { ":status": 200 } as http2.IncomingHttpHeaders & http2.IncomingHttpStatusHeader,
262
- 0,
263
- );
264
- } else if (event === "error") {
265
- reconnectCount += 1;
266
- (callback as (err: Error) => void)(new Error(errorMessage));
267
- }
268
- return mockReq;
269
- });
270
-
271
- mockClient.request.mockReturnValue(mockReq);
272
-
273
- setupAndStartWatcher(WatchEvent.RECONNECT, count => {
274
- expect(count).toEqual(reconnectCount);
275
- });
276
-
277
- watcher.start().catch(errMock);
278
- done();
279
- });
280
- it("should perform a resync after the resync interval", done => {
281
- watcher = K8s(kind.Pod).Watch(evtMock, {
282
- useHTTP2: true,
283
- resyncDelaySec: 1,
284
- });
285
- watcher.start().catch(errMock);
286
- done();
287
- });
288
- it("should handle the GIVE_UP event", done => {
289
- watcher = K8s(kind.Pod).Watch(evtMock, {
290
- useHTTP2: true,
291
- lastSeenLimitSeconds: 0.01,
292
- resyncDelaySec: 0.01,
293
- resyncFailureMax: 1,
294
- });
295
- setupAndStartWatcher(WatchEvent.GIVE_UP, () => {
296
- expect(errMock).toBeCalled();
297
- });
298
- watcher.start().catch(errMock);
299
- done();
300
- });
301
- });
302
-
303
- /**
304
- * Creates a mock pod object
305
- *
306
- * @param name The name of the pod
307
- * @param resourceVersion The resource version of the pod
308
- * @returns A mock pod object
309
- */
310
- function createMockPod(name: string, resourceVersion: string): kind.Pod {
311
- return {
312
- kind: "Pod",
313
- apiVersion: "v1",
314
- metadata: {
315
- name,
316
- resourceVersion,
317
- uid: "abc-123-xyz",
318
- },
319
- spec: {
320
- containers: [
321
- {
322
- name: "nginx",
323
- image: "nginx:1.14.2",
324
- ports: [
325
- {
326
- containerPort: 80,
327
- protocol: "TCP",
328
- },
329
- ],
330
- },
331
- ],
332
- },
333
- status: {},
334
- };
335
- }