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
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
|
-
}
|
package/dist/fetch.test.d.ts
DELETED
package/dist/fetch.test.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"fetch.test.d.ts","sourceRoot":"","sources":["../src/fetch.test.ts"],"names":[],"mappings":""}
|
package/dist/fetch.test.js
DELETED
|
@@ -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
|
-
});
|
package/dist/fluent/index.d.ts
DELETED
|
@@ -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"}
|
package/dist/fluent/index.js
DELETED
|
@@ -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 +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
|
-
});
|