pepr 0.38.3 → 0.39.1

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 (95) hide show
  1. package/dist/cli/build.d.ts +1 -1
  2. package/dist/cli/build.d.ts.map +1 -1
  3. package/dist/cli/build.helpers.d.ts +19 -0
  4. package/dist/cli/build.helpers.d.ts.map +1 -0
  5. package/dist/cli/deploy.d.ts.map +1 -1
  6. package/dist/cli/format.d.ts.map +1 -1
  7. package/dist/cli/init/index.d.ts.map +1 -1
  8. package/dist/cli/init/templates.d.ts +6 -2
  9. package/dist/cli/init/templates.d.ts.map +1 -1
  10. package/dist/cli/monitor.d.ts.map +1 -1
  11. package/dist/cli.js +294 -229
  12. package/dist/controller.js +53 -31
  13. package/dist/lib/assets/deploy.d.ts.map +1 -1
  14. package/dist/lib/assets/helm.d.ts +1 -0
  15. package/dist/lib/assets/helm.d.ts.map +1 -1
  16. package/dist/lib/assets/index.d.ts +1 -1
  17. package/dist/lib/assets/index.d.ts.map +1 -1
  18. package/dist/lib/assets/rbac.d.ts +31 -4
  19. package/dist/lib/assets/rbac.d.ts.map +1 -1
  20. package/dist/lib/assets/yaml.d.ts +2 -2
  21. package/dist/lib/assets/yaml.d.ts.map +1 -1
  22. package/dist/lib/capability.d.ts +2 -8
  23. package/dist/lib/capability.d.ts.map +1 -1
  24. package/dist/lib/controller/store.d.ts +1 -5
  25. package/dist/lib/controller/store.d.ts.map +1 -1
  26. package/dist/lib/controller/storeCache.d.ts +11 -0
  27. package/dist/lib/controller/storeCache.d.ts.map +1 -0
  28. package/dist/lib/enums.d.ts +17 -0
  29. package/dist/lib/enums.d.ts.map +1 -0
  30. package/dist/lib/{adjudicators.d.ts → filter/adjudicators.d.ts} +23 -18
  31. package/dist/lib/filter/adjudicators.d.ts.map +1 -0
  32. package/dist/lib/{filter.d.ts → filter/filter.d.ts} +1 -1
  33. package/dist/lib/filter/filter.d.ts.map +1 -0
  34. package/dist/lib/helpers.d.ts +1 -2
  35. package/dist/lib/helpers.d.ts.map +1 -1
  36. package/dist/lib/k8s.d.ts +1 -1
  37. package/dist/lib/k8s.d.ts.map +1 -1
  38. package/dist/lib/logger.d.ts +4 -0
  39. package/dist/lib/logger.d.ts.map +1 -1
  40. package/dist/lib/metrics.d.ts.map +1 -1
  41. package/dist/lib/module.d.ts +5 -0
  42. package/dist/lib/module.d.ts.map +1 -1
  43. package/dist/lib/mutate-processor.d.ts.map +1 -1
  44. package/dist/lib/mutate-request.d.ts +1 -60
  45. package/dist/lib/mutate-request.d.ts.map +1 -1
  46. package/dist/lib/types.d.ts +8 -24
  47. package/dist/lib/types.d.ts.map +1 -1
  48. package/dist/lib/validate-request.d.ts.map +1 -1
  49. package/dist/lib/watch-processor.d.ts.map +1 -1
  50. package/dist/lib.js +236 -299
  51. package/dist/lib.js.map +4 -4
  52. package/dist/sdk/cosign.d.ts +18 -0
  53. package/dist/sdk/cosign.d.ts.map +1 -0
  54. package/dist/sdk/heredoc.d.ts +2 -0
  55. package/dist/sdk/heredoc.d.ts.map +1 -0
  56. package/dist/sdk/sdk.d.ts +1 -2
  57. package/dist/sdk/sdk.d.ts.map +1 -1
  58. package/package.json +12 -8
  59. package/src/cli/build.helpers.ts +28 -0
  60. package/src/cli/build.ts +124 -121
  61. package/src/cli/deploy.ts +27 -24
  62. package/src/cli/dev.ts +3 -3
  63. package/src/cli/format.ts +3 -6
  64. package/src/cli/init/index.ts +23 -19
  65. package/src/cli/monitor.ts +34 -36
  66. package/src/lib/assets/deploy.ts +12 -3
  67. package/src/lib/assets/helm.ts +14 -0
  68. package/src/lib/assets/index.ts +12 -8
  69. package/src/lib/assets/rbac.ts +69 -17
  70. package/src/lib/assets/webhooks.ts +1 -1
  71. package/src/lib/assets/yaml.ts +8 -4
  72. package/src/lib/capability.ts +7 -12
  73. package/src/lib/controller/index.ts +3 -3
  74. package/src/lib/controller/store.ts +42 -202
  75. package/src/lib/controller/storeCache.ts +63 -0
  76. package/src/lib/enums.ts +21 -0
  77. package/src/lib/{adjudicators.ts → filter/adjudicators.ts} +56 -31
  78. package/src/lib/{filter.ts → filter/filter.ts} +3 -2
  79. package/src/lib/finalizer.ts +1 -1
  80. package/src/lib/helpers.ts +19 -15
  81. package/src/lib/k8s.ts +2 -2
  82. package/src/lib/logger.ts +41 -0
  83. package/src/lib/metrics.ts +3 -1
  84. package/src/lib/module.ts +5 -0
  85. package/src/lib/mutate-processor.ts +14 -12
  86. package/src/lib/mutate-request.ts +4 -69
  87. package/src/lib/types.ts +9 -28
  88. package/src/lib/validate-processor.ts +1 -1
  89. package/src/lib/validate-request.ts +2 -1
  90. package/src/lib/watch-processor.ts +34 -20
  91. package/src/sdk/cosign.ts +327 -0
  92. package/src/sdk/heredoc.ts +36 -0
  93. package/src/sdk/sdk.ts +1 -2
  94. package/dist/lib/adjudicators.d.ts.map +0 -1
  95. package/dist/lib/filter.d.ts.map +0 -1
