pepr 0.36.0 → 0.37.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.
- package/dist/cli/init/index.d.ts.map +1 -1
- package/dist/cli/init/templates.d.ts +4 -3
- package/dist/cli/init/templates.d.ts.map +1 -1
- package/dist/cli/init/utils.d.ts.map +1 -1
- package/dist/cli/init/walkthrough.d.ts +10 -3
- package/dist/cli/init/walkthrough.d.ts.map +1 -1
- package/dist/cli/types.d.ts +3 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli.js +253 -31
- package/dist/controller.js +138 -1
- package/dist/lib/adjudicators.d.ts +63 -0
- package/dist/lib/adjudicators.d.ts.map +1 -0
- package/dist/lib/adjudicators.test.d.ts +2 -0
- package/dist/lib/adjudicators.test.d.ts.map +1 -0
- package/dist/lib/assets/loader.d.ts.map +1 -1
- package/dist/lib/assets/pods.d.ts +1 -0
- package/dist/lib/assets/pods.d.ts.map +1 -1
- package/dist/lib/capability.d.ts +1 -0
- package/dist/lib/capability.d.ts.map +1 -1
- package/dist/lib/capability.test.d.ts +2 -0
- package/dist/lib/capability.test.d.ts.map +1 -0
- package/dist/lib/controller/index.d.ts.map +1 -1
- package/dist/lib/controller/store.d.ts +4 -0
- package/dist/lib/controller/store.d.ts.map +1 -1
- package/dist/lib/controller/store.test.d.ts +2 -0
- package/dist/lib/controller/store.test.d.ts.map +1 -0
- package/dist/lib/filter.d.ts +2 -3
- package/dist/lib/filter.d.ts.map +1 -1
- package/dist/lib/filter.test.d.ts +2 -1
- package/dist/lib/filter.test.d.ts.map +1 -1
- package/dist/lib/finalizer.d.ts +6 -0
- package/dist/lib/finalizer.d.ts.map +1 -0
- package/dist/lib/finalizer.test.d.ts +2 -0
- package/dist/lib/finalizer.test.d.ts.map +1 -0
- package/dist/lib/helpers.d.ts +2 -2
- package/dist/lib/helpers.d.ts.map +1 -1
- package/dist/lib/helpers.test.d.ts +1 -1
- package/dist/lib/helpers.test.d.ts.map +1 -1
- package/dist/lib/k8s.d.ts.map +1 -1
- package/dist/lib/module.d.ts +2 -1
- package/dist/lib/module.d.ts.map +1 -1
- package/dist/lib/mutate-processor.d.ts +2 -1
- package/dist/lib/mutate-processor.d.ts.map +1 -1
- package/dist/lib/mutate-request.d.ts +1 -2
- package/dist/lib/mutate-request.d.ts.map +1 -1
- package/dist/lib/schedule.d.ts +1 -2
- package/dist/lib/schedule.d.ts.map +1 -1
- package/dist/lib/storage.d.ts.map +1 -1
- package/dist/lib/types.d.ts +113 -6
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/validate-processor.d.ts +4 -2
- package/dist/lib/validate-processor.d.ts.map +1 -1
- package/dist/lib/validate-request.d.ts +1 -1
- package/dist/lib/validate-request.d.ts.map +1 -1
- package/dist/lib/watch-processor.d.ts +1 -1
- package/dist/lib/watch-processor.d.ts.map +1 -1
- package/dist/lib.js +383 -204
- package/dist/lib.js.map +4 -4
- package/package.json +13 -12
- package/src/cli/build.ts +3 -3
- package/src/cli/init/index.ts +20 -11
- package/src/cli/init/templates.ts +1 -1
- package/src/cli/init/utils.test.ts +11 -20
- package/src/cli/init/utils.ts +5 -0
- package/src/cli/init/walkthrough.test.ts +92 -11
- package/src/cli/init/walkthrough.ts +71 -16
- package/src/cli/monitor.ts +1 -1
- package/src/cli/types.ts +3 -0
- package/src/cli.ts +4 -2
- package/src/fixtures/data/create-pod.json +1 -1
- package/src/fixtures/data/delete-pod.json +1 -1
- package/src/lib/adjudicators.test.ts +1232 -0
- package/src/lib/adjudicators.ts +235 -0
- package/src/lib/assets/index.ts +1 -1
- package/src/lib/assets/loader.ts +1 -0
- package/src/lib/assets/webhooks.ts +1 -1
- package/src/lib/capability.test.ts +655 -0
- package/src/lib/capability.ts +104 -11
- package/src/lib/controller/index.ts +7 -4
- package/src/lib/controller/store.test.ts +131 -0
- package/src/lib/controller/store.ts +43 -5
- package/src/lib/filter.test.ts +194 -8
- package/src/lib/filter.ts +46 -107
- package/src/lib/finalizer.test.ts +236 -0
- package/src/lib/finalizer.ts +63 -0
- package/src/lib/helpers.test.ts +329 -69
- package/src/lib/helpers.ts +141 -100
- package/src/lib/k8s.ts +4 -0
- package/src/lib/module.ts +3 -3
- package/src/lib/mutate-processor.ts +5 -4
- package/src/lib/mutate-request.test.ts +1 -2
- package/src/lib/mutate-request.ts +1 -3
- package/src/lib/schedule.ts +1 -1
- package/src/lib/storage.ts +5 -6
- package/src/lib/types.ts +148 -5
- package/src/lib/validate-processor.ts +5 -2
- package/src/lib/validate-request.test.ts +1 -4
- package/src/lib/validate-request.ts +1 -1
- package/src/lib/watch-processor.ts +19 -5
package/src/lib/filter.test.ts
CHANGED
|
@@ -6,12 +6,11 @@ import { kind, modelToGroupVersionKind } from "kubernetes-fluent-client";
|
|
|
6
6
|
import * as fc from "fast-check";
|
|
7
7
|
import { CreatePod, DeletePod } from "../fixtures/loader";
|
|
8
8
|
import { shouldSkipRequest } from "./filter";
|
|
9
|
-
import {
|
|
10
|
-
import { AdmissionRequest } from "./k8s";
|
|
9
|
+
import { AdmissionRequest, Binding, Event } from "./types";
|
|
11
10
|
|
|
12
|
-
const callback = () => undefined;
|
|
11
|
+
export const callback = () => undefined;
|
|
13
12
|
|
|
14
|
-
const podKind = modelToGroupVersionKind(kind.Pod.name);
|
|
13
|
+
export const podKind = modelToGroupVersionKind(kind.Pod.name);
|
|
15
14
|
|
|
16
15
|
describe("Fuzzing shouldSkipRequest", () => {
|
|
17
16
|
test("should handle random inputs without crashing", () => {
|
|
@@ -105,14 +104,35 @@ describe("Property-Based Testing shouldSkipRequest", () => {
|
|
|
105
104
|
});
|
|
106
105
|
});
|
|
107
106
|
|
|
108
|
-
test("should reject when name does not match", () => {
|
|
107
|
+
test("create: should reject when regex name does not match", () => {
|
|
109
108
|
const binding = {
|
|
110
109
|
model: kind.Pod,
|
|
111
110
|
event: Event.Any,
|
|
112
111
|
kind: podKind,
|
|
113
112
|
filters: {
|
|
114
|
-
name: "
|
|
113
|
+
name: "",
|
|
114
|
+
namespaces: [],
|
|
115
|
+
regexNamespaces: [],
|
|
116
|
+
regexName: new RegExp(/^default$/).source,
|
|
117
|
+
labels: {},
|
|
118
|
+
annotations: {},
|
|
119
|
+
deletionTimestamp: false,
|
|
120
|
+
},
|
|
121
|
+
callback,
|
|
122
|
+
};
|
|
123
|
+
const pod = CreatePod();
|
|
124
|
+
expect(shouldSkipRequest(binding, pod, [])).toBe(true);
|
|
125
|
+
});
|
|
126
|
+
test("create: should not reject when regex name does match", () => {
|
|
127
|
+
const binding = {
|
|
128
|
+
model: kind.Pod,
|
|
129
|
+
event: Event.Any,
|
|
130
|
+
kind: podKind,
|
|
131
|
+
filters: {
|
|
132
|
+
name: "",
|
|
115
133
|
namespaces: [],
|
|
134
|
+
regexNamespaces: [],
|
|
135
|
+
regexName: new RegExp(/^cool/).source,
|
|
116
136
|
labels: {},
|
|
117
137
|
annotations: {},
|
|
118
138
|
deletionTimestamp: false,
|
|
@@ -120,10 +140,146 @@ test("should reject when name does not match", () => {
|
|
|
120
140
|
callback,
|
|
121
141
|
};
|
|
122
142
|
const pod = CreatePod();
|
|
143
|
+
expect(shouldSkipRequest(binding, pod, [])).toBe(false);
|
|
144
|
+
});
|
|
145
|
+
test("delete: should reject when regex name does not match", () => {
|
|
146
|
+
const binding = {
|
|
147
|
+
model: kind.Pod,
|
|
148
|
+
event: Event.Any,
|
|
149
|
+
kind: podKind,
|
|
150
|
+
filters: {
|
|
151
|
+
name: "",
|
|
152
|
+
namespaces: [],
|
|
153
|
+
regexNamespaces: [],
|
|
154
|
+
regexName: new RegExp(/^default$/).source,
|
|
155
|
+
labels: {},
|
|
156
|
+
annotations: {},
|
|
157
|
+
deletionTimestamp: false,
|
|
158
|
+
},
|
|
159
|
+
callback,
|
|
160
|
+
};
|
|
161
|
+
const pod = DeletePod();
|
|
162
|
+
expect(shouldSkipRequest(binding, pod, [])).toBe(true);
|
|
163
|
+
});
|
|
164
|
+
test("delete: should not reject when regex name does match", () => {
|
|
165
|
+
const binding = {
|
|
166
|
+
model: kind.Pod,
|
|
167
|
+
event: Event.Any,
|
|
168
|
+
kind: podKind,
|
|
169
|
+
filters: {
|
|
170
|
+
name: "",
|
|
171
|
+
namespaces: [],
|
|
172
|
+
regexNamespaces: [],
|
|
173
|
+
regexName: new RegExp(/^cool/).source,
|
|
174
|
+
labels: {},
|
|
175
|
+
annotations: {},
|
|
176
|
+
deletionTimestamp: false,
|
|
177
|
+
},
|
|
178
|
+
callback,
|
|
179
|
+
};
|
|
180
|
+
const pod = DeletePod();
|
|
181
|
+
expect(shouldSkipRequest(binding, pod, [])).toBe(false);
|
|
182
|
+
});
|
|
123
183
|
|
|
184
|
+
test("create: should not reject when regex namespace does match", () => {
|
|
185
|
+
const binding = {
|
|
186
|
+
model: kind.Pod,
|
|
187
|
+
event: Event.Any,
|
|
188
|
+
kind: podKind,
|
|
189
|
+
filters: {
|
|
190
|
+
name: "",
|
|
191
|
+
namespaces: [],
|
|
192
|
+
regexNamespaces: [new RegExp(/^helm/).source],
|
|
193
|
+
regexName: "",
|
|
194
|
+
labels: {},
|
|
195
|
+
annotations: {},
|
|
196
|
+
deletionTimestamp: false,
|
|
197
|
+
},
|
|
198
|
+
callback,
|
|
199
|
+
};
|
|
200
|
+
const pod = CreatePod();
|
|
201
|
+
expect(shouldSkipRequest(binding, pod, [])).toBe(false);
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
test("create: should reject when regex namespace does not match", () => {
|
|
205
|
+
const binding = {
|
|
206
|
+
model: kind.Pod,
|
|
207
|
+
event: Event.Any,
|
|
208
|
+
kind: podKind,
|
|
209
|
+
filters: {
|
|
210
|
+
name: "",
|
|
211
|
+
namespaces: [],
|
|
212
|
+
regexNamespaces: [new RegExp(/^argo/).source],
|
|
213
|
+
regexName: "",
|
|
214
|
+
labels: {},
|
|
215
|
+
annotations: {},
|
|
216
|
+
deletionTimestamp: false,
|
|
217
|
+
},
|
|
218
|
+
callback,
|
|
219
|
+
};
|
|
220
|
+
const pod = CreatePod();
|
|
221
|
+
expect(shouldSkipRequest(binding, pod, [])).toBe(true);
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
test("delete: should reject when regex namespace does not match", () => {
|
|
225
|
+
const binding = {
|
|
226
|
+
model: kind.Pod,
|
|
227
|
+
event: Event.Any,
|
|
228
|
+
kind: podKind,
|
|
229
|
+
filters: {
|
|
230
|
+
name: "bleh",
|
|
231
|
+
namespaces: [],
|
|
232
|
+
regexNamespaces: [new RegExp(/^argo/).source],
|
|
233
|
+
regexName: "",
|
|
234
|
+
labels: {},
|
|
235
|
+
annotations: {},
|
|
236
|
+
deletionTimestamp: false,
|
|
237
|
+
},
|
|
238
|
+
callback,
|
|
239
|
+
};
|
|
240
|
+
const pod = DeletePod();
|
|
124
241
|
expect(shouldSkipRequest(binding, pod, [])).toBe(true);
|
|
125
242
|
});
|
|
126
243
|
|
|
244
|
+
test("delete: should not reject when regex namespace does match", () => {
|
|
245
|
+
const binding = {
|
|
246
|
+
model: kind.Pod,
|
|
247
|
+
event: Event.Any,
|
|
248
|
+
kind: podKind,
|
|
249
|
+
filters: {
|
|
250
|
+
name: "",
|
|
251
|
+
namespaces: [],
|
|
252
|
+
regexNamespaces: [new RegExp(/^helm/).source],
|
|
253
|
+
regexName: "",
|
|
254
|
+
labels: {},
|
|
255
|
+
annotations: {},
|
|
256
|
+
deletionTimestamp: false,
|
|
257
|
+
},
|
|
258
|
+
callback,
|
|
259
|
+
};
|
|
260
|
+
const pod = DeletePod();
|
|
261
|
+
expect(shouldSkipRequest(binding, pod, [])).toBe(false);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
test("delete: should reject when name does not match", () => {
|
|
265
|
+
const binding = {
|
|
266
|
+
model: kind.Pod,
|
|
267
|
+
event: Event.Any,
|
|
268
|
+
kind: podKind,
|
|
269
|
+
filters: {
|
|
270
|
+
name: "bleh",
|
|
271
|
+
namespaces: [],
|
|
272
|
+
regexNamespaces: [],
|
|
273
|
+
regexName: new RegExp(/^not-cool/).source,
|
|
274
|
+
labels: {},
|
|
275
|
+
annotations: {},
|
|
276
|
+
deletionTimestamp: false,
|
|
277
|
+
},
|
|
278
|
+
callback,
|
|
279
|
+
};
|
|
280
|
+
const pod = DeletePod();
|
|
281
|
+
expect(shouldSkipRequest(binding, pod, [])).toBe(true);
|
|
282
|
+
});
|
|
127
283
|
test("should reject when kind does not match", () => {
|
|
128
284
|
const binding = {
|
|
129
285
|
model: kind.Pod,
|
|
@@ -132,6 +288,8 @@ test("should reject when kind does not match", () => {
|
|
|
132
288
|
filters: {
|
|
133
289
|
name: "",
|
|
134
290
|
namespaces: [],
|
|
291
|
+
regexNamespaces: [],
|
|
292
|
+
regexName: "",
|
|
135
293
|
labels: {},
|
|
136
294
|
annotations: {},
|
|
137
295
|
deletionTimestamp: false,
|
|
@@ -154,6 +312,8 @@ test("should reject when group does not match", () => {
|
|
|
154
312
|
labels: {},
|
|
155
313
|
annotations: {},
|
|
156
314
|
deletionTimestamp: false,
|
|
315
|
+
regexNamespaces: [],
|
|
316
|
+
regexName: "",
|
|
157
317
|
},
|
|
158
318
|
callback,
|
|
159
319
|
};
|
|
@@ -177,6 +337,8 @@ test("should reject when version does not match", () => {
|
|
|
177
337
|
labels: {},
|
|
178
338
|
annotations: {},
|
|
179
339
|
deletionTimestamp: false,
|
|
340
|
+
regexNamespaces: [],
|
|
341
|
+
regexName: "",
|
|
180
342
|
},
|
|
181
343
|
callback,
|
|
182
344
|
};
|
|
@@ -196,6 +358,8 @@ test("should allow when group, version, and kind match", () => {
|
|
|
196
358
|
labels: {},
|
|
197
359
|
annotations: {},
|
|
198
360
|
deletionTimestamp: false,
|
|
361
|
+
regexNamespaces: [],
|
|
362
|
+
regexName: "",
|
|
199
363
|
},
|
|
200
364
|
callback,
|
|
201
365
|
};
|
|
@@ -219,6 +383,8 @@ test("should allow when kind match and others are empty", () => {
|
|
|
219
383
|
labels: {},
|
|
220
384
|
annotations: {},
|
|
221
385
|
deletionTimestamp: false,
|
|
386
|
+
regexNamespaces: [],
|
|
387
|
+
regexName: "",
|
|
222
388
|
},
|
|
223
389
|
callback,
|
|
224
390
|
};
|
|
@@ -227,7 +393,7 @@ test("should allow when kind match and others are empty", () => {
|
|
|
227
393
|
expect(shouldSkipRequest(binding, pod, [])).toBe(false);
|
|
228
394
|
});
|
|
229
395
|
|
|
230
|
-
test("should reject when
|
|
396
|
+
test("should reject when the capability namespace does not match", () => {
|
|
231
397
|
const binding = {
|
|
232
398
|
model: kind.Pod,
|
|
233
399
|
event: Event.Any,
|
|
@@ -238,6 +404,8 @@ test("should reject when teh capability namespace does not match", () => {
|
|
|
238
404
|
labels: {},
|
|
239
405
|
annotations: {},
|
|
240
406
|
deletionTimestamp: false,
|
|
407
|
+
regexNamespaces: [],
|
|
408
|
+
regexName: "",
|
|
241
409
|
},
|
|
242
410
|
callback,
|
|
243
411
|
};
|
|
@@ -257,6 +425,8 @@ test("should reject when namespace does not match", () => {
|
|
|
257
425
|
labels: {},
|
|
258
426
|
annotations: {},
|
|
259
427
|
deletionTimestamp: false,
|
|
428
|
+
regexNamespaces: [],
|
|
429
|
+
regexName: "",
|
|
260
430
|
},
|
|
261
431
|
callback,
|
|
262
432
|
};
|
|
@@ -272,10 +442,12 @@ test("should allow when namespace is match", () => {
|
|
|
272
442
|
kind: podKind,
|
|
273
443
|
filters: {
|
|
274
444
|
name: "",
|
|
275
|
-
namespaces: ["
|
|
445
|
+
namespaces: ["helm-releasename", "unicorn", "things"],
|
|
276
446
|
labels: {},
|
|
277
447
|
annotations: {},
|
|
278
448
|
deletionTimestamp: false,
|
|
449
|
+
regexNamespaces: [],
|
|
450
|
+
regexName: "",
|
|
279
451
|
},
|
|
280
452
|
callback,
|
|
281
453
|
};
|
|
@@ -297,6 +469,8 @@ test("should reject when label does not match", () => {
|
|
|
297
469
|
},
|
|
298
470
|
annotations: {},
|
|
299
471
|
deletionTimestamp: false,
|
|
472
|
+
regexNamespaces: [],
|
|
473
|
+
regexName: "",
|
|
300
474
|
},
|
|
301
475
|
callback,
|
|
302
476
|
};
|
|
@@ -314,6 +488,8 @@ test("should allow when label is match", () => {
|
|
|
314
488
|
name: "",
|
|
315
489
|
deletionTimestamp: false,
|
|
316
490
|
namespaces: [],
|
|
491
|
+
regexNamespaces: [],
|
|
492
|
+
regexName: "",
|
|
317
493
|
labels: {
|
|
318
494
|
foo: "bar",
|
|
319
495
|
test: "test1",
|
|
@@ -347,6 +523,8 @@ test("should reject when annotation does not match", () => {
|
|
|
347
523
|
foo: "bar",
|
|
348
524
|
},
|
|
349
525
|
deletionTimestamp: false,
|
|
526
|
+
regexNamespaces: [],
|
|
527
|
+
regexName: "",
|
|
350
528
|
},
|
|
351
529
|
callback,
|
|
352
530
|
};
|
|
@@ -369,6 +547,8 @@ test("should allow when annotation is match", () => {
|
|
|
369
547
|
test: "test1",
|
|
370
548
|
},
|
|
371
549
|
deletionTimestamp: false,
|
|
550
|
+
regexNamespaces: [],
|
|
551
|
+
regexName: "",
|
|
372
552
|
},
|
|
373
553
|
callback,
|
|
374
554
|
};
|
|
@@ -392,6 +572,8 @@ test("should use `oldObject` when the operation is `DELETE`", () => {
|
|
|
392
572
|
filters: {
|
|
393
573
|
name: "",
|
|
394
574
|
namespaces: [],
|
|
575
|
+
regexNamespaces: [],
|
|
576
|
+
regexName: "",
|
|
395
577
|
deletionTimestamp: false,
|
|
396
578
|
labels: {
|
|
397
579
|
"app.kubernetes.io/name": "cool-name-podinfo",
|
|
@@ -417,6 +599,8 @@ test("should skip processing when deletionTimestamp is not present on pod", () =
|
|
|
417
599
|
name: "",
|
|
418
600
|
namespaces: [],
|
|
419
601
|
labels: {},
|
|
602
|
+
regexNamespaces: [],
|
|
603
|
+
regexName: "",
|
|
420
604
|
annotations: {
|
|
421
605
|
foo: "bar",
|
|
422
606
|
test: "test1",
|
|
@@ -446,6 +630,8 @@ test("should processing when deletionTimestamp is not present on pod", () => {
|
|
|
446
630
|
name: "",
|
|
447
631
|
namespaces: [],
|
|
448
632
|
labels: {},
|
|
633
|
+
regexNamespaces: [],
|
|
634
|
+
regexName: "",
|
|
449
635
|
annotations: {
|
|
450
636
|
foo: "bar",
|
|
451
637
|
test: "test1",
|
package/src/lib/filter.ts
CHANGED
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
// SPDX-FileCopyrightText: 2023-Present The Pepr Authors
|
|
3
3
|
|
|
4
|
-
import { AdmissionRequest, Operation } from "./
|
|
5
|
-
import
|
|
6
|
-
|
|
4
|
+
import { AdmissionRequest, Binding, Operation } from "./types";
|
|
5
|
+
import {
|
|
6
|
+
carriesIgnoredNamespace,
|
|
7
|
+
misboundDeleteWithDeletionTimestamp,
|
|
8
|
+
mismatchedDeletionTimestamp,
|
|
9
|
+
mismatchedAnnotations,
|
|
10
|
+
mismatchedLabels,
|
|
11
|
+
mismatchedName,
|
|
12
|
+
mismatchedNameRegex,
|
|
13
|
+
mismatchedNamespace,
|
|
14
|
+
mismatchedNamespaceRegex,
|
|
15
|
+
mismatchedEvent,
|
|
16
|
+
mismatchedGroup,
|
|
17
|
+
mismatchedVersion,
|
|
18
|
+
mismatchedKind,
|
|
19
|
+
unbindableNamespaces,
|
|
20
|
+
uncarryableNamespace,
|
|
21
|
+
} from "./adjudicators";
|
|
7
22
|
|
|
8
23
|
/**
|
|
9
24
|
* shouldSkipRequest determines if a request should be skipped based on the binding filters.
|
|
@@ -12,108 +27,32 @@ import { Binding, Event } from "./types";
|
|
|
12
27
|
* @param req the incoming request
|
|
13
28
|
* @returns
|
|
14
29
|
*/
|
|
15
|
-
export function shouldSkipRequest(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
// Test for matching kinds
|
|
45
|
-
if (kind !== req.kind.kind) {
|
|
46
|
-
return true;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// Test for matching groups
|
|
50
|
-
if (group && group !== req.kind.group) {
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Test for matching versions
|
|
55
|
-
if (version && version !== req.kind.version) {
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Test for matching namespaces
|
|
60
|
-
if (
|
|
61
|
-
(combinedNamespaces.length && !combinedNamespaces.includes(req.namespace || "")) ||
|
|
62
|
-
(!namespaces.includes(req.namespace || "") && capabilityNamespaces.length !== 0 && namespaces.length !== 0)
|
|
63
|
-
) {
|
|
64
|
-
let type = "";
|
|
65
|
-
let label = "";
|
|
66
|
-
|
|
67
|
-
if (binding.isMutate) {
|
|
68
|
-
type = "Mutate";
|
|
69
|
-
label = binding.mutateCallback!.name;
|
|
70
|
-
} else if (binding.isValidate) {
|
|
71
|
-
type = "Validate";
|
|
72
|
-
label = binding.validateCallback!.name;
|
|
73
|
-
} else if (binding.isWatch) {
|
|
74
|
-
type = "Watch";
|
|
75
|
-
label = binding.watchCallback!.name;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
logger.debug({ uid }, `${type} binding (${label}) does not match request namespace "${req.namespace}"`);
|
|
79
|
-
|
|
80
|
-
return true;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Test for matching labels
|
|
84
|
-
for (const [key, value] of Object.entries(labels)) {
|
|
85
|
-
const testKey = metadata?.labels?.[key];
|
|
86
|
-
|
|
87
|
-
// First check if the label exists
|
|
88
|
-
if (!testKey) {
|
|
89
|
-
logger.debug({ uid }, `Label ${key} does not exist`);
|
|
90
|
-
return true;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Then check if the value matches, if specified
|
|
94
|
-
if (value && testKey !== value) {
|
|
95
|
-
logger.debug({ uid }, `${testKey} does not match ${value}`);
|
|
96
|
-
return true;
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
// Test for matching annotations
|
|
101
|
-
for (const [key, value] of Object.entries(annotations)) {
|
|
102
|
-
const testKey = metadata?.annotations?.[key];
|
|
103
|
-
|
|
104
|
-
// First check if the annotation exists
|
|
105
|
-
if (!testKey) {
|
|
106
|
-
logger.debug({ uid }, `Annotation ${key} does not exist`);
|
|
107
|
-
return true;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
// Then check if the value matches, if specified
|
|
111
|
-
if (value && testKey !== value) {
|
|
112
|
-
logger.debug({ uid }, `${testKey} does not match ${value}`);
|
|
113
|
-
return true;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// No failed filters, so we should not skip this request
|
|
118
|
-
return false;
|
|
30
|
+
export function shouldSkipRequest(
|
|
31
|
+
binding: Binding,
|
|
32
|
+
req: AdmissionRequest,
|
|
33
|
+
capabilityNamespaces: string[],
|
|
34
|
+
ignoredNamespaces?: string[],
|
|
35
|
+
): boolean {
|
|
36
|
+
const obj = req.operation === Operation.DELETE ? req.oldObject : req.object;
|
|
37
|
+
|
|
38
|
+
// prettier-ignore
|
|
39
|
+
return (
|
|
40
|
+
misboundDeleteWithDeletionTimestamp(binding) ? true :
|
|
41
|
+
mismatchedDeletionTimestamp(binding, obj) ? true :
|
|
42
|
+
mismatchedEvent(binding, req) ? true :
|
|
43
|
+
mismatchedName(binding, obj) ? true :
|
|
44
|
+
mismatchedGroup(binding, req) ? true :
|
|
45
|
+
mismatchedVersion(binding, req) ? true :
|
|
46
|
+
mismatchedKind(binding, req) ? true :
|
|
47
|
+
unbindableNamespaces(capabilityNamespaces, binding) ? true :
|
|
48
|
+
uncarryableNamespace(capabilityNamespaces, obj) ? true :
|
|
49
|
+
mismatchedNamespace(binding, obj) ? true :
|
|
50
|
+
mismatchedLabels(binding, obj) ? true :
|
|
51
|
+
mismatchedAnnotations(binding, obj) ? true :
|
|
52
|
+
mismatchedNamespaceRegex(binding, obj) ? true :
|
|
53
|
+
mismatchedNameRegex(binding, obj) ? true :
|
|
54
|
+
carriesIgnoredNamespace(ignoredNamespaces, obj) ? true :
|
|
55
|
+
|
|
56
|
+
false
|
|
57
|
+
);
|
|
119
58
|
}
|