pepr 0.46.3-nightly.6 → 0.46.3-nightly.8
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/build.helpers.d.ts.map +1 -1
- package/dist/cli.js +556 -554
- package/dist/controller.js +1 -1
- package/dist/lib/assets/assets.d.ts +3 -2
- package/dist/lib/assets/assets.d.ts.map +1 -1
- package/dist/lib/assets/envrionment.d.ts +4 -0
- package/dist/lib/assets/envrionment.d.ts.map +1 -0
- package/dist/lib/assets/pods.d.ts +1 -3
- package/dist/lib/assets/pods.d.ts.map +1 -1
- package/dist/lib/assets/yaml/overridesFile.d.ts +1 -2
- package/dist/lib/assets/yaml/overridesFile.d.ts.map +1 -1
- package/dist/lib/filter/adjudication.d.ts +22 -0
- package/dist/lib/filter/adjudication.d.ts.map +1 -0
- package/dist/lib/filter/filter.d.ts +0 -19
- package/dist/lib/filter/filter.d.ts.map +1 -1
- package/dist/lib/types.d.ts +1 -0
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib.js +229 -229
- package/dist/lib.js.map +4 -4
- package/package.json +1 -1
- package/src/cli/build.helpers.ts +3 -2
- package/src/cli/init/templates.ts +2 -2
- package/src/lib/assets/assets.ts +24 -5
- package/src/lib/assets/envrionment.ts +26 -0
- package/src/lib/assets/pods.ts +2 -26
- package/src/lib/assets/yaml/overridesFile.ts +2 -3
- package/src/lib/filter/adjudication.ts +196 -0
- package/src/lib/filter/filter.ts +20 -194
- package/src/lib/types.ts +1 -0
package/package.json
CHANGED
package/src/cli/build.helpers.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { promises as fs } from "fs";
|
|
|
11
11
|
import { generateAllYaml } from "../lib/assets/yaml/generateAllYaml";
|
|
12
12
|
import { webhookConfigGenerator } from "../lib/assets/webhooks";
|
|
13
13
|
import { generateZarfYamlGeneric } from "../lib/assets/yaml/generateZarfYaml";
|
|
14
|
+
import { getDeployment, getModuleSecret, getWatcher } from "../lib/assets/pods";
|
|
14
15
|
|
|
15
16
|
interface ImageOptions {
|
|
16
17
|
customImage?: string;
|
|
@@ -191,7 +192,7 @@ export async function generateYamlAndWriteToDisk(obj: {
|
|
|
191
192
|
const yamlFile = `pepr-module-${uuid}.yaml`;
|
|
192
193
|
const chartPath = `${uuid}-chart`;
|
|
193
194
|
const yamlPath = resolve(outputDir, yamlFile);
|
|
194
|
-
const yaml = await assets.allYaml(generateAllYaml, imagePullSecret);
|
|
195
|
+
const yaml = await assets.allYaml(generateAllYaml, getDeployment, getWatcher, imagePullSecret);
|
|
195
196
|
const zarfPath = resolve(outputDir, "zarf.yaml");
|
|
196
197
|
|
|
197
198
|
let localZarf = "";
|
|
@@ -203,6 +204,6 @@ export async function generateYamlAndWriteToDisk(obj: {
|
|
|
203
204
|
await fs.writeFile(yamlPath, yaml);
|
|
204
205
|
await fs.writeFile(zarfPath, localZarf);
|
|
205
206
|
|
|
206
|
-
await assets.generateHelmChart(webhookConfigGenerator, outputDir);
|
|
207
|
+
await assets.generateHelmChart(webhookConfigGenerator, getWatcher, getModuleSecret, outputDir);
|
|
207
208
|
console.info(`✅ K8s resource for the module saved to ${yamlPath}`);
|
|
208
209
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import { dumpYaml } from "@kubernetes/client-node";
|
|
5
5
|
import { inspect } from "util";
|
|
6
|
-
import { v4 as uuidv4
|
|
6
|
+
import { v4 as uuidv4 } from "uuid";
|
|
7
7
|
|
|
8
8
|
import eslintJSON from "../../templates/.eslintrc.template.json";
|
|
9
9
|
import peprSnippetsJSON from "../../templates/pepr.code-snippets.json";
|
|
@@ -48,7 +48,7 @@ export type peprPackageJSON = {
|
|
|
48
48
|
|
|
49
49
|
export function genPkgJSON(opts: InitOptions, pgkVerOverride?: string): peprPackageJSON {
|
|
50
50
|
// Generate a random UUID for the module based on the module name if it is not provided
|
|
51
|
-
const uuid = !opts.uuid ?
|
|
51
|
+
const uuid = !opts.uuid ? uuidv4() : opts.uuid;
|
|
52
52
|
// Generate a name for the module based on the module name
|
|
53
53
|
const name = sanitizeName(opts.name);
|
|
54
54
|
// Make typescript a dev dependency
|
package/src/lib/assets/assets.ts
CHANGED
|
@@ -18,7 +18,6 @@ import {
|
|
|
18
18
|
} from "@kubernetes/client-node/dist/gen";
|
|
19
19
|
import { createDirectoryIfNotExists } from "../filesystemService";
|
|
20
20
|
import { overridesFile } from "./yaml/overridesFile";
|
|
21
|
-
import { getDeployment, getModuleSecret, getWatcher } from "./pods";
|
|
22
21
|
import { helmLayout, createWebhookYaml, toYaml } from "./index";
|
|
23
22
|
import { loadCapabilities } from "./loader";
|
|
24
23
|
import { namespaceComplianceValidator, dedent } from "../helpers";
|
|
@@ -26,6 +25,7 @@ import { promises as fs } from "fs";
|
|
|
26
25
|
import { storeRole, storeRoleBinding, clusterRoleBinding, serviceAccount } from "./rbac";
|
|
27
26
|
import { watcherService, service, tlsSecret, apiPathSecret } from "./networking";
|
|
28
27
|
import { WebhookType } from "../enums";
|
|
28
|
+
import { kind } from "kubernetes-fluent-client";
|
|
29
29
|
|
|
30
30
|
export class Assets {
|
|
31
31
|
readonly name: string;
|
|
@@ -84,6 +84,18 @@ export class Assets {
|
|
|
84
84
|
assets: Assets,
|
|
85
85
|
deployments: { default: V1Deployment; watch: V1Deployment | null },
|
|
86
86
|
) => Promise<string>,
|
|
87
|
+
getDeploymentFunction: (
|
|
88
|
+
assets: Assets,
|
|
89
|
+
hash: string,
|
|
90
|
+
buildTimestamp: string,
|
|
91
|
+
imagePullSecret?: string,
|
|
92
|
+
) => kind.Deployment,
|
|
93
|
+
getWatcherFunction: (
|
|
94
|
+
assets: Assets,
|
|
95
|
+
hash: string,
|
|
96
|
+
buildTimestamp: string,
|
|
97
|
+
imagePullSecret?: string,
|
|
98
|
+
) => kind.Deployment | null,
|
|
87
99
|
imagePullSecret?: string,
|
|
88
100
|
): Promise<string> => {
|
|
89
101
|
this.capabilities = await loadCapabilities(this.path);
|
|
@@ -97,8 +109,8 @@ export class Assets {
|
|
|
97
109
|
const moduleHash = crypto.createHash("sha256").update(code).digest("hex");
|
|
98
110
|
|
|
99
111
|
const deployments = {
|
|
100
|
-
default:
|
|
101
|
-
watch:
|
|
112
|
+
default: getDeploymentFunction(this, moduleHash, this.buildTimestamp, imagePullSecret),
|
|
113
|
+
watch: getWatcherFunction(this, moduleHash, this.buildTimestamp, imagePullSecret),
|
|
102
114
|
};
|
|
103
115
|
|
|
104
116
|
return yamlGenerationFunction(this, deployments);
|
|
@@ -141,6 +153,13 @@ export class Assets {
|
|
|
141
153
|
mutateOrValidate: WebhookType,
|
|
142
154
|
timeoutSeconds: number | undefined,
|
|
143
155
|
) => Promise<V1MutatingWebhookConfiguration | V1ValidatingWebhookConfiguration | null>,
|
|
156
|
+
getWatcherFunction: (
|
|
157
|
+
assets: Assets,
|
|
158
|
+
hash: string,
|
|
159
|
+
buildTimestamp: string,
|
|
160
|
+
imagePullSecret?: string,
|
|
161
|
+
) => kind.Deployment | null,
|
|
162
|
+
getModuleSecretFunction: (name: string, data: Buffer, hash: string) => kind.Secret,
|
|
144
163
|
basePath: string,
|
|
145
164
|
): Promise<void> => {
|
|
146
165
|
const helm = helmLayout(basePath, this.config.uuid);
|
|
@@ -175,7 +194,7 @@ export class Assets {
|
|
|
175
194
|
[helm.files.serviceAccountYaml, (): string => toYaml(serviceAccount(this.name))],
|
|
176
195
|
[
|
|
177
196
|
helm.files.moduleSecretYaml,
|
|
178
|
-
(): string => toYaml(
|
|
197
|
+
(): string => toYaml(getModuleSecretFunction(this.name, code, moduleHash)),
|
|
179
198
|
],
|
|
180
199
|
];
|
|
181
200
|
await Promise.all(pairs.map(async ([file, content]) => await fs.writeFile(file, content())));
|
|
@@ -205,7 +224,7 @@ export class Assets {
|
|
|
205
224
|
|
|
206
225
|
await this.writeWebhookFiles(webhooks.validate, webhooks.mutate, helm);
|
|
207
226
|
|
|
208
|
-
const watchDeployment =
|
|
227
|
+
const watchDeployment = getWatcherFunction(this, moduleHash, this.buildTimestamp);
|
|
209
228
|
if (watchDeployment) {
|
|
210
229
|
await fs.writeFile(
|
|
211
230
|
helm.files.watcherDeploymentYaml,
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { V1EnvVar } from "@kubernetes/client-node";
|
|
2
|
+
import { ModuleConfig } from "../types";
|
|
3
|
+
|
|
4
|
+
export function genEnv(
|
|
5
|
+
config: ModuleConfig,
|
|
6
|
+
watchMode = false,
|
|
7
|
+
ignoreWatchMode = false,
|
|
8
|
+
): V1EnvVar[] {
|
|
9
|
+
const noWatchDef = {
|
|
10
|
+
PEPR_PRETTY_LOG: "false",
|
|
11
|
+
LOG_LEVEL: config.logLevel || "info",
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const def = {
|
|
15
|
+
PEPR_WATCH_MODE: watchMode ? "true" : "false",
|
|
16
|
+
...noWatchDef,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
if (config.env && config.env["PEPR_WATCH_MODE"]) {
|
|
20
|
+
delete config.env["PEPR_WATCH_MODE"];
|
|
21
|
+
}
|
|
22
|
+
const cfg = config.env || {};
|
|
23
|
+
return ignoreWatchMode
|
|
24
|
+
? Object.entries({ ...noWatchDef, ...cfg }).map(([name, value]) => ({ name, value }))
|
|
25
|
+
: Object.entries({ ...def, ...cfg }).map(([name, value]) => ({ name, value }));
|
|
26
|
+
}
|
package/src/lib/assets/pods.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
// SPDX-FileCopyrightText: 2023-Present The Pepr Authors
|
|
3
3
|
|
|
4
|
-
import { KubernetesObject
|
|
4
|
+
import { KubernetesObject } from "@kubernetes/client-node";
|
|
5
5
|
import { kind } from "kubernetes-fluent-client";
|
|
6
6
|
import { gzipSync } from "zlib";
|
|
7
7
|
import { secretOverLimit } from "../helpers";
|
|
8
8
|
import { Assets } from "./assets";
|
|
9
|
-
import { ModuleConfig } from "../types";
|
|
10
9
|
import { Binding } from "../types";
|
|
10
|
+
import { genEnv } from "./envrionment";
|
|
11
11
|
|
|
12
12
|
/** Generate the pepr-system namespace */
|
|
13
13
|
export function getNamespace(namespaceLabels?: Record<string, string>): KubernetesObject {
|
|
@@ -365,27 +365,3 @@ export function getModuleSecret(name: string, data: Buffer, hash: string): kind.
|
|
|
365
365
|
};
|
|
366
366
|
}
|
|
367
367
|
}
|
|
368
|
-
|
|
369
|
-
export function genEnv(
|
|
370
|
-
config: ModuleConfig,
|
|
371
|
-
watchMode = false,
|
|
372
|
-
ignoreWatchMode = false,
|
|
373
|
-
): V1EnvVar[] {
|
|
374
|
-
const noWatchDef = {
|
|
375
|
-
PEPR_PRETTY_LOG: "false",
|
|
376
|
-
LOG_LEVEL: config.logLevel || "info",
|
|
377
|
-
};
|
|
378
|
-
|
|
379
|
-
const def = {
|
|
380
|
-
PEPR_WATCH_MODE: watchMode ? "true" : "false",
|
|
381
|
-
...noWatchDef,
|
|
382
|
-
};
|
|
383
|
-
|
|
384
|
-
if (config.env && config.env["PEPR_WATCH_MODE"]) {
|
|
385
|
-
delete config.env["PEPR_WATCH_MODE"];
|
|
386
|
-
}
|
|
387
|
-
const cfg = config.env || {};
|
|
388
|
-
return ignoreWatchMode
|
|
389
|
-
? Object.entries({ ...noWatchDef, ...cfg }).map(([name, value]) => ({ name, value }))
|
|
390
|
-
: Object.entries({ ...def, ...cfg }).map(([name, value]) => ({ name, value }));
|
|
391
|
-
}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { genEnv } from "../
|
|
2
|
-
import { ModuleConfig } from "../../types";
|
|
3
|
-
import { CapabilityExport } from "../../types";
|
|
1
|
+
import { genEnv } from "../envrionment";
|
|
2
|
+
import { CapabilityExport, ModuleConfig } from "../../types";
|
|
4
3
|
import { dumpYaml } from "@kubernetes/client-node";
|
|
5
4
|
import { clusterRole } from "../rbac";
|
|
6
5
|
import { promises as fs } from "fs";
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { KubernetesObject } from "kubernetes-fluent-client";
|
|
2
|
+
import { AdmissionRequest } from "../common-types";
|
|
3
|
+
import { Binding } from "../types";
|
|
4
|
+
import {
|
|
5
|
+
declaredOperation,
|
|
6
|
+
declaredGroup,
|
|
7
|
+
declaredVersion,
|
|
8
|
+
declaredKind,
|
|
9
|
+
} from "./adjudicators/admissionRequest";
|
|
10
|
+
import {
|
|
11
|
+
definedEvent,
|
|
12
|
+
definedName,
|
|
13
|
+
definedGroup,
|
|
14
|
+
definedVersion,
|
|
15
|
+
definedKind,
|
|
16
|
+
definedNamespaces,
|
|
17
|
+
definedLabels,
|
|
18
|
+
definedAnnotations,
|
|
19
|
+
definedNamespaceRegexes,
|
|
20
|
+
definedNameRegex,
|
|
21
|
+
} from "./adjudicators/binding";
|
|
22
|
+
import {
|
|
23
|
+
carriedName,
|
|
24
|
+
carriedNamespace,
|
|
25
|
+
carriedLabels,
|
|
26
|
+
carriedAnnotations,
|
|
27
|
+
} from "./adjudicators/kubernetesObject";
|
|
28
|
+
import {
|
|
29
|
+
mismatchedDeletionTimestamp,
|
|
30
|
+
mismatchedEvent,
|
|
31
|
+
mismatchedName,
|
|
32
|
+
mismatchedGroup,
|
|
33
|
+
mismatchedVersion,
|
|
34
|
+
mismatchedKind,
|
|
35
|
+
mismatchedNamespace,
|
|
36
|
+
mismatchedLabels,
|
|
37
|
+
mismatchedAnnotations,
|
|
38
|
+
mismatchedNamespaceRegex,
|
|
39
|
+
mismatchedNameRegex,
|
|
40
|
+
} from "./adjudicators/mismatch";
|
|
41
|
+
import {
|
|
42
|
+
misboundNamespace,
|
|
43
|
+
misboundDeleteWithDeletionTimestamp,
|
|
44
|
+
unbindableNamespaces,
|
|
45
|
+
uncarryableNamespace,
|
|
46
|
+
carriesIgnoredNamespace,
|
|
47
|
+
missingCarriableNamespace,
|
|
48
|
+
} from "./adjudicators/postCollection";
|
|
49
|
+
import { AdjudicationResult } from "../types";
|
|
50
|
+
|
|
51
|
+
export function adjudicateMisboundNamespace(binding: Binding): AdjudicationResult {
|
|
52
|
+
return misboundNamespace(binding) ? "Cannot use namespace filter on a namespace object." : null;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function adjudicateMisboundDeleteWithDeletionTimestamp(
|
|
56
|
+
binding: Binding,
|
|
57
|
+
): AdjudicationResult {
|
|
58
|
+
return misboundDeleteWithDeletionTimestamp(binding)
|
|
59
|
+
? "Cannot use deletionTimestamp filter on a DELETE operation."
|
|
60
|
+
: null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function adjudicateMismatchedDeletionTimestamp(
|
|
64
|
+
binding: Binding,
|
|
65
|
+
obj: KubernetesObject,
|
|
66
|
+
): AdjudicationResult {
|
|
67
|
+
return mismatchedDeletionTimestamp(binding, obj)
|
|
68
|
+
? "Binding defines deletionTimestamp but Object does not carry it."
|
|
69
|
+
: null;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function adjudicateMismatchedEvent(
|
|
73
|
+
binding: Binding,
|
|
74
|
+
req: AdmissionRequest,
|
|
75
|
+
): AdjudicationResult {
|
|
76
|
+
return mismatchedEvent(binding, req)
|
|
77
|
+
? `Binding defines event '${definedEvent(binding)}' but Request declares '${declaredOperation(req)}'.`
|
|
78
|
+
: null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function adjudicateMismatchedName(
|
|
82
|
+
binding: Binding,
|
|
83
|
+
obj: KubernetesObject,
|
|
84
|
+
): AdjudicationResult {
|
|
85
|
+
return mismatchedName(binding, obj)
|
|
86
|
+
? `Binding defines name '${definedName(binding)}' but Object carries '${carriedName(obj)}'.`
|
|
87
|
+
: null;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function adjudicateMismatchedGroup(
|
|
91
|
+
binding: Binding,
|
|
92
|
+
req: AdmissionRequest,
|
|
93
|
+
): AdjudicationResult {
|
|
94
|
+
return mismatchedGroup(binding, req)
|
|
95
|
+
? `Binding defines group '${definedGroup(binding)}' but Request declares '${declaredGroup(req)}'.`
|
|
96
|
+
: null;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function adjudicateMismatchedVersion(
|
|
100
|
+
binding: Binding,
|
|
101
|
+
req: AdmissionRequest,
|
|
102
|
+
): AdjudicationResult {
|
|
103
|
+
return mismatchedVersion(binding, req)
|
|
104
|
+
? `Binding defines version '${definedVersion(binding)}' but Request declares '${declaredVersion(req)}'.`
|
|
105
|
+
: null;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export function adjudicateMismatchedKind(
|
|
109
|
+
binding: Binding,
|
|
110
|
+
req: AdmissionRequest,
|
|
111
|
+
): AdjudicationResult {
|
|
112
|
+
return mismatchedKind(binding, req)
|
|
113
|
+
? `Binding defines kind '${definedKind(binding)}' but Request declares '${declaredKind(req)}'.`
|
|
114
|
+
: null;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export function adjudicateUnbindableNamespaces(
|
|
118
|
+
capabilityNamespaces: string[],
|
|
119
|
+
binding: Binding,
|
|
120
|
+
): AdjudicationResult {
|
|
121
|
+
return unbindableNamespaces(capabilityNamespaces, binding)
|
|
122
|
+
? `Binding defines namespaces ${JSON.stringify(definedNamespaces(binding))} but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`
|
|
123
|
+
: null;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function adjudicateUncarryableNamespace(
|
|
127
|
+
capabilityNamespaces: string[],
|
|
128
|
+
obj: KubernetesObject,
|
|
129
|
+
): AdjudicationResult {
|
|
130
|
+
return uncarryableNamespace(capabilityNamespaces, obj)
|
|
131
|
+
? `Object carries namespace '${obj.kind && obj.kind === "Namespace" ? obj.metadata?.name : carriedNamespace(obj)}' but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`
|
|
132
|
+
: null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export function adjudicateMismatchedNamespace(
|
|
136
|
+
binding: Binding,
|
|
137
|
+
obj: KubernetesObject,
|
|
138
|
+
): AdjudicationResult {
|
|
139
|
+
return mismatchedNamespace(binding, obj)
|
|
140
|
+
? `Binding defines namespaces '${JSON.stringify(definedNamespaces(binding))}' but Object carries '${carriedNamespace(obj)}'.`
|
|
141
|
+
: null;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function adjudicateMismatchedLabels(
|
|
145
|
+
binding: Binding,
|
|
146
|
+
obj: KubernetesObject,
|
|
147
|
+
): AdjudicationResult {
|
|
148
|
+
return mismatchedLabels(binding, obj)
|
|
149
|
+
? `Binding defines labels '${JSON.stringify(definedLabels(binding))}' but Object carries '${JSON.stringify(carriedLabels(obj))}'.`
|
|
150
|
+
: null;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export function adjudicateMismatchedAnnotations(
|
|
154
|
+
binding: Binding,
|
|
155
|
+
obj: KubernetesObject,
|
|
156
|
+
): AdjudicationResult {
|
|
157
|
+
return mismatchedAnnotations(binding, obj)
|
|
158
|
+
? `Binding defines annotations '${JSON.stringify(definedAnnotations(binding))}' but Object carries '${JSON.stringify(carriedAnnotations(obj))}'.`
|
|
159
|
+
: null;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export function adjudicateMismatchedNamespaceRegex(
|
|
163
|
+
binding: Binding,
|
|
164
|
+
obj: KubernetesObject,
|
|
165
|
+
): AdjudicationResult {
|
|
166
|
+
return mismatchedNamespaceRegex(binding, obj)
|
|
167
|
+
? `Binding defines namespace regexes '${JSON.stringify(definedNamespaceRegexes(binding))}' but Object carries '${carriedNamespace(obj)}'.`
|
|
168
|
+
: null;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export function adjudicateMismatchedNameRegex(
|
|
172
|
+
binding: Binding,
|
|
173
|
+
obj: KubernetesObject,
|
|
174
|
+
): AdjudicationResult {
|
|
175
|
+
return mismatchedNameRegex(binding, obj)
|
|
176
|
+
? `Binding defines name regex '${definedNameRegex(binding)}' but Object carries '${carriedName(obj)}'.`
|
|
177
|
+
: null;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export function adjudicateCarriesIgnoredNamespace(
|
|
181
|
+
ignoredNamespaces: string[] | undefined,
|
|
182
|
+
obj: KubernetesObject,
|
|
183
|
+
): AdjudicationResult {
|
|
184
|
+
return carriesIgnoredNamespace(ignoredNamespaces, obj)
|
|
185
|
+
? `Object carries namespace '${obj.kind && obj.kind === "Namespace" ? obj.metadata?.name : carriedNamespace(obj)}' but ignored namespaces include '${JSON.stringify(ignoredNamespaces)}'.`
|
|
186
|
+
: null;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export function adjudicateMissingCarriableNamespace(
|
|
190
|
+
capabilityNamespaces: string[],
|
|
191
|
+
obj: KubernetesObject,
|
|
192
|
+
): AdjudicationResult {
|
|
193
|
+
return missingCarriableNamespace(capabilityNamespaces, obj)
|
|
194
|
+
? `Object does not carry a namespace but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`
|
|
195
|
+
: null;
|
|
196
|
+
}
|
package/src/lib/filter/filter.ts
CHANGED
|
@@ -1,57 +1,30 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
// SPDX-FileCopyrightText: 2023-Present The Pepr Authors
|
|
3
3
|
|
|
4
|
-
import { Binding } from "../types";
|
|
4
|
+
import { AdjudicationResult, Binding } from "../types";
|
|
5
5
|
import { Operation } from "../enums";
|
|
6
6
|
import { KubernetesObject } from "kubernetes-fluent-client";
|
|
7
|
-
import {
|
|
8
|
-
carriesIgnoredNamespace,
|
|
9
|
-
misboundDeleteWithDeletionTimestamp,
|
|
10
|
-
misboundNamespace,
|
|
11
|
-
missingCarriableNamespace,
|
|
12
|
-
unbindableNamespaces,
|
|
13
|
-
uncarryableNamespace,
|
|
14
|
-
} from "./adjudicators/postCollection";
|
|
15
|
-
import {
|
|
16
|
-
declaredOperation,
|
|
17
|
-
declaredGroup,
|
|
18
|
-
declaredVersion,
|
|
19
|
-
declaredKind,
|
|
20
|
-
} from "./adjudicators/admissionRequest";
|
|
21
|
-
import {
|
|
22
|
-
definedEvent,
|
|
23
|
-
definedName,
|
|
24
|
-
definedGroup,
|
|
25
|
-
definedVersion,
|
|
26
|
-
definedKind,
|
|
27
|
-
definedNamespaces,
|
|
28
|
-
definedLabels,
|
|
29
|
-
definedAnnotations,
|
|
30
|
-
definedNamespaceRegexes,
|
|
31
|
-
definedNameRegex,
|
|
32
|
-
} from "./adjudicators/binding";
|
|
33
|
-
import {
|
|
34
|
-
carriedName,
|
|
35
|
-
carriedNamespace,
|
|
36
|
-
carriedLabels,
|
|
37
|
-
carriedAnnotations,
|
|
38
|
-
} from "./adjudicators/kubernetesObject";
|
|
39
|
-
import {
|
|
40
|
-
mismatchedDeletionTimestamp,
|
|
41
|
-
mismatchedEvent,
|
|
42
|
-
mismatchedName,
|
|
43
|
-
mismatchedGroup,
|
|
44
|
-
mismatchedVersion,
|
|
45
|
-
mismatchedKind,
|
|
46
|
-
mismatchedNamespace,
|
|
47
|
-
mismatchedLabels,
|
|
48
|
-
mismatchedAnnotations,
|
|
49
|
-
mismatchedNamespaceRegex,
|
|
50
|
-
mismatchedNameRegex,
|
|
51
|
-
} from "./adjudicators/mismatch";
|
|
52
7
|
import { AdmissionRequest } from "../common-types";
|
|
8
|
+
import {
|
|
9
|
+
adjudicateMisboundDeleteWithDeletionTimestamp,
|
|
10
|
+
adjudicateMismatchedDeletionTimestamp,
|
|
11
|
+
adjudicateMismatchedEvent,
|
|
12
|
+
adjudicateMismatchedName,
|
|
13
|
+
adjudicateMismatchedGroup,
|
|
14
|
+
adjudicateMismatchedVersion,
|
|
15
|
+
adjudicateMismatchedKind,
|
|
16
|
+
adjudicateUnbindableNamespaces,
|
|
17
|
+
adjudicateUncarryableNamespace,
|
|
18
|
+
adjudicateMismatchedNamespace,
|
|
19
|
+
adjudicateMismatchedLabels,
|
|
20
|
+
adjudicateMismatchedAnnotations,
|
|
21
|
+
adjudicateMismatchedNamespaceRegex,
|
|
22
|
+
adjudicateMismatchedNameRegex,
|
|
23
|
+
adjudicateCarriesIgnoredNamespace,
|
|
24
|
+
adjudicateMissingCarriableNamespace,
|
|
25
|
+
adjudicateMisboundNamespace,
|
|
26
|
+
} from "./adjudication";
|
|
53
27
|
|
|
54
|
-
type AdjudicationResult = string | null;
|
|
55
28
|
type Adjudicator = () => AdjudicationResult;
|
|
56
29
|
|
|
57
30
|
/**
|
|
@@ -142,150 +115,3 @@ export function filterNoMatchReason(
|
|
|
142
115
|
|
|
143
116
|
return "";
|
|
144
117
|
}
|
|
145
|
-
|
|
146
|
-
export function adjudicateMisboundNamespace(binding: Binding): AdjudicationResult {
|
|
147
|
-
return misboundNamespace(binding) ? "Cannot use namespace filter on a namespace object." : null;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
export function adjudicateMisboundDeleteWithDeletionTimestamp(
|
|
151
|
-
binding: Binding,
|
|
152
|
-
): AdjudicationResult {
|
|
153
|
-
return misboundDeleteWithDeletionTimestamp(binding)
|
|
154
|
-
? "Cannot use deletionTimestamp filter on a DELETE operation."
|
|
155
|
-
: null;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
export function adjudicateMismatchedDeletionTimestamp(
|
|
159
|
-
binding: Binding,
|
|
160
|
-
obj: KubernetesObject,
|
|
161
|
-
): AdjudicationResult {
|
|
162
|
-
return mismatchedDeletionTimestamp(binding, obj)
|
|
163
|
-
? "Binding defines deletionTimestamp but Object does not carry it."
|
|
164
|
-
: null;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
export function adjudicateMismatchedEvent(
|
|
168
|
-
binding: Binding,
|
|
169
|
-
req: AdmissionRequest,
|
|
170
|
-
): AdjudicationResult {
|
|
171
|
-
return mismatchedEvent(binding, req)
|
|
172
|
-
? `Binding defines event '${definedEvent(binding)}' but Request declares '${declaredOperation(req)}'.`
|
|
173
|
-
: null;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
export function adjudicateMismatchedName(
|
|
177
|
-
binding: Binding,
|
|
178
|
-
obj: KubernetesObject,
|
|
179
|
-
): AdjudicationResult {
|
|
180
|
-
return mismatchedName(binding, obj)
|
|
181
|
-
? `Binding defines name '${definedName(binding)}' but Object carries '${carriedName(obj)}'.`
|
|
182
|
-
: null;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
export function adjudicateMismatchedGroup(
|
|
186
|
-
binding: Binding,
|
|
187
|
-
req: AdmissionRequest,
|
|
188
|
-
): AdjudicationResult {
|
|
189
|
-
return mismatchedGroup(binding, req)
|
|
190
|
-
? `Binding defines group '${definedGroup(binding)}' but Request declares '${declaredGroup(req)}'.`
|
|
191
|
-
: null;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
export function adjudicateMismatchedVersion(
|
|
195
|
-
binding: Binding,
|
|
196
|
-
req: AdmissionRequest,
|
|
197
|
-
): AdjudicationResult {
|
|
198
|
-
return mismatchedVersion(binding, req)
|
|
199
|
-
? `Binding defines version '${definedVersion(binding)}' but Request declares '${declaredVersion(req)}'.`
|
|
200
|
-
: null;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
export function adjudicateMismatchedKind(
|
|
204
|
-
binding: Binding,
|
|
205
|
-
req: AdmissionRequest,
|
|
206
|
-
): AdjudicationResult {
|
|
207
|
-
return mismatchedKind(binding, req)
|
|
208
|
-
? `Binding defines kind '${definedKind(binding)}' but Request declares '${declaredKind(req)}'.`
|
|
209
|
-
: null;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
export function adjudicateUnbindableNamespaces(
|
|
213
|
-
capabilityNamespaces: string[],
|
|
214
|
-
binding: Binding,
|
|
215
|
-
): AdjudicationResult {
|
|
216
|
-
return unbindableNamespaces(capabilityNamespaces, binding)
|
|
217
|
-
? `Binding defines namespaces ${JSON.stringify(definedNamespaces(binding))} but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`
|
|
218
|
-
: null;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
export function adjudicateUncarryableNamespace(
|
|
222
|
-
capabilityNamespaces: string[],
|
|
223
|
-
obj: KubernetesObject,
|
|
224
|
-
): AdjudicationResult {
|
|
225
|
-
return uncarryableNamespace(capabilityNamespaces, obj)
|
|
226
|
-
? `Object carries namespace '${obj.kind && obj.kind === "Namespace" ? obj.metadata?.name : carriedNamespace(obj)}' but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`
|
|
227
|
-
: null;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
export function adjudicateMismatchedNamespace(
|
|
231
|
-
binding: Binding,
|
|
232
|
-
obj: KubernetesObject,
|
|
233
|
-
): AdjudicationResult {
|
|
234
|
-
return mismatchedNamespace(binding, obj)
|
|
235
|
-
? `Binding defines namespaces '${JSON.stringify(definedNamespaces(binding))}' but Object carries '${carriedNamespace(obj)}'.`
|
|
236
|
-
: null;
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
export function adjudicateMismatchedLabels(
|
|
240
|
-
binding: Binding,
|
|
241
|
-
obj: KubernetesObject,
|
|
242
|
-
): AdjudicationResult {
|
|
243
|
-
return mismatchedLabels(binding, obj)
|
|
244
|
-
? `Binding defines labels '${JSON.stringify(definedLabels(binding))}' but Object carries '${JSON.stringify(carriedLabels(obj))}'.`
|
|
245
|
-
: null;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
export function adjudicateMismatchedAnnotations(
|
|
249
|
-
binding: Binding,
|
|
250
|
-
obj: KubernetesObject,
|
|
251
|
-
): AdjudicationResult {
|
|
252
|
-
return mismatchedAnnotations(binding, obj)
|
|
253
|
-
? `Binding defines annotations '${JSON.stringify(definedAnnotations(binding))}' but Object carries '${JSON.stringify(carriedAnnotations(obj))}'.`
|
|
254
|
-
: null;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
export function adjudicateMismatchedNamespaceRegex(
|
|
258
|
-
binding: Binding,
|
|
259
|
-
obj: KubernetesObject,
|
|
260
|
-
): AdjudicationResult {
|
|
261
|
-
return mismatchedNamespaceRegex(binding, obj)
|
|
262
|
-
? `Binding defines namespace regexes '${JSON.stringify(definedNamespaceRegexes(binding))}' but Object carries '${carriedNamespace(obj)}'.`
|
|
263
|
-
: null;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
export function adjudicateMismatchedNameRegex(
|
|
267
|
-
binding: Binding,
|
|
268
|
-
obj: KubernetesObject,
|
|
269
|
-
): AdjudicationResult {
|
|
270
|
-
return mismatchedNameRegex(binding, obj)
|
|
271
|
-
? `Binding defines name regex '${definedNameRegex(binding)}' but Object carries '${carriedName(obj)}'.`
|
|
272
|
-
: null;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
export function adjudicateCarriesIgnoredNamespace(
|
|
276
|
-
ignoredNamespaces: string[] | undefined,
|
|
277
|
-
obj: KubernetesObject,
|
|
278
|
-
): AdjudicationResult {
|
|
279
|
-
return carriesIgnoredNamespace(ignoredNamespaces, obj)
|
|
280
|
-
? `Object carries namespace '${obj.kind && obj.kind === "Namespace" ? obj.metadata?.name : carriedNamespace(obj)}' but ignored namespaces include '${JSON.stringify(ignoredNamespaces)}'.`
|
|
281
|
-
: null;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
export function adjudicateMissingCarriableNamespace(
|
|
285
|
-
capabilityNamespaces: string[],
|
|
286
|
-
obj: KubernetesObject,
|
|
287
|
-
): AdjudicationResult {
|
|
288
|
-
return missingCarriableNamespace(capabilityNamespaces, obj)
|
|
289
|
-
? `Object does not carry a namespace but namespaces allowed by Capability are '${JSON.stringify(capabilityNamespaces)}'.`
|
|
290
|
-
: null;
|
|
291
|
-
}
|
package/src/lib/types.ts
CHANGED
|
@@ -308,3 +308,4 @@ export type PeprModuleOptions = {
|
|
|
308
308
|
/** A user-defined callback to post-process or intercept a Pepr response just before it is returned to K8s */
|
|
309
309
|
afterHook?: (res: MutateResponse | ValidateResponse) => void;
|
|
310
310
|
}; // Track if this is a watch mode controller
|
|
311
|
+
export type AdjudicationResult = string | null;
|