pepr 0.2.10 → 0.3.0-rc0

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/dist/fixtures/data/cm1.json +75 -0
  2. package/dist/fixtures/data/deployment1.json +170 -0
  3. package/dist/fixtures/data/ns1.json +72 -0
  4. package/dist/fixtures/data/pod1.json +271 -0
  5. package/dist/fixtures/data/pod2.json +257 -0
  6. package/dist/fixtures/data/svc1.json +100 -0
  7. package/dist/fixtures/loader.js +60 -0
  8. package/dist/package.json +21 -39
  9. package/dist/src/cli/build.js +3 -1
  10. package/dist/src/cli/dev.js +31 -19
  11. package/dist/src/cli/index.js +1 -0
  12. package/dist/src/cli/init/index.js +3 -1
  13. package/dist/src/cli/init/templates.js +3 -2
  14. package/dist/src/cli/init/utils.js +1 -1
  15. package/dist/src/cli/init/utils.test.js +29 -0
  16. package/dist/src/cli/init/walkthrough.js +1 -1
  17. package/dist/src/cli/init/walkthrough.test.js +21 -0
  18. package/dist/src/cli/run.js +17 -17
  19. package/dist/src/cli/update.js +3 -1
  20. package/dist/src/lib/capability.js +1 -1
  21. package/dist/src/lib/controller.js +9 -1
  22. package/dist/src/lib/fetch.js +39 -6
  23. package/dist/src/lib/fetch.test.js +98 -0
  24. package/dist/src/lib/filter.test.js +208 -0
  25. package/dist/src/lib/k8s/kinds.test.js +296 -0
  26. package/dist/src/lib/k8s/webhook.js +22 -22
  27. package/dist/src/lib/logger.test.js +64 -0
  28. package/dist/src/lib/processor.js +4 -1
  29. package/{dist/index.d.ts → index.ts} +21 -3
  30. package/package.json +21 -39
  31. package/src/lib/capability.ts +158 -0
  32. package/src/lib/controller.ts +127 -0
  33. package/src/lib/fetch.test.ts +115 -0
  34. package/src/lib/fetch.ts +75 -0
  35. package/src/lib/filter.test.ts +231 -0
  36. package/src/lib/filter.ts +87 -0
  37. package/{dist/src/lib/k8s/index.d.ts → src/lib/k8s/index.ts} +6 -0
  38. package/src/lib/k8s/kinds.test.ts +333 -0
  39. package/src/lib/k8s/kinds.ts +489 -0
  40. package/src/lib/k8s/tls.ts +90 -0
  41. package/src/lib/k8s/types.ts +183 -0
  42. package/src/lib/k8s/upstream.ts +49 -0
  43. package/src/lib/k8s/webhook.ts +547 -0
  44. package/src/lib/logger.test.ts +80 -0
  45. package/src/lib/logger.ts +136 -0
  46. package/src/lib/module.ts +63 -0
  47. package/src/lib/processor.ts +98 -0
  48. package/src/lib/request.ts +140 -0
  49. package/src/lib/types.ts +211 -0
  50. package/dist/cli.d.ts +0 -2
  51. package/dist/cli.js +0 -4
  52. package/dist/run.d.ts +0 -2
  53. package/dist/run.js +0 -4
  54. package/dist/src/cli/banner.d.ts +0 -1
  55. package/dist/src/cli/build.d.ts +0 -7
  56. package/dist/src/cli/capability.d.ts +0 -2
  57. package/dist/src/cli/deploy.d.ts +0 -2
  58. package/dist/src/cli/dev.d.ts +0 -2
  59. package/dist/src/cli/index.d.ts +0 -1
  60. package/dist/src/cli/init/index.d.ts +0 -2
  61. package/dist/src/cli/init/templates.d.ts +0 -94
  62. package/dist/src/cli/init/utils.d.ts +0 -20
  63. package/dist/src/cli/init/walkthrough.d.ts +0 -7
  64. package/dist/src/cli/root.d.ts +0 -4
  65. package/dist/src/cli/run.d.ts +0 -1
  66. package/dist/src/cli/test.d.ts +0 -2
  67. package/dist/src/cli/update.d.ts +0 -2
  68. package/dist/src/lib/capability.d.ts +0 -28
  69. package/dist/src/lib/controller.d.ts +0 -17
  70. package/dist/src/lib/fetch.d.ts +0 -23
  71. package/dist/src/lib/filter.d.ts +0 -10
  72. package/dist/src/lib/k8s/kinds.d.ts +0 -11
  73. package/dist/src/lib/k8s/tls.d.ts +0 -17
  74. package/dist/src/lib/k8s/types.d.ts +0 -147
  75. package/dist/src/lib/k8s/upstream.d.ts +0 -3
  76. package/dist/src/lib/k8s/webhook.d.ts +0 -34
  77. package/dist/src/lib/logger.d.ts +0 -55
  78. package/dist/src/lib/module.d.ts +0 -32
  79. package/dist/src/lib/processor.d.ts +0 -4
  80. package/dist/src/lib/request.d.ts +0 -77
  81. package/dist/src/lib/types.d.ts +0 -187
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ // SPDX-FileCopyrightText: 2023-Present The Pepr 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 ava_1 = __importDefault(require("ava"));
9
+ const utils_1 = require("./utils");
10
+ (0, ava_1.default)("sanitizeName() sanitizes names correctly", t => {
11
+ const cases = [
12
+ {
13
+ input: "My Test Module",
14
+ expected: "my-test-module",
15
+ },
16
+ {
17
+ input: "!! 123 @@ Module",
18
+ expected: "123-module",
19
+ },
20
+ {
21
+ input: "---Test-Module---",
22
+ expected: "test-module",
23
+ },
24
+ ];
25
+ for (const { input, expected } of cases) {
26
+ const result = (0, utils_1.sanitizeName)(input);
27
+ t.is(result, expected, `sanitizeName(${input}) should be ${expected}`);
28
+ }
29
+ });
@@ -35,7 +35,7 @@ function walkthrough() {
35
35
  const askErrorBehavior = {
36
36
  type: "select",
37
37
  name: "errorBehavior",
38
- validate: val => types_1.ErrorBehavior[val],
38
+ validate: (val) => types_1.ErrorBehavior[val],
39
39
  message: "How do you want Pepr to handle errors encountered during K8s operations?",
40
40
  choices: [
41
41
  {
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ // SPDX-FileCopyrightText: 2023-Present The Pepr 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 ava_1 = __importDefault(require("ava"));
9
+ const prompts_1 = __importDefault(require("prompts"));
10
+ const walkthrough_1 = require("./walkthrough");
11
+ (0, ava_1.default)("walkthrough() returns expected results", async (t) => {
12
+ // Inject predefined answers for the prompts
13
+ prompts_1.default.inject(["My Test Module", "A test module for Pepr", 0]);
14
+ const result = await (0, walkthrough_1.walkthrough)();
15
+ // Check the returned object
16
+ t.deepEqual(result, {
17
+ name: "My Test Module",
18
+ description: "A test module for Pepr",
19
+ errorBehavior: 0,
20
+ });
21
+ });
@@ -1,3 +1,4 @@
1
+ #!/usr/bin/env node
1
2
  "use strict";
2
3
  // SPDX-License-Identifier: Apache-2.0
3
4
  // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
@@ -5,32 +6,29 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
6
  return (mod && mod.__esModule) ? mod : { "default": mod };
6
7
  };
7
8
  Object.defineProperty(exports, "__esModule", { value: true });
8
- const commander_1 = require("commander");
9
+ const child_process_1 = require("child_process");
9
10
  const crypto_1 = __importDefault(require("crypto"));
10
11
  const fs_1 = __importDefault(require("fs"));
11
12
  const zlib_1 = require("zlib");
12
13
  const package_json_1 = require("../../package.json");
13
14
  const logger_1 = __importDefault(require("../lib/logger"));
14
- commander_1.program
15
- .version(package_json_1.version)
16
- .description(`Pepr Kubernetes Runtime (v${package_json_1.version})`)
17
- .argument("<hash>", "Hash of the module to run")
18
- .option("-l, --log-level [level]", "Log level: debug, info, warn, error", "info")
19
- .action((expectedHash, opts) => {
20
- const gzPath = `/app/load/module-${expectedHash}.js.gz`;
21
- const jsPath = `/app/module-${expectedHash}.js`;
22
- // Require the has to be 64 characters long
23
- if (expectedHash.length !== 64) {
15
+ function validateHash(expectedHash) {
16
+ // Require the hash to be 64 characters long
17
+ if (!expectedHash || expectedHash.length !== 64) {
24
18
  logger_1.default.error("Invalid hash");
25
19
  process.exit(1);
26
20
  }
21
+ }
22
+ function runModule(expectedHash) {
23
+ const gzPath = `/app/load/module-${expectedHash}.js.gz`;
24
+ const jsPath = `/app/module-${expectedHash}.js`;
25
+ // Set the log level
26
+ logger_1.default.SetLogLevel("debug");
27
27
  // Check if the path is a valid file
28
28
  if (!fs_1.default.existsSync(gzPath)) {
29
29
  logger_1.default.error(`File not found: ${gzPath}`);
30
30
  process.exit(1);
31
31
  }
32
- // Set the log level
33
- logger_1.default.SetLogLevel(opts.logLevel);
34
32
  try {
35
33
  logger_1.default.info(`Loading module ${gzPath}`);
36
34
  // Extract the code from the file
@@ -47,12 +45,14 @@ commander_1.program
47
45
  // Write the code to a file
48
46
  fs_1.default.writeFileSync(jsPath, code);
49
47
  // Run the module
50
- // @todo: evaluate vm (isolate) vs require
51
- require(jsPath);
48
+ (0, child_process_1.fork)(jsPath);
52
49
  }
53
50
  catch (e) {
54
51
  logger_1.default.error(`Failed to decompress module: ${e}`);
55
52
  process.exit(1);
56
53
  }
57
- });
58
- commander_1.program.parse();
54
+ }
55
+ logger_1.default.info(`Pepr Controller (v${package_json_1.version})`);
56
+ const hash = process.argv[2];
57
+ validateHash(hash);
58
+ runModule(hash);
@@ -48,7 +48,9 @@ function default_1(program) {
48
48
  }
49
49
  catch (e) {
50
50
  logger_1.default.debug(e);
51
- logger_1.default.error(e.message);
51
+ if (e instanceof Error) {
52
+ logger_1.default.error(e.message);
53
+ }
52
54
  process.exit(1);
53
55
  }
54
56
  });
@@ -56,7 +56,7 @@ class Capability {
56
56
  labels: {},
57
57
  annotations: {},
58
58
  },
59
- callback: () => null,
59
+ callback: () => undefined,
60
60
  };
61
61
  const prefix = `${this._name}: ${model.name}`;
62
62
  logger_1.default.info(`Binding created`, prefix);
@@ -29,11 +29,19 @@ class Controller {
29
29
  throw new Error("Cannot start Pepr module: Pepr module was not instantiated with deferStart=true");
30
30
  }
31
31
  // Create HTTPS server
32
- https_1.default.createServer(options, this.app).listen(port, () => {
32
+ const server = https_1.default.createServer(options, this.app).listen(port, () => {
33
33
  console.log(`Server listening on port ${port}`);
34
34
  // Track that the server is running
35
35
  this.running = true;
36
36
  });
37
+ // Listen for the SIGTERM signal and gracefully close the server
38
+ process.on("SIGTERM", () => {
39
+ console.log("Received SIGTERM, closing server");
40
+ server.close(() => {
41
+ console.log("Server closed");
42
+ process.exit(0);
43
+ });
44
+ });
37
45
  };
38
46
  this.logger = (req, res, next) => {
39
47
  const startTime = Date.now();
@@ -1,13 +1,36 @@
1
1
  "use strict";
2
2
  // SPDX-License-Identifier: Apache-2.0
3
3
  // SPDX-FileCopyrightText: 2023-Present The Pepr 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
+ };
4
27
  var __importDefault = (this && this.__importDefault) || function (mod) {
5
28
  return (mod && mod.__esModule) ? mod : { "default": mod };
6
29
  };
7
30
  Object.defineProperty(exports, "__esModule", { value: true });
8
31
  exports.fetch = exports.fetchRaw = void 0;
9
32
  const http_status_codes_1 = require("http-status-codes");
10
- const node_fetch_1 = __importDefault(require("node-fetch"));
33
+ const node_fetch_1 = __importStar(require("node-fetch"));
11
34
  exports.fetchRaw = node_fetch_1.default;
12
35
  const logger_1 = __importDefault(require("./logger"));
13
36
  /**
@@ -24,11 +47,11 @@ const logger_1 = __importDefault(require("./logger"));
24
47
  * @returns
25
48
  */
26
49
  async function fetch(url, init) {
50
+ let data = undefined;
27
51
  try {
28
52
  logger_1.default.debug(`Fetching ${url}`);
29
53
  const resp = await (0, node_fetch_1.default)(url, init);
30
54
  const contentType = resp.headers.get("content-type") || "";
31
- let data;
32
55
  if (resp.ok) {
33
56
  // Parse the response as JSON if the content type is JSON
34
57
  if (contentType.includes("application/json")) {
@@ -47,12 +70,22 @@ async function fetch(url, init) {
47
70
  };
48
71
  }
49
72
  catch (e) {
50
- logger_1.default.debug(`Fetch failed: ${e.message}`);
73
+ if (e instanceof node_fetch_1.FetchError) {
74
+ logger_1.default.debug(`Fetch failed: ${e instanceof Error ? e.message : e}`);
75
+ // Parse the error code from the FetchError or default to 400 (Bad Request)
76
+ const status = parseInt(e.code || "400");
77
+ return {
78
+ data,
79
+ ok: false,
80
+ status,
81
+ statusText: e.message,
82
+ };
83
+ }
51
84
  return {
52
- data: null,
85
+ data,
53
86
  ok: false,
54
- status: e.code || http_status_codes_1.StatusCodes.BAD_REQUEST,
55
- statusText: e.message,
87
+ status: http_status_codes_1.StatusCodes.BAD_REQUEST,
88
+ statusText: "Unknown error",
56
89
  };
57
90
  }
58
91
  }
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
4
+ // fetch.test.ts
5
+ var __importDefault = (this && this.__importDefault) || function (mod) {
6
+ return (mod && mod.__esModule) ? mod : { "default": mod };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ const ava_1 = __importDefault(require("ava"));
10
+ const http_status_codes_1 = require("http-status-codes");
11
+ const nock_1 = __importDefault(require("nock"));
12
+ const fetch_1 = require("./fetch");
13
+ ava_1.default.beforeEach(() => {
14
+ (0, nock_1.default)("https://jsonplaceholder.typicode.com")
15
+ .get("/todos/1")
16
+ .reply(200, {
17
+ userId: 1,
18
+ id: 1,
19
+ title: "Example title",
20
+ completed: false,
21
+ })
22
+ .post("/todos", {
23
+ title: "test todo",
24
+ userId: 1,
25
+ completed: false,
26
+ })
27
+ .reply(200, (uri, requestBody) => requestBody)
28
+ .get("/todos/empty-null")
29
+ .reply(200, undefined)
30
+ .get("/todos/empty-string")
31
+ .reply(200, "")
32
+ .get("/todos/empty-object")
33
+ .reply(200, {})
34
+ .get("/todos/invalid")
35
+ .replyWithError("Something bad happened");
36
+ });
37
+ (0, ava_1.default)("fetch: should return without type data", async (t) => {
38
+ const url = "https://jsonplaceholder.typicode.com/todos/1";
39
+ const { data, ok } = await (0, fetch_1.fetch)(url);
40
+ t.is(ok, true);
41
+ t.is(data["title"], "Example title");
42
+ });
43
+ (0, ava_1.default)("fetch: should return parsed JSON response as a specific type", async (t) => {
44
+ const url = "https://jsonplaceholder.typicode.com/todos/1";
45
+ const { data, ok } = await (0, fetch_1.fetch)(url);
46
+ t.is(ok, true);
47
+ t.is(data.id, 1);
48
+ t.is(typeof data.title, "string");
49
+ t.is(typeof data.completed, "boolean");
50
+ });
51
+ (0, ava_1.default)("fetch: should handle additional request options", async (t) => {
52
+ const url = "https://jsonplaceholder.typicode.com/todos";
53
+ const requestOptions = {
54
+ method: "POST",
55
+ body: JSON.stringify({
56
+ title: "test todo",
57
+ userId: 1,
58
+ completed: false,
59
+ }),
60
+ headers: {
61
+ "Content-type": "application/json; charset=UTF-8",
62
+ },
63
+ };
64
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
65
+ const { data, ok } = await (0, fetch_1.fetch)(url, requestOptions);
66
+ t.is(ok, true);
67
+ t.is(data["title"], "test todo");
68
+ t.is(data["userId"], 1);
69
+ t.is(data["completed"], false);
70
+ });
71
+ (0, ava_1.default)("fetch: should handle empty (null) responses", async (t) => {
72
+ const url = "https://jsonplaceholder.typicode.com/todos/empty-null";
73
+ const resp = await (0, fetch_1.fetch)(url);
74
+ t.is(resp.data, "");
75
+ t.is(resp.ok, true);
76
+ t.is(resp.status, http_status_codes_1.StatusCodes.OK);
77
+ });
78
+ (0, ava_1.default)("fetch: should handle empty (string) responses", async (t) => {
79
+ const url = "https://jsonplaceholder.typicode.com/todos/empty-string";
80
+ const resp = await (0, fetch_1.fetch)(url);
81
+ t.is(resp.data, "");
82
+ t.is(resp.ok, true);
83
+ t.is(resp.status, http_status_codes_1.StatusCodes.OK);
84
+ });
85
+ (0, ava_1.default)("fetch: should handle empty (object) responses", async (t) => {
86
+ const url = "https://jsonplaceholder.typicode.com/todos/empty-object";
87
+ const resp = await (0, fetch_1.fetch)(url);
88
+ t.deepEqual(resp.data, {});
89
+ t.is(resp.ok, true);
90
+ t.is(resp.status, http_status_codes_1.StatusCodes.OK);
91
+ });
92
+ (0, ava_1.default)("fetch: should handle failed requests without throwing an error", async (t) => {
93
+ const url = "https://jsonplaceholder.typicode.com/todos/invalid";
94
+ const resp = await (0, fetch_1.fetch)(url);
95
+ t.is(resp.data, undefined);
96
+ t.is(resp.ok, false);
97
+ t.is(resp.status, http_status_codes_1.StatusCodes.BAD_REQUEST);
98
+ });
@@ -0,0 +1,208 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const ava_1 = __importDefault(require("ava"));
7
+ const loader_1 = require("../../fixtures/loader");
8
+ const filter_1 = require("./filter");
9
+ const k8s_1 = require("./k8s");
10
+ const callback = () => undefined;
11
+ (0, ava_1.default)("should reject when name does not match", t => {
12
+ const binding = {
13
+ kind: k8s_1.gvkMap.V1Pod,
14
+ filters: {
15
+ name: "bleh",
16
+ namespaces: [],
17
+ labels: {},
18
+ annotations: {},
19
+ },
20
+ callback,
21
+ };
22
+ const pod = (0, loader_1.POD1)();
23
+ t.true((0, filter_1.shouldSkipRequest)(binding, pod));
24
+ });
25
+ (0, ava_1.default)("should reject when kind does not match", t => {
26
+ const binding = {
27
+ kind: k8s_1.gvkMap.V1ConfigMap,
28
+ filters: {
29
+ name: "",
30
+ namespaces: [],
31
+ labels: {},
32
+ annotations: {},
33
+ },
34
+ callback,
35
+ };
36
+ const pod = (0, loader_1.POD1)();
37
+ t.true((0, filter_1.shouldSkipRequest)(binding, pod));
38
+ });
39
+ (0, ava_1.default)("should reject when group does not match", t => {
40
+ const binding = {
41
+ kind: k8s_1.gvkMap.V1CronJob,
42
+ filters: {
43
+ name: "",
44
+ namespaces: [],
45
+ labels: {},
46
+ annotations: {},
47
+ },
48
+ callback,
49
+ };
50
+ const pod = (0, loader_1.POD1)();
51
+ t.true((0, filter_1.shouldSkipRequest)(binding, pod));
52
+ });
53
+ (0, ava_1.default)("should reject when version does not match", t => {
54
+ const binding = {
55
+ kind: {
56
+ group: "",
57
+ version: "v2",
58
+ kind: "Pod",
59
+ },
60
+ filters: {
61
+ name: "",
62
+ namespaces: [],
63
+ labels: {},
64
+ annotations: {},
65
+ },
66
+ callback,
67
+ };
68
+ const pod = (0, loader_1.POD1)();
69
+ t.true((0, filter_1.shouldSkipRequest)(binding, pod));
70
+ });
71
+ (0, ava_1.default)("should allow when group, version, and kind match", t => {
72
+ const binding = {
73
+ kind: k8s_1.gvkMap.V1Pod,
74
+ filters: {
75
+ name: "",
76
+ namespaces: [],
77
+ labels: {},
78
+ annotations: {},
79
+ },
80
+ callback,
81
+ };
82
+ const pod = (0, loader_1.POD1)();
83
+ t.false((0, filter_1.shouldSkipRequest)(binding, pod));
84
+ });
85
+ (0, ava_1.default)("should allow when kind match and others are empty", t => {
86
+ const binding = {
87
+ kind: {
88
+ group: "",
89
+ version: "",
90
+ kind: "Pod",
91
+ },
92
+ filters: {
93
+ name: "",
94
+ namespaces: [],
95
+ labels: {},
96
+ annotations: {},
97
+ },
98
+ callback,
99
+ };
100
+ const pod = (0, loader_1.POD1)();
101
+ t.false((0, filter_1.shouldSkipRequest)(binding, pod));
102
+ });
103
+ (0, ava_1.default)("should reject when namespace does not match", t => {
104
+ const binding = {
105
+ kind: k8s_1.gvkMap.V1Pod,
106
+ filters: {
107
+ name: "",
108
+ namespaces: ["bleh"],
109
+ labels: {},
110
+ annotations: {},
111
+ },
112
+ callback,
113
+ };
114
+ const pod = (0, loader_1.POD1)();
115
+ t.true((0, filter_1.shouldSkipRequest)(binding, pod));
116
+ });
117
+ (0, ava_1.default)("should allow when namespace is match", t => {
118
+ const binding = {
119
+ kind: k8s_1.gvkMap.V1Pod,
120
+ filters: {
121
+ name: "",
122
+ namespaces: ["default", "unicorn", "things"],
123
+ labels: {},
124
+ annotations: {},
125
+ },
126
+ callback,
127
+ };
128
+ const pod = (0, loader_1.POD1)();
129
+ t.false((0, filter_1.shouldSkipRequest)(binding, pod));
130
+ });
131
+ (0, ava_1.default)("should reject when label does not match", t => {
132
+ const binding = {
133
+ kind: k8s_1.gvkMap.V1Pod,
134
+ filters: {
135
+ name: "",
136
+ namespaces: [],
137
+ labels: {
138
+ foo: "bar",
139
+ },
140
+ annotations: {},
141
+ },
142
+ callback,
143
+ };
144
+ const pod = (0, loader_1.POD1)();
145
+ t.true((0, filter_1.shouldSkipRequest)(binding, pod));
146
+ });
147
+ (0, ava_1.default)("should allow when label is match", t => {
148
+ const binding = {
149
+ kind: k8s_1.gvkMap.V1Pod,
150
+ filters: {
151
+ name: "",
152
+ namespaces: [],
153
+ labels: {
154
+ foo: "bar",
155
+ test: "test1",
156
+ },
157
+ annotations: {},
158
+ },
159
+ callback,
160
+ };
161
+ const pod = (0, loader_1.POD1)();
162
+ pod.object.metadata = pod.object.metadata || {};
163
+ pod.object.metadata.labels = {
164
+ foo: "bar",
165
+ test: "test1",
166
+ test2: "test2",
167
+ };
168
+ t.false((0, filter_1.shouldSkipRequest)(binding, pod));
169
+ });
170
+ (0, ava_1.default)("should reject when annotation does not match", t => {
171
+ const binding = {
172
+ kind: k8s_1.gvkMap.V1Pod,
173
+ filters: {
174
+ name: "",
175
+ namespaces: [],
176
+ labels: {},
177
+ annotations: {
178
+ foo: "bar",
179
+ },
180
+ },
181
+ callback,
182
+ };
183
+ const pod = (0, loader_1.POD1)();
184
+ t.true((0, filter_1.shouldSkipRequest)(binding, pod));
185
+ });
186
+ (0, ava_1.default)("should allow when annotation is match", t => {
187
+ const binding = {
188
+ kind: k8s_1.gvkMap.V1Pod,
189
+ filters: {
190
+ name: "",
191
+ namespaces: [],
192
+ labels: {},
193
+ annotations: {
194
+ foo: "bar",
195
+ test: "test1",
196
+ },
197
+ },
198
+ callback,
199
+ };
200
+ const pod = (0, loader_1.POD1)();
201
+ pod.object.metadata = pod.object.metadata || {};
202
+ pod.object.metadata.annotations = {
203
+ foo: "bar",
204
+ test: "test1",
205
+ test2: "test2",
206
+ };
207
+ t.false((0, filter_1.shouldSkipRequest)(binding, pod));
208
+ });