pepr 0.35.0 → 0.37.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.
Files changed (107) hide show
  1. package/dist/cli/init/index.d.ts.map +1 -1
  2. package/dist/cli/init/templates.d.ts +3 -1
  3. package/dist/cli/init/templates.d.ts.map +1 -1
  4. package/dist/cli/init/utils.d.ts.map +1 -1
  5. package/dist/cli/init/walkthrough.d.ts +10 -3
  6. package/dist/cli/init/walkthrough.d.ts.map +1 -1
  7. package/dist/cli.js +253 -31
  8. package/dist/controller.js +138 -1
  9. package/dist/lib/adjudicators.d.ts +63 -0
  10. package/dist/lib/adjudicators.d.ts.map +1 -0
  11. package/dist/lib/adjudicators.test.d.ts +2 -0
  12. package/dist/lib/adjudicators.test.d.ts.map +1 -0
  13. package/dist/lib/assets/loader.d.ts.map +1 -1
  14. package/dist/lib/assets/pods.d.ts +1 -0
  15. package/dist/lib/assets/pods.d.ts.map +1 -1
  16. package/dist/lib/capability.d.ts +1 -0
  17. package/dist/lib/capability.d.ts.map +1 -1
  18. package/dist/lib/capability.test.d.ts +2 -0
  19. package/dist/lib/capability.test.d.ts.map +1 -0
  20. package/dist/lib/controller/index.d.ts.map +1 -1
  21. package/dist/lib/controller/store.d.ts +4 -0
  22. package/dist/lib/controller/store.d.ts.map +1 -1
  23. package/dist/lib/controller/store.test.d.ts +2 -0
  24. package/dist/lib/controller/store.test.d.ts.map +1 -0
  25. package/dist/lib/filter.d.ts +2 -3
  26. package/dist/lib/filter.d.ts.map +1 -1
  27. package/dist/lib/filter.test.d.ts +2 -1
  28. package/dist/lib/filter.test.d.ts.map +1 -1
  29. package/dist/lib/finalizer.d.ts +6 -0
  30. package/dist/lib/finalizer.d.ts.map +1 -0
  31. package/dist/lib/finalizer.test.d.ts +2 -0
  32. package/dist/lib/finalizer.test.d.ts.map +1 -0
  33. package/dist/lib/helpers.d.ts +2 -2
  34. package/dist/lib/helpers.d.ts.map +1 -1
  35. package/dist/lib/helpers.test.d.ts +1 -1
  36. package/dist/lib/helpers.test.d.ts.map +1 -1
  37. package/dist/lib/k8s.d.ts.map +1 -1
  38. package/dist/lib/logger.d.ts +1 -1
  39. package/dist/lib/logger.d.ts.map +1 -1
  40. package/dist/lib/module.d.ts +2 -1
  41. package/dist/lib/module.d.ts.map +1 -1
  42. package/dist/lib/mutate-processor.d.ts +2 -1
  43. package/dist/lib/mutate-processor.d.ts.map +1 -1
  44. package/dist/lib/mutate-request.d.ts +1 -2
  45. package/dist/lib/mutate-request.d.ts.map +1 -1
  46. package/dist/lib/queue.d.ts +19 -3
  47. package/dist/lib/queue.d.ts.map +1 -1
  48. package/dist/lib/schedule.d.ts +1 -2
  49. package/dist/lib/schedule.d.ts.map +1 -1
  50. package/dist/lib/storage.d.ts.map +1 -1
  51. package/dist/lib/types.d.ts +118 -6
  52. package/dist/lib/types.d.ts.map +1 -1
  53. package/dist/lib/validate-processor.d.ts +4 -2
  54. package/dist/lib/validate-processor.d.ts.map +1 -1
  55. package/dist/lib/validate-request.d.ts +1 -1
  56. package/dist/lib/validate-request.d.ts.map +1 -1
  57. package/dist/lib/watch-processor.d.ts +8 -6
  58. package/dist/lib/watch-processor.d.ts.map +1 -1
  59. package/dist/lib.js +467 -233
  60. package/dist/lib.js.map +4 -4
  61. package/dist/sdk/sdk.d.ts +5 -3
  62. package/dist/sdk/sdk.d.ts.map +1 -1
  63. package/package.json +13 -11
  64. package/src/cli/build.ts +3 -3
  65. package/src/cli/init/index.ts +20 -11
  66. package/src/cli/init/templates.ts +1 -1
  67. package/src/cli/init/utils.test.ts +11 -20
  68. package/src/cli/init/utils.ts +5 -0
  69. package/src/cli/init/walkthrough.test.ts +92 -11
  70. package/src/cli/init/walkthrough.ts +71 -16
  71. package/src/cli/monitor.ts +1 -1
  72. package/src/cli.ts +4 -2
  73. package/src/fixtures/data/create-pod.json +1 -1
  74. package/src/fixtures/data/delete-pod.json +1 -1
  75. package/src/lib/adjudicators.test.ts +1232 -0
  76. package/src/lib/adjudicators.ts +235 -0
  77. package/src/lib/assets/index.ts +1 -1
  78. package/src/lib/assets/loader.ts +1 -0
  79. package/src/lib/assets/webhooks.ts +1 -1
  80. package/src/lib/capability.test.ts +655 -0
  81. package/src/lib/capability.ts +112 -11
  82. package/src/lib/controller/index.ts +7 -4
  83. package/src/lib/controller/store.test.ts +131 -0
  84. package/src/lib/controller/store.ts +43 -5
  85. package/src/lib/filter.test.ts +279 -9
  86. package/src/lib/filter.ts +46 -98
  87. package/src/lib/finalizer.test.ts +236 -0
  88. package/src/lib/finalizer.ts +63 -0
  89. package/src/lib/helpers.test.ts +359 -65
  90. package/src/lib/helpers.ts +141 -95
  91. package/src/lib/k8s.ts +4 -0
  92. package/src/lib/module.ts +3 -3
  93. package/src/lib/mutate-processor.ts +5 -4
  94. package/src/lib/mutate-request.test.ts +1 -2
  95. package/src/lib/mutate-request.ts +1 -3
  96. package/src/lib/queue.test.ts +138 -44
  97. package/src/lib/queue.ts +48 -13
  98. package/src/lib/schedule.ts +1 -1
  99. package/src/lib/storage.ts +5 -6
  100. package/src/lib/types.ts +154 -5
  101. package/src/lib/validate-processor.ts +5 -2
  102. package/src/lib/validate-request.test.ts +1 -4
  103. package/src/lib/validate-request.ts +1 -1
  104. package/src/lib/watch-processor.test.ts +89 -124
  105. package/src/lib/watch-processor.ts +52 -35
  106. package/src/sdk/sdk.test.ts +46 -13
  107. package/src/sdk/sdk.ts +15 -6
