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/dist/lib.js
CHANGED
|
@@ -31,27 +31,27 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var lib_exports = {};
|
|
32
32
|
__export(lib_exports, {
|
|
33
33
|
Capability: () => Capability,
|
|
34
|
-
K8s: () =>
|
|
34
|
+
K8s: () => import_kubernetes_fluent_client8.K8s,
|
|
35
35
|
Log: () => logger_default,
|
|
36
36
|
PeprModule: () => PeprModule,
|
|
37
37
|
PeprMutateRequest: () => PeprMutateRequest,
|
|
38
38
|
PeprUtils: () => utils_exports,
|
|
39
39
|
PeprValidateRequest: () => PeprValidateRequest,
|
|
40
40
|
R: () => R,
|
|
41
|
-
RegisterKind: () =>
|
|
42
|
-
a: () =>
|
|
43
|
-
fetch: () =>
|
|
44
|
-
fetchStatus: () =>
|
|
45
|
-
kind: () =>
|
|
41
|
+
RegisterKind: () => import_kubernetes_fluent_client8.RegisterKind,
|
|
42
|
+
a: () => import_kubernetes_fluent_client8.kind,
|
|
43
|
+
fetch: () => import_kubernetes_fluent_client8.fetch,
|
|
44
|
+
fetchStatus: () => import_kubernetes_fluent_client8.fetchStatus,
|
|
45
|
+
kind: () => import_kubernetes_fluent_client8.kind,
|
|
46
46
|
sdk: () => sdk_exports
|
|
47
47
|
});
|
|
48
48
|
module.exports = __toCommonJS(lib_exports);
|
|
49
|
-
var
|
|
49
|
+
var import_kubernetes_fluent_client8 = require("kubernetes-fluent-client");
|
|
50
50
|
var R = __toESM(require("ramda"));
|
|
51
51
|
|
|
52
52
|
// src/lib/capability.ts
|
|
53
|
-
var
|
|
54
|
-
var
|
|
53
|
+
var import_kubernetes_fluent_client7 = require("kubernetes-fluent-client");
|
|
54
|
+
var import_ramda7 = require("ramda");
|
|
55
55
|
|
|
56
56
|
// src/lib/logger.ts
|
|
57
57
|
var import_pino = require("pino");
|
|
@@ -74,7 +74,7 @@ if (process.env.LOG_LEVEL) {
|
|
|
74
74
|
var logger_default = Log;
|
|
75
75
|
|
|
76
76
|
// src/lib/module.ts
|
|
77
|
-
var
|
|
77
|
+
var import_ramda5 = require("ramda");
|
|
78
78
|
|
|
79
79
|
// src/lib/controller/index.ts
|
|
80
80
|
var import_express = __toESM(require("express"));
|
|
@@ -224,90 +224,151 @@ function ValidateError(error = "") {
|
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
-
// src/lib/
|
|
228
|
-
var
|
|
229
|
-
var
|
|
230
|
-
|
|
231
|
-
var
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
(0,
|
|
227
|
+
// src/lib/adjudicators.ts
|
|
228
|
+
var import_ramda = require("ramda");
|
|
229
|
+
var declaredOperation = (0, import_ramda.pipe)((request) => request?.operation, (0, import_ramda.defaultTo)(""));
|
|
230
|
+
var declaredGroup = (0, import_ramda.pipe)((request) => request?.kind?.group, (0, import_ramda.defaultTo)(""));
|
|
231
|
+
var declaredVersion = (0, import_ramda.pipe)((request) => request?.kind?.version, (0, import_ramda.defaultTo)(""));
|
|
232
|
+
var declaredKind = (0, import_ramda.pipe)((request) => request?.kind?.kind, (0, import_ramda.defaultTo)(""));
|
|
233
|
+
var declaredUid = (0, import_ramda.pipe)((request) => request?.uid, (0, import_ramda.defaultTo)(""));
|
|
234
|
+
var carriesDeletionTimestamp = (0, import_ramda.pipe)((obj) => !!obj.metadata?.deletionTimestamp, (0, import_ramda.defaultTo)(false));
|
|
235
|
+
var missingDeletionTimestamp = (0, import_ramda.complement)(carriesDeletionTimestamp);
|
|
236
|
+
var carriedName = (0, import_ramda.pipe)((obj) => obj?.metadata?.name, (0, import_ramda.defaultTo)(""));
|
|
237
|
+
var carriesName = (0, import_ramda.pipe)(carriedName, (0, import_ramda.equals)(""), import_ramda.not);
|
|
238
|
+
var missingName = (0, import_ramda.complement)(carriesName);
|
|
239
|
+
var carriedNamespace = (0, import_ramda.pipe)((obj) => obj?.metadata?.namespace, (0, import_ramda.defaultTo)(""));
|
|
240
|
+
var carriesNamespace = (0, import_ramda.pipe)(carriedNamespace, (0, import_ramda.equals)(""), import_ramda.not);
|
|
241
|
+
var carriedAnnotations = (0, import_ramda.pipe)((obj) => obj?.metadata?.annotations, (0, import_ramda.defaultTo)({}));
|
|
242
|
+
var carriesAnnotations = (0, import_ramda.pipe)(carriedAnnotations, (0, import_ramda.equals)({}), import_ramda.not);
|
|
243
|
+
var carriedLabels = (0, import_ramda.pipe)((obj) => obj?.metadata?.labels, (0, import_ramda.defaultTo)({}));
|
|
244
|
+
var carriesLabels = (0, import_ramda.pipe)(carriedLabels, (0, import_ramda.equals)({}), import_ramda.not);
|
|
245
|
+
var definesDeletionTimestamp = (0, import_ramda.pipe)((binding) => binding?.filters?.deletionTimestamp, (0, import_ramda.defaultTo)(false));
|
|
246
|
+
var ignoresDeletionTimestamp = (0, import_ramda.complement)(definesDeletionTimestamp);
|
|
247
|
+
var definedName = (0, import_ramda.pipe)((binding) => binding?.filters?.name, (0, import_ramda.defaultTo)(""));
|
|
248
|
+
var definesName = (0, import_ramda.pipe)(definedName, (0, import_ramda.equals)(""), import_ramda.not);
|
|
249
|
+
var ignoresName = (0, import_ramda.complement)(definesName);
|
|
250
|
+
var definedNameRegex = (0, import_ramda.pipe)((binding) => binding?.filters?.regexName, (0, import_ramda.defaultTo)(""));
|
|
251
|
+
var definesNameRegex = (0, import_ramda.pipe)(definedNameRegex, (0, import_ramda.equals)(""), import_ramda.not);
|
|
252
|
+
var definedNamespaces = (0, import_ramda.pipe)((binding) => binding?.filters?.namespaces, (0, import_ramda.defaultTo)([]));
|
|
253
|
+
var definesNamespaces = (0, import_ramda.pipe)(definedNamespaces, (0, import_ramda.equals)([]), import_ramda.not);
|
|
254
|
+
var definedNamespaceRegexes = (0, import_ramda.pipe)((binding) => binding?.filters?.regexNamespaces, (0, import_ramda.defaultTo)([]));
|
|
255
|
+
var definesNamespaceRegexes = (0, import_ramda.pipe)(definedNamespaceRegexes, (0, import_ramda.equals)([]), import_ramda.not);
|
|
256
|
+
var definedAnnotations = (0, import_ramda.pipe)((binding) => binding?.filters?.annotations, (0, import_ramda.defaultTo)({}));
|
|
257
|
+
var definesAnnotations = (0, import_ramda.pipe)(definedAnnotations, (0, import_ramda.equals)({}), import_ramda.not);
|
|
258
|
+
var definedLabels = (0, import_ramda.pipe)((binding) => binding?.filters?.labels, (0, import_ramda.defaultTo)({}));
|
|
259
|
+
var definesLabels = (0, import_ramda.pipe)(definedLabels, (0, import_ramda.equals)({}), import_ramda.not);
|
|
260
|
+
var definedEvent = (0, import_ramda.pipe)((binding) => binding?.event, (0, import_ramda.defaultTo)(""));
|
|
261
|
+
var definesDelete = (0, import_ramda.pipe)(definedEvent, (0, import_ramda.equals)("DELETE" /* DELETE */));
|
|
262
|
+
var definedGroup = (0, import_ramda.pipe)((binding) => binding?.kind?.group, (0, import_ramda.defaultTo)(""));
|
|
263
|
+
var definesGroup = (0, import_ramda.pipe)(definedGroup, (0, import_ramda.equals)(""), import_ramda.not);
|
|
264
|
+
var definedVersion = (0, import_ramda.pipe)((binding) => binding?.kind?.version, (0, import_ramda.defaultTo)(""));
|
|
265
|
+
var definesVersion = (0, import_ramda.pipe)(definedVersion, (0, import_ramda.equals)(""), import_ramda.not);
|
|
266
|
+
var definedKind = (0, import_ramda.pipe)((binding) => binding?.kind?.kind, (0, import_ramda.defaultTo)(""));
|
|
267
|
+
var definesKind = (0, import_ramda.pipe)(definedKind, (0, import_ramda.equals)(""), import_ramda.not);
|
|
268
|
+
var definedCategory = (0, import_ramda.pipe)((binding) => {
|
|
269
|
+
return binding.isFinalize ? "Finalize" : binding.isWatch ? "Watch" : binding.isMutate ? "Mutate" : binding.isValidate ? "Validate" : "";
|
|
270
|
+
});
|
|
271
|
+
var definedCallback = (0, import_ramda.pipe)((binding) => {
|
|
272
|
+
return binding.isFinalize ? binding.finalizeCallback : binding.isWatch ? binding.watchCallback : binding.isMutate ? binding.mutateCallback : binding.isValidate ? binding.validateCallback : null;
|
|
273
|
+
});
|
|
274
|
+
var definedCallbackName = (0, import_ramda.pipe)(definedCallback, (0, import_ramda.defaultTo)({ name: "" }), (cb) => cb.name);
|
|
275
|
+
var mismatchedDeletionTimestamp = (0, import_ramda.allPass)([
|
|
276
|
+
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesDeletionTimestamp),
|
|
277
|
+
(0, import_ramda.pipe)((0, import_ramda.nthArg)(1), missingDeletionTimestamp)
|
|
278
|
+
]);
|
|
279
|
+
var mismatchedName = (0, import_ramda.allPass)([
|
|
280
|
+
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesName),
|
|
281
|
+
(0, import_ramda.pipe)((bnd, obj) => definedName(bnd) !== carriedName(obj))
|
|
282
|
+
]);
|
|
283
|
+
var mismatchedNameRegex = (0, import_ramda.allPass)([
|
|
284
|
+
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesNameRegex),
|
|
285
|
+
(0, import_ramda.pipe)((bnd, obj) => new RegExp(definedNameRegex(bnd)).test(carriedName(obj)), import_ramda.not)
|
|
286
|
+
]);
|
|
287
|
+
var bindsToKind = (0, import_ramda.curry)(
|
|
288
|
+
(0, import_ramda.allPass)([(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definedKind, (0, import_ramda.equals)(""), import_ramda.not), (0, import_ramda.pipe)((bnd, knd) => definedKind(bnd) === knd)])
|
|
289
|
+
);
|
|
290
|
+
var bindsToNamespace = (0, import_ramda.curry)((0, import_ramda.pipe)(bindsToKind(import_ramda.__, "Namespace")));
|
|
291
|
+
var misboundNamespace = (0, import_ramda.allPass)([bindsToNamespace, definesNamespaces]);
|
|
292
|
+
var mismatchedNamespace = (0, import_ramda.allPass)([
|
|
293
|
+
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesNamespaces),
|
|
294
|
+
(0, import_ramda.pipe)((bnd, obj) => definedNamespaces(bnd).includes(carriedNamespace(obj)), import_ramda.not)
|
|
295
|
+
]);
|
|
296
|
+
var mismatchedNamespaceRegex = (0, import_ramda.allPass)([
|
|
297
|
+
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesNamespaceRegexes),
|
|
298
|
+
(0, import_ramda.pipe)(
|
|
299
|
+
(bnd, obj) => (0, import_ramda.pipe)(
|
|
300
|
+
(0, import_ramda.any)((rex) => new RegExp(rex).test(carriedNamespace(obj))),
|
|
301
|
+
import_ramda.not
|
|
302
|
+
)(definedNamespaceRegexes(bnd))
|
|
303
|
+
)
|
|
304
|
+
]);
|
|
305
|
+
var metasMismatch = (0, import_ramda.pipe)(
|
|
306
|
+
(defined, carried) => {
|
|
307
|
+
const result = { defined, carried, unalike: {} };
|
|
308
|
+
result.unalike = Object.entries(result.defined).map(([key, val]) => {
|
|
309
|
+
const keyMissing = !Object.hasOwn(result.carried, key);
|
|
310
|
+
const noValue = !val;
|
|
311
|
+
const valMissing = !result.carried[key];
|
|
312
|
+
return keyMissing ? { [key]: val } : noValue ? {} : valMissing ? { [key]: val } : {};
|
|
313
|
+
}).reduce((acc, cur) => ({ ...acc, ...cur }), {});
|
|
314
|
+
return result.unalike;
|
|
315
|
+
},
|
|
316
|
+
(unalike) => Object.keys(unalike).length > 0
|
|
317
|
+
);
|
|
318
|
+
var mismatchedAnnotations = (0, import_ramda.allPass)([
|
|
319
|
+
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesAnnotations),
|
|
320
|
+
(0, import_ramda.pipe)((bnd, obj) => metasMismatch(definedAnnotations(bnd), carriedAnnotations(obj)))
|
|
321
|
+
]);
|
|
322
|
+
var mismatchedLabels = (0, import_ramda.allPass)([
|
|
323
|
+
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesLabels),
|
|
324
|
+
(0, import_ramda.pipe)((bnd, obj) => metasMismatch(definedLabels(bnd), carriedLabels(obj)))
|
|
325
|
+
]);
|
|
326
|
+
var uncarryableNamespace = (0, import_ramda.allPass)([
|
|
327
|
+
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), import_ramda.length, (0, import_ramda.gt)(import_ramda.__, 0)),
|
|
328
|
+
(0, import_ramda.pipe)((0, import_ramda.nthArg)(1), carriesNamespace),
|
|
329
|
+
(0, import_ramda.pipe)((nss, obj) => nss.includes(carriedNamespace(obj)), import_ramda.not)
|
|
330
|
+
]);
|
|
331
|
+
var carriesIgnoredNamespace = (0, import_ramda.allPass)([
|
|
332
|
+
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), import_ramda.length, (0, import_ramda.gt)(import_ramda.__, 0)),
|
|
333
|
+
(0, import_ramda.pipe)((0, import_ramda.nthArg)(1), carriesNamespace),
|
|
334
|
+
(0, import_ramda.pipe)((nss, obj) => nss.includes(carriedNamespace(obj)))
|
|
335
|
+
]);
|
|
336
|
+
var unbindableNamespaces = (0, import_ramda.allPass)([
|
|
337
|
+
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), import_ramda.length, (0, import_ramda.gt)(import_ramda.__, 0)),
|
|
338
|
+
(0, import_ramda.pipe)((0, import_ramda.nthArg)(1), definesNamespaces),
|
|
339
|
+
(0, import_ramda.pipe)((nss, bnd) => (0, import_ramda.difference)(definedNamespaces(bnd), nss), import_ramda.length, (0, import_ramda.equals)(0), import_ramda.not)
|
|
340
|
+
]);
|
|
341
|
+
var misboundDeleteWithDeletionTimestamp = (0, import_ramda.allPass)([definesDelete, definesDeletionTimestamp]);
|
|
342
|
+
var operationMatchesEvent = (0, import_ramda.anyPass)([
|
|
343
|
+
(0, import_ramda.pipe)((0, import_ramda.nthArg)(1), (0, import_ramda.equals)("*" /* Any */)),
|
|
344
|
+
(0, import_ramda.pipe)((op, evt) => op === evt),
|
|
345
|
+
(0, import_ramda.pipe)((op, evt) => op ? evt.includes(op) : false)
|
|
346
|
+
]);
|
|
347
|
+
var mismatchedEvent = (0, import_ramda.pipe)(
|
|
348
|
+
(binding, request) => operationMatchesEvent(declaredOperation(request), definedEvent(binding)),
|
|
349
|
+
import_ramda.not
|
|
350
|
+
);
|
|
351
|
+
var mismatchedGroup = (0, import_ramda.allPass)([
|
|
352
|
+
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesGroup),
|
|
353
|
+
(0, import_ramda.pipe)((binding, request) => definedGroup(binding) !== declaredGroup(request))
|
|
354
|
+
]);
|
|
355
|
+
var mismatchedVersion = (0, import_ramda.allPass)([
|
|
356
|
+
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesVersion),
|
|
357
|
+
(0, import_ramda.pipe)((binding, request) => definedVersion(binding) !== declaredVersion(request))
|
|
358
|
+
]);
|
|
359
|
+
var mismatchedKind = (0, import_ramda.allPass)([
|
|
360
|
+
(0, import_ramda.pipe)((0, import_ramda.nthArg)(0), definesKind),
|
|
361
|
+
(0, import_ramda.pipe)((binding, request) => definedKind(binding) !== declaredKind(request))
|
|
362
|
+
]);
|
|
237
363
|
|
|
238
364
|
// src/lib/filter.ts
|
|
239
|
-
function shouldSkipRequest(binding, req, capabilityNamespaces) {
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
const operation = req.operation.toUpperCase();
|
|
243
|
-
const uid = req.uid;
|
|
244
|
-
const srcObject = operation === "DELETE" /* DELETE */ ? req.oldObject : req.object;
|
|
245
|
-
const { metadata } = srcObject || {};
|
|
246
|
-
const combinedNamespaces = [...namespaces, ...capabilityNamespaces];
|
|
247
|
-
if (binding.event.includes("DELETE" /* Delete */) && binding.filters?.deletionTimestamp) {
|
|
248
|
-
return true;
|
|
249
|
-
}
|
|
250
|
-
if (binding.filters?.deletionTimestamp && !req.object.metadata?.deletionTimestamp) {
|
|
251
|
-
return true;
|
|
252
|
-
}
|
|
253
|
-
if (!binding.event.includes(operation) && !binding.event.includes("*" /* Any */)) {
|
|
254
|
-
return true;
|
|
255
|
-
}
|
|
256
|
-
if (name && name !== req.name) {
|
|
257
|
-
return true;
|
|
258
|
-
}
|
|
259
|
-
if (kind4 !== req.kind.kind) {
|
|
260
|
-
return true;
|
|
261
|
-
}
|
|
262
|
-
if (group && group !== req.kind.group) {
|
|
263
|
-
return true;
|
|
264
|
-
}
|
|
265
|
-
if (version && version !== req.kind.version) {
|
|
266
|
-
return true;
|
|
267
|
-
}
|
|
268
|
-
if (combinedNamespaces.length && !combinedNamespaces.includes(req.namespace || "") || !namespaces.includes(req.namespace || "") && capabilityNamespaces.length !== 0 && namespaces.length !== 0) {
|
|
269
|
-
let type = "";
|
|
270
|
-
let label = "";
|
|
271
|
-
if (binding.isMutate) {
|
|
272
|
-
type = "Mutate";
|
|
273
|
-
label = binding.mutateCallback.name;
|
|
274
|
-
} else if (binding.isValidate) {
|
|
275
|
-
type = "Validate";
|
|
276
|
-
label = binding.validateCallback.name;
|
|
277
|
-
} else if (binding.isWatch) {
|
|
278
|
-
type = "Watch";
|
|
279
|
-
label = binding.watchCallback.name;
|
|
280
|
-
}
|
|
281
|
-
logger_default.debug({ uid }, `${type} binding (${label}) does not match request namespace "${req.namespace}"`);
|
|
282
|
-
return true;
|
|
283
|
-
}
|
|
284
|
-
for (const [key, value] of Object.entries(labels)) {
|
|
285
|
-
const testKey = metadata?.labels?.[key];
|
|
286
|
-
if (!testKey) {
|
|
287
|
-
logger_default.debug({ uid }, `Label ${key} does not exist`);
|
|
288
|
-
return true;
|
|
289
|
-
}
|
|
290
|
-
if (value && testKey !== value) {
|
|
291
|
-
logger_default.debug({ uid }, `${testKey} does not match ${value}`);
|
|
292
|
-
return true;
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
for (const [key, value] of Object.entries(annotations)) {
|
|
296
|
-
const testKey = metadata?.annotations?.[key];
|
|
297
|
-
if (!testKey) {
|
|
298
|
-
logger_default.debug({ uid }, `Annotation ${key} does not exist`);
|
|
299
|
-
return true;
|
|
300
|
-
}
|
|
301
|
-
if (value && testKey !== value) {
|
|
302
|
-
logger_default.debug({ uid }, `${testKey} does not match ${value}`);
|
|
303
|
-
return true;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
return false;
|
|
365
|
+
function shouldSkipRequest(binding, req, capabilityNamespaces, ignoredNamespaces) {
|
|
366
|
+
const obj = req.operation === "DELETE" /* DELETE */ ? req.oldObject : req.object;
|
|
367
|
+
return misboundDeleteWithDeletionTimestamp(binding) ? true : mismatchedDeletionTimestamp(binding, obj) ? true : mismatchedEvent(binding, req) ? true : mismatchedName(binding, obj) ? true : mismatchedGroup(binding, req) ? true : mismatchedVersion(binding, req) ? true : mismatchedKind(binding, req) ? true : unbindableNamespaces(capabilityNamespaces, binding) ? true : uncarryableNamespace(capabilityNamespaces, obj) ? true : mismatchedNamespace(binding, obj) ? true : mismatchedLabels(binding, obj) ? true : mismatchedAnnotations(binding, obj) ? true : mismatchedNamespaceRegex(binding, obj) ? true : mismatchedNameRegex(binding, obj) ? true : carriesIgnoredNamespace(ignoredNamespaces, obj) ? true : false;
|
|
307
368
|
}
|
|
308
369
|
|
|
309
370
|
// src/lib/mutate-request.ts
|
|
310
|
-
var
|
|
371
|
+
var import_ramda2 = require("ramda");
|
|
311
372
|
var PeprMutateRequest = class {
|
|
312
373
|
Raw;
|
|
313
374
|
#input;
|
|
@@ -342,9 +403,9 @@ var PeprMutateRequest = class {
|
|
|
342
403
|
constructor(input) {
|
|
343
404
|
this.#input = input;
|
|
344
405
|
if (input.operation.toUpperCase() === "DELETE" /* DELETE */) {
|
|
345
|
-
this.Raw = (0,
|
|
406
|
+
this.Raw = (0, import_ramda2.clone)(input.oldObject);
|
|
346
407
|
} else {
|
|
347
|
-
this.Raw = (0,
|
|
408
|
+
this.Raw = (0, import_ramda2.clone)(input.object);
|
|
348
409
|
}
|
|
349
410
|
if (!this.Raw) {
|
|
350
411
|
throw new Error("unable to load the request object into PeprRequest.RawP");
|
|
@@ -356,7 +417,7 @@ var PeprMutateRequest = class {
|
|
|
356
417
|
* @param obj - The object to merge with the current resource.
|
|
357
418
|
*/
|
|
358
419
|
Merge = (obj) => {
|
|
359
|
-
this.Raw = (0,
|
|
420
|
+
this.Raw = (0, import_ramda2.mergeDeepRight)(this.Raw, obj);
|
|
360
421
|
};
|
|
361
422
|
/**
|
|
362
423
|
* Updates a label on the Kubernetes resource.
|
|
@@ -489,7 +550,7 @@ async function mutateProcessor(config, capabilities, req, reqMetadata) {
|
|
|
489
550
|
if (!action.mutateCallback) {
|
|
490
551
|
continue;
|
|
491
552
|
}
|
|
492
|
-
if (shouldSkipRequest(action, req, namespaces)) {
|
|
553
|
+
if (shouldSkipRequest(action, req, namespaces, config?.alwaysIgnore?.namespaces)) {
|
|
493
554
|
continue;
|
|
494
555
|
}
|
|
495
556
|
const label = action.mutateCallback.name;
|
|
@@ -562,7 +623,7 @@ async function mutateProcessor(config, capabilities, req, reqMetadata) {
|
|
|
562
623
|
}
|
|
563
624
|
|
|
564
625
|
// src/lib/validate-request.ts
|
|
565
|
-
var
|
|
626
|
+
var import_ramda3 = require("ramda");
|
|
566
627
|
var PeprValidateRequest = class {
|
|
567
628
|
Raw;
|
|
568
629
|
#input;
|
|
@@ -587,9 +648,9 @@ var PeprValidateRequest = class {
|
|
|
587
648
|
constructor(input) {
|
|
588
649
|
this.#input = input;
|
|
589
650
|
if (input.operation.toUpperCase() === "DELETE" /* DELETE */) {
|
|
590
|
-
this.Raw = (0,
|
|
651
|
+
this.Raw = (0, import_ramda3.clone)(input.oldObject);
|
|
591
652
|
} else {
|
|
592
|
-
this.Raw = (0,
|
|
653
|
+
this.Raw = (0, import_ramda3.clone)(input.object);
|
|
593
654
|
}
|
|
594
655
|
if (!this.Raw) {
|
|
595
656
|
throw new Error("unable to load the request object into PeprRequest.Raw");
|
|
@@ -640,7 +701,7 @@ var PeprValidateRequest = class {
|
|
|
640
701
|
};
|
|
641
702
|
|
|
642
703
|
// src/lib/validate-processor.ts
|
|
643
|
-
async function validateProcessor(capabilities, req, reqMetadata) {
|
|
704
|
+
async function validateProcessor(config, capabilities, req, reqMetadata) {
|
|
644
705
|
const wrapped = new PeprValidateRequest(req);
|
|
645
706
|
const response = [];
|
|
646
707
|
const isSecret = req.kind.version == "v1" && req.kind.kind == "Secret";
|
|
@@ -659,7 +720,7 @@ async function validateProcessor(capabilities, req, reqMetadata) {
|
|
|
659
720
|
allowed: true
|
|
660
721
|
// Assume it's allowed until a validation check fails
|
|
661
722
|
};
|
|
662
|
-
if (shouldSkipRequest(action, req, namespaces)) {
|
|
723
|
+
if (shouldSkipRequest(action, req, namespaces, config?.alwaysIgnore?.namespaces)) {
|
|
663
724
|
continue;
|
|
664
725
|
}
|
|
665
726
|
const label = action.validateCallback.name;
|
|
@@ -691,7 +752,21 @@ async function validateProcessor(capabilities, req, reqMetadata) {
|
|
|
691
752
|
|
|
692
753
|
// src/lib/controller/store.ts
|
|
693
754
|
var import_kubernetes_fluent_client2 = require("kubernetes-fluent-client");
|
|
694
|
-
var
|
|
755
|
+
var import_ramda4 = require("ramda");
|
|
756
|
+
|
|
757
|
+
// src/lib/k8s.ts
|
|
758
|
+
var import_kubernetes_fluent_client = require("kubernetes-fluent-client");
|
|
759
|
+
var PeprStore = class extends import_kubernetes_fluent_client.GenericKind {
|
|
760
|
+
};
|
|
761
|
+
var peprStoreGVK = {
|
|
762
|
+
kind: "PeprStore",
|
|
763
|
+
version: "v1",
|
|
764
|
+
group: "pepr.dev"
|
|
765
|
+
};
|
|
766
|
+
(0, import_kubernetes_fluent_client.RegisterKind)(PeprStore, peprStoreGVK);
|
|
767
|
+
|
|
768
|
+
// src/lib/controller/store.ts
|
|
769
|
+
var redactedValue = "**redacted**";
|
|
695
770
|
var namespace = "pepr-system";
|
|
696
771
|
var debounceBackoff = 5e3;
|
|
697
772
|
var PeprControllerStore = class {
|
|
@@ -728,7 +803,7 @@ var PeprControllerStore = class {
|
|
|
728
803
|
watcher.start().catch((e) => logger_default.error(e, "Error starting Pepr store watch"));
|
|
729
804
|
};
|
|
730
805
|
#migrateAndSetupWatch = async (store) => {
|
|
731
|
-
logger_default.debug(store, "Pepr Store migration");
|
|
806
|
+
logger_default.debug(redactedStore(store), "Pepr Store migration");
|
|
732
807
|
const data = store.data || {};
|
|
733
808
|
const migrateCache = {};
|
|
734
809
|
const flushCache = async () => {
|
|
@@ -738,7 +813,9 @@ var PeprControllerStore = class {
|
|
|
738
813
|
delete migrateCache[idx];
|
|
739
814
|
}
|
|
740
815
|
try {
|
|
741
|
-
|
|
816
|
+
if (payload.length > 0) {
|
|
817
|
+
await (0, import_kubernetes_fluent_client2.K8s)(PeprStore, { namespace, name: this.#name }).Patch(payload);
|
|
818
|
+
}
|
|
742
819
|
} catch (err) {
|
|
743
820
|
logger_default.error(err, "Pepr store update failure");
|
|
744
821
|
if (err.status === 422) {
|
|
@@ -774,7 +851,7 @@ var PeprControllerStore = class {
|
|
|
774
851
|
for (const name of Object.keys(this.#stores)) {
|
|
775
852
|
const offset = `${name}-`.length;
|
|
776
853
|
for (const key of Object.keys(data)) {
|
|
777
|
-
if ((0,
|
|
854
|
+
if ((0, import_ramda4.startsWith)(name, key) && !(0, import_ramda4.startsWith)(`${name}-v2`, key)) {
|
|
778
855
|
fillCache(name, "remove", [key.slice(offset)], data[key]);
|
|
779
856
|
fillCache(name, "add", [key.slice(offset)], data[key]);
|
|
780
857
|
}
|
|
@@ -784,14 +861,14 @@ var PeprControllerStore = class {
|
|
|
784
861
|
this.#setupWatch();
|
|
785
862
|
};
|
|
786
863
|
#receive = (store) => {
|
|
787
|
-
logger_default.debug(store, "Pepr Store update");
|
|
864
|
+
logger_default.debug(redactedStore(store), "Pepr Store update");
|
|
788
865
|
const debounced = () => {
|
|
789
866
|
const data = store.data || {};
|
|
790
867
|
for (const name of Object.keys(this.#stores)) {
|
|
791
868
|
const offset = `${name}-`.length;
|
|
792
869
|
const filtered = {};
|
|
793
870
|
for (const key of Object.keys(data)) {
|
|
794
|
-
if ((0,
|
|
871
|
+
if ((0, import_ramda4.startsWith)(name, key)) {
|
|
795
872
|
filtered[key.slice(offset)] = data[key];
|
|
796
873
|
}
|
|
797
874
|
}
|
|
@@ -835,7 +912,9 @@ var PeprControllerStore = class {
|
|
|
835
912
|
delete sendCache[idx];
|
|
836
913
|
}
|
|
837
914
|
try {
|
|
838
|
-
|
|
915
|
+
if (payload.length > 0) {
|
|
916
|
+
await (0, import_kubernetes_fluent_client2.K8s)(PeprStore, { namespace, name: this.#name }).Patch(payload);
|
|
917
|
+
}
|
|
839
918
|
} catch (err) {
|
|
840
919
|
logger_default.error(err, "Pepr store update failure");
|
|
841
920
|
if (err.status === 422) {
|
|
@@ -852,7 +931,7 @@ var PeprControllerStore = class {
|
|
|
852
931
|
};
|
|
853
932
|
setInterval(() => {
|
|
854
933
|
if (Object.keys(sendCache).length > 0) {
|
|
855
|
-
logger_default.debug(sendCache, "Sending updates to Pepr store");
|
|
934
|
+
logger_default.debug(redactedPatch(sendCache), "Sending updates to Pepr store");
|
|
856
935
|
void flushCache();
|
|
857
936
|
}
|
|
858
937
|
}, debounceBackoff);
|
|
@@ -878,8 +957,38 @@ var PeprControllerStore = class {
|
|
|
878
957
|
}
|
|
879
958
|
};
|
|
880
959
|
};
|
|
960
|
+
function redactedStore(store) {
|
|
961
|
+
const redacted = process.env.PEPR_STORE_REDACT_VALUES === "true";
|
|
962
|
+
return {
|
|
963
|
+
...store,
|
|
964
|
+
data: Object.keys(store.data).reduce((acc, key) => {
|
|
965
|
+
acc[key] = redacted ? redactedValue : store.data[key];
|
|
966
|
+
return acc;
|
|
967
|
+
}, {})
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
function redactedPatch(patch = {}) {
|
|
971
|
+
const redacted = process.env.PEPR_STORE_REDACT_VALUES === "true";
|
|
972
|
+
if (!redacted) {
|
|
973
|
+
return patch;
|
|
974
|
+
}
|
|
975
|
+
const redactedCache = {};
|
|
976
|
+
Object.keys(patch).forEach((key) => {
|
|
977
|
+
const operation = patch[key];
|
|
978
|
+
const redactedKey = key.includes(":") ? key.substring(0, key.lastIndexOf(":")) + ":**redacted**" : key;
|
|
979
|
+
const redactedOperation = {
|
|
980
|
+
...operation,
|
|
981
|
+
..."value" in operation ? { value: "**redacted**" } : {}
|
|
982
|
+
};
|
|
983
|
+
redactedCache[redactedKey] = redactedOperation;
|
|
984
|
+
});
|
|
985
|
+
return redactedCache;
|
|
986
|
+
}
|
|
881
987
|
|
|
882
988
|
// src/lib/controller/index.ts
|
|
989
|
+
if (!process.env.PEPR_NODE_WARNINGS) {
|
|
990
|
+
process.removeAllListeners("warning");
|
|
991
|
+
}
|
|
883
992
|
var Controller = class _Controller {
|
|
884
993
|
// Track whether the server is running
|
|
885
994
|
#running = false;
|
|
@@ -939,7 +1048,7 @@ var Controller = class _Controller {
|
|
|
939
1048
|
});
|
|
940
1049
|
server.on("error", (e) => {
|
|
941
1050
|
if (e.code === "EADDRINUSE") {
|
|
942
|
-
logger_default.
|
|
1051
|
+
logger_default.info(
|
|
943
1052
|
`Address in use, retrying in 2 seconds. If this persists, ensure ${port} is not in use, e.g. "lsof -i :${port}"`
|
|
944
1053
|
);
|
|
945
1054
|
setTimeout(() => {
|
|
@@ -978,7 +1087,7 @@ var Controller = class _Controller {
|
|
|
978
1087
|
const { token } = req.params;
|
|
979
1088
|
if (token !== this.#token) {
|
|
980
1089
|
const err = `Unauthorized: invalid token '${token.replace(/[^\w]/g, "_")}'`;
|
|
981
|
-
logger_default.
|
|
1090
|
+
logger_default.info(err);
|
|
982
1091
|
res.status(401).send(err);
|
|
983
1092
|
this.#metricsCollector.alert();
|
|
984
1093
|
return;
|
|
@@ -1025,7 +1134,7 @@ var Controller = class _Controller {
|
|
|
1025
1134
|
if (admissionKind === "Mutate") {
|
|
1026
1135
|
response = await mutateProcessor(this.#config, this.#capabilities, request, reqMetadata);
|
|
1027
1136
|
} else {
|
|
1028
|
-
response = await validateProcessor(this.#capabilities, request, reqMetadata);
|
|
1137
|
+
response = await validateProcessor(this.#config, this.#capabilities, request, reqMetadata);
|
|
1029
1138
|
}
|
|
1030
1139
|
const responseList = Array.isArray(response) ? response : [response];
|
|
1031
1140
|
responseList.map((res2) => {
|
|
@@ -1086,7 +1195,7 @@ var Controller = class _Controller {
|
|
|
1086
1195
|
status: res.statusCode,
|
|
1087
1196
|
duration: `${elapsedTime} ms`
|
|
1088
1197
|
};
|
|
1089
|
-
|
|
1198
|
+
logger_default.info(message);
|
|
1090
1199
|
});
|
|
1091
1200
|
next();
|
|
1092
1201
|
}
|
|
@@ -1107,8 +1216,8 @@ var Controller = class _Controller {
|
|
|
1107
1216
|
};
|
|
1108
1217
|
|
|
1109
1218
|
// src/lib/watch-processor.ts
|
|
1110
|
-
var
|
|
1111
|
-
var
|
|
1219
|
+
var import_kubernetes_fluent_client6 = require("kubernetes-fluent-client");
|
|
1220
|
+
var import_types6 = require("kubernetes-fluent-client/dist/fluent/types");
|
|
1112
1221
|
|
|
1113
1222
|
// src/lib/helpers.ts
|
|
1114
1223
|
var import_kubernetes_fluent_client4 = require("kubernetes-fluent-client");
|
|
@@ -1179,59 +1288,51 @@ function sanitizeResourceName(name) {
|
|
|
1179
1288
|
}
|
|
1180
1289
|
|
|
1181
1290
|
// src/lib/helpers.ts
|
|
1182
|
-
function
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
}
|
|
1186
|
-
let matchCount = 0;
|
|
1187
|
-
for (const key in bindingFilters) {
|
|
1188
|
-
if (Object.prototype.hasOwnProperty.call(objectFilters, key)) {
|
|
1189
|
-
const val1 = bindingFilters[key];
|
|
1190
|
-
const val2 = objectFilters[key];
|
|
1191
|
-
if (val1 === "" && key in objectFilters) {
|
|
1192
|
-
matchCount++;
|
|
1193
|
-
} else if (val1 !== "" && val1 === val2) {
|
|
1194
|
-
matchCount++;
|
|
1195
|
-
}
|
|
1196
|
-
}
|
|
1197
|
-
}
|
|
1198
|
-
return matchCount === Object.keys(bindingFilters).length;
|
|
1291
|
+
function filterNoMatchReason(binding, obj, capabilityNamespaces, ignoredNamespaces) {
|
|
1292
|
+
const prefix = "Ignoring Watch Callback:";
|
|
1293
|
+
return mismatchedDeletionTimestamp(binding, obj) ? `${prefix} Binding defines deletionTimestamp but Object does not carry it.` : mismatchedName(binding, obj) ? `${prefix} Binding defines name '${definedName(binding)}' but Object carries '${carriedName(obj)}'.` : misboundNamespace(binding) ? `${prefix} Cannot use namespace filter on a namespace object.` : mismatchedLabels(binding, obj) ? `${prefix} Binding defines labels '${JSON.stringify(definedLabels(binding))}' but Object carries '${JSON.stringify(carriedLabels(obj))}'.` : mismatchedAnnotations(binding, obj) ? `${prefix} Binding defines annotations '${JSON.stringify(definedAnnotations(binding))}' but Object carries '${JSON.stringify(carriedAnnotations(obj))}'.` : uncarryableNamespace(capabilityNamespaces, obj) ? `${prefix} Object carries namespace '${carriedNamespace(obj)}' but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.` : unbindableNamespaces(capabilityNamespaces, binding) ? `${prefix} Binding defines namespaces ${JSON.stringify(definedNamespaces(binding))} but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.` : mismatchedNamespace(binding, obj) ? `${prefix} Binding defines namespaces '${JSON.stringify(definedNamespaces(binding))}' but Object carries '${carriedNamespace(obj)}'.` : mismatchedNamespaceRegex(binding, obj) ? `${prefix} Binding defines namespace regexes '${JSON.stringify(definedNamespaceRegexes(binding))}' but Object carries '${carriedNamespace(obj)}'.` : mismatchedNameRegex(binding, obj) ? `${prefix} Binding defines name regex '${definedNameRegex(binding)}' but Object carries '${carriedName(obj)}'.` : carriesIgnoredNamespace(ignoredNamespaces, obj) ? `${prefix} Object carries namespace '${carriedNamespace(obj)}' but ignored namespaces include '${JSON.stringify(ignoredNamespaces)}'.` : "";
|
|
1199
1294
|
}
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
if (
|
|
1205
|
-
return
|
|
1206
|
-
}
|
|
1207
|
-
if (typeof obj === "object" && obj !== null && "metadata" in obj && obj.metadata !== void 0 && binding.filters) {
|
|
1208
|
-
if (obj.metadata.labels && !checkOverlap(binding.filters.labels, obj.metadata.labels)) {
|
|
1209
|
-
return `Ignoring Watch Callback: No overlap between binding and object labels. Binding labels ${JSON.stringify(
|
|
1210
|
-
binding.filters.labels
|
|
1211
|
-
)}, Object Labels ${JSON.stringify(obj.metadata.labels)}.`;
|
|
1212
|
-
}
|
|
1213
|
-
if (obj.metadata.annotations && !checkOverlap(binding.filters.annotations, obj.metadata.annotations)) {
|
|
1214
|
-
return `Ignoring Watch Callback: No overlap between binding and object annotations. Binding annotations ${JSON.stringify(
|
|
1215
|
-
binding.filters.annotations
|
|
1216
|
-
)}, Object annotations ${JSON.stringify(obj.metadata.annotations)}.`;
|
|
1217
|
-
}
|
|
1295
|
+
|
|
1296
|
+
// src/lib/finalizer.ts
|
|
1297
|
+
var import_kubernetes_fluent_client5 = require("kubernetes-fluent-client");
|
|
1298
|
+
function addFinalizer(request) {
|
|
1299
|
+
if (request.Request.operation === "DELETE" /* DELETE */) {
|
|
1300
|
+
return;
|
|
1218
1301
|
}
|
|
1219
|
-
if (
|
|
1220
|
-
return
|
|
1221
|
-
", "
|
|
1222
|
-
)}, Object namespace: ${obj.metadata.namespace}.`;
|
|
1302
|
+
if (request.Request.operation === "UPDATE" /* UPDATE */ && request.Raw.metadata?.deletionTimestamp) {
|
|
1303
|
+
return;
|
|
1223
1304
|
}
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1305
|
+
const peprFinal = "pepr.dev/finalizer";
|
|
1306
|
+
const finalizers = request.Raw.metadata?.finalizers || [];
|
|
1307
|
+
if (!finalizers.includes(peprFinal)) {
|
|
1308
|
+
finalizers.push(peprFinal);
|
|
1228
1309
|
}
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1310
|
+
request.Merge({ metadata: { finalizers } });
|
|
1311
|
+
}
|
|
1312
|
+
async function removeFinalizer(binding, obj) {
|
|
1313
|
+
const peprFinal = "pepr.dev/finalizer";
|
|
1314
|
+
const meta = obj.metadata;
|
|
1315
|
+
const resource = `${meta.namespace || "ClusterScoped"}/${meta.name}`;
|
|
1316
|
+
logger_default.debug({ obj }, `Removing finalizer '${peprFinal}' from '${resource}'`);
|
|
1317
|
+
const { model, kind: kind4 } = binding;
|
|
1318
|
+
try {
|
|
1319
|
+
(0, import_kubernetes_fluent_client5.RegisterKind)(model, kind4);
|
|
1320
|
+
} catch (e) {
|
|
1321
|
+
const expected = e.message === `GVK ${model.name} already registered`;
|
|
1322
|
+
if (!expected) {
|
|
1323
|
+
logger_default.error({ model, kind: kind4, error: e }, `Error registering "${kind4}" during finalization.`);
|
|
1324
|
+
return;
|
|
1325
|
+
}
|
|
1233
1326
|
}
|
|
1234
|
-
|
|
1327
|
+
const finalizers = meta.finalizers?.filter((f) => f !== peprFinal) || [];
|
|
1328
|
+
obj = await (0, import_kubernetes_fluent_client5.K8s)(model, meta).Patch([
|
|
1329
|
+
{
|
|
1330
|
+
op: "replace",
|
|
1331
|
+
path: `/metadata/finalizers`,
|
|
1332
|
+
value: finalizers
|
|
1333
|
+
}
|
|
1334
|
+
]);
|
|
1335
|
+
logger_default.debug({ obj }, `Removed finalizer '${peprFinal}' from '${resource}'`);
|
|
1235
1336
|
}
|
|
1236
1337
|
|
|
1237
1338
|
// src/lib/queue.ts
|
|
@@ -1354,26 +1455,37 @@ var watchCfg = {
|
|
|
1354
1455
|
relistIntervalSec: process.env.PEPR_RELIST_INTERVAL_SECONDS ? parseInt(process.env.PEPR_RELIST_INTERVAL_SECONDS, 10) : 600
|
|
1355
1456
|
};
|
|
1356
1457
|
var eventToPhaseMap = {
|
|
1357
|
-
["CREATE" /* Create */]: [
|
|
1358
|
-
["UPDATE" /* Update */]: [
|
|
1359
|
-
["CREATEORUPDATE" /* CreateOrUpdate */]: [
|
|
1360
|
-
["DELETE" /* Delete */]: [
|
|
1361
|
-
["*" /* Any */]: [
|
|
1458
|
+
["CREATE" /* Create */]: [import_types6.WatchPhase.Added],
|
|
1459
|
+
["UPDATE" /* Update */]: [import_types6.WatchPhase.Modified],
|
|
1460
|
+
["CREATEORUPDATE" /* CreateOrUpdate */]: [import_types6.WatchPhase.Added, import_types6.WatchPhase.Modified],
|
|
1461
|
+
["DELETE" /* Delete */]: [import_types6.WatchPhase.Deleted],
|
|
1462
|
+
["*" /* Any */]: [import_types6.WatchPhase.Added, import_types6.WatchPhase.Modified, import_types6.WatchPhase.Deleted]
|
|
1362
1463
|
};
|
|
1363
|
-
function setupWatch(capabilities) {
|
|
1464
|
+
function setupWatch(capabilities, ignoredNamespaces) {
|
|
1364
1465
|
capabilities.map(
|
|
1365
|
-
(capability) => capability.bindings.filter((binding) => binding.isWatch).forEach((bindingElement) => runBinding(bindingElement, capability.namespaces))
|
|
1466
|
+
(capability) => capability.bindings.filter((binding) => binding.isWatch).forEach((bindingElement) => runBinding(bindingElement, capability.namespaces, ignoredNamespaces))
|
|
1366
1467
|
);
|
|
1367
1468
|
}
|
|
1368
|
-
async function runBinding(binding, capabilityNamespaces) {
|
|
1469
|
+
async function runBinding(binding, capabilityNamespaces, ignoredNamespaces) {
|
|
1369
1470
|
const phaseMatch = eventToPhaseMap[binding.event] || eventToPhaseMap["*" /* Any */];
|
|
1370
1471
|
logger_default.debug({ watchCfg }, "Effective WatchConfig");
|
|
1371
1472
|
const watchCallback = async (obj, phase) => {
|
|
1372
1473
|
if (phaseMatch.includes(phase)) {
|
|
1373
1474
|
try {
|
|
1374
|
-
const filterMatch = filterNoMatchReason(binding, obj, capabilityNamespaces);
|
|
1475
|
+
const filterMatch = filterNoMatchReason(binding, obj, capabilityNamespaces, ignoredNamespaces);
|
|
1375
1476
|
if (filterMatch === "") {
|
|
1376
|
-
|
|
1477
|
+
if (binding.isFinalize) {
|
|
1478
|
+
if (!obj.metadata?.deletionTimestamp) {
|
|
1479
|
+
return;
|
|
1480
|
+
}
|
|
1481
|
+
try {
|
|
1482
|
+
await binding.finalizeCallback?.(obj);
|
|
1483
|
+
} finally {
|
|
1484
|
+
await removeFinalizer(binding, obj);
|
|
1485
|
+
}
|
|
1486
|
+
} else {
|
|
1487
|
+
await binding.watchCallback?.(obj, phase);
|
|
1488
|
+
}
|
|
1377
1489
|
} else {
|
|
1378
1490
|
logger_default.debug(filterMatch);
|
|
1379
1491
|
}
|
|
@@ -1382,7 +1494,7 @@ async function runBinding(binding, capabilityNamespaces) {
|
|
|
1382
1494
|
}
|
|
1383
1495
|
}
|
|
1384
1496
|
};
|
|
1385
|
-
const watcher = (0,
|
|
1497
|
+
const watcher = (0, import_kubernetes_fluent_client6.K8s)(binding.model, binding.filters).Watch(async (obj, phase) => {
|
|
1386
1498
|
logger_default.debug(obj, `Watch event ${phase} received`);
|
|
1387
1499
|
if (binding.isQueue) {
|
|
1388
1500
|
const queue = getOrCreateQueue(obj);
|
|
@@ -1391,30 +1503,30 @@ async function runBinding(binding, capabilityNamespaces) {
|
|
|
1391
1503
|
await watchCallback(obj, phase);
|
|
1392
1504
|
}
|
|
1393
1505
|
}, watchCfg);
|
|
1394
|
-
watcher.events.on(
|
|
1506
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.GIVE_UP, (err) => {
|
|
1395
1507
|
logger_default.error(err, "Watch failed after 5 attempts, giving up");
|
|
1396
1508
|
process.exit(1);
|
|
1397
1509
|
});
|
|
1398
|
-
watcher.events.on(
|
|
1399
|
-
watcher.events.on(
|
|
1510
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.CONNECT, (url) => logEvent(import_kubernetes_fluent_client6.WatchEvent.CONNECT, url));
|
|
1511
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.DATA_ERROR, (err) => logEvent(import_kubernetes_fluent_client6.WatchEvent.DATA_ERROR, err.message));
|
|
1400
1512
|
watcher.events.on(
|
|
1401
|
-
|
|
1402
|
-
(retryCount) => logEvent(
|
|
1513
|
+
import_kubernetes_fluent_client6.WatchEvent.RECONNECT,
|
|
1514
|
+
(retryCount) => logEvent(import_kubernetes_fluent_client6.WatchEvent.RECONNECT, `Reconnecting after ${retryCount} attempt${retryCount === 1 ? "" : "s"}`)
|
|
1403
1515
|
);
|
|
1404
|
-
watcher.events.on(
|
|
1405
|
-
watcher.events.on(
|
|
1406
|
-
watcher.events.on(
|
|
1407
|
-
watcher.events.on(
|
|
1408
|
-
watcher.events.on(
|
|
1409
|
-
watcher.events.on(
|
|
1410
|
-
watcher.events.on(
|
|
1411
|
-
watcher.events.on(
|
|
1516
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.RECONNECT_PENDING, () => logEvent(import_kubernetes_fluent_client6.WatchEvent.RECONNECT_PENDING));
|
|
1517
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.GIVE_UP, (err) => logEvent(import_kubernetes_fluent_client6.WatchEvent.GIVE_UP, err.message));
|
|
1518
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.ABORT, (err) => logEvent(import_kubernetes_fluent_client6.WatchEvent.ABORT, err.message));
|
|
1519
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.OLD_RESOURCE_VERSION, (err) => logEvent(import_kubernetes_fluent_client6.WatchEvent.OLD_RESOURCE_VERSION, err));
|
|
1520
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.NETWORK_ERROR, (err) => logEvent(import_kubernetes_fluent_client6.WatchEvent.NETWORK_ERROR, err.message));
|
|
1521
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.LIST_ERROR, (err) => logEvent(import_kubernetes_fluent_client6.WatchEvent.LIST_ERROR, err.message));
|
|
1522
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.LIST, (list) => logEvent(import_kubernetes_fluent_client6.WatchEvent.LIST, JSON.stringify(list, void 0, 2)));
|
|
1523
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.CACHE_MISS, (windowName) => {
|
|
1412
1524
|
metricsCollector.incCacheMiss(windowName);
|
|
1413
1525
|
});
|
|
1414
|
-
watcher.events.on(
|
|
1526
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.INIT_CACHE_MISS, (windowName) => {
|
|
1415
1527
|
metricsCollector.initCacheMissWindow(windowName);
|
|
1416
1528
|
});
|
|
1417
|
-
watcher.events.on(
|
|
1529
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.INC_RESYNC_FAILURE_COUNT, (retryCount) => {
|
|
1418
1530
|
metricsCollector.incRetryCount(retryCount);
|
|
1419
1531
|
});
|
|
1420
1532
|
try {
|
|
@@ -1447,7 +1559,7 @@ var PeprModule = class {
|
|
|
1447
1559
|
* @param opts Options for the Pepr runtime
|
|
1448
1560
|
*/
|
|
1449
1561
|
constructor({ description, pepr }, capabilities = [], opts = {}) {
|
|
1450
|
-
const config = (0,
|
|
1562
|
+
const config = (0, import_ramda5.clone)(pepr);
|
|
1451
1563
|
config.description = description;
|
|
1452
1564
|
ValidateError(config.onError);
|
|
1453
1565
|
if (isBuildMode()) {
|
|
@@ -1470,7 +1582,7 @@ var PeprModule = class {
|
|
|
1470
1582
|
this.#controller = new Controller(config, capabilities, opts.beforeHook, opts.afterHook, () => {
|
|
1471
1583
|
if (isWatchMode() || isDevMode()) {
|
|
1472
1584
|
try {
|
|
1473
|
-
setupWatch(capabilities);
|
|
1585
|
+
setupWatch(capabilities, pepr?.alwaysIgnore?.namespaces);
|
|
1474
1586
|
} catch (e) {
|
|
1475
1587
|
logger_default.error(e, "Error setting up watch");
|
|
1476
1588
|
process.exit(1);
|
|
@@ -1494,7 +1606,7 @@ var PeprModule = class {
|
|
|
1494
1606
|
};
|
|
1495
1607
|
|
|
1496
1608
|
// src/lib/storage.ts
|
|
1497
|
-
var
|
|
1609
|
+
var import_ramda6 = require("ramda");
|
|
1498
1610
|
var import_json_pointer = __toESM(require("json-pointer"));
|
|
1499
1611
|
var MAX_WAIT_TIME = 15e3;
|
|
1500
1612
|
var STORE_VERSION_PREFIX = "v2";
|
|
@@ -1514,11 +1626,10 @@ var Storage = class {
|
|
|
1514
1626
|
this.#send = send;
|
|
1515
1627
|
};
|
|
1516
1628
|
receive = (data) => {
|
|
1517
|
-
logger_default.debug(data, `Pepr store data received`);
|
|
1518
1629
|
this.#store = data || {};
|
|
1519
1630
|
this.#onReady();
|
|
1520
1631
|
for (const idx in this.#subscribers) {
|
|
1521
|
-
this.#subscribers[idx]((0,
|
|
1632
|
+
this.#subscribers[idx]((0, import_ramda6.clone)(this.#store));
|
|
1522
1633
|
}
|
|
1523
1634
|
};
|
|
1524
1635
|
getItem = (key) => {
|
|
@@ -1529,7 +1640,7 @@ var Storage = class {
|
|
|
1529
1640
|
return null;
|
|
1530
1641
|
};
|
|
1531
1642
|
clear = () => {
|
|
1532
|
-
this.#dispatchUpdate(
|
|
1643
|
+
Object.keys(this.#store).length > 0 && this.#dispatchUpdate(
|
|
1533
1644
|
"remove",
|
|
1534
1645
|
Object.keys(this.#store).map((key) => import_json_pointer.default.escape(key))
|
|
1535
1646
|
);
|
|
@@ -1602,7 +1713,7 @@ var Storage = class {
|
|
|
1602
1713
|
};
|
|
1603
1714
|
#onReady = () => {
|
|
1604
1715
|
for (const handler of this.#readyHandlers) {
|
|
1605
|
-
handler((0,
|
|
1716
|
+
handler((0, import_ramda6.clone)(this.#store));
|
|
1606
1717
|
}
|
|
1607
1718
|
this.#onReady = () => {
|
|
1608
1719
|
};
|
|
@@ -1782,6 +1893,9 @@ var Capability = class {
|
|
|
1782
1893
|
});
|
|
1783
1894
|
}
|
|
1784
1895
|
};
|
|
1896
|
+
getScheduleStore() {
|
|
1897
|
+
return this.#scheduleStore;
|
|
1898
|
+
}
|
|
1785
1899
|
/**
|
|
1786
1900
|
* Store is a key-value data store that can be used to persist data that should be shared
|
|
1787
1901
|
* between requests. Each capability has its own store, and the data is persisted in Kubernetes
|
|
@@ -1876,7 +1990,7 @@ var Capability = class {
|
|
|
1876
1990
|
* @returns
|
|
1877
1991
|
*/
|
|
1878
1992
|
When = (model, kind4) => {
|
|
1879
|
-
const matchedKind = (0,
|
|
1993
|
+
const matchedKind = (0, import_kubernetes_fluent_client7.modelToGroupVersionKind)(model.name);
|
|
1880
1994
|
if (!matchedKind && !kind4) {
|
|
1881
1995
|
throw new Error(`Kind not specified for ${model.name}`);
|
|
1882
1996
|
}
|
|
@@ -1888,6 +2002,8 @@ var Capability = class {
|
|
|
1888
2002
|
filters: {
|
|
1889
2003
|
name: "",
|
|
1890
2004
|
namespaces: [],
|
|
2005
|
+
regexNamespaces: [],
|
|
2006
|
+
regexName: "",
|
|
1891
2007
|
labels: {},
|
|
1892
2008
|
annotations: {},
|
|
1893
2009
|
deletionTimestamp: false
|
|
@@ -1895,10 +2011,10 @@ var Capability = class {
|
|
|
1895
2011
|
};
|
|
1896
2012
|
const bindings = this.#bindings;
|
|
1897
2013
|
const prefix = `${this.#name}: ${model.name}`;
|
|
1898
|
-
const commonChain = { WithLabel, WithAnnotation, WithDeletionTimestamp, Mutate, Validate, Watch, Reconcile };
|
|
2014
|
+
const commonChain = { WithLabel, WithAnnotation, WithDeletionTimestamp, Mutate, Validate, Watch, Reconcile, Alias };
|
|
1899
2015
|
const isNotEmpty = (value) => Object.keys(value).length > 0;
|
|
1900
2016
|
const log = (message, cbString) => {
|
|
1901
|
-
const filteredObj = (0,
|
|
2017
|
+
const filteredObj = (0, import_ramda7.pickBy)(isNotEmpty, binding.filters);
|
|
1902
2018
|
logger_default.info(`${message} configured for ${binding.event}`, prefix);
|
|
1903
2019
|
logger_default.info(filteredObj, prefix);
|
|
1904
2020
|
logger_default.debug(cbString, prefix);
|
|
@@ -1906,10 +2022,14 @@ var Capability = class {
|
|
|
1906
2022
|
function Validate(validateCallback) {
|
|
1907
2023
|
if (registerAdmission) {
|
|
1908
2024
|
log("Validate Action", validateCallback.toString());
|
|
2025
|
+
const aliasLogger = logger_default.child({ alias: binding.alias || "no alias provided" });
|
|
1909
2026
|
bindings.push({
|
|
1910
2027
|
...binding,
|
|
1911
2028
|
isValidate: true,
|
|
1912
|
-
validateCallback
|
|
2029
|
+
validateCallback: async (req, logger = aliasLogger) => {
|
|
2030
|
+
logger_default.info(`Executing validate action with alias: ${binding.alias || "no alias provided"}`);
|
|
2031
|
+
return await validateCallback(req, logger);
|
|
2032
|
+
}
|
|
1913
2033
|
});
|
|
1914
2034
|
}
|
|
1915
2035
|
return { Watch, Reconcile };
|
|
@@ -1917,10 +2037,14 @@ var Capability = class {
|
|
|
1917
2037
|
function Mutate(mutateCallback) {
|
|
1918
2038
|
if (registerAdmission) {
|
|
1919
2039
|
log("Mutate Action", mutateCallback.toString());
|
|
2040
|
+
const aliasLogger = logger_default.child({ alias: binding.alias || "no alias provided" });
|
|
1920
2041
|
bindings.push({
|
|
1921
2042
|
...binding,
|
|
1922
2043
|
isMutate: true,
|
|
1923
|
-
mutateCallback
|
|
2044
|
+
mutateCallback: async (req, logger = aliasLogger) => {
|
|
2045
|
+
logger_default.info(`Executing mutation action with alias: ${binding.alias || "no alias provided"}`);
|
|
2046
|
+
await mutateCallback(req, logger);
|
|
2047
|
+
}
|
|
1924
2048
|
});
|
|
1925
2049
|
}
|
|
1926
2050
|
return { Watch, Validate, Reconcile };
|
|
@@ -1928,34 +2052,81 @@ var Capability = class {
|
|
|
1928
2052
|
function Watch(watchCallback) {
|
|
1929
2053
|
if (registerWatch) {
|
|
1930
2054
|
log("Watch Action", watchCallback.toString());
|
|
2055
|
+
const aliasLogger = logger_default.child({ alias: binding.alias || "no alias provided" });
|
|
1931
2056
|
bindings.push({
|
|
1932
2057
|
...binding,
|
|
1933
2058
|
isWatch: true,
|
|
1934
|
-
watchCallback
|
|
2059
|
+
watchCallback: async (update, phase, logger = aliasLogger) => {
|
|
2060
|
+
logger_default.info(`Executing watch action with alias: ${binding.alias || "no alias provided"}`);
|
|
2061
|
+
await watchCallback(update, phase, logger);
|
|
2062
|
+
}
|
|
1935
2063
|
});
|
|
1936
2064
|
}
|
|
2065
|
+
return { Finalize };
|
|
1937
2066
|
}
|
|
1938
|
-
function Reconcile(
|
|
2067
|
+
function Reconcile(reconcileCallback) {
|
|
1939
2068
|
if (registerWatch) {
|
|
1940
|
-
log("Reconcile Action",
|
|
2069
|
+
log("Reconcile Action", reconcileCallback.toString());
|
|
2070
|
+
const aliasLogger = logger_default.child({ alias: binding.alias || "no alias provided" });
|
|
1941
2071
|
bindings.push({
|
|
1942
2072
|
...binding,
|
|
1943
2073
|
isWatch: true,
|
|
1944
2074
|
isQueue: true,
|
|
1945
|
-
watchCallback
|
|
2075
|
+
watchCallback: async (update, phase, logger = aliasLogger) => {
|
|
2076
|
+
logger_default.info(`Executing reconcile action with alias: ${binding.alias || "no alias provided"}`);
|
|
2077
|
+
await reconcileCallback(update, phase, logger);
|
|
2078
|
+
}
|
|
1946
2079
|
});
|
|
1947
2080
|
}
|
|
2081
|
+
return { Finalize };
|
|
2082
|
+
}
|
|
2083
|
+
function Finalize(finalizeCallback) {
|
|
2084
|
+
log("Finalize Action", finalizeCallback.toString());
|
|
2085
|
+
const aliasLogger = logger_default.child({ alias: binding.alias || "no alias provided" });
|
|
2086
|
+
if (registerAdmission) {
|
|
2087
|
+
const mutateBinding = {
|
|
2088
|
+
...binding,
|
|
2089
|
+
isMutate: true,
|
|
2090
|
+
isFinalize: true,
|
|
2091
|
+
event: "*" /* Any */,
|
|
2092
|
+
mutateCallback: addFinalizer
|
|
2093
|
+
};
|
|
2094
|
+
bindings.push(mutateBinding);
|
|
2095
|
+
}
|
|
2096
|
+
if (registerWatch) {
|
|
2097
|
+
const watchBinding = {
|
|
2098
|
+
...binding,
|
|
2099
|
+
isWatch: true,
|
|
2100
|
+
isFinalize: true,
|
|
2101
|
+
event: "UPDATE" /* Update */,
|
|
2102
|
+
finalizeCallback: async (update, logger = aliasLogger) => {
|
|
2103
|
+
logger_default.info(`Executing finalize action with alias: ${binding.alias || "no alias provided"}`);
|
|
2104
|
+
await finalizeCallback(update, logger);
|
|
2105
|
+
}
|
|
2106
|
+
};
|
|
2107
|
+
bindings.push(watchBinding);
|
|
2108
|
+
}
|
|
1948
2109
|
}
|
|
1949
2110
|
function InNamespace(...namespaces) {
|
|
1950
2111
|
logger_default.debug(`Add namespaces filter ${namespaces}`, prefix);
|
|
1951
2112
|
binding.filters.namespaces.push(...namespaces);
|
|
1952
|
-
return { ...commonChain, WithName };
|
|
2113
|
+
return { ...commonChain, WithName, WithNameRegex };
|
|
2114
|
+
}
|
|
2115
|
+
function InNamespaceRegex(...namespaces) {
|
|
2116
|
+
logger_default.debug(`Add regex namespaces filter ${namespaces}`, prefix);
|
|
2117
|
+
binding.filters.regexNamespaces.push(...namespaces.map((regex) => regex.source));
|
|
2118
|
+
return { ...commonChain, WithName, WithNameRegex };
|
|
1953
2119
|
}
|
|
1954
2120
|
function WithDeletionTimestamp() {
|
|
1955
2121
|
logger_default.debug("Add deletionTimestamp filter");
|
|
1956
2122
|
binding.filters.deletionTimestamp = true;
|
|
1957
2123
|
return commonChain;
|
|
1958
2124
|
}
|
|
2125
|
+
function WithNameRegex(regexName) {
|
|
2126
|
+
logger_default.debug(`Add regex name filter ${regexName}`, prefix);
|
|
2127
|
+
binding.filters.regexName = regexName.source;
|
|
2128
|
+
return commonChain;
|
|
2129
|
+
}
|
|
1959
2130
|
function WithName(name) {
|
|
1960
2131
|
logger_default.debug(`Add name filter ${name}`, prefix);
|
|
1961
2132
|
binding.filters.name = name;
|
|
@@ -1971,13 +2142,21 @@ var Capability = class {
|
|
|
1971
2142
|
binding.filters.annotations[key] = value;
|
|
1972
2143
|
return commonChain;
|
|
1973
2144
|
}
|
|
2145
|
+
function Alias(alias) {
|
|
2146
|
+
logger_default.debug(`Adding prefix alias ${alias}`, prefix);
|
|
2147
|
+
binding.alias = alias;
|
|
2148
|
+
return commonChain;
|
|
2149
|
+
}
|
|
1974
2150
|
function bindEvent(event) {
|
|
1975
2151
|
binding.event = event;
|
|
1976
2152
|
return {
|
|
1977
2153
|
...commonChain,
|
|
1978
2154
|
InNamespace,
|
|
2155
|
+
InNamespaceRegex,
|
|
1979
2156
|
WithName,
|
|
1980
|
-
|
|
2157
|
+
WithNameRegex,
|
|
2158
|
+
WithDeletionTimestamp,
|
|
2159
|
+
Alias
|
|
1981
2160
|
};
|
|
1982
2161
|
}
|
|
1983
2162
|
return {
|