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.
Files changed (81) hide show
  1. package/.prettierignore +4 -0
  2. package/README.md +24 -0
  3. package/e2e/cli.e2e.test.ts +127 -0
  4. package/e2e/crds/policyreports.default.expected/policyreport-v1alpha1.ts +332 -0
  5. package/e2e/crds/policyreports.default.expected/policyreport-v1alpha2.ts +360 -0
  6. package/e2e/crds/policyreports.default.expected/policyreport-v1beta1.ts +360 -0
  7. package/e2e/crds/policyreports.no.post.expected/policyreport-v1alpha1.ts +331 -0
  8. package/e2e/crds/policyreports.no.post.expected/policyreport-v1alpha2.ts +360 -0
  9. package/e2e/crds/policyreports.no.post.expected/policyreport-v1beta1.ts +360 -0
  10. package/e2e/crds/test.yaml/policyreports.test.yaml +1008 -0
  11. package/e2e/crds/test.yaml/uds-podmonitors.test.yaml +1245 -0
  12. package/e2e/crds/uds-podmonitors.default.expected/podmonitor-v1.ts +1333 -0
  13. package/e2e/crds/uds-podmonitors.no.post.expected/podmonitor-v1.ts +1360 -0
  14. package/package.json +8 -7
  15. package/src/cli.ts +25 -1
  16. package/src/fileSystem.test.ts +67 -0
  17. package/src/fileSystem.ts +25 -0
  18. package/src/generate.test.ts +368 -358
  19. package/src/generate.ts +173 -154
  20. package/src/postProcessing.test.ts +742 -0
  21. package/src/postProcessing.ts +568 -0
  22. package/dist/cli.d.ts +0 -3
  23. package/dist/cli.d.ts.map +0 -1
  24. package/dist/cli.js +0 -48
  25. package/dist/fetch.d.ts +0 -22
  26. package/dist/fetch.d.ts.map +0 -1
  27. package/dist/fetch.js +0 -82
  28. package/dist/fetch.test.d.ts +0 -2
  29. package/dist/fetch.test.d.ts.map +0 -1
  30. package/dist/fetch.test.js +0 -97
  31. package/dist/fluent/index.d.ts +0 -12
  32. package/dist/fluent/index.d.ts.map +0 -1
  33. package/dist/fluent/index.js +0 -228
  34. package/dist/fluent/index.test.d.ts +0 -2
  35. package/dist/fluent/index.test.d.ts.map +0 -1
  36. package/dist/fluent/index.test.js +0 -193
  37. package/dist/fluent/types.d.ts +0 -187
  38. package/dist/fluent/types.d.ts.map +0 -1
  39. package/dist/fluent/types.js +0 -16
  40. package/dist/fluent/utils.d.ts +0 -41
  41. package/dist/fluent/utils.d.ts.map +0 -1
  42. package/dist/fluent/utils.js +0 -153
  43. package/dist/fluent/utils.test.d.ts +0 -2
  44. package/dist/fluent/utils.test.d.ts.map +0 -1
  45. package/dist/fluent/utils.test.js +0 -215
  46. package/dist/fluent/watch.d.ts +0 -86
  47. package/dist/fluent/watch.d.ts.map +0 -1
  48. package/dist/fluent/watch.js +0 -425
  49. package/dist/fluent/watch.spec.d.ts +0 -2
  50. package/dist/fluent/watch.spec.d.ts.map +0 -1
  51. package/dist/fluent/watch.spec.js +0 -261
  52. package/dist/generate.d.ts +0 -24
  53. package/dist/generate.d.ts.map +0 -1
  54. package/dist/generate.js +0 -195
  55. package/dist/generate.test.d.ts +0 -2
  56. package/dist/generate.test.d.ts.map +0 -1
  57. package/dist/generate.test.js +0 -373
  58. package/dist/helpers.d.ts +0 -33
  59. package/dist/helpers.d.ts.map +0 -1
  60. package/dist/helpers.js +0 -103
  61. package/dist/helpers.test.d.ts +0 -2
  62. package/dist/helpers.test.d.ts.map +0 -1
  63. package/dist/helpers.test.js +0 -37
  64. package/dist/index.d.ts +0 -14
  65. package/dist/index.d.ts.map +0 -1
  66. package/dist/index.js +0 -60
  67. package/dist/kinds.d.ts +0 -16
  68. package/dist/kinds.d.ts.map +0 -1
  69. package/dist/kinds.js +0 -570
  70. package/dist/kinds.test.d.ts +0 -2
  71. package/dist/kinds.test.d.ts.map +0 -1
  72. package/dist/kinds.test.js +0 -155
  73. package/dist/patch.d.ts +0 -7
  74. package/dist/patch.d.ts.map +0 -1
  75. package/dist/patch.js +0 -2
  76. package/dist/types.d.ts +0 -32
  77. package/dist/types.d.ts.map +0 -1
  78. package/dist/types.js +0 -16
  79. package/dist/upstream.d.ts +0 -4
  80. package/dist/upstream.d.ts.map +0 -1
  81. package/dist/upstream.js +0 -56
