pepr 0.27.0 → 0.28.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.js +71 -25
- package/dist/controller.js +1 -1
- package/dist/lib/assets/helm.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/assets/yaml.d.ts.map +1 -1
- package/dist/lib/controller/index.d.ts +2 -2
- package/dist/lib/controller/index.d.ts.map +1 -1
- package/dist/lib/helpers.d.ts +7 -0
- package/dist/lib/helpers.d.ts.map +1 -1
- package/dist/lib/k8s.d.ts +0 -11
- package/dist/lib/k8s.d.ts.map +1 -1
- package/dist/lib/module.d.ts +0 -2
- package/dist/lib/module.d.ts.map +1 -1
- package/dist/lib/watch-processor.d.ts +1 -2
- package/dist/lib/watch-processor.d.ts.map +1 -1
- package/dist/lib.js +87 -61
- package/dist/lib.js.map +4 -4
- package/package.json +8 -8
- package/src/cli.ts +2 -0
- package/src/lib/assets/helm.ts +2 -0
- package/src/lib/assets/pods.ts +2 -0
- package/src/lib/assets/yaml.ts +8 -4
- package/src/lib/controller/index.ts +2 -2
- package/src/lib/controller/store.ts +1 -1
- package/src/lib/helpers.ts +96 -6
- package/src/lib/k8s.ts +0 -11
- package/src/lib/module.ts +4 -4
- package/src/lib/watch-processor.ts +22 -65
- package/src/templates/package.json +1 -2
package/dist/lib.js
CHANGED
|
@@ -31,26 +31,26 @@ 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_client6.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: () =>
|
|
41
|
+
RegisterKind: () => import_kubernetes_fluent_client6.RegisterKind,
|
|
42
|
+
a: () => import_kubernetes_fluent_client6.kind,
|
|
43
43
|
containers: () => containers,
|
|
44
|
-
fetch: () =>
|
|
45
|
-
fetchStatus: () =>
|
|
46
|
-
kind: () =>
|
|
44
|
+
fetch: () => import_kubernetes_fluent_client6.fetch,
|
|
45
|
+
fetchStatus: () => import_kubernetes_fluent_client6.fetchStatus,
|
|
46
|
+
kind: () => import_kubernetes_fluent_client6.kind
|
|
47
47
|
});
|
|
48
48
|
module.exports = __toCommonJS(lib_exports);
|
|
49
|
-
var
|
|
49
|
+
var import_kubernetes_fluent_client6 = require("kubernetes-fluent-client");
|
|
50
50
|
var R = __toESM(require("ramda"));
|
|
51
51
|
|
|
52
52
|
// src/lib/capability.ts
|
|
53
|
-
var
|
|
53
|
+
var import_kubernetes_fluent_client5 = require("kubernetes-fluent-client");
|
|
54
54
|
var import_ramda6 = require("ramda");
|
|
55
55
|
|
|
56
56
|
// src/lib/logger.ts
|
|
@@ -187,7 +187,7 @@ var peprStoreGVK = {
|
|
|
187
187
|
|
|
188
188
|
// src/lib/filter.ts
|
|
189
189
|
function shouldSkipRequest(binding, req, capabilityNamespaces) {
|
|
190
|
-
const { group, kind:
|
|
190
|
+
const { group, kind: kind3, version } = binding.kind || {};
|
|
191
191
|
const { namespaces, labels, annotations, name } = binding.filters || {};
|
|
192
192
|
const operation = req.operation.toUpperCase();
|
|
193
193
|
const srcObject = operation === "DELETE" /* DELETE */ ? req.oldObject : req.object;
|
|
@@ -199,7 +199,7 @@ function shouldSkipRequest(binding, req, capabilityNamespaces) {
|
|
|
199
199
|
if (name && name !== req.name) {
|
|
200
200
|
return true;
|
|
201
201
|
}
|
|
202
|
-
if (
|
|
202
|
+
if (kind3 !== req.kind.kind) {
|
|
203
203
|
return true;
|
|
204
204
|
}
|
|
205
205
|
if (group && group !== req.kind.group) {
|
|
@@ -668,7 +668,7 @@ var PeprControllerStore = class {
|
|
|
668
668
|
}
|
|
669
669
|
};
|
|
670
670
|
clearTimeout(this.#sendDebounce);
|
|
671
|
-
this.#sendDebounce = setTimeout(debounced, debounceBackoff);
|
|
671
|
+
this.#sendDebounce = setTimeout(debounced, this.#onReady ? 0 : debounceBackoff);
|
|
672
672
|
};
|
|
673
673
|
#send = (capabilityName) => {
|
|
674
674
|
const sendCache = {};
|
|
@@ -969,7 +969,7 @@ var Controller = class _Controller {
|
|
|
969
969
|
|
|
970
970
|
// src/lib/watch-processor.ts
|
|
971
971
|
var import_crypto = require("crypto");
|
|
972
|
-
var
|
|
972
|
+
var import_kubernetes_fluent_client4 = require("kubernetes-fluent-client");
|
|
973
973
|
var import_types2 = require("kubernetes-fluent-client/dist/fluent/types");
|
|
974
974
|
|
|
975
975
|
// src/lib/queue.ts
|
|
@@ -1023,39 +1023,61 @@ var Queue = class {
|
|
|
1023
1023
|
}
|
|
1024
1024
|
};
|
|
1025
1025
|
|
|
1026
|
-
// src/lib/
|
|
1027
|
-
var
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
const namespace2 = "pepr-system";
|
|
1032
|
-
try {
|
|
1033
|
-
const k8sStore = await (0, import_kubernetes_fluent_client3.K8s)(PeprStore).InNamespace(namespace2).Get(name);
|
|
1034
|
-
Object.entries(k8sStore.data).forEach(([key, value]) => {
|
|
1035
|
-
store[key] = value;
|
|
1036
|
-
});
|
|
1037
|
-
} catch (e) {
|
|
1038
|
-
logger_default.debug(e, "Watch store does not exist yet");
|
|
1026
|
+
// src/lib/helpers.ts
|
|
1027
|
+
var import_kubernetes_fluent_client3 = require("kubernetes-fluent-client");
|
|
1028
|
+
function checkOverlap(record1, record2) {
|
|
1029
|
+
if (Object.keys(record1).length === 0) {
|
|
1030
|
+
return true;
|
|
1039
1031
|
}
|
|
1040
|
-
|
|
1041
|
-
if (
|
|
1042
|
-
|
|
1043
|
-
metadata: {
|
|
1044
|
-
name,
|
|
1045
|
-
namespace: namespace2
|
|
1046
|
-
},
|
|
1047
|
-
data: store
|
|
1048
|
-
}).then(() => storeUpdates = false).catch((e) => {
|
|
1049
|
-
logger_default.error(e, "Error updating watch store");
|
|
1050
|
-
});
|
|
1032
|
+
for (const key in record1) {
|
|
1033
|
+
if (Object.prototype.hasOwnProperty.call(record1, key) && Object.prototype.hasOwnProperty.call(record2, key) && record1[key] === record2[key]) {
|
|
1034
|
+
return true;
|
|
1051
1035
|
}
|
|
1052
|
-
}
|
|
1036
|
+
}
|
|
1037
|
+
return false;
|
|
1053
1038
|
}
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1039
|
+
var filterMatcher = (binding, obj, capabilityNamespaces) => {
|
|
1040
|
+
if (binding.kind && binding.kind.kind === "Namespace" && binding.filters && binding.filters.namespaces.length !== 0) {
|
|
1041
|
+
return `Ignoring Watch Callback: Cannot use a namespace filter in a namespace object.`;
|
|
1042
|
+
}
|
|
1043
|
+
if (typeof obj === "object" && obj !== null && "metadata" in obj && obj.metadata !== void 0 && binding.filters) {
|
|
1044
|
+
if (obj.metadata.labels && !checkOverlap(binding.filters.labels, obj.metadata.labels)) {
|
|
1045
|
+
return `Ignoring Watch Callback: No overlap between binding and object labels. Binding labels ${JSON.stringify(
|
|
1046
|
+
binding.filters.labels
|
|
1047
|
+
)}, Object Labels ${JSON.stringify(obj.metadata.labels)}.`;
|
|
1048
|
+
}
|
|
1049
|
+
if (obj.metadata.annotations && !checkOverlap(binding.filters.annotations, obj.metadata.annotations)) {
|
|
1050
|
+
return `Ignoring Watch Callback: No overlap between binding and object annotations. Binding annotations ${JSON.stringify(
|
|
1051
|
+
binding.filters.annotations
|
|
1052
|
+
)}, Object annotations ${JSON.stringify(obj.metadata.annotations)}.`;
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
if (Array.isArray(capabilityNamespaces) && capabilityNamespaces.length > 0 && obj.metadata && obj.metadata.namespace && !capabilityNamespaces.includes(obj.metadata.namespace)) {
|
|
1056
|
+
return `Ignoring Watch Callback: Object is not in the capability namespace. Capability namespaces: ${capabilityNamespaces.join(
|
|
1057
|
+
", "
|
|
1058
|
+
)}, Object namespace: ${obj.metadata.namespace}.`;
|
|
1059
|
+
}
|
|
1060
|
+
if (Array.isArray(capabilityNamespaces) && capabilityNamespaces.length > 0 && binding.filters && Array.isArray(binding.filters.namespaces) && binding.filters.namespaces.length > 0 && !binding.filters.namespaces.every((ns) => capabilityNamespaces.includes(ns))) {
|
|
1061
|
+
return `Ignoring Watch Callback: Binding namespace is not part of capability namespaces. Capability namespaces: ${capabilityNamespaces.join(
|
|
1062
|
+
", "
|
|
1063
|
+
)}, Binding namespaces: ${binding.filters.namespaces.join(", ")}.`;
|
|
1064
|
+
}
|
|
1065
|
+
if (binding.filters && Array.isArray(binding.filters.namespaces) && binding.filters.namespaces.length > 0 && obj.metadata && obj.metadata.namespace && !binding.filters.namespaces.includes(obj.metadata.namespace)) {
|
|
1066
|
+
return `Ignoring Watch Callback: Binding namespace and object namespace are not the same. Binding namespaces: ${binding.filters.namespaces.join(
|
|
1067
|
+
", "
|
|
1068
|
+
)}, Object namespace: ${obj.metadata.namespace}.`;
|
|
1069
|
+
}
|
|
1070
|
+
return "";
|
|
1071
|
+
};
|
|
1072
|
+
|
|
1073
|
+
// src/lib/watch-processor.ts
|
|
1074
|
+
var store = {};
|
|
1075
|
+
function setupWatch(capabilities) {
|
|
1076
|
+
capabilities.map(
|
|
1077
|
+
(capability) => capability.bindings.filter((binding) => binding.isWatch).forEach((bindingElement) => runBinding(bindingElement, capability.namespaces))
|
|
1078
|
+
);
|
|
1057
1079
|
}
|
|
1058
|
-
async function runBinding(binding) {
|
|
1080
|
+
async function runBinding(binding, capabilityNamespaces) {
|
|
1059
1081
|
const eventToPhaseMap = {
|
|
1060
1082
|
["CREATE" /* Create */]: [import_types2.WatchPhase.Added],
|
|
1061
1083
|
["UPDATE" /* Update */]: [import_types2.WatchPhase.Modified],
|
|
@@ -1071,23 +1093,33 @@ async function runBinding(binding) {
|
|
|
1071
1093
|
let watcher;
|
|
1072
1094
|
if (binding.isQueue) {
|
|
1073
1095
|
const queue = new Queue();
|
|
1074
|
-
watcher = (0,
|
|
1096
|
+
watcher = (0, import_kubernetes_fluent_client4.K8s)(binding.model, binding.filters).Watch(async (obj, type) => {
|
|
1075
1097
|
logger_default.debug(obj, `Watch event ${type} received`);
|
|
1076
1098
|
if (phaseMatch.includes(type)) {
|
|
1077
1099
|
try {
|
|
1078
|
-
|
|
1079
|
-
|
|
1100
|
+
const filterMatch = filterMatcher(binding, obj, capabilityNamespaces);
|
|
1101
|
+
if (filterMatch === "") {
|
|
1102
|
+
queue.setReconcile(async () => await binding.watchCallback?.(obj, type));
|
|
1103
|
+
await queue.enqueue(obj);
|
|
1104
|
+
} else {
|
|
1105
|
+
logger_default.debug(filterMatch);
|
|
1106
|
+
}
|
|
1080
1107
|
} catch (e) {
|
|
1081
1108
|
logger_default.error(e, "Error executing watch callback");
|
|
1082
1109
|
}
|
|
1083
1110
|
}
|
|
1084
1111
|
}, watchCfg);
|
|
1085
1112
|
} else {
|
|
1086
|
-
watcher = (0,
|
|
1113
|
+
watcher = (0, import_kubernetes_fluent_client4.K8s)(binding.model, binding.filters).Watch(async (obj, type) => {
|
|
1087
1114
|
logger_default.debug(obj, `Watch event ${type} received`);
|
|
1088
1115
|
if (phaseMatch.includes(type)) {
|
|
1089
1116
|
try {
|
|
1090
|
-
|
|
1117
|
+
const filterMatch = filterMatcher(binding, obj, capabilityNamespaces);
|
|
1118
|
+
if (filterMatch === "") {
|
|
1119
|
+
await binding.watchCallback?.(obj, type);
|
|
1120
|
+
} else {
|
|
1121
|
+
logger_default.debug(filterMatch);
|
|
1122
|
+
}
|
|
1091
1123
|
} catch (e) {
|
|
1092
1124
|
logger_default.error(e, "Error executing watch callback");
|
|
1093
1125
|
}
|
|
@@ -1096,15 +1128,7 @@ async function runBinding(binding) {
|
|
|
1096
1128
|
}
|
|
1097
1129
|
const cacheSuffix = (0, import_crypto.createHash)("sha224").update(binding.watchCallback.toString()).digest("hex").substring(0, 5);
|
|
1098
1130
|
const cacheID = [watcher.getCacheID(), cacheSuffix].join("-");
|
|
1099
|
-
watcher.events.on(
|
|
1100
|
-
logger_default.debug(`Received watch cache: ${cacheID}:${version}`);
|
|
1101
|
-
if (store[cacheID] !== version) {
|
|
1102
|
-
logger_default.debug(`Updating watch cache: ${cacheID}: ${store[cacheID]} => ${version}`);
|
|
1103
|
-
store[cacheID] = version;
|
|
1104
|
-
storeUpdates = true;
|
|
1105
|
-
}
|
|
1106
|
-
});
|
|
1107
|
-
watcher.events.on(import_kubernetes_fluent_client3.WatchEvent.GIVE_UP, (err) => {
|
|
1131
|
+
watcher.events.on(import_kubernetes_fluent_client4.WatchEvent.GIVE_UP, (err) => {
|
|
1108
1132
|
logger_default.error(err, "Watch failed after 5 attempts, giving up");
|
|
1109
1133
|
process.exit(1);
|
|
1110
1134
|
});
|
|
@@ -1157,10 +1181,12 @@ var PeprModule = class {
|
|
|
1157
1181
|
}
|
|
1158
1182
|
this.#controller = new Controller(config, capabilities, opts.beforeHook, opts.afterHook, () => {
|
|
1159
1183
|
if (isWatchMode() || isDevMode()) {
|
|
1160
|
-
|
|
1184
|
+
try {
|
|
1185
|
+
setupWatch(capabilities);
|
|
1186
|
+
} catch (e) {
|
|
1161
1187
|
logger_default.error(e, "Error setting up watch");
|
|
1162
1188
|
process.exit(1);
|
|
1163
|
-
}
|
|
1189
|
+
}
|
|
1164
1190
|
}
|
|
1165
1191
|
});
|
|
1166
1192
|
if (opts.deferStart) {
|
|
@@ -1547,15 +1573,15 @@ var Capability = class {
|
|
|
1547
1573
|
* @param kind if using a custom KubernetesObject not available in `a.*`, specify the GroupVersionKind
|
|
1548
1574
|
* @returns
|
|
1549
1575
|
*/
|
|
1550
|
-
When = (model,
|
|
1551
|
-
const matchedKind = (0,
|
|
1552
|
-
if (!matchedKind && !
|
|
1576
|
+
When = (model, kind3) => {
|
|
1577
|
+
const matchedKind = (0, import_kubernetes_fluent_client5.modelToGroupVersionKind)(model.name);
|
|
1578
|
+
if (!matchedKind && !kind3) {
|
|
1553
1579
|
throw new Error(`Kind not specified for ${model.name}`);
|
|
1554
1580
|
}
|
|
1555
1581
|
const binding = {
|
|
1556
1582
|
model,
|
|
1557
1583
|
// If the kind is not specified, use the matched kind from the model
|
|
1558
|
-
kind:
|
|
1584
|
+
kind: kind3 || matchedKind,
|
|
1559
1585
|
event: "*" /* Any */,
|
|
1560
1586
|
filters: {
|
|
1561
1587
|
name: "",
|