pepr 0.42.0 → 0.42.2
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.d.ts +1 -0
- package/dist/cli/build.d.ts.map +1 -1
- package/dist/cli/build.helpers.d.ts +66 -0
- package/dist/cli/build.helpers.d.ts.map +1 -1
- package/dist/cli/deploy.d.ts +15 -0
- package/dist/cli/deploy.d.ts.map +1 -1
- package/dist/cli/dev.d.ts.map +1 -1
- package/dist/cli/format.d.ts.map +1 -1
- package/dist/cli/format.helpers.d.ts +3 -0
- package/dist/cli/format.helpers.d.ts.map +1 -0
- package/dist/cli/init/enums.d.ts +10 -0
- package/dist/cli/init/enums.d.ts.map +1 -0
- package/dist/cli/init/index.d.ts.map +1 -1
- package/dist/cli/init/templates.d.ts +15 -11
- 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 +3 -2
- package/dist/cli/init/walkthrough.d.ts.map +1 -1
- package/dist/cli/kfc.d.ts.map +1 -1
- package/dist/cli/monitor.d.ts +23 -0
- package/dist/cli/monitor.d.ts.map +1 -1
- package/dist/cli/root.d.ts.map +1 -1
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/uuid.d.ts.map +1 -1
- package/dist/cli.js +483 -586
- package/dist/controller.js +1 -195
- package/dist/fixtures/loader.d.ts.map +1 -1
- package/dist/lib/assets/deploy.d.ts.map +1 -1
- package/dist/lib/assets/destroy.d.ts.map +1 -1
- package/dist/lib/assets/helm.d.ts +1 -1
- package/dist/lib/assets/helm.d.ts.map +1 -1
- package/dist/lib/assets/index.d.ts +1 -1
- package/dist/lib/assets/index.d.ts.map +1 -1
- package/dist/lib/assets/pods.d.ts +6 -22
- package/dist/lib/assets/pods.d.ts.map +1 -1
- package/dist/lib/assets/rbac.d.ts.map +1 -1
- package/dist/lib/assets/webhooks.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/controller/store.d.ts +1 -2
- package/dist/lib/controller/store.d.ts.map +1 -1
- package/dist/lib/controller/storeCache.d.ts +2 -1
- package/dist/lib/controller/storeCache.d.ts.map +1 -1
- package/dist/lib/{capability.d.ts → core/capability.d.ts} +1 -1
- package/dist/lib/core/capability.d.ts.map +1 -0
- package/dist/lib/{module.d.ts → core/module.d.ts} +2 -2
- package/dist/lib/core/module.d.ts.map +1 -0
- package/dist/lib/core/queue.d.ts.map +1 -0
- package/dist/lib/{schedule.d.ts → core/schedule.d.ts} +0 -1
- package/dist/lib/core/schedule.d.ts.map +1 -0
- package/dist/lib/{storage.d.ts → core/storage.d.ts} +4 -4
- package/dist/lib/core/storage.d.ts.map +1 -0
- package/dist/lib/deploymentChecks.d.ts.map +1 -1
- package/dist/lib/errors.d.ts +0 -5
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/filesystemService.d.ts.map +1 -1
- package/dist/lib/filter/adjudicators/adjudicators.d.ts +5 -4
- package/dist/lib/filter/adjudicators/adjudicators.d.ts.map +1 -1
- package/dist/lib/filter/filter.d.ts +33 -1
- package/dist/lib/filter/filter.d.ts.map +1 -1
- package/dist/lib/finalizer.d.ts.map +1 -1
- package/dist/lib/helpers.d.ts +4 -9
- package/dist/lib/helpers.d.ts.map +1 -1
- package/dist/lib/included-files.d.ts.map +1 -1
- package/dist/lib/mutate-request.d.ts +2 -2
- package/dist/lib/mutate-request.d.ts.map +1 -1
- package/dist/lib/processors/mutate-processor.d.ts +28 -0
- package/dist/lib/processors/mutate-processor.d.ts.map +1 -0
- package/dist/lib/processors/validate-processor.d.ts +9 -0
- package/dist/lib/processors/validate-processor.d.ts.map +1 -0
- package/dist/lib/{watch-processor.d.ts → processors/watch-processor.d.ts} +2 -2
- package/dist/lib/processors/watch-processor.d.ts.map +1 -0
- package/dist/lib/telemetry/logger.d.ts.map +1 -1
- package/dist/lib/telemetry/metrics.d.ts.map +1 -1
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/validate-request.d.ts +2 -2
- package/dist/lib/validate-request.d.ts.map +1 -1
- package/dist/lib.d.ts +2 -2
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +508 -341
- package/dist/lib.js.map +4 -4
- package/dist/sdk/heredoc.d.ts.map +1 -1
- package/package.json +9 -9
- package/src/cli/build.helpers.ts +180 -0
- package/src/cli/build.ts +85 -133
- package/src/cli/deploy.ts +113 -74
- package/src/cli/dev.ts +2 -2
- package/src/cli/format.helpers.ts +27 -0
- package/src/cli/format.ts +4 -18
- package/src/cli/init/enums.ts +9 -0
- package/src/cli/init/index.ts +4 -3
- package/src/cli/init/templates.ts +30 -2
- package/src/cli/init/utils.ts +3 -3
- package/src/cli/init/walkthrough.ts +7 -8
- package/src/cli/kfc.ts +1 -1
- package/src/cli/monitor.ts +108 -65
- package/src/cli/root.ts +1 -1
- package/src/cli/update.ts +1 -1
- package/src/cli/uuid.ts +1 -1
- package/src/fixtures/loader.ts +2 -2
- package/src/lib/assets/deploy.ts +11 -11
- package/src/lib/assets/destroy.ts +1 -1
- package/src/lib/assets/helm.ts +6 -6
- package/src/lib/assets/index.ts +23 -23
- package/src/lib/assets/pods.ts +11 -6
- package/src/lib/assets/webhooks.ts +31 -46
- package/src/lib/assets/yaml.ts +12 -9
- package/src/lib/controller/index.ts +13 -11
- package/src/lib/controller/store.ts +25 -12
- package/src/lib/controller/storeCache.ts +16 -3
- package/src/lib/{capability.ts → core/capability.ts} +25 -14
- package/src/lib/{module.ts → core/module.ts} +10 -10
- package/src/lib/{queue.ts → core/queue.ts} +13 -5
- package/src/lib/{storage.ts → core/storage.ts} +33 -24
- package/src/lib/deploymentChecks.ts +2 -2
- package/src/lib/errors.ts +3 -8
- package/src/lib/filesystemService.ts +1 -1
- package/src/lib/filter/adjudicators/adjudicators.ts +40 -9
- package/src/lib/filter/filter.ts +204 -111
- package/src/lib/finalizer.ts +2 -2
- package/src/lib/helpers.ts +20 -133
- package/src/lib/included-files.ts +1 -1
- package/src/lib/mutate-request.ts +11 -11
- package/src/lib/processors/mutate-processor.ts +225 -0
- package/src/lib/processors/validate-processor.ts +93 -0
- package/src/lib/{watch-processor.ts → processors/watch-processor.ts} +19 -15
- package/src/lib/telemetry/logger.ts +3 -1
- package/src/lib/tls.ts +5 -1
- package/src/lib/utils.ts +5 -5
- package/src/lib/validate-request.ts +4 -4
- package/src/lib.ts +2 -2
- package/src/runtime/controller.ts +2 -2
- package/src/sdk/cosign.ts +4 -4
- package/src/sdk/heredoc.ts +1 -1
- package/dist/lib/capability.d.ts.map +0 -1
- package/dist/lib/module.d.ts.map +0 -1
- package/dist/lib/mutate-processor.d.ts +0 -6
- package/dist/lib/mutate-processor.d.ts.map +0 -1
- package/dist/lib/queue.d.ts.map +0 -1
- package/dist/lib/schedule.d.ts.map +0 -1
- package/dist/lib/storage.d.ts.map +0 -1
- package/dist/lib/validate-processor.d.ts +0 -6
- package/dist/lib/validate-processor.d.ts.map +0 -1
- package/dist/lib/watch-processor.d.ts.map +0 -1
- package/src/lib/mutate-processor.ts +0 -165
- package/src/lib/validate-processor.ts +0 -85
- /package/dist/lib/{queue.d.ts → core/queue.d.ts} +0 -0
- /package/src/lib/{schedule.ts → core/schedule.ts} +0 -0
|
@@ -11,19 +11,19 @@ export class PeprMutateRequest<T extends KubernetesObject> {
|
|
|
11
11
|
Raw: T;
|
|
12
12
|
#input: AdmissionRequest<T>;
|
|
13
13
|
|
|
14
|
-
get PermitSideEffects() {
|
|
14
|
+
get PermitSideEffects(): boolean {
|
|
15
15
|
return !this.#input.dryRun;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
get IsDryRun() {
|
|
18
|
+
get IsDryRun(): boolean | undefined {
|
|
19
19
|
return this.#input.dryRun;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
get OldResource() {
|
|
22
|
+
get OldResource(): KubernetesObject | undefined {
|
|
23
23
|
return this.#input.oldObject;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
get Request() {
|
|
26
|
+
get Request(): AdmissionRequest<KubernetesObject> {
|
|
27
27
|
return this.#input;
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -42,11 +42,11 @@ export class PeprMutateRequest<T extends KubernetesObject> {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
Merge = (obj: DeepPartial<T>) => {
|
|
45
|
+
Merge = (obj: DeepPartial<T>): void => {
|
|
46
46
|
this.Raw = mergeDeepRight(this.Raw, obj) as unknown as T;
|
|
47
47
|
};
|
|
48
48
|
|
|
49
|
-
SetLabel = (key: string, value: string) => {
|
|
49
|
+
SetLabel = (key: string, value: string): this => {
|
|
50
50
|
const ref = this.Raw;
|
|
51
51
|
ref.metadata = ref.metadata ?? {};
|
|
52
52
|
ref.metadata.labels = ref.metadata.labels ?? {};
|
|
@@ -54,7 +54,7 @@ export class PeprMutateRequest<T extends KubernetesObject> {
|
|
|
54
54
|
return this;
|
|
55
55
|
};
|
|
56
56
|
|
|
57
|
-
SetAnnotation = (key: string, value: string) => {
|
|
57
|
+
SetAnnotation = (key: string, value: string): this => {
|
|
58
58
|
const ref = this.Raw;
|
|
59
59
|
ref.metadata = ref.metadata ?? {};
|
|
60
60
|
ref.metadata.annotations = ref.metadata.annotations ?? {};
|
|
@@ -62,25 +62,25 @@ export class PeprMutateRequest<T extends KubernetesObject> {
|
|
|
62
62
|
return this;
|
|
63
63
|
};
|
|
64
64
|
|
|
65
|
-
RemoveLabel = (key: string) => {
|
|
65
|
+
RemoveLabel = (key: string): this => {
|
|
66
66
|
if (this.Raw.metadata?.labels?.[key]) {
|
|
67
67
|
delete this.Raw.metadata.labels[key];
|
|
68
68
|
}
|
|
69
69
|
return this;
|
|
70
70
|
};
|
|
71
71
|
|
|
72
|
-
RemoveAnnotation = (key: string) => {
|
|
72
|
+
RemoveAnnotation = (key: string): this => {
|
|
73
73
|
if (this.Raw.metadata?.annotations?.[key]) {
|
|
74
74
|
delete this.Raw.metadata.annotations[key];
|
|
75
75
|
}
|
|
76
76
|
return this;
|
|
77
77
|
};
|
|
78
78
|
|
|
79
|
-
HasLabel = (key: string) => {
|
|
79
|
+
HasLabel = (key: string): boolean => {
|
|
80
80
|
return this.Raw.metadata?.labels?.[key] !== undefined;
|
|
81
81
|
};
|
|
82
82
|
|
|
83
|
-
HasAnnotation = (key: string) => {
|
|
83
|
+
HasAnnotation = (key: string): boolean => {
|
|
84
84
|
return this.Raw.metadata?.annotations?.[key] !== undefined;
|
|
85
85
|
};
|
|
86
86
|
}
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// SPDX-FileCopyrightText: 2023-Present The Pepr Authors
|
|
3
|
+
|
|
4
|
+
import jsonPatch from "fast-json-patch";
|
|
5
|
+
import { kind, KubernetesObject } from "kubernetes-fluent-client";
|
|
6
|
+
import { clone } from "ramda";
|
|
7
|
+
|
|
8
|
+
import { Capability } from "../core/capability";
|
|
9
|
+
import { shouldSkipRequest } from "../filter/filter";
|
|
10
|
+
import { MutateResponse } from "../k8s";
|
|
11
|
+
import { AdmissionRequest, Binding } from "../types";
|
|
12
|
+
import Log from "../telemetry/logger";
|
|
13
|
+
import { ModuleConfig } from "../core/module";
|
|
14
|
+
import { PeprMutateRequest } from "../mutate-request";
|
|
15
|
+
import { base64Encode, convertFromBase64Map, convertToBase64Map } from "../utils";
|
|
16
|
+
import { OnError } from "../../cli/init/enums";
|
|
17
|
+
|
|
18
|
+
export interface Bindable {
|
|
19
|
+
req: AdmissionRequest;
|
|
20
|
+
config: ModuleConfig;
|
|
21
|
+
name: string;
|
|
22
|
+
namespaces: string[];
|
|
23
|
+
binding: Binding;
|
|
24
|
+
actMeta: Record<string, string>;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface Result {
|
|
28
|
+
wrapped: PeprMutateRequest<KubernetesObject>;
|
|
29
|
+
response: MutateResponse;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Add annotations to the request to indicate that the capability started processing
|
|
33
|
+
// this will allow tracking of failed mutations that were permitted to continue
|
|
34
|
+
export function updateStatus(
|
|
35
|
+
config: ModuleConfig,
|
|
36
|
+
name: string,
|
|
37
|
+
wrapped: PeprMutateRequest<KubernetesObject>,
|
|
38
|
+
status: string,
|
|
39
|
+
): PeprMutateRequest<KubernetesObject> {
|
|
40
|
+
// Only update the status if the request is a CREATE or UPDATE (we don't use CONNECT)
|
|
41
|
+
if (wrapped.Request.operation === "DELETE") {
|
|
42
|
+
return wrapped;
|
|
43
|
+
}
|
|
44
|
+
wrapped.SetAnnotation(`${config.uuid}.pepr.dev/${name}`, status);
|
|
45
|
+
|
|
46
|
+
return wrapped;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function logMutateErrorMessage(e: Error): string {
|
|
50
|
+
try {
|
|
51
|
+
if (e.message && e.message !== "[object Object]") {
|
|
52
|
+
return e.message;
|
|
53
|
+
} else {
|
|
54
|
+
throw new Error("An error occurred in the mutate action.");
|
|
55
|
+
}
|
|
56
|
+
} catch (e) {
|
|
57
|
+
return "An error occurred with the mutate action.";
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function decodeData(wrapped: PeprMutateRequest<KubernetesObject>): {
|
|
62
|
+
skipped: string[];
|
|
63
|
+
wrapped: PeprMutateRequest<KubernetesObject>;
|
|
64
|
+
} {
|
|
65
|
+
let skipped: string[] = [];
|
|
66
|
+
|
|
67
|
+
const isSecret = wrapped.Request.kind.version === "v1" && wrapped.Request.kind.kind === "Secret";
|
|
68
|
+
if (isSecret) {
|
|
69
|
+
// convertFromBase64Map modifies it's arg rather than returing a mod'ed copy (ye olde side-effect special, blerg)
|
|
70
|
+
skipped = convertFromBase64Map(wrapped.Raw as unknown as kind.Secret);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return { skipped, wrapped };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function reencodeData(wrapped: PeprMutateRequest<KubernetesObject>, skipped: string[]): KubernetesObject {
|
|
77
|
+
const transformed = clone(wrapped.Raw);
|
|
78
|
+
|
|
79
|
+
const isSecret = wrapped.Request.kind.version === "v1" && wrapped.Request.kind.kind === "Secret";
|
|
80
|
+
if (isSecret) {
|
|
81
|
+
// convertToBase64Map modifies it's arg rather than returing a mod'ed copy (ye olde side-effect special, blerg)
|
|
82
|
+
convertToBase64Map(transformed as unknown as kind.Secret, skipped);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return transformed;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export async function processRequest(
|
|
89
|
+
bindable: Bindable,
|
|
90
|
+
wrapped: PeprMutateRequest<KubernetesObject>,
|
|
91
|
+
response: MutateResponse,
|
|
92
|
+
): Promise<Result> {
|
|
93
|
+
const { binding, actMeta, name, config } = bindable;
|
|
94
|
+
|
|
95
|
+
const label = binding.mutateCallback!.name;
|
|
96
|
+
Log.info(actMeta, `Processing mutation action (${label})`);
|
|
97
|
+
|
|
98
|
+
wrapped = updateStatus(config, name, wrapped, "started");
|
|
99
|
+
|
|
100
|
+
try {
|
|
101
|
+
// Run the action
|
|
102
|
+
await binding.mutateCallback!(wrapped);
|
|
103
|
+
|
|
104
|
+
// Log on success
|
|
105
|
+
Log.info(actMeta, `Mutation action succeeded (${label})`);
|
|
106
|
+
|
|
107
|
+
// Add annotations to the request to indicate that the capability succeeded
|
|
108
|
+
wrapped = updateStatus(config, name, wrapped, "succeeded");
|
|
109
|
+
} catch (e) {
|
|
110
|
+
wrapped = updateStatus(config, name, wrapped, "warning");
|
|
111
|
+
response.warnings = response.warnings || [];
|
|
112
|
+
|
|
113
|
+
const errorMessage = logMutateErrorMessage(e);
|
|
114
|
+
|
|
115
|
+
// Log on failure
|
|
116
|
+
Log.error(actMeta, `Action failed: ${errorMessage}`);
|
|
117
|
+
response.warnings.push(`Action failed: ${errorMessage}`);
|
|
118
|
+
|
|
119
|
+
switch (config.onError) {
|
|
120
|
+
case OnError.REJECT:
|
|
121
|
+
response.result = "Pepr module configured to reject on error";
|
|
122
|
+
break;
|
|
123
|
+
|
|
124
|
+
case OnError.AUDIT:
|
|
125
|
+
response.auditAnnotations = response.auditAnnotations || {};
|
|
126
|
+
response.auditAnnotations[Date.now()] = `Action failed: ${errorMessage}`;
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
return { wrapped, response };
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/* eslint max-statements: ["warn", 25] */
|
|
135
|
+
export async function mutateProcessor(
|
|
136
|
+
config: ModuleConfig,
|
|
137
|
+
capabilities: Capability[],
|
|
138
|
+
req: AdmissionRequest,
|
|
139
|
+
reqMetadata: Record<string, string>,
|
|
140
|
+
): Promise<MutateResponse> {
|
|
141
|
+
let response: MutateResponse = {
|
|
142
|
+
uid: req.uid,
|
|
143
|
+
warnings: [],
|
|
144
|
+
allowed: false,
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const decoded = decodeData(new PeprMutateRequest(req));
|
|
148
|
+
let wrapped = decoded.wrapped;
|
|
149
|
+
|
|
150
|
+
Log.info(reqMetadata, `Processing request`);
|
|
151
|
+
|
|
152
|
+
let bindables: Bindable[] = capabilities.flatMap(capa =>
|
|
153
|
+
capa.bindings.map(bind => ({
|
|
154
|
+
req,
|
|
155
|
+
config,
|
|
156
|
+
name: capa.name,
|
|
157
|
+
namespaces: capa.namespaces,
|
|
158
|
+
binding: bind,
|
|
159
|
+
actMeta: { ...reqMetadata, name: capa.name },
|
|
160
|
+
})),
|
|
161
|
+
);
|
|
162
|
+
|
|
163
|
+
bindables = bindables.filter(bind => {
|
|
164
|
+
if (!bind.binding.mutateCallback) {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const shouldSkip = shouldSkipRequest(
|
|
169
|
+
bind.binding,
|
|
170
|
+
bind.req,
|
|
171
|
+
bind.namespaces,
|
|
172
|
+
bind.config?.alwaysIgnore?.namespaces,
|
|
173
|
+
);
|
|
174
|
+
if (shouldSkip !== "") {
|
|
175
|
+
Log.debug(shouldSkip);
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return true;
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
for (const bindable of bindables) {
|
|
183
|
+
({ wrapped, response } = await processRequest(bindable, wrapped, response));
|
|
184
|
+
if (config.onError === OnError.REJECT && response?.warnings!.length > 0) {
|
|
185
|
+
return response;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// If we've made it this far, the request is allowed
|
|
190
|
+
response.allowed = true;
|
|
191
|
+
|
|
192
|
+
// If no capability matched the request, exit early
|
|
193
|
+
if (bindables.length === 0) {
|
|
194
|
+
Log.info(reqMetadata, `No matching actions found`);
|
|
195
|
+
return response;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// delete operations can't be mutate, just return before the transformation
|
|
199
|
+
if (req.operation === "DELETE") {
|
|
200
|
+
return response;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// unskip base64-encoded data fields that were skipDecode'd
|
|
204
|
+
const transformed = reencodeData(wrapped, decoded.skipped);
|
|
205
|
+
|
|
206
|
+
// Compare the original request to the modified request to get the patches
|
|
207
|
+
const patches = jsonPatch.compare(req.object, transformed);
|
|
208
|
+
|
|
209
|
+
// Only add the patch if there are patches to apply
|
|
210
|
+
if (patches.length > 0) {
|
|
211
|
+
response.patchType = "JSONPatch";
|
|
212
|
+
// Webhook must be base64-encoded
|
|
213
|
+
// https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#response
|
|
214
|
+
response.patch = base64Encode(JSON.stringify(patches));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Remove the warnings array if it's empty
|
|
218
|
+
if (response.warnings && response.warnings.length < 1) {
|
|
219
|
+
delete response.warnings;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
Log.debug({ ...reqMetadata, patches }, `Patches generated`);
|
|
223
|
+
|
|
224
|
+
return response;
|
|
225
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// SPDX-FileCopyrightText: 2023-Present The Pepr Authors
|
|
3
|
+
|
|
4
|
+
import { kind, KubernetesObject } from "kubernetes-fluent-client";
|
|
5
|
+
import { Capability } from "../core/capability";
|
|
6
|
+
import { shouldSkipRequest } from "../filter/filter";
|
|
7
|
+
import { ValidateResponse } from "../k8s";
|
|
8
|
+
import { AdmissionRequest, Binding } from "../types";
|
|
9
|
+
import Log from "../telemetry/logger";
|
|
10
|
+
import { convertFromBase64Map } from "../utils";
|
|
11
|
+
import { PeprValidateRequest } from "../validate-request";
|
|
12
|
+
import { ModuleConfig } from "../core/module";
|
|
13
|
+
|
|
14
|
+
export async function processRequest(
|
|
15
|
+
binding: Binding,
|
|
16
|
+
actionMetadata: Record<string, string>,
|
|
17
|
+
peprValidateRequest: PeprValidateRequest<KubernetesObject>,
|
|
18
|
+
): Promise<ValidateResponse> {
|
|
19
|
+
const label = binding.validateCallback!.name;
|
|
20
|
+
Log.info(actionMetadata, `Processing validation action (${label})`);
|
|
21
|
+
|
|
22
|
+
const valResp: ValidateResponse = {
|
|
23
|
+
uid: peprValidateRequest.Request.uid,
|
|
24
|
+
allowed: true, // Assume it's allowed until a validation check fails
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
try {
|
|
28
|
+
// Run the validation callback, if it fails set allowed to false
|
|
29
|
+
const callbackResp = await binding.validateCallback!(peprValidateRequest);
|
|
30
|
+
valResp.allowed = callbackResp.allowed;
|
|
31
|
+
|
|
32
|
+
// If the validation callback returned a status code or message, set it in the Response
|
|
33
|
+
if (callbackResp.statusCode || callbackResp.statusMessage) {
|
|
34
|
+
valResp.status = {
|
|
35
|
+
code: callbackResp.statusCode || 400,
|
|
36
|
+
message: callbackResp.statusMessage || `Validation failed for ${name}`,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
Log.info(actionMetadata, `Validation action complete (${label}): ${callbackResp.allowed ? "allowed" : "denied"}`);
|
|
41
|
+
return valResp;
|
|
42
|
+
} catch (e) {
|
|
43
|
+
// If any validation throws an error, note the failure in the Response
|
|
44
|
+
Log.error(actionMetadata, `Action failed: ${JSON.stringify(e)}`);
|
|
45
|
+
valResp.allowed = false;
|
|
46
|
+
valResp.status = {
|
|
47
|
+
code: 500,
|
|
48
|
+
message: `Action failed with error: ${JSON.stringify(e)}`,
|
|
49
|
+
};
|
|
50
|
+
return valResp;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export async function validateProcessor(
|
|
55
|
+
config: ModuleConfig,
|
|
56
|
+
capabilities: Capability[],
|
|
57
|
+
req: AdmissionRequest,
|
|
58
|
+
reqMetadata: Record<string, string>,
|
|
59
|
+
): Promise<ValidateResponse[]> {
|
|
60
|
+
const wrapped = new PeprValidateRequest(req);
|
|
61
|
+
const response: ValidateResponse[] = [];
|
|
62
|
+
|
|
63
|
+
// If the resource is a secret, decode the data
|
|
64
|
+
const isSecret = req.kind.version === "v1" && req.kind.kind === "Secret";
|
|
65
|
+
if (isSecret) {
|
|
66
|
+
convertFromBase64Map(wrapped.Raw as unknown as kind.Secret);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
Log.info(reqMetadata, `Processing validation request`);
|
|
70
|
+
|
|
71
|
+
for (const { name, bindings, namespaces } of capabilities) {
|
|
72
|
+
const actionMetadata = { ...reqMetadata, name };
|
|
73
|
+
|
|
74
|
+
for (const binding of bindings) {
|
|
75
|
+
// Skip this action if it's not a validation action
|
|
76
|
+
if (!binding.validateCallback) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Continue to the next action without doing anything if this one should be skipped
|
|
81
|
+
const shouldSkip = shouldSkipRequest(binding, req, namespaces, config?.alwaysIgnore?.namespaces);
|
|
82
|
+
if (shouldSkip !== "") {
|
|
83
|
+
Log.debug(shouldSkip);
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const resp = await processRequest(binding, actionMetadata, wrapped);
|
|
88
|
+
response.push(resp);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
return response;
|
|
93
|
+
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
// SPDX-License-Identifier: Apache-2.0
|
|
2
2
|
// SPDX-FileCopyrightText: 2023-Present The Pepr Authors
|
|
3
|
+
import Log from "../telemetry/logger";
|
|
4
|
+
import { Binding } from "../types";
|
|
5
|
+
import { Capability } from "../core/capability";
|
|
6
|
+
import { Event } from "../enums";
|
|
3
7
|
import { K8s, KubernetesObject, WatchCfg, WatchEvent } from "kubernetes-fluent-client";
|
|
8
|
+
import { Queue } from "../core/queue";
|
|
4
9
|
import { WatchPhase } from "kubernetes-fluent-client/dist/fluent/types";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { removeFinalizer } from "
|
|
8
|
-
import Log from "./telemetry/logger";
|
|
9
|
-
import { Queue } from "./queue";
|
|
10
|
-
import { Binding } from "./types";
|
|
11
|
-
import { Event } from "./enums";
|
|
12
|
-
import { metricsCollector } from "./telemetry/metrics";
|
|
10
|
+
import { filterNoMatchReason } from "../filter/filter";
|
|
11
|
+
import { metricsCollector } from "../telemetry/metrics";
|
|
12
|
+
import { removeFinalizer } from "../finalizer";
|
|
13
13
|
|
|
14
14
|
// stores Queue instances
|
|
15
15
|
const queues: Record<string, Queue<KubernetesObject>> = {};
|
|
@@ -20,7 +20,7 @@ const queues: Record<string, Queue<KubernetesObject>> = {};
|
|
|
20
20
|
* @param obj The object to derive a key from
|
|
21
21
|
* @returns The key to a Queue in the list of queues
|
|
22
22
|
*/
|
|
23
|
-
export function queueKey(obj: KubernetesObject) {
|
|
23
|
+
export function queueKey(obj: KubernetesObject): string {
|
|
24
24
|
const options = ["kind", "kindNs", "kindNsName", "global"];
|
|
25
25
|
const d3fault = "kind";
|
|
26
26
|
|
|
@@ -40,7 +40,7 @@ export function queueKey(obj: KubernetesObject) {
|
|
|
40
40
|
return lookup[strat];
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
export function getOrCreateQueue(obj: KubernetesObject) {
|
|
43
|
+
export function getOrCreateQueue(obj: KubernetesObject): Queue<KubernetesObject> {
|
|
44
44
|
const key = queueKey(obj);
|
|
45
45
|
if (!queues[key]) {
|
|
46
46
|
queues[key] = new Queue<KubernetesObject>(key);
|
|
@@ -74,7 +74,7 @@ const eventToPhaseMap = {
|
|
|
74
74
|
*
|
|
75
75
|
* @param capabilities The capabilities to load watches for
|
|
76
76
|
*/
|
|
77
|
-
export function setupWatch(capabilities: Capability[], ignoredNamespaces?: string[]) {
|
|
77
|
+
export function setupWatch(capabilities: Capability[], ignoredNamespaces?: string[]): void {
|
|
78
78
|
capabilities.map(capability =>
|
|
79
79
|
capability.bindings
|
|
80
80
|
.filter(binding => binding.isWatch)
|
|
@@ -88,14 +88,18 @@ export function setupWatch(capabilities: Capability[], ignoredNamespaces?: strin
|
|
|
88
88
|
* @param binding the binding to watch
|
|
89
89
|
* @param capabilityNamespaces list of namespaces to filter on
|
|
90
90
|
*/
|
|
91
|
-
async function runBinding(
|
|
91
|
+
async function runBinding(
|
|
92
|
+
binding: Binding,
|
|
93
|
+
capabilityNamespaces: string[],
|
|
94
|
+
ignoredNamespaces?: string[],
|
|
95
|
+
): Promise<void> {
|
|
92
96
|
// Get the phases to match, fallback to any
|
|
93
97
|
const phaseMatch: WatchPhase[] = eventToPhaseMap[binding.event] || eventToPhaseMap[Event.ANY];
|
|
94
98
|
|
|
95
99
|
// The watch callback is run when an object is received or dequeued
|
|
96
100
|
Log.debug({ watchCfg }, "Effective WatchConfig");
|
|
97
101
|
|
|
98
|
-
const watchCallback = async (kubernetesObject: KubernetesObject, phase: WatchPhase) => {
|
|
102
|
+
const watchCallback = async (kubernetesObject: KubernetesObject, phase: WatchPhase): Promise<void> => {
|
|
99
103
|
// First, filter the object based on the phase
|
|
100
104
|
if (phaseMatch.includes(phase)) {
|
|
101
105
|
try {
|
|
@@ -117,7 +121,7 @@ async function runBinding(binding: Binding, capabilityNamespaces: string[], igno
|
|
|
117
121
|
}
|
|
118
122
|
};
|
|
119
123
|
|
|
120
|
-
const handleFinalizerRemoval = async (kubernetesObject: KubernetesObject) => {
|
|
124
|
+
const handleFinalizerRemoval = async (kubernetesObject: KubernetesObject): Promise<void> => {
|
|
121
125
|
if (!kubernetesObject.metadata?.deletionTimestamp) {
|
|
122
126
|
return;
|
|
123
127
|
}
|
|
@@ -191,7 +195,7 @@ async function runBinding(binding: Binding, capabilityNamespaces: string[], igno
|
|
|
191
195
|
}
|
|
192
196
|
}
|
|
193
197
|
|
|
194
|
-
export function logEvent(event: WatchEvent, message: string = "", obj?: KubernetesObject) {
|
|
198
|
+
export function logEvent(event: WatchEvent, message: string = "", obj?: KubernetesObject): void {
|
|
195
199
|
const logMessage = `Watch event ${event} received${message ? `. ${message}.` : "."}`;
|
|
196
200
|
if (obj) {
|
|
197
201
|
Log.debug(obj, logMessage);
|
|
@@ -18,7 +18,9 @@ const pretty = {
|
|
|
18
18
|
const transport = isPrettyLog ? pretty : undefined;
|
|
19
19
|
// epochTime is the pino default
|
|
20
20
|
const pinoTimeFunction =
|
|
21
|
-
process.env.PINO_TIME_STAMP === "iso"
|
|
21
|
+
process.env.PINO_TIME_STAMP === "iso"
|
|
22
|
+
? (): string => stdTimeFunctions.isoTime()
|
|
23
|
+
: (): string => stdTimeFunctions.epochTime();
|
|
22
24
|
const Log = pino({
|
|
23
25
|
transport,
|
|
24
26
|
timestamp: pinoTimeFunction,
|
package/src/lib/tls.ts
CHANGED
|
@@ -62,7 +62,11 @@ export function genTLS(name: string): TLSOut {
|
|
|
62
62
|
return { ca, key, crt, pem };
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
function genCert(
|
|
65
|
+
function genCert(
|
|
66
|
+
key: forge.pki.rsa.KeyPair,
|
|
67
|
+
name: string,
|
|
68
|
+
issuer: forge.pki.CertificateField[],
|
|
69
|
+
): forge.pki.Certificate {
|
|
66
70
|
const crt = forge.pki.createCertificate();
|
|
67
71
|
crt.publicKey = key.publicKey;
|
|
68
72
|
crt.serialNumber = "01";
|
package/src/lib/utils.ts
CHANGED
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
import Log from "./telemetry/logger";
|
|
5
5
|
|
|
6
6
|
/** Test if a string is ascii or not */
|
|
7
|
-
export const isAscii = /^[\s\x20-\x7E]*$/;
|
|
7
|
+
export const isAscii: RegExp = /^[\s\x20-\x7E]*$/;
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Encode all ascii values in a map to base64
|
|
11
11
|
* @param obj The object to encode
|
|
12
12
|
* @param skip A list of keys to skip encoding
|
|
13
13
|
*/
|
|
14
|
-
export function convertToBase64Map(obj: { data?: Record<string, string> }, skip: string[]) {
|
|
14
|
+
export function convertToBase64Map(obj: { data?: Record<string, string> }, skip: string[]): void {
|
|
15
15
|
obj.data = obj.data ?? {};
|
|
16
16
|
for (const key in obj.data) {
|
|
17
17
|
const value = obj.data[key];
|
|
@@ -25,7 +25,7 @@ export function convertToBase64Map(obj: { data?: Record<string, string> }, skip:
|
|
|
25
25
|
* @param obj The object to decode
|
|
26
26
|
* @returns A list of keys that were skipped
|
|
27
27
|
*/
|
|
28
|
-
export function convertFromBase64Map(obj: { data?: Record<string, string> }) {
|
|
28
|
+
export function convertFromBase64Map(obj: { data?: Record<string, string> }): string[] {
|
|
29
29
|
const skip: string[] = [];
|
|
30
30
|
|
|
31
31
|
obj.data = obj.data ?? {};
|
|
@@ -47,11 +47,11 @@ export function convertFromBase64Map(obj: { data?: Record<string, string> }) {
|
|
|
47
47
|
}
|
|
48
48
|
|
|
49
49
|
/** Decode a base64 string */
|
|
50
|
-
export function base64Decode(data: string) {
|
|
50
|
+
export function base64Decode(data: string): string {
|
|
51
51
|
return Buffer.from(data, "base64").toString("utf-8");
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
/** Encode a string to base64 */
|
|
55
|
-
export function base64Encode(data: string) {
|
|
55
|
+
export function base64Encode(data: string): string {
|
|
56
56
|
return Buffer.from(data).toString("base64");
|
|
57
57
|
}
|
|
@@ -23,7 +23,7 @@ export class PeprValidateRequest<T extends KubernetesObject> {
|
|
|
23
23
|
* Provides access to the old resource in the request if available.
|
|
24
24
|
* @returns The old Kubernetes resource object or null if not available.
|
|
25
25
|
*/
|
|
26
|
-
get OldResource() {
|
|
26
|
+
get OldResource(): KubernetesObject | undefined {
|
|
27
27
|
return this.#input.oldObject;
|
|
28
28
|
}
|
|
29
29
|
|
|
@@ -31,7 +31,7 @@ export class PeprValidateRequest<T extends KubernetesObject> {
|
|
|
31
31
|
* Provides access to the request object.
|
|
32
32
|
* @returns The request object containing the Kubernetes resource.
|
|
33
33
|
*/
|
|
34
|
-
get Request() {
|
|
34
|
+
get Request(): AdmissionRequest<KubernetesObject> {
|
|
35
35
|
return this.#input;
|
|
36
36
|
}
|
|
37
37
|
|
|
@@ -61,7 +61,7 @@ export class PeprValidateRequest<T extends KubernetesObject> {
|
|
|
61
61
|
* @param key the label key to check
|
|
62
62
|
* @returns
|
|
63
63
|
*/
|
|
64
|
-
HasLabel = (key: string) => {
|
|
64
|
+
HasLabel = (key: string): boolean => {
|
|
65
65
|
return this.Raw.metadata?.labels?.[key] !== undefined;
|
|
66
66
|
};
|
|
67
67
|
|
|
@@ -71,7 +71,7 @@ export class PeprValidateRequest<T extends KubernetesObject> {
|
|
|
71
71
|
* @param key the annotation key to check
|
|
72
72
|
* @returns
|
|
73
73
|
*/
|
|
74
|
-
HasAnnotation = (key: string) => {
|
|
74
|
+
HasAnnotation = (key: string): boolean => {
|
|
75
75
|
return this.Raw.metadata?.annotations?.[key] !== undefined;
|
|
76
76
|
};
|
|
77
77
|
|
package/src/lib.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { K8s, RegisterKind, kind as a, fetch, fetchStatus, kind } from "kubernetes-fluent-client";
|
|
2
2
|
import * as R from "ramda";
|
|
3
3
|
|
|
4
|
-
import { Capability } from "./lib/capability";
|
|
4
|
+
import { Capability } from "./lib/core/capability";
|
|
5
5
|
import Log from "./lib/telemetry/logger";
|
|
6
|
-
import { PeprModule } from "./lib/module";
|
|
6
|
+
import { PeprModule } from "./lib/core/module";
|
|
7
7
|
import { PeprMutateRequest } from "./lib/mutate-request";
|
|
8
8
|
import * as PeprUtils from "./lib/utils";
|
|
9
9
|
import { PeprValidateRequest } from "./lib/validate-request";
|
|
@@ -14,7 +14,7 @@ import { peprStoreCRD } from "../lib/assets/store";
|
|
|
14
14
|
import { validateHash } from "../lib/helpers";
|
|
15
15
|
const { version } = packageJSON;
|
|
16
16
|
|
|
17
|
-
function runModule(expectedHash: string) {
|
|
17
|
+
function runModule(expectedHash: string): void {
|
|
18
18
|
const gzPath = `/app/load/module-${expectedHash}.js.gz`;
|
|
19
19
|
const jsPath = `/app/module-${expectedHash}.js`;
|
|
20
20
|
|
|
@@ -59,7 +59,7 @@ Log.info(`Pepr Controller (v${version})`);
|
|
|
59
59
|
|
|
60
60
|
const hash = process.argv[2];
|
|
61
61
|
|
|
62
|
-
const startup = async () => {
|
|
62
|
+
const startup = async (): Promise<void> => {
|
|
63
63
|
try {
|
|
64
64
|
Log.info("Applying the Pepr Store CRD if it doesn't exist");
|
|
65
65
|
await K8s(kind.CustomResourceDefinition).Apply(peprStoreCRD, { force: true });
|
package/src/sdk/cosign.ts
CHANGED
|
@@ -212,15 +212,15 @@ export async function verifyImage(
|
|
|
212
212
|
url: `https://${X.iref.host}/v2/${X.iref.name}/manifests/${X.iref.tag}`,
|
|
213
213
|
};
|
|
214
214
|
|
|
215
|
-
const supportsMediaType = async (url: string, mediaType: string) => {
|
|
215
|
+
const supportsMediaType = async (url: string, mediaType: string): Promise<boolean> => {
|
|
216
216
|
return (await head(url, mediaType, { ca: tlsCrts }))["content-type"] === mediaType;
|
|
217
217
|
};
|
|
218
218
|
|
|
219
|
-
const canOciV1Manifest = async (manifestUrl: string) => {
|
|
219
|
+
const canOciV1Manifest = async (manifestUrl: string): Promise<boolean> => {
|
|
220
220
|
return supportsMediaType(manifestUrl, MediaTypeOciV1.Manifest);
|
|
221
221
|
};
|
|
222
222
|
|
|
223
|
-
const canDockerV2Manifest = async (manifestUrl: string) => {
|
|
223
|
+
const canDockerV2Manifest = async (manifestUrl: string): Promise<boolean> => {
|
|
224
224
|
return supportsMediaType(manifestUrl, MediaTypeDockerV2.Manifest);
|
|
225
225
|
};
|
|
226
226
|
|
|
@@ -228,7 +228,7 @@ export async function verifyImage(
|
|
|
228
228
|
const manifestResp =
|
|
229
229
|
await canOciV1Manifest(X.manifest.url) ? await get(X.manifest.url, MediaTypeOciV1.Manifest, {ca: tlsCrts}) :
|
|
230
230
|
await canDockerV2Manifest(X.manifest.url) ? await get(X.manifest.url, MediaTypeDockerV2.Manifest, {ca: tlsCrts}) :
|
|
231
|
-
(() => { throw "Can't pull image manifest with supported MediaType." })();
|
|
231
|
+
(():never => { throw "Can't pull image manifest with supported MediaType." })();
|
|
232
232
|
X.manifest.content = manifestResp.body;
|
|
233
233
|
|
|
234
234
|
X.manifest.digest = `sha256:${crypto
|
package/src/sdk/heredoc.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Refs:
|
|
2
2
|
// - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates
|
|
3
3
|
|
|
4
|
-
export function heredoc(strings: TemplateStringsArray, ...values: string[]) {
|
|
4
|
+
export function heredoc(strings: TemplateStringsArray, ...values: string[]): string {
|
|
5
5
|
// shuffle strings & expression values back together
|
|
6
6
|
const zipped = strings
|
|
7
7
|
.reduce((acc: string[], cur, idx) => {
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../../src/lib/capability.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAA2B,MAAM,0BAA0B,CAAC;AAInG,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAc,QAAQ,EAAE,MAAM,YAAY,CAAC;AAElD,OAAO,EACL,OAAO,EAGP,aAAa,EACb,gBAAgB,EAQhB,YAAY,EACb,MAAM,SAAS,CAAC;AAMjB;;GAEG;AACH,qBAAa,UAAW,YAAW,gBAAgB;;IASjD,WAAW,EAAE,OAAO,CAAC;IAErB;;;;;OAKG;IACH,UAAU,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAqBtC;IAEK,gBAAgB;IAIvB;;;;;;OAMG;IACH,KAAK,EAAE,SAAS,CASd;IAEF;;;;;;OAMG;IACH,aAAa,EAAE,SAAS,CAStB;IAEF,IAAI,QAAQ,cAEX;IAED,IAAI,IAAI,WAEP;IAED,IAAI,WAAW,WAEd;IAED,IAAI,UAAU,aAEb;gBAEW,GAAG,EAAE,aAAa;IAU9B;;OAEG;IACH,qBAAqB,QAAO,OAAO,CAWjC;IAEF;;;;OAIG;IACH,aAAa,QAAO,OAAO,CAWzB;IAEF;;;;;;;;OAQG;IACH,IAAI,4CAA6C,gBAAgB,qBAiO/D;CACH"}
|
package/dist/lib/module.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/lib/module.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AACxE,OAAO,EAAoB,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAG7D,OAAO,EAAE,YAAY,IAAI,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErE,0CAA0C;AAC1C,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AACD,iDAAiD;AACjD,MAAM,MAAM,YAAY,GAAG;IACzB,wCAAwC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yFAAyF;IACzF,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yBAAyB;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,YAAY,EAAE,aAAa,CAAC;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wDAAwD;IACxD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,2CAA2C;IAC3C,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,wBAAwB;IACxB,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC;IACpB,yFAAyF;IACzF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,YAAY,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB,qHAAqH;IACrH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAE7C,6GAA6G;IAC7G,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,cAAc,GAAG,gBAAgB,KAAK,IAAI,CAAC;CAC9D,CAAC;AAGF,eAAO,MAAM,WAAW,eAA+C,CAAC;AAGxE,eAAO,MAAM,WAAW,eAA0C,CAAC;AAEnE,eAAO,MAAM,SAAS,eAAwC,CAAC;AAE/D,qBAAa,UAAU;;IAGrB;;;;;;OAMG;gBACS,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,YAAY,GAAE,UAAU,EAAO,EAAE,IAAI,GAAE,iBAAsB;IAsD7G;;;;;OAKG;IACH,KAAK,0BAEH;CACH"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { Capability } from "./capability";
|
|
2
|
-
import { MutateResponse } from "./k8s";
|
|
3
|
-
import { AdmissionRequest } from "./types";
|
|
4
|
-
import { ModuleConfig } from "./module";
|
|
5
|
-
export declare function mutateProcessor(config: ModuleConfig, capabilities: Capability[], req: AdmissionRequest, reqMetadata: Record<string, string>): Promise<MutateResponse>;
|
|
6
|
-
//# sourceMappingURL=mutate-processor.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mutate-processor.d.ts","sourceRoot":"","sources":["../../src/lib/mutate-processor.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAG1C,OAAO,EAAE,cAAc,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3C,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAIxC,wBAAsB,eAAe,CACnC,MAAM,EAAE,YAAY,EACpB,YAAY,EAAE,UAAU,EAAE,EAC1B,GAAG,EAAE,gBAAgB,EACrB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAClC,OAAO,CAAC,cAAc,CAAC,CAmIzB"}
|