package/dist/fetch.js DELETED
@@ -1,82 +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.fetch = fetch;
29
- const http_status_codes_1 = require("http-status-codes");
30
- const node_fetch_1 = __importStar(require("node-fetch"));
31
- /**
32
- * Perform an async HTTP call and return the parsed JSON response, optionally
33
- * as a specific type.
34
- *
35
- * @example
36
- * ```ts
37
- * fetch<string[]>("https://example.com/api/foo");
38
- * ```
39
- *
40
- * @param url The URL or Request object to fetch
41
- * @param init Additional options for the request
42
- * @returns The parsed JSON response
43
- */
44
- async function fetch(url, init) {
45
- let data = undefined;
46
- try {
47
- const resp = await (0, node_fetch_1.default)(url, init);
48
- const contentType = resp.headers.get("content-type") || "";
49
- // Parse the response as JSON if the content type is JSON
50
- if (contentType.includes("application/json")) {
51
- data = await resp.json();
52
- }
53
- else {
54
- // Otherwise, return however the response was read
55
- data = (await resp.text());
56
- }
57
- return {
58
- data,
59
- ok: resp.ok,
60
- status: resp.status,
61
- statusText: resp.statusText,
62
- };
63
- }
64
- catch (e) {
65
- if (e instanceof node_fetch_1.FetchError) {
66
- // Parse the error code from the FetchError or default to 400 (Bad Request)
67
- const status = parseInt(e.code || "400");
68
- return {
69
- data,
70
- ok: false,
71
- status,
72
- statusText: e.message,
73
- };
74
- }
75
- return {
76
- data,
77
- ok: false,
78
- status: http_status_codes_1.StatusCodes.BAD_REQUEST,
79
- statusText: "Unknown error",
80
- };
81
- }
82
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=fetch.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"fetch.test.d.ts","sourceRoot":"","sources":["../src/fetch.test.ts"],"names":[],"mappings":""}
@@ -1,97 +0,0 @@
1
- "use strict";
2
- // SPDX-License-Identifier: Apache-2.0
3
- // SPDX-FileCopyrightText: 2023-Present The Kubernetes Fluent Client Authors
4
- var __importDefault = (this && this.__importDefault) || function (mod) {
5
- return (mod && mod.__esModule) ? mod : { "default": mod };
6
- };
7
- Object.defineProperty(exports, "__esModule", { value: true });
8
- const globals_1 = require("@jest/globals");
9
- const http_status_codes_1 = require("http-status-codes");
10
- const nock_1 = __importDefault(require("nock"));
11
- const fetch_1 = require("./fetch");
12
- (0, globals_1.beforeEach)(() => {
13
- (0, nock_1.default)("https://jsonplaceholder.typicode.com")
14
- .get("/todos/1")
15
- .reply(200, {
16
- userId: 1,
17
- id: 1,
18
- title: "Example title",
19
- completed: false,
20
- })
21
- .post("/todos", {
22
- title: "test todo",
23
- userId: 1,
24
- completed: false,
25
- })
26
- .reply(200, (uri, requestBody) => requestBody)
27
- .get("/todos/empty-null")
28
- .reply(200, undefined)
29
- .get("/todos/empty-string")
30
- .reply(200, "")
31
- .get("/todos/empty-object")
32
- .reply(200, {})
33
- .get("/todos/invalid")
34
- .replyWithError("Something bad happened");
35
- });
36
- (0, globals_1.test)("fetch: should return without type data", async () => {
37
- const url = "https://jsonplaceholder.typicode.com/todos/1";
38
- const { data, ok } = await (0, fetch_1.fetch)(url);
39
- (0, globals_1.expect)(ok).toBe(true);
40
- (0, globals_1.expect)(data["title"]).toBe("Example title");
41
- });
42
- (0, globals_1.test)("fetch: should return parsed JSON response as a specific type", async () => {
43
- const url = "https://jsonplaceholder.typicode.com/todos/1";
44
- const { data, ok } = await (0, fetch_1.fetch)(url);
45
- (0, globals_1.expect)(ok).toBe(true);
46
- (0, globals_1.expect)(data.id).toBe(1);
47
- (0, globals_1.expect)(typeof data.title).toBe("string");
48
- (0, globals_1.expect)(typeof data.completed).toBe("boolean");
49
- });
50
- (0, globals_1.test)("fetch: should handle additional request options", async () => {
51
- const url = "https://jsonplaceholder.typicode.com/todos";
52
- const requestOptions = {
53
- method: "POST",
54
- body: JSON.stringify({
55
- title: "test todo",
56
- userId: 1,
57
- completed: false,
58
- }),
59
- headers: {
60
- "Content-type": "application/json; charset=UTF-8",
61
- },
62
- };
63
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
64
- const { data, ok } = await (0, fetch_1.fetch)(url, requestOptions);
65
- (0, globals_1.expect)(ok).toBe(true);
66
- (0, globals_1.expect)(data["title"]).toBe("test todo");
67
- (0, globals_1.expect)(data["userId"]).toBe(1);
68
- (0, globals_1.expect)(data["completed"]).toBe(false);
69
- });
70
- (0, globals_1.test)("fetch: should handle empty (null) responses", async () => {
71
- const url = "https://jsonplaceholder.typicode.com/todos/empty-null";
72
- const resp = await (0, fetch_1.fetch)(url);
73
- (0, globals_1.expect)(resp.data).toBe("");
74
- (0, globals_1.expect)(resp.ok).toBe(true);
75
- (0, globals_1.expect)(resp.status).toBe(http_status_codes_1.StatusCodes.OK);
76
- });
77
- (0, globals_1.test)("fetch: should handle empty (string) responses", async () => {
78
- const url = "https://jsonplaceholder.typicode.com/todos/empty-string";
79
- const resp = await (0, fetch_1.fetch)(url);
80
- (0, globals_1.expect)(resp.data).toBe("");
81
- (0, globals_1.expect)(resp.ok).toBe(true);
82
- (0, globals_1.expect)(resp.status).toBe(http_status_codes_1.StatusCodes.OK);
83
- });
84
- (0, globals_1.test)("fetch: should handle empty (object) responses", async () => {
85
- const url = "https://jsonplaceholder.typicode.com/todos/empty-object";
86
- const resp = await (0, fetch_1.fetch)(url);
87
- (0, globals_1.expect)(resp.data).toEqual({});
88
- (0, globals_1.expect)(resp.ok).toBe(true);
89
- (0, globals_1.expect)(resp.status).toBe(http_status_codes_1.StatusCodes.OK);
90
- });
91
- (0, globals_1.test)("fetch: should handle failed requests without throwing an error", async () => {
92
- const url = "https://jsonplaceholder.typicode.com/todos/invalid";
93
- const resp = await (0, fetch_1.fetch)(url);
94
- (0, globals_1.expect)(resp.data).toBe(undefined);
95
- (0, globals_1.expect)(resp.ok).toBe(false);
96
- (0, globals_1.expect)(resp.status).toBe(http_status_codes_1.StatusCodes.BAD_REQUEST);
97
- });
@@ -1,12 +0,0 @@
1
- import { KubernetesObject } from "@kubernetes/client-node";
2
- import { GenericClass } from "../types";
3
- import { Filters, K8sInit } from "./types";
4
- /**
5
- * Kubernetes fluent API inspired by Kubectl. Pass in a model, then call filters and actions on it.
6
- *
7
- * @param model - the model to use for the API
8
- * @param filters - (optional) filter overrides, can also be chained
9
- * @returns a fluent API for the model
10
- */
11
- export declare function K8s<T extends GenericClass, K extends KubernetesObject = InstanceType<T>>(model: T, filters?: Filters): K8sInit<T, K>;
12
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/fluent/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAwB,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAOjF,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAA0B,OAAO,EAAE,OAAO,EAAsB,MAAM,SAAS,CAAC;AAKvF;;;;;;GAMG;AACH,wBAAgB,GAAG,CAAC,CAAC,SAAS,YAAY,EAAE,CAAC,SAAS,gBAAgB,GAAG,YAAY,CAAC,CAAC,CAAC,EACtF,KAAK,EAAE,CAAC,EACR,OAAO,GAAE,OAAY,GACpB,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CA0Pf"}
@@ -1,228 +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
- exports.K8s = K8s;
6
- const http_status_codes_1 = require("http-status-codes");
7
- const fetch_1 = require("../fetch");
8
- const kinds_1 = require("../kinds");
9
- const utils_1 = require("./utils");
10
- const watch_1 = require("./watch");
11
- const helpers_1 = require("../helpers");
12
- const upstream_1 = require("../upstream");
13
- /**
14
- * Kubernetes fluent API inspired by Kubectl. Pass in a model, then call filters and actions on it.
15
- *
16
- * @param model - the model to use for the API
17
- * @param filters - (optional) filter overrides, can also be chained
18
- * @returns a fluent API for the model
19
- */
20
- function K8s(model, filters = {}) {
21
- const withFilters = { WithField, WithLabel, Get, Delete, Watch, Logs };
22
- const matchedKind = filters.kindOverride || (0, kinds_1.modelToGroupVersionKind)(model.name);
23
- /**
24
- * @inheritdoc
25
- * @see {@link K8sInit.InNamespace}
26
- */
27
- function InNamespace(namespace) {
28
- if (filters.namespace) {
29
- throw new Error(`Namespace already specified: ${filters.namespace}`);
30
- }
31
- filters.namespace = namespace;
32
- return withFilters;
33
- }
34
- /**
35
- * @inheritdoc
36
- * @see {@link K8sInit.WithField}
37
- */
38
- function WithField(key, value) {
39
- filters.fields = filters.fields || {};
40
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
41
- // @ts-ignore
42
- filters.fields[key] = value;
43
- return withFilters;
44
- }
45
- /**
46
- * @inheritdoc
47
- * @see {@link K8sInit.WithLabel}
48
- */
49
- function WithLabel(key, value = "") {
50
- filters.labels = filters.labels || {};
51
- filters.labels[key] = value;
52
- return withFilters;
53
- }
54
- /**
55
- * Sync the filters with the provided payload.
56
- *
57
- * @param payload - the payload to sync with
58
- */
59
- function syncFilters(payload) {
60
- // Ensure the payload has metadata
61
- payload.metadata = payload.metadata || {};
62
- if (!filters.namespace) {
63
- filters.namespace = payload.metadata.namespace;
64
- }
65
- if (!filters.name) {
66
- filters.name = payload.metadata.name;
67
- }
68
- if (!payload.apiVersion) {
69
- payload.apiVersion = [matchedKind.group, matchedKind.version].filter(Boolean).join("/");
70
- }
71
- if (!payload.kind) {
72
- payload.kind = matchedKind.kind;
73
- }
74
- }
75
- /**
76
- * @inheritdoc
77
- * @see {@link K8sInit.Logs}
78
- */
79
- async function Logs(name) {
80
- let labels = {};
81
- const { kind } = matchedKind;
82
- const { namespace } = filters;
83
- const podList = [];
84
- if (name) {
85
- if (filters.name) {
86
- throw new Error(`Name already specified: ${filters.name}`);
87
- }
88
- filters.name = name;
89
- }
90
- if (!namespace) {
91
- throw new Error("Namespace must be defined");
92
- }
93
- if (!(0, helpers_1.hasLogs)(kind)) {
94
- throw new Error("Kind must be Pod or have a selector");
95
- }
96
- try {
97
- const object = await (0, utils_1.k8sExec)(model, filters, "GET");
98
- if (kind !== "Pod") {
99
- if (kind === "Service") {
100
- const svc = object;
101
- labels = svc.spec.selector ?? {};
102
- }
103
- else if (kind === "ReplicaSet" ||
104
- kind === "Deployment" ||
105
- kind === "StatefulSet" ||
106
- kind === "DaemonSet") {
107
- const rs = object;
108
- labels = rs.spec.selector.matchLabels ?? {};
109
- }
110
- const list = await K8s(upstream_1.Pod, { namespace: filters.namespace, labels }).Get();
111
- list.items.forEach(item => {
112
- return podList.push(item);
113
- });
114
- }
115
- else {
116
- podList.push(object);
117
- }
118
- }
119
- catch {
120
- throw new Error(`Failed to get logs in KFC Logs function`);
121
- }
122
- const podModel = { ...model, name: "V1Pod" };
123
- const logPromises = podList.map(po => (0, utils_1.k8sExec)(podModel, { ...filters, name: po.metadata.name }, "LOG"));
124
- const responses = await Promise.all(logPromises);
125
- const combinedString = responses.reduce((accumulator, currentString, i) => {
126
- const prefixedLines = currentString
127
- .split("\n")
128
- .map(line => {
129
- return line !== "" ? `[pod/${podList[i].metadata.name}] ${line}` : "";
130
- })
131
- .filter(str => str !== "");
132
- return [...accumulator, ...prefixedLines];
133
- }, []);
134
- return combinedString;
135
- }
136
- /**
137
- * @inheritdoc
138
- * @see {@link K8sInit.Get}
139
- */
140
- async function Get(name) {
141
- if (name) {
142
- if (filters.name) {
143
- throw new Error(`Name already specified: ${filters.name}`);
144
- }
145
- filters.name = name;
146
- }
147
- return (0, utils_1.k8sExec)(model, filters, "GET");
148
- }
149
- /**
150
- * @inheritdoc
151
- * @see {@link K8sInit.Delete}
152
- */
153
- async function Delete(filter) {
154
- if (typeof filter === "string") {
155
- filters.name = filter;
156
- }
157
- else if (filter) {
158
- syncFilters(filter);
159
- }
160
- try {
161
- // Try to delete the resource
162
- await (0, utils_1.k8sExec)(model, filters, "DELETE");
163
- }
164
- catch (e) {
165
- // If the resource doesn't exist, ignore the error
166
- if (e.status === http_status_codes_1.StatusCodes.NOT_FOUND) {
167
- return;
168
- }
169
- throw e;
170
- }
171
- }
172
- /**
173
- * @inheritdoc
174
- * @see {@link K8sInit.Apply}
175
- */
176
- async function Apply(resource, applyCfg = { force: false }) {
177
- syncFilters(resource);
178
- return (0, utils_1.k8sExec)(model, filters, "APPLY", resource, applyCfg);
179
- }
180
- /**
181
- * @inheritdoc
182
- * @see {@link K8sInit.Create}
183
- */
184
- async function Create(resource) {
185
- syncFilters(resource);
186
- return (0, utils_1.k8sExec)(model, filters, "POST", resource);
187
- }
188
- /**
189
- * @inheritdoc
190
- * @see {@link K8sInit.Patch}
191
- */
192
- async function Patch(payload) {
193
- // If there are no operations, throw an error
194
- if (payload.length < 1) {
195
- throw new Error("No operations specified");
196
- }
197
- return (0, utils_1.k8sExec)(model, filters, "PATCH", payload);
198
- }
199
- /**
200
- * @inheritdoc
201
- * @see {@link K8sInit.PatchStatus}
202
- */
203
- async function PatchStatus(resource) {
204
- syncFilters(resource);
205
- return (0, utils_1.k8sExec)(model, filters, "PATCH_STATUS", resource);
206
- }
207
- /**
208
- * @inheritdoc
209
- * @see {@link K8sInit.Watch}
210
- */
211
- function Watch(callback, watchCfg) {
212
- return new watch_1.Watcher(model, filters, callback, watchCfg);
213
- }
214
- /**
215
- * @inheritdoc
216
- * @see {@link K8sInit.Raw}
217
- */
218
- async function Raw(url, method = "GET") {
219
- const thing = await (0, utils_1.k8sCfg)(method);
220
- const { opts, serverUrl } = thing;
221
- const resp = await (0, fetch_1.fetch)(`${serverUrl}${url}`, opts);
222
- if (resp.ok) {
223
- return resp.data;
224
- }
225
- throw resp;
226
- }
227
- return { InNamespace, Apply, Create, Patch, PatchStatus, Raw, ...withFilters };
228
- }
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=index.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../src/fluent/index.test.ts"],"names":[],"mappings":""}
@@ -1,193 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const globals_1 = require("@jest/globals");
4
- const client_node_1 = require("@kubernetes/client-node");
5
- const _1 = require(".");
6
- const fetch_1 = require("../fetch");
7
- const upstream_1 = require("../upstream");
8
- const utils_1 = require("./utils");
9
- // Setup mocks
10
- globals_1.jest.mock("./utils");
11
- globals_1.jest.mock("../fetch");
12
- const generateFakePodManagedFields = (manager) => {
13
- return [
14
- {
15
- apiVersion: "v1",
16
- fieldsType: "FieldsV1",
17
- fieldsV1: {
18
- "f:metadata": {
19
- "f:labels": {
20
- "f:fake": {},
21
- },
22
- "f:spec": {
23
- "f:containers": {
24
- 'k:{"name":"fake"}': {
25
- "f:image": {},
26
- "f:name": {},
27
- "f:resources": {
28
- "f:limits": {
29
- "f:cpu": {},
30
- "f:memory": {},
31
- },
32
- "f:requests": {
33
- "f:cpu": {},
34
- "f:memory": {},
35
- },
36
- },
37
- },
38
- },
39
- },
40
- },
41
- },
42
- manager: manager,
43
- operation: "Apply",
44
- },
45
- ];
46
- };
47
- (0, globals_1.describe)("Kube", () => {
48
- const fakeResource = {
49
- metadata: {
50
- name: "fake",
51
- namespace: "default",
52
- managedFields: generateFakePodManagedFields("pepr"),
53
- },
54
- };
55
- const mockedKubeCfg = globals_1.jest.mocked(utils_1.k8sCfg);
56
- const mockedKubeExec = globals_1.jest.mocked(utils_1.k8sExec).mockResolvedValue(fakeResource);
57
- (0, globals_1.beforeEach)(() => {
58
- // Clear all instances and calls to constructor and all methods:
59
- mockedKubeExec.mockClear();
60
- });
61
- (0, globals_1.it)("should create a resource", async () => {
62
- const result = await (0, _1.K8s)(upstream_1.Pod).Create(fakeResource);
63
- (0, globals_1.expect)(result).toEqual(fakeResource);
64
- (0, globals_1.expect)(mockedKubeExec).toHaveBeenCalledWith(upstream_1.Pod, globals_1.expect.objectContaining({
65
- name: "fake",
66
- namespace: "default",
67
- }), "POST", fakeResource);
68
- });
69
- (0, globals_1.it)("should delete a resource", async () => {
70
- await (0, _1.K8s)(upstream_1.Pod).Delete(fakeResource);
71
- (0, globals_1.expect)(mockedKubeExec).toHaveBeenCalledWith(upstream_1.Pod, globals_1.expect.objectContaining({
72
- name: "fake",
73
- namespace: "default",
74
- }), "DELETE");
75
- });
76
- (0, globals_1.it)("should patch a resource", async () => {
77
- const patchOperations = [
78
- { op: "replace", path: "/metadata/name", value: "new-fake" },
79
- ];
80
- const result = await (0, _1.K8s)(upstream_1.Pod).Patch(patchOperations);
81
- (0, globals_1.expect)(result).toEqual(fakeResource);
82
- (0, globals_1.expect)(mockedKubeExec).toHaveBeenCalledWith(upstream_1.Pod, {}, "PATCH", patchOperations);
83
- });
84
- (0, globals_1.it)("should patch the status of a resource", async () => {
85
- await (0, _1.K8s)(upstream_1.Pod).PatchStatus({
86
- metadata: {
87
- name: "fake",
88
- namespace: "default",
89
- managedFields: generateFakePodManagedFields("pepr"),
90
- },
91
- spec: { priority: 3 },
92
- status: {
93
- phase: "Ready",
94
- },
95
- });
96
- (0, globals_1.expect)(utils_1.k8sExec).toBeCalledWith(upstream_1.Pod, globals_1.expect.objectContaining({
97
- name: "fake",
98
- namespace: "default",
99
- }), "PATCH_STATUS", {
100
- apiVersion: "v1",
101
- kind: "Pod",
102
- metadata: {
103
- name: "fake",
104
- namespace: "default",
105
- managedFields: generateFakePodManagedFields("pepr"),
106
- },
107
- spec: { priority: 3 },
108
- status: {
109
- phase: "Ready",
110
- },
111
- });
112
- });
113
- (0, globals_1.it)("should filter with WithField", async () => {
114
- await (0, _1.K8s)(upstream_1.Pod).WithField("metadata.name", "fake").Get();
115
- (0, globals_1.expect)(mockedKubeExec).toHaveBeenCalledWith(upstream_1.Pod, globals_1.expect.objectContaining({
116
- fields: {
117
- "metadata.name": "fake",
118
- },
119
- }), "GET");
120
- });
121
- (0, globals_1.it)("should filter with WithLabel", async () => {
122
- await (0, _1.K8s)(upstream_1.Pod).WithLabel("app", "fakeApp").Get();
123
- (0, globals_1.expect)(mockedKubeExec).toHaveBeenCalledWith(upstream_1.Pod, globals_1.expect.objectContaining({
124
- labels: {
125
- app: "fakeApp",
126
- },
127
- }), "GET");
128
- });
129
- (0, globals_1.it)("should use InNamespace", async () => {
130
- await (0, _1.K8s)(upstream_1.Pod).InNamespace("fakeNamespace").Get();
131
- (0, globals_1.expect)(mockedKubeExec).toHaveBeenCalledWith(upstream_1.Pod, globals_1.expect.objectContaining({
132
- namespace: "fakeNamespace",
133
- }), "GET");
134
- });
135
- (0, globals_1.it)("should throw an error if namespace is already specified", async () => {
136
- (0, globals_1.expect)(() => (0, _1.K8s)(upstream_1.Pod, { namespace: "default" }).InNamespace("fakeNamespace")).toThrow("Namespace already specified: default");
137
- });
138
- (0, globals_1.it)("should handle Delete when the resource doesn't exist", async () => {
139
- mockedKubeExec.mockRejectedValueOnce({ status: 404 }); // Not Found on first call
140
- await (0, globals_1.expect)((0, _1.K8s)(upstream_1.Pod).Delete("fakeResource")).resolves.toBeUndefined();
141
- });
142
- (0, globals_1.it)("should handle Get", async () => {
143
- const result = await (0, _1.K8s)(upstream_1.Pod).Get("fakeResource");
144
- (0, globals_1.expect)(result).toEqual(fakeResource);
145
- (0, globals_1.expect)(mockedKubeExec).toHaveBeenCalledWith(upstream_1.Pod, globals_1.expect.objectContaining({
146
- name: "fakeResource",
147
- }), "GET");
148
- });
149
- (0, globals_1.it)("should thrown an error if Get is called with a name and filters are already specified a name", async () => {
150
- await (0, globals_1.expect)((0, _1.K8s)(upstream_1.Pod, { name: "fake" }).Get("fakeResource")).rejects.toThrow("Name already specified: fake");
151
- });
152
- (0, globals_1.it)("should throw an error if no patch operations provided", async () => {
153
- await (0, globals_1.expect)((0, _1.K8s)(upstream_1.Pod).Patch([])).rejects.toThrow("No operations specified");
154
- });
155
- (0, globals_1.it)("should allow Apply of deep partials", async () => {
156
- const result = await (0, _1.K8s)(upstream_1.Pod).Apply({ metadata: { name: "fake" }, spec: { priority: 3 } });
157
- (0, globals_1.expect)(result).toEqual(fakeResource);
158
- });
159
- (0, globals_1.it)("should allow force apply to resolve FieldManagerConflict", async () => {
160
- const result = await (0, _1.K8s)(upstream_1.Pod).Apply({
161
- metadata: { name: "fake", managedFields: generateFakePodManagedFields("kubectl") },
162
- spec: { priority: 3 },
163
- }, { force: true });
164
- (0, globals_1.expect)(result).toEqual(fakeResource);
165
- });
166
- (0, globals_1.it)("should throw an error if a Delete failed for a reason other than Not Found", async () => {
167
- mockedKubeExec.mockRejectedValueOnce({ status: 500 }); // Internal Server Error on first call
168
- await (0, globals_1.expect)((0, _1.K8s)(upstream_1.Pod).Delete("fakeResource")).rejects.toEqual(globals_1.expect.objectContaining({ status: 500 }));
169
- });
170
- (0, globals_1.it)("should create a raw api request", async () => {
171
- mockedKubeCfg.mockReturnValue(new Promise(r => r({
172
- serverUrl: "http://localhost:8080",
173
- opts: {},
174
- })));
175
- const mockResp = {
176
- kind: "APIVersions",
177
- versions: ["v1"],
178
- serverAddressByClientCIDRs: [
179
- {
180
- serverAddress: "172.27.0.3:6443",
181
- },
182
- ],
183
- };
184
- globals_1.jest.mocked(fetch_1.fetch).mockResolvedValue({
185
- ok: true,
186
- data: mockResp,
187
- status: 200,
188
- statusText: "OK",
189
- });
190
- const result = await (0, _1.K8s)(client_node_1.V1APIGroup).Raw("/api");
191
- (0, globals_1.expect)(result).toEqual(mockResp);
192
- });
193
- });