kubernetes-fluent-client 3.0.4 → 3.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 (76) hide show
  1. package/e2e/cli.e2e.test.ts +11 -7
  2. package/package.json +6 -6
  3. package/src/fluent/http2-watch.spec.ts +335 -0
  4. package/src/fluent/watch.ts +174 -35
  5. package/dist/cli.d.ts +0 -3
  6. package/dist/cli.d.ts.map +0 -1
  7. package/dist/cli.js +0 -68
  8. package/dist/fetch.d.ts +0 -22
  9. package/dist/fetch.d.ts.map +0 -1
  10. package/dist/fetch.js +0 -82
  11. package/dist/fetch.test.d.ts +0 -2
  12. package/dist/fetch.test.d.ts.map +0 -1
  13. package/dist/fetch.test.js +0 -97
  14. package/dist/fileSystem.d.ts +0 -11
  15. package/dist/fileSystem.d.ts.map +0 -1
  16. package/dist/fileSystem.js +0 -42
  17. package/dist/fileSystem.test.d.ts +0 -2
  18. package/dist/fileSystem.test.d.ts.map +0 -1
  19. package/dist/fileSystem.test.js +0 -75
  20. package/dist/fluent/index.d.ts +0 -12
  21. package/dist/fluent/index.d.ts.map +0 -1
  22. package/dist/fluent/index.js +0 -228
  23. package/dist/fluent/index.test.d.ts +0 -2
  24. package/dist/fluent/index.test.d.ts.map +0 -1
  25. package/dist/fluent/index.test.js +0 -193
  26. package/dist/fluent/types.d.ts +0 -187
  27. package/dist/fluent/types.d.ts.map +0 -1
  28. package/dist/fluent/types.js +0 -16
  29. package/dist/fluent/utils.d.ts +0 -41
  30. package/dist/fluent/utils.d.ts.map +0 -1
  31. package/dist/fluent/utils.js +0 -153
  32. package/dist/fluent/utils.test.d.ts +0 -2
  33. package/dist/fluent/utils.test.d.ts.map +0 -1
  34. package/dist/fluent/utils.test.js +0 -215
  35. package/dist/fluent/watch.d.ts +0 -86
  36. package/dist/fluent/watch.d.ts.map +0 -1
  37. package/dist/fluent/watch.js +0 -425
  38. package/dist/fluent/watch.spec.d.ts +0 -2
  39. package/dist/fluent/watch.spec.d.ts.map +0 -1
  40. package/dist/fluent/watch.spec.js +0 -261
  41. package/dist/generate.d.ts +0 -84
  42. package/dist/generate.d.ts.map +0 -1
  43. package/dist/generate.js +0 -208
  44. package/dist/generate.test.d.ts +0 -2
  45. package/dist/generate.test.d.ts.map +0 -1
  46. package/dist/generate.test.js +0 -320
  47. package/dist/helpers.d.ts +0 -33
  48. package/dist/helpers.d.ts.map +0 -1
  49. package/dist/helpers.js +0 -103
  50. package/dist/helpers.test.d.ts +0 -2
  51. package/dist/helpers.test.d.ts.map +0 -1
  52. package/dist/helpers.test.js +0 -37
  53. package/dist/index.d.ts +0 -14
  54. package/dist/index.d.ts.map +0 -1
  55. package/dist/index.js +0 -60
  56. package/dist/kinds.d.ts +0 -16
  57. package/dist/kinds.d.ts.map +0 -1
  58. package/dist/kinds.js +0 -570
  59. package/dist/kinds.test.d.ts +0 -2
  60. package/dist/kinds.test.d.ts.map +0 -1
  61. package/dist/kinds.test.js +0 -155
  62. package/dist/patch.d.ts +0 -7
  63. package/dist/patch.d.ts.map +0 -1
  64. package/dist/patch.js +0 -2
  65. package/dist/postProcessing.d.ts +0 -246
  66. package/dist/postProcessing.d.ts.map +0 -1
  67. package/dist/postProcessing.js +0 -497
  68. package/dist/postProcessing.test.d.ts +0 -2
  69. package/dist/postProcessing.test.d.ts.map +0 -1
  70. package/dist/postProcessing.test.js +0 -550
  71. package/dist/types.d.ts +0 -32
  72. package/dist/types.d.ts.map +0 -1
  73. package/dist/types.js +0 -16
  74. package/dist/upstream.d.ts +0 -4
  75. package/dist/upstream.d.ts.map +0 -1
  76. package/dist/upstream.js +0 -56