package/src/lib/queue.ts CHANGED
@@ -2,11 +2,15 @@
2
2
  // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
3
  import { KubernetesObject } from "@kubernetes/client-node";
4
4
  import { WatchPhase } from "kubernetes-fluent-client/dist/fluent/types";
5
+ import { randomBytes } from "node:crypto";
5
6
  import Log from "./logger";
6
7
 
8
+ type WatchCallback = (obj: KubernetesObject, phase: WatchPhase) => Promise<void>;
9
+
7
10
  type QueueItem<K extends KubernetesObject> = {
8
11
  item: K;
9
- type: WatchPhase;
12
+ phase: WatchPhase;
13
+ callback: WatchCallback;
10
14
  resolve: (value: void | PromiseLike<void>) => void;
11
15
  reject: (reason?: string) => void;
12
16
  };
@@ -15,16 +19,27 @@ type QueueItem<K extends KubernetesObject> = {
15
19
  * Queue is a FIFO queue for reconciling
16
20
  */
17
21
  export class Queue<K extends KubernetesObject> {
22
+ #name: string;
23
+ #uid: string;
18
24
  #queue: QueueItem<K>[] = [];
19
25
  #pendingPromise = false;
20
- #reconcile?: (obj: KubernetesObject, type: WatchPhase) => Promise<void>;
21
26
 
22
- constructor() {
23
- this.#reconcile = async () => await new Promise(resolve => resolve());
27
+ constructor(name: string) {
28
+ this.#name = name;
29
+ this.#uid = `${Date.now()}-${randomBytes(2).toString("hex")}`;
30
+ }
31
+
32
+ label() {
33
+ return { name: this.#name, uid: this.#uid };
24
34
  }
25
35
 
26
- setReconcile(reconcile: (obj: KubernetesObject, type: WatchPhase) => Promise<void>) {
27
- this.#reconcile = reconcile;
36
+ stats() {
37
+ return {
38
+ queue: this.label(),
39
+ stats: {
40
+ length: this.#queue.length,
41
+ },
42
+ };
28
43
  }
29
44
 
30
45
  /**
@@ -32,12 +47,23 @@ export class Queue<K extends KubernetesObject> {
32
47
  * reconciled.
33
48
  *
34
49
  * @param item The object to reconcile
50
+ * @param type The watch phase requested for reconcile
51
+ * @param reconcile The callback to enqueue for reconcile
35
52
  * @returns A promise that resolves when the object is reconciled
36
53
  */
37
- enqueue(item: K, type: WatchPhase) {
38
- Log.debug(`Enqueueing ${item.metadata!.namespace}/${item.metadata!.name}`);
54
+ enqueue(item: K, phase: WatchPhase, reconcile: WatchCallback) {
55
+ const note = {
56
+ queue: this.label(),
57
+ item: {
58
+ name: item.metadata?.name,
59
+ namespace: item.metadata?.namespace,
60
+ resourceVersion: item.metadata?.resourceVersion,
61
+ },
62
+ };
63
+ Log.debug(note, "Enqueueing");
39
64
  return new Promise<void>((resolve, reject) => {
40
- this.#queue.push({ item, type, resolve, reject });
65
+ this.#queue.push({ item, phase, callback: reconcile, resolve, reject });
66
+ Log.debug(this.stats(), "Queue stats - push");
41
67
  return this.#dequeue();
42
68
  });
43
69
  }
@@ -68,16 +94,25 @@ export class Queue<K extends KubernetesObject> {
68
94
  this.#pendingPromise = true;
69
95
 
70
96
  // Reconcile the element
71
- if (this.#reconcile) {
72
- Log.debug(`Reconciling ${element.item.metadata!.name}`);
73
- await this.#reconcile(element.item, element.type);
74
- }
97
+ const note = {
98
+ queue: this.label(),
99
+ item: {
100
+ name: element.item.metadata?.name,
101
+ namespace: element.item.metadata?.namespace,
102
+ resourceVersion: element.item.metadata?.resourceVersion,
103
+ },
104
+ };
105
+ Log.debug(note, "Reconciling");
106
+ await element.callback(element.item, element.phase);
107
+ Log.debug(note, "Reconciled");
75
108
 
76
109
  element.resolve();
77
110
  } catch (e) {
78
111
  Log.debug(`Error reconciling ${element.item.metadata!.name}`, { error: e });
79
112
  element.reject(e);
80
113
  } finally {
114
+ Log.debug(this.stats(), "Queue stats - shift");
115
+
81
116
  // Reset the pending promise flag
82
117
  Log.debug("Resetting pending promise and dequeuing");
83
118
  this.#pendingPromise = false;
@@ -3,7 +3,7 @@
3
3
 
4
4
  import { PeprStore } from "./storage";
5
5
 
6
- type Unit = "seconds" | "second" | "minute" | "minutes" | "hours" | "hour";
6
+ export type Unit = "seconds" | "second" | "minute" | "minutes" | "hours" | "hour";
7
7
 
8
8
  export interface Schedule {
9
9
  /**
@@ -2,7 +2,6 @@
2
2
  // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
3
 
4
4
  import { clone } from "ramda";
5
- import Log from "./logger";
6
5
  import pointer from "json-pointer";
7
6
  export type DataOp = "add" | "remove";
8
7
  export type DataStore = Record<string, string>;
@@ -86,7 +85,6 @@ export class Storage implements PeprStore {
86
85
  };
87
86
 
88
87
  receive = (data: DataStore) => {
89
- Log.debug(data, `Pepr store data received`);
90
88
  this.#store = data || {};
91
89
 
92
90
  this.#onReady();
@@ -107,10 +105,11 @@ export class Storage implements PeprStore {
107
105
  };
108
106
 
109
107
  clear = () => {
110
- this.#dispatchUpdate(
111
- "remove",
112
- Object.keys(this.#store).map(key => pointer.escape(key)),
113
- );
108
+ Object.keys(this.#store).length > 0 &&
109
+ this.#dispatchUpdate(
110
+ "remove",
111
+ Object.keys(this.#store).map(key => pointer.escape(key)),
112
+ );
114
113
  };
115
114
 
116
115
  removeItem = (key: string) => {
package/src/lib/types.ts CHANGED
@@ -2,11 +2,21 @@
2
2
  // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
3
 
4
4
  import { GenericClass, GroupVersionKind, KubernetesObject } from "kubernetes-fluent-client";
5
- import { WatchAction } from "kubernetes-fluent-client/dist/fluent/types";
5
+
6
+ import { WatchPhase } from "kubernetes-fluent-client/dist/fluent/types";
6
7
 
7
8
  import { PeprMutateRequest } from "./mutate-request";
8
9
  import { PeprValidateRequest } from "./validate-request";
10
+ import { Answers } from "prompts";
11
+
12
+ import { Logger } from "pino";
9
13
 
14
+ export enum Operation {
15
+ CREATE = "CREATE",
16
+ UPDATE = "UPDATE",
17
+ DELETE = "DELETE",
18
+ CONNECT = "CONNECT",
19
+ }
10
20
  /**
11
21
  * Specifically for deploying images with a private registry
12
22
  */
@@ -80,24 +90,33 @@ export type WhenSelector<T extends GenericClass> = {
80
90
  /** Register an action to be executed when a Kubernetes resource is deleted. */
81
91
  IsDeleted: () => BindingAll<T>;
82
92
  };
83
-
93
+ export interface RegExpFilter {
94
+ obj: RegExp;
95
+ source: string;
96
+ }
84
97
  export type Binding = {
85
98
  event: Event;
86
99
  isMutate?: boolean;
87
100
  isValidate?: boolean;
88
101
  isWatch?: boolean;
89
102
  isQueue?: boolean;
103
+ isFinalize?: boolean;
90
104
  readonly model: GenericClass;
91
105
  readonly kind: GroupVersionKind;
92
106
  readonly filters: {
93
107
  name: string;
108
+ regexName: string;
94
109
  namespaces: string[];
110
+ regexNamespaces: string[];
95
111
  labels: Record<string, string>;
96
112
  annotations: Record<string, string>;
113
+ deletionTimestamp: boolean;
97
114
  };
115
+ alias?: string;
98
116
  readonly mutateCallback?: MutateAction<GenericClass, InstanceType<GenericClass>>;
99
117
  readonly validateCallback?: ValidateAction<GenericClass, InstanceType<GenericClass>>;
100
- readonly watchCallback?: WatchAction<GenericClass, InstanceType<GenericClass>>;
118
+ readonly watchCallback?: WatchLogAction<GenericClass, InstanceType<GenericClass>>;
119
+ readonly finalizeCallback?: FinalizeAction<GenericClass, InstanceType<GenericClass>>;
101
120
  };
102
121
 
103
122
  export type BindingFilter<T extends GenericClass> = CommonActionChain<T> & {
@@ -137,16 +156,22 @@ export type BindingFilter<T extends GenericClass> = CommonActionChain<T> & {
137
156
  * @param value
138
157
  */
139
158
  WithAnnotation: (key: string, value?: string) => BindingFilter<T>;
159
+ /** Only apply the action if the resource has a deletionTimestamp. */
160
+ WithDeletionTimestamp: () => BindingFilter<T>;
140
161
  };
141
162
 
142
163
  export type BindingWithName<T extends GenericClass> = BindingFilter<T> & {
143
164
  /** Only apply the action if the resource name matches the specified name. */
144
165
  WithName: (name: string) => BindingFilter<T>;
166
+ /** Only apply the action if the resource name matches the specified regex name. */
167
+ WithNameRegex: (name: RegExp) => BindingFilter<T>;
145
168
  };
146
169
 
147
170
  export type BindingAll<T extends GenericClass> = BindingWithName<T> & {
148
171
  /** Only apply the action if the resource is in one of the specified namespaces.*/
149
172
  InNamespace: (...namespaces: string[]) => BindingWithName<T>;
173
+ /** Only apply the action if the resource is in one of the specified regex namespaces.*/
174
+ InNamespaceRegex: (...namespaces: RegExp[]) => BindingWithName<T>;
150
175
  };
151
176
 
152
177
  export type CommonActionChain<T extends GenericClass> = MutateActionChain<T> & {
@@ -159,6 +184,7 @@ export type CommonActionChain<T extends GenericClass> = MutateActionChain<T> & {
159
184
  * @param action The action to be executed when the Kubernetes resource is processed by the AdmissionController.
160
185
  */
161
186
  Mutate: (action: MutateAction<T, InstanceType<T>>) => MutateActionChain<T>;
187
+ Alias: (alias: string) => BindingFilter<T>;
162
188
  };
163
189
 
164
190
  export type ValidateActionChain<T extends GenericClass> = {
@@ -173,7 +199,8 @@ export type ValidateActionChain<T extends GenericClass> = {
173
199
  * @param action
174
200
  * @returns
175
201
  */
176
- Watch: (action: WatchAction<T, InstanceType<T>>) => void;
202
+
203
+ Watch: (action: WatchLogAction<T, InstanceType<T>>) => FinalizeActionChain<T>;
177
204
 
178
205
  /**
179
206
  * Establish a reconcile for the specified resource. The callback function will be executed after the admission controller has
@@ -186,7 +213,8 @@ export type ValidateActionChain<T extends GenericClass> = {
186
213
  * @param action
187
214
  * @returns
188
215
  */
189
- Reconcile: (action: WatchAction<T, InstanceType<T>>) => void;
216
+
217
+ Reconcile: (action: WatchLogAction<T, InstanceType<T>>) => FinalizeActionChain<T>;
190
218
  };
191
219
 
192
220
  export type MutateActionChain<T extends GenericClass> = ValidateActionChain<T> & {
@@ -216,14 +244,135 @@ export type MutateActionChain<T extends GenericClass> = ValidateActionChain<T> &
216
244
 
217
245
  export type MutateAction<T extends GenericClass, K extends KubernetesObject = InstanceType<T>> = (
218
246
  req: PeprMutateRequest<K>,
247
+ logger?: Logger,
219
248
  ) => Promise<void> | void | Promise<PeprMutateRequest<K>> | PeprMutateRequest<K>;
220
249
 
221
250
  export type ValidateAction<T extends GenericClass, K extends KubernetesObject = InstanceType<T>> = (
222
251
  req: PeprValidateRequest<K>,
252
+ logger?: Logger,
223
253
  ) => Promise<ValidateActionResponse> | ValidateActionResponse;
224
254
 
255
+ // Define WatchLogAction by adding an optional logger parameter to the WatchAction
256
+ export type WatchLogAction<T extends GenericClass, K extends KubernetesObject = InstanceType<T>> = (
257
+ update: K,
258
+ phase: WatchPhase,
259
+ logger?: Logger,
260
+ ) => Promise<void> | void;
261
+
225
262
  export type ValidateActionResponse = {
226
263
  allowed: boolean;
227
264
  statusCode?: number;
228
265
  statusMessage?: string;
229
266
  };
267
+
268
+ export type FinalizeAction<T extends GenericClass, K extends KubernetesObject = InstanceType<T>> = (
269
+ update: K,
270
+ logger?: Logger,
271
+ ) => Promise<void> | void;
272
+
273
+ export type FinalizeActionChain<T extends GenericClass> = {
274
+ /**
275
+ * Establish a finalizer for the specified resource. The callback given will be executed by the watch
276
+ * controller after it has received notification of an update adding a deletionTimestamp.
277
+ *
278
+ * **Beta Function**: This method is still in early testing and edge cases may still exist.
279
+ *
280
+ * @since 0.35.0
281
+ *
282
+ * @param action
283
+ * @returns
284
+ */
285
+ Finalize: (action: FinalizeAction<T, InstanceType<T>>) => void;
286
+ };
287
+
288
+ export type InitOptions = Answers<"name" | "description" | "errorBehavior">;
289
+
290
+ /**
291
+ * A Kubernetes admission request to be processed by a capability.
292
+ */
293
+ export interface AdmissionRequest<T = KubernetesObject> {
294
+ /** UID is an identifier for the individual request/response. */
295
+ readonly uid: string;
296
+
297
+ /** Kind is the fully-qualified type of object being submitted (for example, v1.Pod or autoscaling.v1.Scale) */
298
+ readonly kind: GroupVersionKind;
299
+
300
+ /** Resource is the fully-qualified resource being requested (for example, v1.pods) */
301
+ readonly resource: GroupVersionResource;
302
+
303
+ /** SubResource is the sub-resource being requested, if any (for example, "status" or "scale") */
304
+ readonly subResource?: string;
305
+
306
+ /** RequestKind is the fully-qualified type of the original API request (for example, v1.Pod or autoscaling.v1.Scale). */
307
+ readonly requestKind?: GroupVersionKind;
308
+
309
+ /** RequestResource is the fully-qualified resource of the original API request (for example, v1.pods). */
310
+ readonly requestResource?: GroupVersionResource;
311
+
312
+ /** RequestSubResource is the sub-resource of the original API request, if any (for example, "status" or "scale"). */
313
+ readonly requestSubResource?: string;
314
+
315
+ /**
316
+ * Name is the name of the object as presented in the request. On a CREATE operation, the client may omit name and
317
+ * rely on the server to generate the name. If that is the case, this method will return the empty string.
318
+ */
319
+ readonly name: string;
320
+
321
+ /** Namespace is the namespace associated with the request (if any). */
322
+ readonly namespace?: string;
323
+
324
+ /**
325
+ * Operation is the operation being performed. This may be different than the operation
326
+ * requested. e.g. a patch can result in either a CREATE or UPDATE Operation.
327
+ */
328
+ readonly operation: Operation;
329
+
330
+ /** UserInfo is information about the requesting user */
331
+ readonly userInfo: {
332
+ /** The name that uniquely identifies this user among all active users. */
333
+ username?: string;
334
+
335
+ /**
336
+ * A unique value that identifies this user across time. If this user is deleted
337
+ * and another user by the same name is added, they will have different UIDs.
338
+ */
339
+ uid?: string;
340
+
341
+ /** The names of groups this user is a part of. */
342
+ groups?: string[];
343
+
344
+ /** Any additional information provided by the authenticator. */
345
+ extra?: {
346
+ [key: string]: string[];
347
+ };
348
+ };
349
+
350
+ /** Object is the object from the incoming request prior to default values being applied */
351
+ readonly object: T;
352
+
353
+ /** OldObject is the existing object. Only populated for UPDATE or DELETE requests. */
354
+ readonly oldObject?: T;
355
+
356
+ /** DryRun indicates that modifications will definitely not be persisted for this request. Defaults to false. */
357
+ readonly dryRun?: boolean;
358
+
359
+ /**
360
+ * Options contains the options for the operation being performed.
361
+ * e.g. `meta.k8s.io/v1.DeleteOptions` or `meta.k8s.io/v1.CreateOptions`. This may be
362
+ * different than the options the caller provided. e.g. for a patch request the performed
363
+ * Operation might be a CREATE, in which case the Options will a
364
+ * `meta.k8s.io/v1.CreateOptions` even though the caller provided `meta.k8s.io/v1.PatchOptions`.
365
+ */
366
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
367
+ readonly options?: any;
368
+ }
369
+
370
+ /**
371
+ * GroupVersionResource unambiguously identifies a resource. It doesn't anonymously include GroupVersion
372
+ * to avoid automatic coercion. It doesn't use a GroupVersion to avoid custom marshalling
373
+ */
374
+ export interface GroupVersionResource {
375
+ readonly group: string;
376
+ readonly version: string;
377
+ readonly resource: string;
378
+ }
@@ -5,12 +5,15 @@ import { kind } from "kubernetes-fluent-client";
5
5
 
6
6
  import { Capability } from "./capability";
7
7
  import { shouldSkipRequest } from "./filter";
8
- import { AdmissionRequest, ValidateResponse } from "./k8s";
8
+ import { ValidateResponse } from "./k8s";
9
+ import { AdmissionRequest } from "./types";
9
10
  import Log from "./logger";
10
11
  import { convertFromBase64Map } from "./utils";
11
12
  import { PeprValidateRequest } from "./validate-request";
13
+ import { ModuleConfig } from "./module";
12
14
 
13
15
  export async function validateProcessor(
16
+ config: ModuleConfig,
14
17
  capabilities: Capability[],
15
18
  req: AdmissionRequest,
16
19
  reqMetadata: Record<string, string>,
@@ -41,7 +44,7 @@ export async function validateProcessor(
41
44
  };
42
45
 
43
46
  // Continue to the next action without doing anything if this one should be skipped
44
- if (shouldSkipRequest(action, req, namespaces)) {
47
+ if (shouldSkipRequest(action, req, namespaces, config?.alwaysIgnore?.namespaces)) {
45
48
  continue;
46
49
  }
47
50
 
@@ -3,11 +3,8 @@
3
3
 
4
4
  import { beforeEach, describe, expect, it } from "@jest/globals";
5
5
  import { KubernetesObject } from "kubernetes-fluent-client";
6
-
7
- import { Operation, AdmissionRequest } from "./k8s";
8
- import { ValidateActionResponse } from "./types";
6
+ import { ValidateActionResponse, AdmissionRequest, Operation } from "./types";
9
7
  import { PeprValidateRequest } from "./validate-request";
10
-
11
8
  describe("PeprValidateRequest", () => {
12
9
  let mockRequest: AdmissionRequest<KubernetesObject>;
13
10
 
@@ -6,7 +6,7 @@
6
6
  import { KubernetesObject } from "kubernetes-fluent-client";
7
7
 
8
8
  import { clone } from "ramda";
9
- import { Operation, AdmissionRequest } from "./k8s";
9
+ import { AdmissionRequest, Operation } from "./types";
10
10
  import { ValidateActionResponse } from "./types";
11
11
 
12
12
  /**