@@ -6,15 +6,15 @@ import { K8s } from "kubernetes-fluent-client";
6
6
  import { startsWith } from "ramda";
7
7
 
8
8
  import { Capability } from "../capability";
9
- import { PeprStore } from "../k8s";
10
- import Log from "../logger";
9
+ import { Store } from "../k8s";
10
+ import Log, { redactedPatch, redactedStore } from "../logger";
11
11
  import { DataOp, DataSender, DataStore, Storage } from "../storage";
12
+ import { fillStoreCache, sendUpdatesAndFlushCache } from "./storeCache";
12
13
 
13
- const redactedValue = "**redacted**";
14
14
  const namespace = "pepr-system";
15
15
  export const debounceBackoff = 5000;
16
16
 
17
- export class PeprControllerStore {
17
+ export class StoreController {
18
18
  #name: string;
19
19
  #stores: Record<string, Storage> = {};
20
20
  #sendDebounce: NodeJS.Timeout | undefined;
@@ -23,124 +23,53 @@ export class PeprControllerStore {
23
23
  constructor(capabilities: Capability[], name: string, onReady?: () => void) {
24
24
  this.#onReady = onReady;
25
25
 
26
- // Setup Pepr State bindings
27
26
  this.#name = name;
28
27
 
28
+ const setStorageInstance = (registrationFunction: () => Storage, name: string) => {
29
+ const scheduleStore = registrationFunction();
30
+
31
+ // Bind the store sender to the capability
32
+ scheduleStore.registerSender(this.#send(name));
33
+
34
+ // Store the storage instance
35
+ this.#stores[name] = scheduleStore;
36
+ };
37
+
29
38
  if (name.includes("schedule")) {
30
39
  // Establish the store for each capability
31
40
  for (const { name, registerScheduleStore, hasSchedule } of capabilities) {
32
- // Guard Clause to exit early
33
- if (hasSchedule !== true) {
34
- continue;
41
+ if (hasSchedule === true) {
42
+ // Register the scheduleStore with the capability
43
+ setStorageInstance(registerScheduleStore, name);
35
44
  }
36
- // Register the scheduleStore with the capability
37
- const { scheduleStore } = registerScheduleStore();
38
-
39
- // Bind the store sender to the capability
40
- scheduleStore.registerSender(this.#send(name));
41
-
42
- // Store the storage instance
43
- this.#stores[name] = scheduleStore;
44
45
  }
45
46
  } else {
46
47
  // Establish the store for each capability
47
48
  for (const { name, registerStore } of capabilities) {
48
- // Register the store with the capability
49
- const { store } = registerStore();
50
-
51
- // Bind the store sender to the capability
52
- store.registerSender(this.#send(name));
53
-
54
- // Store the storage instance
55
- this.#stores[name] = store;
49
+ setStorageInstance(registerStore, name);
56
50
  }
57
51
  }
58
52
 
59
- // Add a jitter to the Store creation to avoid collisions
60
53
  setTimeout(
61
54
  () =>
62
- K8s(PeprStore)
55
+ K8s(Store)
63
56
  .InNamespace(namespace)
64
57
  .Get(this.#name)
65
- // If the get succeeds, migrate and setup the watch
66
- .then(async (store: PeprStore) => await this.#migrateAndSetupWatch(store))
67
- // Otherwise, create the resource
58
+ .then(async (store: Store) => await this.#migrateAndSetupWatch(store))
68
59
  .catch(this.#createStoreResource),
69
- Math.random() * 3000,
60
+ Math.random() * 3000, // Add a jitter to the Store creation to avoid collisions
70
61
  );
71
62
  }
72
63
 
73
64
  #setupWatch = () => {
74
- const watcher = K8s(PeprStore, { name: this.#name, namespace }).Watch(this.#receive);
65
+ const watcher = K8s(Store, { name: this.#name, namespace }).Watch(this.#receive);
75
66
  watcher.start().catch(e => Log.error(e, "Error starting Pepr store watch"));
76
67
  };
77
68
 
78
- #migrateAndSetupWatch = async (store: PeprStore) => {
69
+ #migrateAndSetupWatch = async (store: Store) => {
79
70
  Log.debug(redactedStore(store), "Pepr Store migration");
80
71
  const data: DataStore = store.data || {};
81
- const migrateCache: Record<string, Operation> = {};
82
-
83
- // Send the cached updates to the cluster
84
- const flushCache = async () => {
85
- const indexes = Object.keys(migrateCache);
86
- const payload = Object.values(migrateCache);
87
-
88
- // Loop over each key in the cache and delete it to avoid collisions with other sender calls
89
- for (const idx of indexes) {
90
- delete migrateCache[idx];
91
- }
92
-
93
- try {
94
- // Send the patch to the cluster
95
- if (payload.length > 0) {
96
- await K8s(PeprStore, { namespace, name: this.#name }).Patch(payload);
97
- }
98
- } catch (err) {
99
- Log.error(err, "Pepr store update failure");
100
-
101
- if (err.status === 422) {
102
- Object.keys(migrateCache).forEach(key => delete migrateCache[key]);
103
- } else {
104
- // On failure to update, re-add the operations to the cache to be retried
105
- for (const idx of indexes) {
106
- migrateCache[idx] = payload[Number(idx)];
107
- }
108
- }
109
- }
110
- };
111
-
112
- const fillCache = (name: string, op: DataOp, key: string[], val?: string) => {
113
- if (op === "add") {
114
- // adjust the path for the capability
115
- const path = `/data/${name}-v2-${key}`;
116
- const value = val || "";
117
- const cacheIdx = [op, path, value].join(":");
118
-
119
- // Add the operation to the cache
120
- migrateCache[cacheIdx] = { op, path, value };
121
-
122
- return;
123
- }
124
-
125
- if (op === "remove") {
126
- if (key.length < 1) {
127
- throw new Error(`Key is required for REMOVE operation`);
128
- }
129
-
130
- for (const k of key) {
131
- const path = `/data/${name}-${k}`;
132
- const cacheIdx = [op, path].join(":");
133
-
134
- // Add the operation to the cache
135
- migrateCache[cacheIdx] = { op, path };
136
- }
137
-
138
- return;
139
- }
140
-
141
- // If we get here, the operation is not supported
142
- throw new Error(`Unsupported operation: ${op}`);
143
- };
72
+ let storeCache: Record<string, Operation> = {};
144
73
 
145
74
  for (const name of Object.keys(this.#stores)) {
146
75
  // Get the prefix offset for the keys
@@ -151,16 +80,23 @@ export class PeprControllerStore {
151
80
  // Match on the capability name as a prefix for non v2 keys
152
81
  if (startsWith(name, key) && !startsWith(`${name}-v2`, key)) {
153
82
  // populate migrate cache
154
- fillCache(name, "remove", [key.slice(offset)], data[key]);
155
- fillCache(name, "add", [key.slice(offset)], data[key]);
83
+ storeCache = fillStoreCache(storeCache, name, "remove", {
84
+ key: [key.slice(offset)],
85
+ value: data[key],
86
+ });
87
+ storeCache = fillStoreCache(storeCache, name, "add", {
88
+ key: [key.slice(offset)],
89
+ value: data[key],
90
+ version: "v2",
91
+ });
156
92
  }
157
93
  }
158
94
  }
159
- await flushCache();
95
+ storeCache = await sendUpdatesAndFlushCache(storeCache, namespace, this.#name);
160
96
  this.#setupWatch();
161
97
  };
162
98
 
163
- #receive = (store: PeprStore) => {
99
+ #receive = (store: Store) => {
164
100
  Log.debug(redactedStore(store), "Pepr Store update");
165
101
 
166
102
  // Wrap the update in a debounced function
@@ -202,81 +138,18 @@ export class PeprControllerStore {
202
138
  };
203
139
 
204
140
  #send = (capabilityName: string) => {
205
- const sendCache: Record<string, Operation> = {};
206
-
207
- // Load the sendCache with patch operations
208
- const fillCache = (op: DataOp, key: string[], val?: string) => {
209
- if (op === "add") {
210
- // adjust the path for the capability
211
- const path = `/data/${capabilityName}-${key}`;
212
- const value = val || "";
213
- const cacheIdx = [op, path, value].join(":");
214
-
215
- // Add the operation to the cache
216
- sendCache[cacheIdx] = { op, path, value };
217
-
218
- return;
219
- }
220
-
221
- if (op === "remove") {
222
- if (key.length < 1) {
223
- throw new Error(`Key is required for REMOVE operation`);
224
- }
225
-
226
- for (const k of key) {
227
- const path = `/data/${capabilityName}-${k}`;
228
- const cacheIdx = [op, path].join(":");
229
-
230
- // Add the operation to the cache
231
- sendCache[cacheIdx] = { op, path };
232
- }
233
-
234
- return;
235
- }
236
-
237
- // If we get here, the operation is not supported
238
- throw new Error(`Unsupported operation: ${op}`);
239
- };
240
-
241
- // Send the cached updates to the cluster
242
- const flushCache = async () => {
243
- const indexes = Object.keys(sendCache);
244
- const payload = Object.values(sendCache);
245
-
246
- // Loop over each key in the cache and delete it to avoid collisions with other sender calls
247
- for (const idx of indexes) {
248
- delete sendCache[idx];
249
- }
250
-
251
- try {
252
- // Send the patch to the cluster
253
- if (payload.length > 0) {
254
- await K8s(PeprStore, { namespace, name: this.#name }).Patch(payload);
255
- }
256
- } catch (err) {
257
- Log.error(err, "Pepr store update failure");
258
-
259
- if (err.status === 422) {
260
- Object.keys(sendCache).forEach(key => delete sendCache[key]);
261
- } else {
262
- // On failure to update, re-add the operations to the cache to be retried
263
- for (const idx of indexes) {
264
- sendCache[idx] = payload[Number(idx)];
265
- }
266
- }
267
- }
268
- };
141
+ let storeCache: Record<string, Operation> = {};
269
142
 
270
143
  // Create a sender function for the capability to add/remove data from the store
271
- const sender: DataSender = async (op: DataOp, key: string[], val?: string) => {
272
- fillCache(op, key, val);
144
+ const sender: DataSender = async (op: DataOp, key: string[], value?: string) => {
145
+ storeCache = fillStoreCache(storeCache, capabilityName, op, { key, value });
273
146
  };
274
147
 
275
148
  // Send any cached updates every debounceBackoff milliseconds
276
149
  setInterval(() => {
277
- if (Object.keys(sendCache).length > 0) {
278
- Log.debug(redactedPatch(sendCache), "Sending updates to Pepr store");
279
- void flushCache();
150
+ if (Object.keys(storeCache).length > 0) {
151
+ Log.debug(redactedPatch(storeCache), "Sending updates to Pepr store");
152
+ void sendUpdatesAndFlushCache(storeCache, namespace, this.#name);
280
153
  }
281
154
  }, debounceBackoff);
282
155
 
@@ -288,7 +161,7 @@ export class PeprControllerStore {
288
161
  Log.debug(e);
289
162
 
290
163
  try {
291
- await K8s(PeprStore).Apply({
164
+ await K8s(Store).Apply({
292
165
  metadata: {
293
166
  name: this.#name,
294
167
  namespace,
@@ -306,36 +179,3 @@ export class PeprControllerStore {
306
179
  }
307
180
  };
308
181
  }
309
-
310
- export function redactedStore(store: PeprStore): PeprStore {
311
- const redacted = process.env.PEPR_STORE_REDACT_VALUES === "true";
312
- return {
313
- ...store,
314
- data: Object.keys(store.data).reduce((acc: Record<string, string>, key: string) => {
315
- acc[key] = redacted ? redactedValue : store.data[key];
316
- return acc;
317
- }, {}),
318
- };
319
- }
320
-
321
- export function redactedPatch(patch: Record<string, Operation> = {}): Record<string, Operation> {
322
- const redacted = process.env.PEPR_STORE_REDACT_VALUES === "true";
323
-
324
- if (!redacted) {
325
- return patch;
326
- }
327
-
328
- const redactedCache: Record<string, Operation> = {};
329
-
330
- Object.keys(patch).forEach(key => {
331
- const operation = patch[key];
332
- const redactedKey = key.includes(":") ? key.substring(0, key.lastIndexOf(":")) + ":**redacted**" : key;
333
- const redactedOperation: Operation = {
334
- ...operation,
335
- ...("value" in operation ? { value: "**redacted**" } : {}),
336
- };
337
- redactedCache[redactedKey] = redactedOperation;
338
- });
339
-
340
- return redactedCache;
341
- }
@@ -0,0 +1,63 @@
1
+ import { DataOp } from "../storage";
2
+ import Log from "../logger";
3
+ import { K8s } from "kubernetes-fluent-client";
4
+ import { Store } from "../k8s";
5
+ import { StatusCodes } from "http-status-codes";
6
+ import { Operation } from "fast-json-patch";
7
+
8
+ export const sendUpdatesAndFlushCache = async (cache: Record<string, Operation>, namespace: string, name: string) => {
9
+ const indexes = Object.keys(cache);
10
+ const payload = Object.values(cache);
11
+
12
+ try {
13
+ if (payload.length > 0) {
14
+ await K8s(Store, { namespace, name }).Patch(payload); // Send patch to cluster
15
+ Object.keys(cache).forEach(key => delete cache[key]);
16
+ }
17
+ } catch (err) {
18
+ Log.error(err, "Pepr store update failure");
19
+
20
+ if (err.status === StatusCodes.UNPROCESSABLE_ENTITY) {
21
+ Object.keys(cache).forEach(key => delete cache[key]);
22
+ } else {
23
+ indexes.forEach(index => {
24
+ cache[index] = payload[Number(index)]; // On failure to update, re-add the operations to the cache to be retried
25
+ });
26
+ }
27
+ }
28
+ return cache;
29
+ };
30
+
31
+ type CacheItem = {
32
+ key: string[];
33
+ value?: string;
34
+ version?: string;
35
+ };
36
+
37
+ export const fillStoreCache = (
38
+ cache: Record<string, Operation>,
39
+ capabilityName: string,
40
+ op: DataOp,
41
+ cacheItem: CacheItem,
42
+ ): Record<string, Operation> => {
43
+ const path = [`/data/${capabilityName}`, cacheItem.version, cacheItem.key] // adjust the path, see ADR-0008
44
+ .filter(str => str !== "" && str !== undefined)
45
+ .join("-");
46
+ if (op === "add") {
47
+ const value = cacheItem.value || "";
48
+ const cacheIdx = [op, path, value].join(":");
49
+
50
+ // Add the operation to the cache
51
+ cache[cacheIdx] = { op, path, value };
52
+ } else if (op === "remove") {
53
+ if (cacheItem.key.length < 1) {
54
+ throw new Error(`Key is required for REMOVE operation`);
55
+ }
56
+ const cacheIndex = [op, path].join(":");
57
+ // Add the operation to the cache
58
+ cache[cacheIndex] = { op, path };
59
+ } else {
60
+ throw new Error(`Unsupported operation: ${op}`);
61
+ }
62
+ return cache;
63
+ };
@@ -0,0 +1,21 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
+
4
+ // Operation type for mutation operations
5
+ export enum Operation {
6
+ CREATE = "CREATE",
7
+ UPDATE = "UPDATE",
8
+ DELETE = "DELETE",
9
+ CONNECT = "CONNECT",
10
+ }
11
+
12
+ /**
13
+ * The type of Kubernetes mutating webhook event that the action is registered for.
14
+ */
15
+ export enum Event {
16
+ Create = "CREATE",
17
+ Update = "UPDATE",
18
+ Delete = "DELETE",
19
+ CreateOrUpdate = "CREATEORUPDATE",
20
+ Any = "*",
21
+ }
@@ -1,7 +1,8 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
3
 
4
- import { Event, Operation } from "./types";
4
+ import { Event, Operation } from "../enums";
5
+ import { AdmissionRequest } from "../../lib/types";
5
6
  import {
6
7
  __,
7
8
  allPass,
@@ -18,6 +19,7 @@ import {
18
19
  nthArg,
19
20
  pipe,
20
21
  } from "ramda";
22
+ import { KubernetesObject } from "kubernetes-fluent-client";
21
23
 
22
24
  /*
23
25
  Naming scheme:
@@ -29,34 +31,52 @@ import {
29
31
  /*
30
32
  AdmissionRequest collectors
31
33
  */
32
- export const declaredOperation = pipe(request => request?.operation, defaultTo(""));
33
- export const declaredGroup = pipe(request => request?.kind?.group, defaultTo(""));
34
- export const declaredVersion = pipe(request => request?.kind?.version, defaultTo(""));
35
- export const declaredKind = pipe(request => request?.kind?.kind, defaultTo(""));
36
- export const declaredUid = pipe(request => request?.uid, defaultTo(""));
34
+ export const declaredOperation = pipe(
35
+ (request: AdmissionRequest<KubernetesObject>): Operation => request?.operation,
36
+ defaultTo(""),
37
+ );
38
+ export const declaredGroup = pipe(
39
+ (request: AdmissionRequest<KubernetesObject>): string => request?.kind?.group,
40
+ defaultTo(""),
41
+ );
42
+ export const declaredVersion = pipe(
43
+ (request: AdmissionRequest<KubernetesObject>): string | undefined => request?.kind?.version,
44
+ defaultTo(""),
45
+ );
46
+ export const declaredKind = pipe(
47
+ (request: AdmissionRequest<KubernetesObject>): string => request?.kind?.kind,
48
+ defaultTo(""),
49
+ );
50
+ export const declaredUid = pipe((request: AdmissionRequest<KubernetesObject>): string => request?.uid, defaultTo(""));
37
51
 
38
52
  /*
39
53
  KubernetesObject collectors
40
54
  */
41
- export const carriesDeletionTimestamp = pipe(obj => !!obj.metadata?.deletionTimestamp, defaultTo(false));
55
+ export const carriesDeletionTimestamp = pipe(
56
+ kubernetesObject => !!kubernetesObject.metadata?.deletionTimestamp,
57
+ defaultTo(false),
58
+ );
42
59
  export const missingDeletionTimestamp = complement(carriesDeletionTimestamp);
43
60
 
44
- export const carriedName = pipe(obj => obj?.metadata?.name, defaultTo(""));
61
+ export const carriedKind = pipe(kubernetesObject => kubernetesObject?.metadata?.kind, defaultTo("not set"));
62
+ export const carriedVersion = pipe(kubernetesObject => kubernetesObject?.metadata?.version, defaultTo("not set"));
63
+ export const carriedName = pipe(kubernetesObject => kubernetesObject?.metadata?.name, defaultTo(""));
45
64
  export const carriesName = pipe(carriedName, equals(""), not);
46
65
  export const missingName = complement(carriesName);
47
66
 
48
- export const carriedNamespace = pipe(obj => obj?.metadata?.namespace, defaultTo(""));
67
+ export const carriedNamespace = pipe(kubernetesObject => kubernetesObject?.metadata?.namespace, defaultTo(""));
49
68
  export const carriesNamespace = pipe(carriedNamespace, equals(""), not);
50
69
 
51
- export const carriedAnnotations = pipe(obj => obj?.metadata?.annotations, defaultTo({}));
70
+ export const carriedAnnotations = pipe(kubernetesObject => kubernetesObject?.metadata?.annotations, defaultTo({}));
52
71
  export const carriesAnnotations = pipe(carriedAnnotations, equals({}), not);
53
72
 
54
- export const carriedLabels = pipe(obj => obj?.metadata?.labels, defaultTo({}));
73
+ export const carriedLabels = pipe(kubernetesObject => kubernetesObject?.metadata?.labels, defaultTo({}));
55
74
  export const carriesLabels = pipe(carriedLabels, equals({}), not);
56
75
 
57
76
  /*
58
77
  Binding collectors
59
78
  */
79
+
60
80
  export const definesDeletionTimestamp = pipe(binding => binding?.filters?.deletionTimestamp, defaultTo(false));
61
81
  export const ignoresDeletionTimestamp = complement(definesDeletionTimestamp);
62
82
 
@@ -112,7 +132,7 @@ export const definedCallback = pipe(binding => {
112
132
  null
113
133
  );
114
134
  });
115
- export const definedCallbackName = pipe(definedCallback, defaultTo({ name: "" }), cb => cb.name);
135
+ export const definedCallbackName = pipe(definedCallback, defaultTo({ name: "" }), callback => callback.name);
116
136
 
117
137
  /*
118
138
  post-collection comparitors
@@ -124,32 +144,32 @@ export const mismatchedDeletionTimestamp = allPass([
124
144
 
125
145
  export const mismatchedName = allPass([
126
146
  pipe(nthArg(0), definesName),
127
- pipe((bnd, obj) => definedName(bnd) !== carriedName(obj)),
147
+ pipe((binding, kubernetesObject) => definedName(binding) !== carriedName(kubernetesObject)),
128
148
  ]);
129
149
 
130
150
  export const mismatchedNameRegex = allPass([
131
151
  pipe(nthArg(0), definesNameRegex),
132
- pipe((bnd, obj) => new RegExp(definedNameRegex(bnd)).test(carriedName(obj)), not),
152
+ pipe((binding, kubernetesObject) => new RegExp(definedNameRegex(binding)).test(carriedName(kubernetesObject)), not),
133
153
  ]);
134
154
 
135
155
  export const bindsToKind = curry(
136
- allPass([pipe(nthArg(0), definedKind, equals(""), not), pipe((bnd, knd) => definedKind(bnd) === knd)]),
156
+ allPass([pipe(nthArg(0), definedKind, equals(""), not), pipe((binding, kind) => definedKind(binding) === kind)]),
137
157
  );
138
158
  export const bindsToNamespace = curry(pipe(bindsToKind(__, "Namespace")));
139
159
  export const misboundNamespace = allPass([bindsToNamespace, definesNamespaces]);
140
160
 
141
161
  export const mismatchedNamespace = allPass([
142
162
  pipe(nthArg(0), definesNamespaces),
143
- pipe((bnd, obj) => definedNamespaces(bnd).includes(carriedNamespace(obj)), not),
163
+ pipe((binding, kubernetesObject) => definedNamespaces(binding).includes(carriedNamespace(kubernetesObject)), not),
144
164
  ]);
145
165
 
146
166
  export const mismatchedNamespaceRegex = allPass([
147
167
  pipe(nthArg(0), definesNamespaceRegexes),
148
- pipe((bnd, obj) =>
168
+ pipe((binding, kubernetesObject) =>
149
169
  pipe(
150
- any((rex: string) => new RegExp(rex).test(carriedNamespace(obj))),
170
+ any((regEx: string) => new RegExp(regEx).test(carriedNamespace(kubernetesObject))),
151
171
  not,
152
- )(definedNamespaceRegexes(bnd)),
172
+ )(definedNamespaceRegexes(binding)),
153
173
  ),
154
174
  ]);
155
175
 
@@ -158,18 +178,18 @@ export const metasMismatch = pipe(
158
178
  const result = { defined, carried, unalike: {} };
159
179
 
160
180
  result.unalike = Object.entries(result.defined)
161
- .map(([key, val]) => {
181
+ .map(([key, value]) => {
162
182
  const keyMissing = !Object.hasOwn(result.carried, key);
163
- const noValue = !val;
183
+ const noValue = !value;
164
184
  const valMissing = !result.carried[key];
165
185
  const valDiffers = result.carried[key] !== result.defined[key];
166
186
 
167
187
  // prettier-ignore
168
188
  return (
169
- keyMissing ? { [key]: val } :
189
+ keyMissing ? { [key]: value } :
170
190
  noValue ? {} :
171
- valMissing ? { [key]: val } :
172
- valDiffers ? { [key]: val } :
191
+ valMissing ? { [key]: value } :
192
+ valDiffers ? { [key]: value } :
173
193
  {}
174
194
  )
175
195
  })
@@ -182,38 +202,43 @@ export const metasMismatch = pipe(
182
202
 
183
203
  export const mismatchedAnnotations = allPass([
184
204
  pipe(nthArg(0), definesAnnotations),
185
- pipe((bnd, obj) => metasMismatch(definedAnnotations(bnd), carriedAnnotations(obj))),
205
+ pipe((binding, kubernetesObject) => metasMismatch(definedAnnotations(binding), carriedAnnotations(kubernetesObject))),
186
206
  ]);
187
207
 
188
208
  export const mismatchedLabels = allPass([
189
209
  pipe(nthArg(0), definesLabels),
190
- pipe((bnd, obj) => metasMismatch(definedLabels(bnd), carriedLabels(obj))),
210
+ pipe((binding, kubernetesObject) => metasMismatch(definedLabels(binding), carriedLabels(kubernetesObject))),
191
211
  ]);
192
212
 
193
213
  export const uncarryableNamespace = allPass([
194
214
  pipe(nthArg(0), length, gt(__, 0)),
195
215
  pipe(nthArg(1), carriesNamespace),
196
- pipe((nss, obj) => nss.includes(carriedNamespace(obj)), not),
216
+ pipe((namespaceSelector, kubernetesObject) => namespaceSelector.includes(carriedNamespace(kubernetesObject)), not),
197
217
  ]);
198
218
 
199
219
  export const carriesIgnoredNamespace = allPass([
200
220
  pipe(nthArg(0), length, gt(__, 0)),
201
221
  pipe(nthArg(1), carriesNamespace),
202
- pipe((nss, obj) => nss.includes(carriedNamespace(obj))),
222
+ pipe((namespaceSelector, kubernetesObject) => namespaceSelector.includes(carriedNamespace(kubernetesObject))),
203
223
  ]);
204
224
 
205
225
  export const unbindableNamespaces = allPass([
206
226
  pipe(nthArg(0), length, gt(__, 0)),
207
227
  pipe(nthArg(1), definesNamespaces),
208
- pipe((nss, bnd) => difference(definedNamespaces(bnd), nss), length, equals(0), not),
228
+ pipe(
229
+ (namespaceSelector, binding) => difference(definedNamespaces(binding), namespaceSelector),
230
+ length,
231
+ equals(0),
232
+ not,
233
+ ),
209
234
  ]);
210
235
 
211
236
  export const misboundDeleteWithDeletionTimestamp = allPass([definesDelete, definesDeletionTimestamp]);
212
237
 
213
238
  export const operationMatchesEvent = anyPass([
214
239
  pipe(nthArg(1), equals(Event.Any)),
215
- pipe((op, evt) => op === evt),
216
- pipe((op, evt) => (op ? evt.includes(op) : false)),
240
+ pipe((operation, event) => operation === event),
241
+ pipe((operation, event) => (operation ? event.includes(operation) : false)),
217
242
  ]);
218
243
 
219
244
  export const mismatchedEvent = pipe(
@@ -1,7 +1,8 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
3
 
4
- import { AdmissionRequest, Binding, Operation } from "./types";
4
+ import { AdmissionRequest, Binding } from "../types";
5
+ import { Operation } from "../enums";
5
6
  import {
6
7
  carriesIgnoredNamespace,
7
8
  carriedName,
@@ -56,7 +57,7 @@ export function shouldSkipRequest(
56
57
 
57
58
  // prettier-ignore
58
59
  return (
59
- misboundDeleteWithDeletionTimestamp(binding) ?
60
+ misboundDeleteWithDeletionTimestamp(binding) ?
60
61
  `${prefix} Cannot use deletionTimestamp filter on a DELETE operation.` :
61
62
 
62
63
  mismatchedDeletionTimestamp(binding, obj) ?
@@ -4,7 +4,7 @@
4
4
  import { K8s, KubernetesObject, RegisterKind } from "kubernetes-fluent-client";
5
5
  import Log from "./logger";
6
6
  import { Binding, DeepPartial } from "./types";
7
- import { Operation } from "./types";
7
+ import { Operation } from "./enums";
8
8
  import { PeprMutateRequest } from "./mutate-request";
9
9
 
10
10
  export function addFinalizer<K extends KubernetesObject>(request: PeprMutateRequest<K>) {