@@ -1,215 +0,0 @@
1
- "use strict";
2
- // SPDX-License-Identifier: Apache-2.0
3
- // SPDX-FileCopyrightText: 2023-Present The Kubernetes Fluent Client Authors
4
- Object.defineProperty(exports, "__esModule", { value: true });
5
- const globals_1 = require("@jest/globals");
6
- const node_fetch_1 = require("node-fetch");
7
- const fetch_1 = require("../fetch");
8
- const kinds_1 = require("../kinds");
9
- const upstream_1 = require("../upstream");
10
- const utils_1 = require("./utils");
11
- globals_1.jest.mock("https");
12
- globals_1.jest.mock("../fetch");
13
- (0, globals_1.describe)("pathBuilder Function", () => {
14
- const serverUrl = "https://jest-test:8080";
15
- (0, globals_1.it)("should throw an error if the kind is not specified and the model is not a KubernetesObject", () => {
16
- const model = { name: "Unknown" };
17
- const filters = {};
18
- (0, globals_1.expect)(() => (0, utils_1.pathBuilder)("", model, filters)).toThrow("Kind not specified for Unknown");
19
- });
20
- (0, globals_1.it)("should generate a path with a set-based label selector", () => {
21
- const filters = {
22
- namespace: "default",
23
- name: "mypod",
24
- labels: { iamalabel: "" },
25
- };
26
- const result = (0, utils_1.pathBuilder)(serverUrl, upstream_1.Pod, filters);
27
- const expected = new URL("/api/v1/namespaces/default/pods/mypod?labelSelector=iamalabel", serverUrl);
28
- (0, globals_1.expect)(result.toString()).toEqual(expected.toString());
29
- });
30
- (0, globals_1.it)("should generate a path for core group kinds (with custom filters)", () => {
31
- const filters = {
32
- namespace: "default",
33
- name: "mypod",
34
- fields: { iamafield: "iamavalue" },
35
- labels: { iamalabel: "iamalabelvalue" },
36
- };
37
- const result = (0, utils_1.pathBuilder)(serverUrl, upstream_1.Pod, filters);
38
- const expected = new URL("/api/v1/namespaces/default/pods/mypod?fieldSelector=iamafield%3Diamavalue&labelSelector=iamalabel%3Diamalabelvalue", serverUrl);
39
- (0, globals_1.expect)(result.toString()).toEqual(expected.toString());
40
- });
41
- (0, globals_1.it)("Version not specified in a Kind", () => {
42
- const filters = {
43
- namespace: "default",
44
- name: "mypod",
45
- };
46
- class Fake {
47
- name;
48
- constructor() {
49
- this.name = "Fake";
50
- }
51
- }
52
- (0, kinds_1.RegisterKind)(Fake, {
53
- kind: "Fake",
54
- version: "",
55
- group: "fake",
56
- });
57
- try {
58
- (0, utils_1.pathBuilder)(serverUrl, Fake, filters);
59
- }
60
- catch (e) {
61
- (0, globals_1.expect)(e.message).toEqual(`Version not specified for Fake`);
62
- }
63
- });
64
- (0, globals_1.it)("should generate a path for core group kinds", () => {
65
- const filters = { namespace: "default", name: "mypod" };
66
- const result = (0, utils_1.pathBuilder)(serverUrl, upstream_1.Pod, filters);
67
- const expected = new URL("/api/v1/namespaces/default/pods/mypod", serverUrl);
68
- (0, globals_1.expect)(result).toEqual(expected);
69
- });
70
- (0, globals_1.it)("should generate a path for non-core group kinds", () => {
71
- const filters = {
72
- namespace: "default",
73
- name: "myingress",
74
- };
75
- const result = (0, utils_1.pathBuilder)(serverUrl, upstream_1.Ingress, filters);
76
- const expected = new URL("/apis/networking.k8s.io/v1/namespaces/default/ingresses/myingress", serverUrl);
77
- (0, globals_1.expect)(result).toEqual(expected);
78
- });
79
- (0, globals_1.it)("should generate a path without a namespace if not provided", () => {
80
- const filters = { name: "tester" };
81
- const result = (0, utils_1.pathBuilder)(serverUrl, upstream_1.ClusterRole, filters);
82
- const expected = new URL("/apis/rbac.authorization.k8s.io/v1/clusterroles/tester", serverUrl);
83
- (0, globals_1.expect)(result).toEqual(expected);
84
- });
85
- (0, globals_1.it)("should generate a path without a name if excludeName is true", () => {
86
- const filters = { namespace: "default", name: "mypod" };
87
- const result = (0, utils_1.pathBuilder)(serverUrl, upstream_1.Pod, filters, true);
88
- const expected = new URL("/api/v1/namespaces/default/pods", serverUrl);
89
- (0, globals_1.expect)(result).toEqual(expected);
90
- });
91
- });
92
- (0, globals_1.describe)("kubeExec Function", () => {
93
- const mockedFetch = globals_1.jest.mocked(fetch_1.fetch);
94
- const fakeFilters = { name: "fake", namespace: "default" };
95
- const fakeMethod = "GET";
96
- const fakePayload = {
97
- metadata: { name: "fake", namespace: "default" },
98
- status: { phase: "Ready" },
99
- };
100
- const fakeUrl = new URL("http://jest-test:8080/api/v1/namespaces/default/pods/fake");
101
- const fakeOpts = {
102
- body: JSON.stringify(fakePayload),
103
- compress: true,
104
- headers: new node_fetch_1.Headers({
105
- "Content-Type": "application/json",
106
- "User-Agent": `kubernetes-fluent-client`,
107
- }),
108
- method: fakeMethod,
109
- };
110
- (0, globals_1.beforeEach)(() => {
111
- mockedFetch.mockClear();
112
- });
113
- (0, globals_1.it)("should make a successful fetch call", async () => {
114
- mockedFetch.mockResolvedValueOnce({
115
- ok: true,
116
- data: fakePayload,
117
- status: 200,
118
- statusText: "OK",
119
- });
120
- const result = await (0, utils_1.k8sExec)(upstream_1.Pod, fakeFilters, fakeMethod, fakePayload);
121
- (0, globals_1.expect)(result).toEqual(fakePayload);
122
- (0, globals_1.expect)(mockedFetch).toHaveBeenCalledWith(fakeUrl, globals_1.expect.objectContaining(fakeOpts));
123
- });
124
- (0, globals_1.it)("should handle PATCH_STATUS", async () => {
125
- mockedFetch.mockResolvedValueOnce({
126
- ok: true,
127
- data: fakePayload,
128
- status: 200,
129
- statusText: "OK",
130
- });
131
- const result = await (0, utils_1.k8sExec)(upstream_1.Pod, fakeFilters, "PATCH_STATUS", fakePayload);
132
- (0, globals_1.expect)(result).toEqual(fakePayload);
133
- (0, globals_1.expect)(mockedFetch).toHaveBeenCalledWith(new URL("http://jest-test:8080/api/v1/namespaces/default/pods/fake/status"), globals_1.expect.objectContaining({
134
- method: "PATCH",
135
- compress: true,
136
- headers: new node_fetch_1.Headers({
137
- "Content-Type": "application/merge-patch+json",
138
- "User-Agent": `kubernetes-fluent-client`,
139
- }),
140
- body: JSON.stringify({ status: fakePayload.status }),
141
- }));
142
- });
143
- (0, globals_1.it)("should handle PATCH", async () => {
144
- mockedFetch.mockResolvedValueOnce({
145
- ok: true,
146
- data: fakePayload,
147
- status: 200,
148
- statusText: "OK",
149
- });
150
- const patchPayload = [{ op: "replace", path: "/status/phase", value: "Ready" }];
151
- const result = await (0, utils_1.k8sExec)(upstream_1.Pod, fakeFilters, "PATCH", patchPayload);
152
- (0, globals_1.expect)(result).toEqual(fakePayload);
153
- (0, globals_1.expect)(mockedFetch).toHaveBeenCalledWith(new URL("http://jest-test:8080/api/v1/namespaces/default/pods/fake"), globals_1.expect.objectContaining({
154
- method: "PATCH",
155
- compress: true,
156
- headers: new node_fetch_1.Headers({
157
- "Content-Type": "application/json-patch+json",
158
- "User-Agent": `kubernetes-fluent-client`,
159
- }),
160
- body: JSON.stringify(patchPayload),
161
- }));
162
- });
163
- (0, globals_1.it)("should handle APPLY", async () => {
164
- mockedFetch.mockResolvedValueOnce({
165
- ok: true,
166
- data: fakePayload,
167
- status: 200,
168
- statusText: "OK",
169
- });
170
- const result = await (0, utils_1.k8sExec)(upstream_1.Pod, fakeFilters, "APPLY", fakePayload);
171
- (0, globals_1.expect)(result).toEqual(fakePayload);
172
- (0, globals_1.expect)(mockedFetch).toHaveBeenCalledWith(new URL("http://jest-test:8080/api/v1/namespaces/default/pods/fake?fieldManager=pepr&fieldValidation=Strict&force=false"), globals_1.expect.objectContaining({
173
- method: "PATCH",
174
- compress: true,
175
- headers: new node_fetch_1.Headers({
176
- "Content-Type": "application/apply-patch+yaml",
177
- "User-Agent": `kubernetes-fluent-client`,
178
- }),
179
- body: JSON.stringify(fakePayload),
180
- }));
181
- });
182
- (0, globals_1.it)("should handle APPLY with force", async () => {
183
- mockedFetch.mockResolvedValueOnce({
184
- ok: true,
185
- data: fakePayload,
186
- status: 200,
187
- statusText: "OK",
188
- });
189
- const result = await (0, utils_1.k8sExec)(upstream_1.Pod, fakeFilters, "APPLY", fakePayload, { force: true });
190
- (0, globals_1.expect)(result).toEqual(fakePayload);
191
- (0, globals_1.expect)(mockedFetch).toHaveBeenCalledWith(new URL("http://jest-test:8080/api/v1/namespaces/default/pods/fake?fieldManager=pepr&fieldValidation=Strict&force=true"), globals_1.expect.objectContaining({
192
- method: "PATCH",
193
- compress: true,
194
- headers: new node_fetch_1.Headers({
195
- "Content-Type": "application/apply-patch+yaml",
196
- "User-Agent": `kubernetes-fluent-client`,
197
- }),
198
- body: JSON.stringify(fakePayload),
199
- }));
200
- });
201
- (0, globals_1.it)("should handle fetch call failure", async () => {
202
- const fakeStatus = 404;
203
- const fakeStatusText = "Not Found";
204
- mockedFetch.mockResolvedValueOnce({
205
- ok: false,
206
- data: null,
207
- status: fakeStatus,
208
- statusText: fakeStatusText,
209
- });
210
- await (0, globals_1.expect)((0, utils_1.k8sExec)(upstream_1.Pod, fakeFilters, fakeMethod, fakePayload)).rejects.toEqual(globals_1.expect.objectContaining({
211
- status: fakeStatus,
212
- statusText: fakeStatusText,
213
- }));
214
- });
215
- });
@@ -1,86 +0,0 @@
1
- import { EventEmitter } from "events";
2
- import { GenericClass } from "../types";
3
- import { Filters, WatchAction } from "./types";
4
- export declare enum WatchEvent {
5
- /** Watch is connected successfully */
6
- CONNECT = "connect",
7
- /** Network error occurs */
8
- NETWORK_ERROR = "network_error",
9
- /** Error decoding data or running the callback */
10
- DATA_ERROR = "data_error",
11
- /** Reconnect is called */
12
- RECONNECT = "reconnect",
13
- /** Retry limit is exceeded */
14
- GIVE_UP = "give_up",
15
- /** Abort is called */
16
- ABORT = "abort",
17
- /** Data is received and decoded */
18
- DATA = "data",
19
- /** 410 (old resource version) occurs */
20
- OLD_RESOURCE_VERSION = "old_resource_version",
21
- /** A reconnect is already pending */
22
- RECONNECT_PENDING = "reconnect_pending",
23
- /** Resource list operation run */
24
- LIST = "list",
25
- /** List operation error */
26
- LIST_ERROR = "list_error",
27
- /** Cache Misses */
28
- CACHE_MISS = "cache_miss",
29
- /** Increment resync failure count */
30
- INC_RESYNC_FAILURE_COUNT = "inc_resync_failure_count",
31
- /** Initialize a relist window */
32
- INIT_CACHE_MISS = "init_cache_miss"
33
- }
34
- /** Configuration for the watch function. */
35
- export type WatchCfg = {
36
- /** The maximum number of times to retry the watch, the retry count is reset on success. Unlimited retries if not specified. */
37
- resyncFailureMax?: number;
38
- /** Seconds between each resync check. Defaults to 5. */
39
- resyncDelaySec?: number;
40
- /** Amount of seconds to wait before relisting the watch list. Defaults to 600 (10 minutes). */
41
- relistIntervalSec?: number;
42
- /** Max amount of seconds to go without receiving an event before reconciliation starts. Defaults to 300 (5 minutes). */
43
- lastSeenLimitSeconds?: number;
44
- };
45
- /** A wrapper around the Kubernetes watch API. */
46
- export declare class Watcher<T extends GenericClass> {
47
- #private;
48
- $relistTimer?: NodeJS.Timeout;
49
- /**
50
- * Setup a Kubernetes watcher for the specified model and filters. The callback function will be called for each event received.
51
- * The watch can be aborted by calling {@link Watcher.close} or by calling abort() on the AbortController returned by {@link Watcher.start}.
52
- *
53
- *
54
- * Kubernetes API docs: {@link https://kubernetes.io/docs/reference/using-api/api-concepts/#efficient-detection-of-changes}
55
- *
56
- * @param model - the model to use for the API
57
- * @param filters - (optional) filter overrides, can also be chained
58
- * @param callback - the callback function to call when an event is received
59
- * @param watchCfg - (optional) watch configuration
60
- */
61
- constructor(model: T, filters: Filters, callback: WatchAction<T>, watchCfg?: WatchCfg);
62
- /**
63
- * Start the watch.
64
- *
65
- * @returns The AbortController for the watch.
66
- */
67
- start(): Promise<AbortController>;
68
- /** Close the watch. Also available on the AbortController returned by {@link Watcher.start}. */
69
- close(): void;
70
- /**
71
- * Get a unique ID for the watch based on the model and filters.
72
- * This is useful for caching the watch data or resource versions.
73
- *
74
- * @returns the watch CacheID
75
- */
76
- getCacheID(): string;
77
- /**
78
- * Subscribe to watch events. This is an EventEmitter that emits the following events:
79
- *
80
- * Use {@link WatchEvent} for the event names.
81
- *
82
- * @returns an EventEmitter
83
- */
84
- get events(): EventEmitter;
85
- }
86
- //# sourceMappingURL=watch.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/fluent/watch.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAItC,OAAO,EAAE,YAAY,EAAwB,MAAM,UAAU,CAAC;AAC9D,OAAO,EAAE,OAAO,EAAE,WAAW,EAAc,MAAM,SAAS,CAAC;AAG3D,oBAAY,UAAU;IACpB,sCAAsC;IACtC,OAAO,YAAY;IACnB,2BAA2B;IAC3B,aAAa,kBAAkB;IAC/B,kDAAkD;IAClD,UAAU,eAAe;IACzB,0BAA0B;IAC1B,SAAS,cAAc;IACvB,8BAA8B;IAC9B,OAAO,YAAY;IACnB,sBAAsB;IACtB,KAAK,UAAU;IACf,mCAAmC;IACnC,IAAI,SAAS;IACb,wCAAwC;IACxC,oBAAoB,yBAAyB;IAC7C,qCAAqC;IACrC,iBAAiB,sBAAsB;IACvC,kCAAkC;IAClC,IAAI,SAAS;IACb,2BAA2B;IAC3B,UAAU,eAAe;IACzB,mBAAmB;IACnB,UAAU,eAAe;IACzB,qCAAqC;IACrC,wBAAwB,6BAA6B;IACrD,iCAAiC;IACjC,eAAe,oBAAoB;CACpC;AAED,4CAA4C;AAC5C,MAAM,MAAM,QAAQ,GAAG;IACrB,+HAA+H;IAC/H,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+FAA+F;IAC/F,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,wHAAwH;IACxH,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B,CAAC;AAKF,iDAAiD;AACjD,qBAAa,OAAO,CAAC,CAAC,SAAS,YAAY;;IAyBzC,YAAY,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC;IAc9B;;;;;;;;;;;OAWG;gBACS,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,QAAQ,GAAE,QAAa;IA0CzF;;;;OAIG;IACU,KAAK,IAAI,OAAO,CAAC,eAAe,CAAC;IAM9C,gGAAgG;IACzF,KAAK;IAOZ;;;;;OAKG;IACI,UAAU;IAWjB;;;;;;OAMG;IACH,IAAW,MAAM,IAAI,YAAY,CAEhC;CAiUF"}