pepr 0.37.2 → 0.38.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.
package/package.json CHANGED
@@ -13,7 +13,7 @@
13
13
  "/dist",
14
14
  "/src"
15
15
  ],
16
- "version": "0.37.2",
16
+ "version": "0.38.0",
17
17
  "main": "dist/lib.js",
18
18
  "types": "dist/lib.d.ts",
19
19
  "scripts": {
@@ -39,12 +39,12 @@
39
39
  },
40
40
  "dependencies": {
41
41
  "@types/ramda": "0.30.2",
42
- "express": "4.21.0",
42
+ "express": "4.21.1",
43
43
  "fast-json-patch": "3.1.1",
44
44
  "json-pointer": "^0.6.2",
45
- "kubernetes-fluent-client": "3.0.4",
46
- "pino": "9.4.0",
47
- "pino-pretty": "11.2.2",
45
+ "kubernetes-fluent-client": "3.1.1",
46
+ "pino": "9.5.0",
47
+ "pino-pretty": "11.3.0",
48
48
  "prom-client": "15.1.3",
49
49
  "ramda": "0.30.1"
50
50
  },
package/src/cli/build.ts CHANGED
@@ -138,7 +138,7 @@ export default function (program: RootCmd) {
138
138
  );
139
139
 
140
140
  // If registry is set to Iron Bank, use Iron Bank image
