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.
- package/dist/cli/init/index.d.ts.map +1 -1
- package/dist/cli/init/templates.d.ts +3 -1
- 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.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/logger.d.ts +1 -1
- package/dist/lib/logger.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/queue.d.ts +19 -3
- package/dist/lib/queue.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 +118 -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 +8 -6
- package/dist/lib/watch-processor.d.ts.map +1 -1
- package/dist/lib.js +467 -233
- package/dist/lib.js.map +4 -4
- package/dist/sdk/sdk.d.ts +5 -3
- package/dist/sdk/sdk.d.ts.map +1 -1
- package/package.json +13 -11
- 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.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 +112 -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 +279 -9
- package/src/lib/filter.ts +46 -98
- package/src/lib/finalizer.test.ts +236 -0
- package/src/lib/finalizer.ts +63 -0
- package/src/lib/helpers.test.ts +359 -65
- package/src/lib/helpers.ts +141 -95
- 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/queue.test.ts +138 -44
- package/src/lib/queue.ts +48 -13
- package/src/lib/schedule.ts +1 -1
- package/src/lib/storage.ts +5 -6
- package/src/lib/types.ts +154 -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.test.ts +89 -124
- package/src/lib/watch-processor.ts +52 -35
- package/src/sdk/sdk.test.ts +46 -13
- package/src/sdk/sdk.ts +15 -6
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,84 +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(operation) && !binding.event.includes("*" /* Any */)) {
|
|
248
|
-
return true;
|
|
249
|
-
}
|
|
250
|
-
if (name && name !== req.name) {
|
|
251
|
-
return true;
|
|
252
|
-
}
|
|
253
|
-
if (kind4 !== req.kind.kind) {
|
|
254
|
-
return true;
|
|
255
|
-
}
|
|
256
|
-
if (group && group !== req.kind.group) {
|
|
257
|
-
return true;
|
|
258
|
-
}
|
|
259
|
-
if (version && version !== req.kind.version) {
|
|
260
|
-
return true;
|
|
261
|
-
}
|
|
262
|
-
if (combinedNamespaces.length && !combinedNamespaces.includes(req.namespace || "") || !namespaces.includes(req.namespace || "") && capabilityNamespaces.length !== 0 && namespaces.length !== 0) {
|
|
263
|
-
let type = "";
|
|
264
|
-
let label = "";
|
|
265
|
-
if (binding.isMutate) {
|
|
266
|
-
type = "Mutate";
|
|
267
|
-
label = binding.mutateCallback.name;
|
|
268
|
-
} else if (binding.isValidate) {
|
|
269
|
-
type = "Validate";
|
|
270
|
-
label = binding.validateCallback.name;
|
|
271
|
-
} else if (binding.isWatch) {
|
|
272
|
-
type = "Watch";
|
|
273
|
-
label = binding.watchCallback.name;
|
|
274
|
-
}
|
|
275
|
-
logger_default.debug({ uid }, `${type} binding (${label}) does not match request namespace "${req.namespace}"`);
|
|
276
|
-
return true;
|
|
277
|
-
}
|
|
278
|
-
for (const [key, value] of Object.entries(labels)) {
|
|
279
|
-
const testKey = metadata?.labels?.[key];
|
|
280
|
-
if (!testKey) {
|
|
281
|
-
logger_default.debug({ uid }, `Label ${key} does not exist`);
|
|
282
|
-
return true;
|
|
283
|
-
}
|
|
284
|
-
if (value && testKey !== value) {
|
|
285
|
-
logger_default.debug({ uid }, `${testKey} does not match ${value}`);
|
|
286
|
-
return true;
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
for (const [key, value] of Object.entries(annotations)) {
|
|
290
|
-
const testKey = metadata?.annotations?.[key];
|
|
291
|
-
if (!testKey) {
|
|
292
|
-
logger_default.debug({ uid }, `Annotation ${key} does not exist`);
|
|
293
|
-
return true;
|
|
294
|
-
}
|
|
295
|
-
if (value && testKey !== value) {
|
|
296
|
-
logger_default.debug({ uid }, `${testKey} does not match ${value}`);
|
|
297
|
-
return true;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
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;
|
|
301
368
|
}
|
|
302
369
|
|
|
303
370
|
// src/lib/mutate-request.ts
|
|
304
|
-
var
|
|
371
|
+
var import_ramda2 = require("ramda");
|
|
305
372
|
var PeprMutateRequest = class {
|
|
306
373
|
Raw;
|
|
307
374
|
#input;
|
|
@@ -336,9 +403,9 @@ var PeprMutateRequest = class {
|
|
|
336
403
|
constructor(input) {
|
|
337
404
|
this.#input = input;
|
|
338
405
|
if (input.operation.toUpperCase() === "DELETE" /* DELETE */) {
|
|
339
|
-
this.Raw = (0,
|
|
406
|
+
this.Raw = (0, import_ramda2.clone)(input.oldObject);
|
|
340
407
|
} else {
|
|
341
|
-
this.Raw = (0,
|
|
408
|
+
this.Raw = (0, import_ramda2.clone)(input.object);
|
|
342
409
|
}
|
|
343
410
|
if (!this.Raw) {
|
|
344
411
|
throw new Error("unable to load the request object into PeprRequest.RawP");
|
|
@@ -350,7 +417,7 @@ var PeprMutateRequest = class {
|
|
|
350
417
|
* @param obj - The object to merge with the current resource.
|
|
351
418
|
*/
|
|
352
419
|
Merge = (obj) => {
|
|
353
|
-
this.Raw = (0,
|
|
420
|
+
this.Raw = (0, import_ramda2.mergeDeepRight)(this.Raw, obj);
|
|
354
421
|
};
|
|
355
422
|
/**
|
|
356
423
|
* Updates a label on the Kubernetes resource.
|
|
@@ -483,7 +550,7 @@ async function mutateProcessor(config, capabilities, req, reqMetadata) {
|
|
|
483
550
|
if (!action.mutateCallback) {
|
|
484
551
|
continue;
|
|
485
552
|
}
|
|
486
|
-
if (shouldSkipRequest(action, req, namespaces)) {
|
|
553
|
+
if (shouldSkipRequest(action, req, namespaces, config?.alwaysIgnore?.namespaces)) {
|
|
487
554
|
continue;
|
|
488
555
|
}
|
|
489
556
|
const label = action.mutateCallback.name;
|
|
@@ -556,7 +623,7 @@ async function mutateProcessor(config, capabilities, req, reqMetadata) {
|
|
|
556
623
|
}
|
|
557
624
|
|
|
558
625
|
// src/lib/validate-request.ts
|
|
559
|
-
var
|
|
626
|
+
var import_ramda3 = require("ramda");
|
|
560
627
|
var PeprValidateRequest = class {
|
|
561
628
|
Raw;
|
|
562
629
|
#input;
|
|
@@ -581,9 +648,9 @@ var PeprValidateRequest = class {
|
|
|
581
648
|
constructor(input) {
|
|
582
649
|
this.#input = input;
|
|
583
650
|
if (input.operation.toUpperCase() === "DELETE" /* DELETE */) {
|
|
584
|
-
this.Raw = (0,
|
|
651
|
+
this.Raw = (0, import_ramda3.clone)(input.oldObject);
|
|
585
652
|
} else {
|
|
586
|
-
this.Raw = (0,
|
|
653
|
+
this.Raw = (0, import_ramda3.clone)(input.object);
|
|
587
654
|
}
|
|
588
655
|
if (!this.Raw) {
|
|
589
656
|
throw new Error("unable to load the request object into PeprRequest.Raw");
|
|
@@ -634,7 +701,7 @@ var PeprValidateRequest = class {
|
|
|
634
701
|
};
|
|
635
702
|
|
|
636
703
|
// src/lib/validate-processor.ts
|
|
637
|
-
async function validateProcessor(capabilities, req, reqMetadata) {
|
|
704
|
+
async function validateProcessor(config, capabilities, req, reqMetadata) {
|
|
638
705
|
const wrapped = new PeprValidateRequest(req);
|
|
639
706
|
const response = [];
|
|
640
707
|
const isSecret = req.kind.version == "v1" && req.kind.kind == "Secret";
|
|
@@ -653,7 +720,7 @@ async function validateProcessor(capabilities, req, reqMetadata) {
|
|
|
653
720
|
allowed: true
|
|
654
721
|
// Assume it's allowed until a validation check fails
|
|
655
722
|
};
|
|
656
|
-
if (shouldSkipRequest(action, req, namespaces)) {
|
|
723
|
+
if (shouldSkipRequest(action, req, namespaces, config?.alwaysIgnore?.namespaces)) {
|
|
657
724
|
continue;
|
|
658
725
|
}
|
|
659
726
|
const label = action.validateCallback.name;
|
|
@@ -685,7 +752,21 @@ async function validateProcessor(capabilities, req, reqMetadata) {
|
|
|
685
752
|
|
|
686
753
|
// src/lib/controller/store.ts
|
|
687
754
|
var import_kubernetes_fluent_client2 = require("kubernetes-fluent-client");
|
|
688
|
-
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**";
|
|
689
770
|
var namespace = "pepr-system";
|
|
690
771
|
var debounceBackoff = 5e3;
|
|
691
772
|
var PeprControllerStore = class {
|
|
@@ -722,7 +803,7 @@ var PeprControllerStore = class {
|
|
|
722
803
|
watcher.start().catch((e) => logger_default.error(e, "Error starting Pepr store watch"));
|
|
723
804
|
};
|
|
724
805
|
#migrateAndSetupWatch = async (store) => {
|
|
725
|
-
logger_default.debug(store, "Pepr Store migration");
|
|
806
|
+
logger_default.debug(redactedStore(store), "Pepr Store migration");
|
|
726
807
|
const data = store.data || {};
|
|
727
808
|
const migrateCache = {};
|
|
728
809
|
const flushCache = async () => {
|
|
@@ -732,7 +813,9 @@ var PeprControllerStore = class {
|
|
|
732
813
|
delete migrateCache[idx];
|
|
733
814
|
}
|
|
734
815
|
try {
|
|
735
|
-
|
|
816
|
+
if (payload.length > 0) {
|
|
817
|
+
await (0, import_kubernetes_fluent_client2.K8s)(PeprStore, { namespace, name: this.#name }).Patch(payload);
|
|
818
|
+
}
|
|
736
819
|
} catch (err) {
|
|
737
820
|
logger_default.error(err, "Pepr store update failure");
|
|
738
821
|
if (err.status === 422) {
|
|
@@ -768,7 +851,7 @@ var PeprControllerStore = class {
|
|
|
768
851
|
for (const name of Object.keys(this.#stores)) {
|
|
769
852
|
const offset = `${name}-`.length;
|
|
770
853
|
for (const key of Object.keys(data)) {
|
|
771
|
-
if ((0,
|
|
854
|
+
if ((0, import_ramda4.startsWith)(name, key) && !(0, import_ramda4.startsWith)(`${name}-v2`, key)) {
|
|
772
855
|
fillCache(name, "remove", [key.slice(offset)], data[key]);
|
|
773
856
|
fillCache(name, "add", [key.slice(offset)], data[key]);
|
|
774
857
|
}
|
|
@@ -778,14 +861,14 @@ var PeprControllerStore = class {
|
|
|
778
861
|
this.#setupWatch();
|
|
779
862
|
};
|
|
780
863
|
#receive = (store) => {
|
|
781
|
-
logger_default.debug(store, "Pepr Store update");
|
|
864
|
+
logger_default.debug(redactedStore(store), "Pepr Store update");
|
|
782
865
|
const debounced = () => {
|
|
783
866
|
const data = store.data || {};
|
|
784
867
|
for (const name of Object.keys(this.#stores)) {
|
|
785
868
|
const offset = `${name}-`.length;
|
|
786
869
|
const filtered = {};
|
|
787
870
|
for (const key of Object.keys(data)) {
|
|
788
|
-
if ((0,
|
|
871
|
+
if ((0, import_ramda4.startsWith)(name, key)) {
|
|
789
872
|
filtered[key.slice(offset)] = data[key];
|
|
790
873
|
}
|
|
791
874
|
}
|
|
@@ -829,7 +912,9 @@ var PeprControllerStore = class {
|
|
|
829
912
|
delete sendCache[idx];
|
|
830
913
|
}
|
|
831
914
|
try {
|
|
832
|
-
|
|
915
|
+
if (payload.length > 0) {
|
|
916
|
+
await (0, import_kubernetes_fluent_client2.K8s)(PeprStore, { namespace, name: this.#name }).Patch(payload);
|
|
917
|
+
}
|
|
833
918
|
} catch (err) {
|
|
834
919
|
logger_default.error(err, "Pepr store update failure");
|
|
835
920
|
if (err.status === 422) {
|
|
@@ -846,7 +931,7 @@ var PeprControllerStore = class {
|
|
|
846
931
|
};
|
|
847
932
|
setInterval(() => {
|
|
848
933
|
if (Object.keys(sendCache).length > 0) {
|
|
849
|
-
logger_default.debug(sendCache, "Sending updates to Pepr store");
|
|
934
|
+
logger_default.debug(redactedPatch(sendCache), "Sending updates to Pepr store");
|
|
850
935
|
void flushCache();
|
|
851
936
|
}
|
|
852
937
|
}, debounceBackoff);
|
|
@@ -872,8 +957,38 @@ var PeprControllerStore = class {
|
|
|
872
957
|
}
|
|
873
958
|
};
|
|
874
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
|
+
}
|
|
875
987
|
|
|
876
988
|
// src/lib/controller/index.ts
|
|
989
|
+
if (!process.env.PEPR_NODE_WARNINGS) {
|
|
990
|
+
process.removeAllListeners("warning");
|
|
991
|
+
}
|
|
877
992
|
var Controller = class _Controller {
|
|
878
993
|
// Track whether the server is running
|
|
879
994
|
#running = false;
|
|
@@ -933,7 +1048,7 @@ var Controller = class _Controller {
|
|
|
933
1048
|
});
|
|
934
1049
|
server.on("error", (e) => {
|
|
935
1050
|
if (e.code === "EADDRINUSE") {
|
|
936
|
-
logger_default.
|
|
1051
|
+
logger_default.info(
|
|
937
1052
|
`Address in use, retrying in 2 seconds. If this persists, ensure ${port} is not in use, e.g. "lsof -i :${port}"`
|
|
938
1053
|
);
|
|
939
1054
|
setTimeout(() => {
|
|
@@ -972,7 +1087,7 @@ var Controller = class _Controller {
|
|
|
972
1087
|
const { token } = req.params;
|
|
973
1088
|
if (token !== this.#token) {
|
|
974
1089
|
const err = `Unauthorized: invalid token '${token.replace(/[^\w]/g, "_")}'`;
|
|
975
|
-
logger_default.
|
|
1090
|
+
logger_default.info(err);
|
|
976
1091
|
res.status(401).send(err);
|
|
977
1092
|
this.#metricsCollector.alert();
|
|
978
1093
|
return;
|
|
@@ -1019,7 +1134,7 @@ var Controller = class _Controller {
|
|
|
1019
1134
|
if (admissionKind === "Mutate") {
|
|
1020
1135
|
response = await mutateProcessor(this.#config, this.#capabilities, request, reqMetadata);
|
|
1021
1136
|
} else {
|
|
1022
|
-
response = await validateProcessor(this.#capabilities, request, reqMetadata);
|
|
1137
|
+
response = await validateProcessor(this.#config, this.#capabilities, request, reqMetadata);
|
|
1023
1138
|
}
|
|
1024
1139
|
const responseList = Array.isArray(response) ? response : [response];
|
|
1025
1140
|
responseList.map((res2) => {
|
|
@@ -1080,7 +1195,7 @@ var Controller = class _Controller {
|
|
|
1080
1195
|
status: res.statusCode,
|
|
1081
1196
|
duration: `${elapsedTime} ms`
|
|
1082
1197
|
};
|
|
1083
|
-
|
|
1198
|
+
logger_default.info(message);
|
|
1084
1199
|
});
|
|
1085
1200
|
next();
|
|
1086
1201
|
}
|
|
@@ -1101,8 +1216,8 @@ var Controller = class _Controller {
|
|
|
1101
1216
|
};
|
|
1102
1217
|
|
|
1103
1218
|
// src/lib/watch-processor.ts
|
|
1104
|
-
var
|
|
1105
|
-
var
|
|
1219
|
+
var import_kubernetes_fluent_client6 = require("kubernetes-fluent-client");
|
|
1220
|
+
var import_types6 = require("kubernetes-fluent-client/dist/fluent/types");
|
|
1106
1221
|
|
|
1107
1222
|
// src/lib/helpers.ts
|
|
1108
1223
|
var import_kubernetes_fluent_client4 = require("kubernetes-fluent-client");
|
|
@@ -1154,14 +1269,17 @@ async function writeEvent(cr, event, eventType, eventReason, reportingComponent,
|
|
|
1154
1269
|
reportingInstance
|
|
1155
1270
|
});
|
|
1156
1271
|
}
|
|
1157
|
-
function getOwnerRefFrom(
|
|
1158
|
-
const {
|
|
1272
|
+
function getOwnerRefFrom(customResource, blockOwnerDeletion, controller) {
|
|
1273
|
+
const { apiVersion, kind: kind4, metadata } = customResource;
|
|
1274
|
+
const { name, uid } = metadata;
|
|
1159
1275
|
return [
|
|
1160
1276
|
{
|
|
1161
|
-
apiVersion
|
|
1162
|
-
kind:
|
|
1277
|
+
apiVersion,
|
|
1278
|
+
kind: kind4,
|
|
1163
1279
|
uid,
|
|
1164
|
-
name
|
|
1280
|
+
name,
|
|
1281
|
+
...blockOwnerDeletion !== void 0 && { blockOwnerDeletion },
|
|
1282
|
+
...controller !== void 0 && { controller }
|
|
1165
1283
|
}
|
|
1166
1284
|
];
|
|
1167
1285
|
}
|
|
@@ -1170,80 +1288,97 @@ function sanitizeResourceName(name) {
|
|
|
1170
1288
|
}
|
|
1171
1289
|
|
|
1172
1290
|
// src/lib/helpers.ts
|
|
1173
|
-
function
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
}
|
|
1177
|
-
let matchCount = 0;
|
|
1178
|
-
for (const key in bindingFilters) {
|
|
1179
|
-
if (Object.prototype.hasOwnProperty.call(objectFilters, key)) {
|
|
1180
|
-
const val1 = bindingFilters[key];
|
|
1181
|
-
const val2 = objectFilters[key];
|
|
1182
|
-
if (val1 === "" && key in objectFilters) {
|
|
1183
|
-
matchCount++;
|
|
1184
|
-
} else if (val1 !== "" && val1 === val2) {
|
|
1185
|
-
matchCount++;
|
|
1186
|
-
}
|
|
1187
|
-
}
|
|
1188
|
-
}
|
|
1189
|
-
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)}'.` : "";
|
|
1190
1294
|
}
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
if (
|
|
1196
|
-
|
|
1197
|
-
return `Ignoring Watch Callback: No overlap between binding and object labels. Binding labels ${JSON.stringify(
|
|
1198
|
-
binding.filters.labels
|
|
1199
|
-
)}, Object Labels ${JSON.stringify(obj.metadata.labels)}.`;
|
|
1200
|
-
}
|
|
1201
|
-
if (obj.metadata.annotations && !checkOverlap(binding.filters.annotations, obj.metadata.annotations)) {
|
|
1202
|
-
return `Ignoring Watch Callback: No overlap between binding and object annotations. Binding annotations ${JSON.stringify(
|
|
1203
|
-
binding.filters.annotations
|
|
1204
|
-
)}, Object annotations ${JSON.stringify(obj.metadata.annotations)}.`;
|
|
1205
|
-
}
|
|
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;
|
|
1206
1301
|
}
|
|
1207
|
-
if (
|
|
1208
|
-
return
|
|
1209
|
-
", "
|
|
1210
|
-
)}, Object namespace: ${obj.metadata.namespace}.`;
|
|
1302
|
+
if (request.Request.operation === "UPDATE" /* UPDATE */ && request.Raw.metadata?.deletionTimestamp) {
|
|
1303
|
+
return;
|
|
1211
1304
|
}
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1305
|
+
const peprFinal = "pepr.dev/finalizer";
|
|
1306
|
+
const finalizers = request.Raw.metadata?.finalizers || [];
|
|
1307
|
+
if (!finalizers.includes(peprFinal)) {
|
|
1308
|
+
finalizers.push(peprFinal);
|
|
1216
1309
|
}
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
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
|
+
}
|
|
1221
1326
|
}
|
|
1222
|
-
|
|
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}'`);
|
|
1223
1336
|
}
|
|
1224
1337
|
|
|
1225
1338
|
// src/lib/queue.ts
|
|
1339
|
+
var import_node_crypto = require("node:crypto");
|
|
1226
1340
|
var Queue = class {
|
|
1341
|
+
#name;
|
|
1342
|
+
#uid;
|
|
1227
1343
|
#queue = [];
|
|
1228
1344
|
#pendingPromise = false;
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
this.#
|
|
1345
|
+
constructor(name) {
|
|
1346
|
+
this.#name = name;
|
|
1347
|
+
this.#uid = `${Date.now()}-${(0, import_node_crypto.randomBytes)(2).toString("hex")}`;
|
|
1232
1348
|
}
|
|
1233
|
-
|
|
1234
|
-
this.#
|
|
1349
|
+
label() {
|
|
1350
|
+
return { name: this.#name, uid: this.#uid };
|
|
1351
|
+
}
|
|
1352
|
+
stats() {
|
|
1353
|
+
return {
|
|
1354
|
+
queue: this.label(),
|
|
1355
|
+
stats: {
|
|
1356
|
+
length: this.#queue.length
|
|
1357
|
+
}
|
|
1358
|
+
};
|
|
1235
1359
|
}
|
|
1236
1360
|
/**
|
|
1237
1361
|
* Enqueue adds an item to the queue and returns a promise that resolves when the item is
|
|
1238
1362
|
* reconciled.
|
|
1239
1363
|
*
|
|
1240
1364
|
* @param item The object to reconcile
|
|
1365
|
+
* @param type The watch phase requested for reconcile
|
|
1366
|
+
* @param reconcile The callback to enqueue for reconcile
|
|
1241
1367
|
* @returns A promise that resolves when the object is reconciled
|
|
1242
1368
|
*/
|
|
1243
|
-
enqueue(item,
|
|
1244
|
-
|
|
1369
|
+
enqueue(item, phase, reconcile) {
|
|
1370
|
+
const note = {
|
|
1371
|
+
queue: this.label(),
|
|
1372
|
+
item: {
|
|
1373
|
+
name: item.metadata?.name,
|
|
1374
|
+
namespace: item.metadata?.namespace,
|
|
1375
|
+
resourceVersion: item.metadata?.resourceVersion
|
|
1376
|
+
}
|
|
1377
|
+
};
|
|
1378
|
+
logger_default.debug(note, "Enqueueing");
|
|
1245
1379
|
return new Promise((resolve, reject) => {
|
|
1246
|
-
this.#queue.push({ item,
|
|
1380
|
+
this.#queue.push({ item, phase, callback: reconcile, resolve, reject });
|
|
1381
|
+
logger_default.debug(this.stats(), "Queue stats - push");
|
|
1247
1382
|
return this.#dequeue();
|
|
1248
1383
|
});
|
|
1249
1384
|
}
|
|
@@ -1264,15 +1399,23 @@ var Queue = class {
|
|
|
1264
1399
|
}
|
|
1265
1400
|
try {
|
|
1266
1401
|
this.#pendingPromise = true;
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1402
|
+
const note = {
|
|
1403
|
+
queue: this.label(),
|
|
1404
|
+
item: {
|
|
1405
|
+
name: element.item.metadata?.name,
|
|
1406
|
+
namespace: element.item.metadata?.namespace,
|
|
1407
|
+
resourceVersion: element.item.metadata?.resourceVersion
|
|
1408
|
+
}
|
|
1409
|
+
};
|
|
1410
|
+
logger_default.debug(note, "Reconciling");
|
|
1411
|
+
await element.callback(element.item, element.phase);
|
|
1412
|
+
logger_default.debug(note, "Reconciled");
|
|
1271
1413
|
element.resolve();
|
|
1272
1414
|
} catch (e) {
|
|
1273
1415
|
logger_default.debug(`Error reconciling ${element.item.metadata.name}`, { error: e });
|
|
1274
1416
|
element.reject(e);
|
|
1275
1417
|
} finally {
|
|
1418
|
+
logger_default.debug(this.stats(), "Queue stats - shift");
|
|
1276
1419
|
logger_default.debug("Resetting pending promise and dequeuing");
|
|
1277
1420
|
this.#pendingPromise = false;
|
|
1278
1421
|
await this.#dequeue();
|
|
@@ -1281,16 +1424,29 @@ var Queue = class {
|
|
|
1281
1424
|
};
|
|
1282
1425
|
|
|
1283
1426
|
// src/lib/watch-processor.ts
|
|
1284
|
-
var
|
|
1285
|
-
function
|
|
1286
|
-
const options = ["
|
|
1287
|
-
const d3fault = "
|
|
1427
|
+
var queues = {};
|
|
1428
|
+
function queueKey(obj) {
|
|
1429
|
+
const options = ["kind", "kindNs", "kindNsName", "global"];
|
|
1430
|
+
const d3fault = "kind";
|
|
1288
1431
|
let strat = process.env.PEPR_RECONCILE_STRATEGY || d3fault;
|
|
1289
1432
|
strat = options.includes(strat) ? strat : d3fault;
|
|
1290
1433
|
const ns = obj.metadata?.namespace ?? "cluster-scoped";
|
|
1291
1434
|
const kind4 = obj.kind ?? "UnknownKind";
|
|
1292
1435
|
const name = obj.metadata?.name ?? "Unnamed";
|
|
1293
|
-
|
|
1436
|
+
const lookup = {
|
|
1437
|
+
kind: `${kind4}`,
|
|
1438
|
+
kindNs: `${kind4}/${ns}`,
|
|
1439
|
+
kindNsName: `${kind4}/${ns}/${name}`,
|
|
1440
|
+
global: "global"
|
|
1441
|
+
};
|
|
1442
|
+
return lookup[strat];
|
|
1443
|
+
}
|
|
1444
|
+
function getOrCreateQueue(obj) {
|
|
1445
|
+
const key = queueKey(obj);
|
|
1446
|
+
if (!queues[key]) {
|
|
1447
|
+
queues[key] = new Queue(key);
|
|
1448
|
+
}
|
|
1449
|
+
return queues[key];
|
|
1294
1450
|
}
|
|
1295
1451
|
var watchCfg = {
|
|
1296
1452
|
resyncFailureMax: process.env.PEPR_RESYNC_FAILURE_MAX ? parseInt(process.env.PEPR_RESYNC_FAILURE_MAX, 10) : 5,
|
|
@@ -1299,26 +1455,37 @@ var watchCfg = {
|
|
|
1299
1455
|
relistIntervalSec: process.env.PEPR_RELIST_INTERVAL_SECONDS ? parseInt(process.env.PEPR_RELIST_INTERVAL_SECONDS, 10) : 600
|
|
1300
1456
|
};
|
|
1301
1457
|
var eventToPhaseMap = {
|
|
1302
|
-
["CREATE" /* Create */]: [
|
|
1303
|
-
["UPDATE" /* Update */]: [
|
|
1304
|
-
["CREATEORUPDATE" /* CreateOrUpdate */]: [
|
|
1305
|
-
["DELETE" /* Delete */]: [
|
|
1306
|
-
["*" /* 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]
|
|
1307
1463
|
};
|
|
1308
|
-
function setupWatch(capabilities) {
|
|
1464
|
+
function setupWatch(capabilities, ignoredNamespaces) {
|
|
1309
1465
|
capabilities.map(
|
|
1310
|
-
(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))
|
|
1311
1467
|
);
|
|
1312
1468
|
}
|
|
1313
|
-
async function runBinding(binding, capabilityNamespaces) {
|
|
1469
|
+
async function runBinding(binding, capabilityNamespaces, ignoredNamespaces) {
|
|
1314
1470
|
const phaseMatch = eventToPhaseMap[binding.event] || eventToPhaseMap["*" /* Any */];
|
|
1315
1471
|
logger_default.debug({ watchCfg }, "Effective WatchConfig");
|
|
1316
|
-
const watchCallback = async (obj,
|
|
1317
|
-
if (phaseMatch.includes(
|
|
1472
|
+
const watchCallback = async (obj, phase) => {
|
|
1473
|
+
if (phaseMatch.includes(phase)) {
|
|
1318
1474
|
try {
|
|
1319
|
-
const filterMatch = filterNoMatchReason(binding, obj, capabilityNamespaces);
|
|
1475
|
+
const filterMatch = filterNoMatchReason(binding, obj, capabilityNamespaces, ignoredNamespaces);
|
|
1320
1476
|
if (filterMatch === "") {
|
|
1321
|
-
|
|
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
|
+
}
|
|
1322
1489
|
} else {
|
|
1323
1490
|
logger_default.debug(filterMatch);
|
|
1324
1491
|
}
|
|
@@ -1327,46 +1494,39 @@ async function runBinding(binding, capabilityNamespaces) {
|
|
|
1327
1494
|
}
|
|
1328
1495
|
}
|
|
1329
1496
|
};
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
queueRecord[key] = new Queue();
|
|
1333
|
-
queueRecord[key].setReconcile(watchCallback);
|
|
1334
|
-
}
|
|
1335
|
-
return queueRecord[key];
|
|
1336
|
-
}
|
|
1337
|
-
const watcher = (0, import_kubernetes_fluent_client5.K8s)(binding.model, binding.filters).Watch(async (obj, type) => {
|
|
1338
|
-
logger_default.debug(obj, `Watch event ${type} received`);
|
|
1339
|
-
const queue = getOrCreateQueue(queueRecordKey(obj));
|
|
1497
|
+
const watcher = (0, import_kubernetes_fluent_client6.K8s)(binding.model, binding.filters).Watch(async (obj, phase) => {
|
|
1498
|
+
logger_default.debug(obj, `Watch event ${phase} received`);
|
|
1340
1499
|
if (binding.isQueue) {
|
|
1341
|
-
|
|
1500
|
+
const queue = getOrCreateQueue(obj);
|
|
1501
|
+
await queue.enqueue(obj, phase, watchCallback);
|
|
1342
1502
|
} else {
|
|
1343
|
-
await watchCallback(obj,
|
|
1503
|
+
await watchCallback(obj, phase);
|
|
1344
1504
|
}
|
|
1345
1505
|
}, watchCfg);
|
|
1346
|
-
watcher.events.on(
|
|
1506
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.GIVE_UP, (err) => {
|
|
1347
1507
|
logger_default.error(err, "Watch failed after 5 attempts, giving up");
|
|
1348
1508
|
process.exit(1);
|
|
1349
1509
|
});
|
|
1350
|
-
watcher.events.on(
|
|
1351
|
-
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));
|
|
1352
1512
|
watcher.events.on(
|
|
1353
|
-
|
|
1354
|
-
(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"}`)
|
|
1355
1515
|
);
|
|
1356
|
-
watcher.events.on(
|
|
1357
|
-
watcher.events.on(
|
|
1358
|
-
watcher.events.on(
|
|
1359
|
-
watcher.events.on(
|
|
1360
|
-
watcher.events.on(
|
|
1361
|
-
watcher.events.on(
|
|
1362
|
-
watcher.events.on(
|
|
1363
|
-
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) => {
|
|
1364
1524
|
metricsCollector.incCacheMiss(windowName);
|
|
1365
1525
|
});
|
|
1366
|
-
watcher.events.on(
|
|
1526
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.INIT_CACHE_MISS, (windowName) => {
|
|
1367
1527
|
metricsCollector.initCacheMissWindow(windowName);
|
|
1368
1528
|
});
|
|
1369
|
-
watcher.events.on(
|
|
1529
|
+
watcher.events.on(import_kubernetes_fluent_client6.WatchEvent.INC_RESYNC_FAILURE_COUNT, (retryCount) => {
|
|
1370
1530
|
metricsCollector.incRetryCount(retryCount);
|
|
1371
1531
|
});
|
|
1372
1532
|
try {
|
|
@@ -1376,8 +1536,8 @@ async function runBinding(binding, capabilityNamespaces) {
|
|
|
1376
1536
|
process.exit(1);
|
|
1377
1537
|
}
|
|
1378
1538
|
}
|
|
1379
|
-
function logEvent(
|
|
1380
|
-
const logMessage = `Watch event ${
|
|
1539
|
+
function logEvent(event, message = "", obj) {
|
|
1540
|
+
const logMessage = `Watch event ${event} received${message ? `. ${message}.` : "."}`;
|
|
1381
1541
|
if (obj) {
|
|
1382
1542
|
logger_default.debug(obj, logMessage);
|
|
1383
1543
|
} else {
|
|
@@ -1399,7 +1559,7 @@ var PeprModule = class {
|
|
|
1399
1559
|
* @param opts Options for the Pepr runtime
|
|
1400
1560
|
*/
|
|
1401
1561
|
constructor({ description, pepr }, capabilities = [], opts = {}) {
|
|
1402
|
-
const config = (0,
|
|
1562
|
+
const config = (0, import_ramda5.clone)(pepr);
|
|
1403
1563
|
config.description = description;
|
|
1404
1564
|
ValidateError(config.onError);
|
|
1405
1565
|
if (isBuildMode()) {
|
|
@@ -1422,7 +1582,7 @@ var PeprModule = class {
|
|
|
1422
1582
|
this.#controller = new Controller(config, capabilities, opts.beforeHook, opts.afterHook, () => {
|
|
1423
1583
|
if (isWatchMode() || isDevMode()) {
|
|
1424
1584
|
try {
|
|
1425
|
-
setupWatch(capabilities);
|
|
1585
|
+
setupWatch(capabilities, pepr?.alwaysIgnore?.namespaces);
|
|
1426
1586
|
} catch (e) {
|
|
1427
1587
|
logger_default.error(e, "Error setting up watch");
|
|
1428
1588
|
process.exit(1);
|
|
@@ -1446,7 +1606,7 @@ var PeprModule = class {
|
|
|
1446
1606
|
};
|
|
1447
1607
|
|
|
1448
1608
|
// src/lib/storage.ts
|
|
1449
|
-
var
|
|
1609
|
+
var import_ramda6 = require("ramda");
|
|
1450
1610
|
var import_json_pointer = __toESM(require("json-pointer"));
|
|
1451
1611
|
var MAX_WAIT_TIME = 15e3;
|
|
1452
1612
|
var STORE_VERSION_PREFIX = "v2";
|
|
@@ -1466,11 +1626,10 @@ var Storage = class {
|
|
|
1466
1626
|
this.#send = send;
|
|
1467
1627
|
};
|
|
1468
1628
|
receive = (data) => {
|
|
1469
|
-
logger_default.debug(data, `Pepr store data received`);
|
|
1470
1629
|
this.#store = data || {};
|
|
1471
1630
|
this.#onReady();
|
|
1472
1631
|
for (const idx in this.#subscribers) {
|
|
1473
|
-
this.#subscribers[idx]((0,
|
|
1632
|
+
this.#subscribers[idx]((0, import_ramda6.clone)(this.#store));
|
|
1474
1633
|
}
|
|
1475
1634
|
};
|
|
1476
1635
|
getItem = (key) => {
|
|
@@ -1481,7 +1640,7 @@ var Storage = class {
|
|
|
1481
1640
|
return null;
|
|
1482
1641
|
};
|
|
1483
1642
|
clear = () => {
|
|
1484
|
-
this.#dispatchUpdate(
|
|
1643
|
+
Object.keys(this.#store).length > 0 && this.#dispatchUpdate(
|
|
1485
1644
|
"remove",
|
|
1486
1645
|
Object.keys(this.#store).map((key) => import_json_pointer.default.escape(key))
|
|
1487
1646
|
);
|
|
@@ -1554,7 +1713,7 @@ var Storage = class {
|
|
|
1554
1713
|
};
|
|
1555
1714
|
#onReady = () => {
|
|
1556
1715
|
for (const handler of this.#readyHandlers) {
|
|
1557
|
-
handler((0,
|
|
1716
|
+
handler((0, import_ramda6.clone)(this.#store));
|
|
1558
1717
|
}
|
|
1559
1718
|
this.#onReady = () => {
|
|
1560
1719
|
};
|
|
@@ -1734,6 +1893,9 @@ var Capability = class {
|
|
|
1734
1893
|
});
|
|
1735
1894
|
}
|
|
1736
1895
|
};
|
|
1896
|
+
getScheduleStore() {
|
|
1897
|
+
return this.#scheduleStore;
|
|
1898
|
+
}
|
|
1737
1899
|
/**
|
|
1738
1900
|
* Store is a key-value data store that can be used to persist data that should be shared
|
|
1739
1901
|
* between requests. Each capability has its own store, and the data is persisted in Kubernetes
|
|
@@ -1828,7 +1990,7 @@ var Capability = class {
|
|
|
1828
1990
|
* @returns
|
|
1829
1991
|
*/
|
|
1830
1992
|
When = (model, kind4) => {
|
|
1831
|
-
const matchedKind = (0,
|
|
1993
|
+
const matchedKind = (0, import_kubernetes_fluent_client7.modelToGroupVersionKind)(model.name);
|
|
1832
1994
|
if (!matchedKind && !kind4) {
|
|
1833
1995
|
throw new Error(`Kind not specified for ${model.name}`);
|
|
1834
1996
|
}
|
|
@@ -1840,16 +2002,19 @@ var Capability = class {
|
|
|
1840
2002
|
filters: {
|
|
1841
2003
|
name: "",
|
|
1842
2004
|
namespaces: [],
|
|
2005
|
+
regexNamespaces: [],
|
|
2006
|
+
regexName: "",
|
|
1843
2007
|
labels: {},
|
|
1844
|
-
annotations: {}
|
|
2008
|
+
annotations: {},
|
|
2009
|
+
deletionTimestamp: false
|
|
1845
2010
|
}
|
|
1846
2011
|
};
|
|
1847
2012
|
const bindings = this.#bindings;
|
|
1848
2013
|
const prefix = `${this.#name}: ${model.name}`;
|
|
1849
|
-
const commonChain = { WithLabel, WithAnnotation, Mutate, Validate, Watch, Reconcile };
|
|
2014
|
+
const commonChain = { WithLabel, WithAnnotation, WithDeletionTimestamp, Mutate, Validate, Watch, Reconcile, Alias };
|
|
1850
2015
|
const isNotEmpty = (value) => Object.keys(value).length > 0;
|
|
1851
2016
|
const log = (message, cbString) => {
|
|
1852
|
-
const filteredObj = (0,
|
|
2017
|
+
const filteredObj = (0, import_ramda7.pickBy)(isNotEmpty, binding.filters);
|
|
1853
2018
|
logger_default.info(`${message} configured for ${binding.event}`, prefix);
|
|
1854
2019
|
logger_default.info(filteredObj, prefix);
|
|
1855
2020
|
logger_default.debug(cbString, prefix);
|
|
@@ -1857,10 +2022,14 @@ var Capability = class {
|
|
|
1857
2022
|
function Validate(validateCallback) {
|
|
1858
2023
|
if (registerAdmission) {
|
|
1859
2024
|
log("Validate Action", validateCallback.toString());
|
|
2025
|
+
const aliasLogger = logger_default.child({ alias: binding.alias || "no alias provided" });
|
|
1860
2026
|
bindings.push({
|
|
1861
2027
|
...binding,
|
|
1862
2028
|
isValidate: true,
|
|
1863
|
-
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
|
+
}
|
|
1864
2033
|
});
|
|
1865
2034
|
}
|
|
1866
2035
|
return { Watch, Reconcile };
|
|
@@ -1868,10 +2037,14 @@ var Capability = class {
|
|
|
1868
2037
|
function Mutate(mutateCallback) {
|
|
1869
2038
|
if (registerAdmission) {
|
|
1870
2039
|
log("Mutate Action", mutateCallback.toString());
|
|
2040
|
+
const aliasLogger = logger_default.child({ alias: binding.alias || "no alias provided" });
|
|
1871
2041
|
bindings.push({
|
|
1872
2042
|
...binding,
|
|
1873
2043
|
isMutate: true,
|
|
1874
|
-
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
|
+
}
|
|
1875
2048
|
});
|
|
1876
2049
|
}
|
|
1877
2050
|
return { Watch, Validate, Reconcile };
|
|
@@ -1879,28 +2052,80 @@ var Capability = class {
|
|
|
1879
2052
|
function Watch(watchCallback) {
|
|
1880
2053
|
if (registerWatch) {
|
|
1881
2054
|
log("Watch Action", watchCallback.toString());
|
|
2055
|
+
const aliasLogger = logger_default.child({ alias: binding.alias || "no alias provided" });
|
|
1882
2056
|
bindings.push({
|
|
1883
2057
|
...binding,
|
|
1884
2058
|
isWatch: true,
|
|
1885
|
-
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
|
+
}
|
|
1886
2063
|
});
|
|
1887
2064
|
}
|
|
2065
|
+
return { Finalize };
|
|
1888
2066
|
}
|
|
1889
|
-
function Reconcile(
|
|
2067
|
+
function Reconcile(reconcileCallback) {
|
|
1890
2068
|
if (registerWatch) {
|
|
1891
|
-
log("Reconcile Action",
|
|
2069
|
+
log("Reconcile Action", reconcileCallback.toString());
|
|
2070
|
+
const aliasLogger = logger_default.child({ alias: binding.alias || "no alias provided" });
|
|
1892
2071
|
bindings.push({
|
|
1893
2072
|
...binding,
|
|
1894
2073
|
isWatch: true,
|
|
1895
2074
|
isQueue: true,
|
|
1896
|
-
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
|
+
}
|
|
1897
2079
|
});
|
|
1898
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
|
+
}
|
|
1899
2109
|
}
|
|
1900
2110
|
function InNamespace(...namespaces) {
|
|
1901
2111
|
logger_default.debug(`Add namespaces filter ${namespaces}`, prefix);
|
|
1902
2112
|
binding.filters.namespaces.push(...namespaces);
|
|
1903
|
-
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 };
|
|
2119
|
+
}
|
|
2120
|
+
function WithDeletionTimestamp() {
|
|
2121
|
+
logger_default.debug("Add deletionTimestamp filter");
|
|
2122
|
+
binding.filters.deletionTimestamp = true;
|
|
2123
|
+
return commonChain;
|
|
2124
|
+
}
|
|
2125
|
+
function WithNameRegex(regexName) {
|
|
2126
|
+
logger_default.debug(`Add regex name filter ${regexName}`, prefix);
|
|
2127
|
+
binding.filters.regexName = regexName.source;
|
|
2128
|
+
return commonChain;
|
|
1904
2129
|
}
|
|
1905
2130
|
function WithName(name) {
|
|
1906
2131
|
logger_default.debug(`Add name filter ${name}`, prefix);
|
|
@@ -1917,12 +2142,21 @@ var Capability = class {
|
|
|
1917
2142
|
binding.filters.annotations[key] = value;
|
|
1918
2143
|
return commonChain;
|
|
1919
2144
|
}
|
|
2145
|
+
function Alias(alias) {
|
|
2146
|
+
logger_default.debug(`Adding prefix alias ${alias}`, prefix);
|
|
2147
|
+
binding.alias = alias;
|
|
2148
|
+
return commonChain;
|
|
2149
|
+
}
|
|
1920
2150
|
function bindEvent(event) {
|
|
1921
2151
|
binding.event = event;
|
|
1922
2152
|
return {
|
|
1923
2153
|
...commonChain,
|
|
1924
2154
|
InNamespace,
|
|
1925
|
-
|
|
2155
|
+
InNamespaceRegex,
|
|
2156
|
+
WithName,
|
|
2157
|
+
WithNameRegex,
|
|
2158
|
+
WithDeletionTimestamp,
|
|
2159
|
+
Alias
|
|
1926
2160
|
};
|
|
1927
2161
|
}
|
|
1928
2162
|
return {
|