141
- if (opts?.registry == "Iron Bank") {
141
+ if (opts?.registry === "Iron Bank") {
142
142
  console.info(
143
143
  `\n\tThis command assumes the latest release. Pepr's Iron Bank image release cycle is dictated by renovate and is typically released a few days after the GitHub release.\n\tAs an alternative you may consider custom --custom-image to target a specific image and version.`,
144
144
  );
@@ -1,6 +1,6 @@
1
1
  import { kind } from "kubernetes-fluent-client";
2
2
 
3
- import { AdmissionRequest } from "../lib/k8s";
3
+ import { AdmissionRequest } from "../lib/types";
4
4
  import createPod from "./data/create-pod.json";
5
5
  import deletePod from "./data/delete-pod.json";
6
6
 
@@ -6,7 +6,7 @@ import { V1Pod } from "@kubernetes/client-node";
6
6
  import { expect, describe, jest, beforeEach, it } from "@jest/globals";
7
7
  import { PeprMutateRequest } from "./mutate-request";
8
8
  import { PeprValidateRequest } from "./validate-request";
9
- import { Operation, AdmissionRequest } from "./k8s";
9
+ import { Operation, AdmissionRequest } from "./types";
10
10
  import { WatchPhase } from "kubernetes-fluent-client/dist/fluent/types";
11
11
  import { Event } from "./types";
12
12
  import { GenericClass } from "kubernetes-fluent-client";
@@ -6,14 +6,14 @@ import fs from "fs";
6
6
  import https from "https";
7
7
 
8
8
  import { Capability } from "../capability";
9
- import { MutateResponse, AdmissionRequest, ValidateResponse } from "../k8s";
9
+ import { MutateResponse, ValidateResponse } from "../k8s";
10
10
  import Log from "../logger";
11
11
  import { metricsCollector, MetricsCollector } from "../metrics";
12
12
  import { ModuleConfig, isWatchMode } from "../module";
13
13
  import { mutateProcessor } from "../mutate-processor";
14
14
  import { validateProcessor } from "../validate-processor";
15
15
  import { PeprControllerStore } from "./store";
16
- import { ResponseItem } from "../types";
16
+ import { ResponseItem, AdmissionRequest } from "../types";
17
17
 
18
18
  if (!process.env.PEPR_NODE_WARNINGS) {
19
19
  process.removeAllListeners("warning");
package/src/lib/k8s.ts CHANGED
@@ -1,15 +1,7 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
3
 
4
- import { GenericKind, GroupVersionKind, KubernetesObject, RegisterKind } from "kubernetes-fluent-client";
5
-
6
- // DEPRECATED: Use Operation in types.ts instead
7
- export enum Operation {
8
- CREATE = "CREATE",
9
- UPDATE = "UPDATE",
10
- DELETE = "DELETE",
11
- CONNECT = "CONNECT",
12
- }
4
+ import { GenericKind, RegisterKind } from "kubernetes-fluent-client";
13
5
 
14
6
  /**
15
7
  * PeprStore for internal use by Pepr. This is used to store arbitrary data in the cluster.
@@ -28,99 +20,6 @@ export const peprStoreGVK = {
28
20
 
29
21
  RegisterKind(PeprStore, peprStoreGVK);
30
22
 
31
- // DEPRECATED: Use Operation in types.ts instead
32
- /**
33
- * GroupVersionResource unambiguously identifies a resource. It doesn't anonymously include GroupVersion
34
- * to avoid automatic coercion. It doesn't use a GroupVersion to avoid custom marshalling
35
- */
36
- export interface GroupVersionResource {
37
- readonly group: string;
38
- readonly version: string;
39
- readonly resource: string;
40
- }
41
-
42
- // DEPRECATED: Use Operation in types.ts instead
43
-
44
- /**
45
- * A Kubernetes admission request to be processed by a capability.
46
- */
47
- export interface AdmissionRequest<T = KubernetesObject> {
48
- /** UID is an identifier for the individual request/response. */
49
- readonly uid: string;
50
-
51
- /** Kind is the fully-qualified type of object being submitted (for example, v1.Pod or autoscaling.v1.Scale) */
52
- readonly kind: GroupVersionKind;
53
-
54
- /** Resource is the fully-qualified resource being requested (for example, v1.pods) */
55
- readonly resource: GroupVersionResource;
56
-
57
- /** SubResource is the sub-resource being requested, if any (for example, "status" or "scale") */
58
- readonly subResource?: string;
59
-
60
- /** RequestKind is the fully-qualified type of the original API request (for example, v1.Pod or autoscaling.v1.Scale). */
61
- readonly requestKind?: GroupVersionKind;
62
-
63
- /** RequestResource is the fully-qualified resource of the original API request (for example, v1.pods). */
64
- readonly requestResource?: GroupVersionResource;
65
-
66
- /** RequestSubResource is the sub-resource of the original API request, if any (for example, "status" or "scale"). */
67
- readonly requestSubResource?: string;
68
-
69
- /**
70
- * Name is the name of the object as presented in the request. On a CREATE operation, the client may omit name and
71
- * rely on the server to generate the name. If that is the case, this method will return the empty string.
72
- */
73
- readonly name: string;
74
-
75
- /** Namespace is the namespace associated with the request (if any). */
76
- readonly namespace?: string;
77
-
78
- /**
79
- * Operation is the operation being performed. This may be different than the operation
80
- * requested. e.g. a patch can result in either a CREATE or UPDATE Operation.
81
- */
82
- readonly operation: Operation;
83
-
84
- /** UserInfo is information about the requesting user */
85
- readonly userInfo: {
86
- /** The name that uniquely identifies this user among all active users. */
87
- username?: string;
88
-
89
- /**
90
- * A unique value that identifies this user across time. If this user is deleted
91
- * and another user by the same name is added, they will have different UIDs.
92
- */
93
- uid?: string;
94
-
95
- /** The names of groups this user is a part of. */
96
- groups?: string[];
97
-
98
- /** Any additional information provided by the authenticator. */
99
- extra?: {
100
- [key: string]: string[];
101
- };
102
- };
103
-
104
- /** Object is the object from the incoming request prior to default values being applied */
105
- readonly object: T;
106
-
107
- /** OldObject is the existing object. Only populated for UPDATE or DELETE requests. */
108
- readonly oldObject?: T;
109
-
110
- /** DryRun indicates that modifications will definitely not be persisted for this request. Defaults to false. */
111
- readonly dryRun?: boolean;
112
-
113
- /**
114
- * Options contains the options for the operation being performed.
115
- * e.g. `meta.k8s.io/v1.DeleteOptions` or `meta.k8s.io/v1.CreateOptions`. This may be
116
- * different than the options the caller provided. e.g. for a patch request the performed
117
- * Operation might be a CREATE, in which case the Options will a
118
- * `meta.k8s.io/v1.CreateOptions` even though the caller provided `meta.k8s.io/v1.PatchOptions`.
119
- */
120
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
121
- readonly options?: any;
122
- }
123
-
124
23
  export interface MutateResponse {
125
24
  /** UID is an identifier for the individual request/response. This must be copied over from the corresponding AdmissionRequest. */
126
25
  uid: string;
@@ -34,7 +34,7 @@ export async function mutateProcessor(
34
34
  let skipDecode: string[] = [];
35
35
 
36
36
  // If the resource is a secret, decode the data
37
- const isSecret = req.kind.version == "v1" && req.kind.kind == "Secret";
37
+ const isSecret = req.kind.version === "v1" && req.kind.kind === "Secret";
38
38
  if (isSecret) {
39
39
  skipDecode = convertFromBase64Map(wrapped.Raw as unknown as kind.Secret);
40
40
  }
@@ -64,7 +64,7 @@ export async function mutateProcessor(
64
64
  // this will allow tracking of failed mutations that were permitted to continue
65
65
  const updateStatus = (status: string) => {
66
66
  // Only update the status if the request is a CREATE or UPDATE (we don't use CONNECT)
67
- if (req.operation == "DELETE") {
67
+ if (req.operation === "DELETE") {
68
68
  return;
69
69
  }
70
70
 
@@ -130,7 +130,7 @@ export async function mutateProcessor(
130
130
  }
131
131
 
132
132
  // delete operations can't be mutate, just return before the transformation
133
- if (req.operation == "DELETE") {
133
+ if (req.operation === "DELETE") {
134
134
  return response;
135
135
  }
136
136
 
package/src/lib/utils.ts CHANGED
@@ -30,7 +30,7 @@ export function convertFromBase64Map(obj: { data?: Record<string, string> }) {
30
30
 
31
31
  obj.data = obj.data ?? {};
32
32
  for (const key in obj.data) {
33
- if (obj.data[key] == undefined) {
33
+ if (obj.data[key] === undefined) {
34
34
  obj.data[key] = "";
35
35
  } else {
36
36
  const decoded = base64Decode(obj.data[key]);
@@ -22,7 +22,7 @@ export async function validateProcessor(
22
22
  const response: ValidateResponse[] = [];
23
23
 
24
24
  // If the resource is a secret, decode the data
25
- const isSecret = req.kind.version == "v1" && req.kind.kind == "Secret";
25
+ const isSecret = req.kind.version === "v1" && req.kind.kind === "Secret";
26
26
  if (isSecret) {
27
27
  convertFromBase64Map(wrapped.Raw as unknown as kind.Secret);
28
28
  }
@@ -26,7 +26,6 @@ jest.mock("./metrics", () => ({
26
26
  incRetryCount: jest.fn(),
27
27
  },
28
28
  }));
29
-
30
29
  describe("WatchProcessor", () => {
31
30
  const mockStart = jest.fn();
32
31
  const mockK8s = jest.mocked(K8s);
@@ -49,6 +49,7 @@ export function getOrCreateQueue(obj: KubernetesObject) {
49
49
 
50
50
  // Watch configuration
51
51
  const watchCfg: WatchCfg = {
52
+ useHTTP2: process.env.PEPR_HTTP2_WATCH === "true",
52
53
  resyncFailureMax: process.env.PEPR_RESYNC_FAILURE_MAX ? parseInt(process.env.PEPR_RESYNC_FAILURE_MAX, 10) : 5,
53
54
  resyncDelaySec: process.env.PEPR_RESYNC_DELAY_SECONDS ? parseInt(process.env.PEPR_RESYNC_DELAY_SECONDS, 10) : 5,
54
55
  lastSeenLimitSeconds: process.env.PEPR_LAST_SEEN_LIMIT_SECONDS