pepr 0.44.0 → 0.45.0-nightly.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/README.md +1 -1
- package/dist/cli/build.d.ts +3 -3
- package/dist/cli/build.d.ts.map +1 -1
- package/dist/cli/build.helpers.d.ts +13 -7
- package/dist/cli/build.helpers.d.ts.map +1 -1
- package/dist/cli/deploy.d.ts.map +1 -1
- package/dist/cli/init/templates.d.ts +7 -8
- package/dist/cli/init/templates.d.ts.map +1 -1
- package/dist/cli.js +120 -100
- package/dist/controller.js +1 -1
- package/dist/lib/assets/assets.d.ts +2 -2
- package/dist/lib/assets/assets.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 +1 -1
- 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 +2 -0
- package/dist/lib/assets/webhooks.d.ts.map +1 -1
- package/dist/lib/assets/yaml/overridesFile.d.ts +2 -4
- package/dist/lib/assets/yaml/overridesFile.d.ts.map +1 -1
- package/dist/lib/controller/index.d.ts +7 -2
- package/dist/lib/controller/index.d.ts.map +1 -1
- package/dist/lib/core/envChecks.d.ts +4 -0
- package/dist/lib/core/envChecks.d.ts.map +1 -0
- package/dist/lib/core/module.d.ts +1 -48
- package/dist/lib/core/module.d.ts.map +1 -1
- package/dist/lib/core/storage.d.ts.map +1 -1
- package/dist/lib/processors/mutate-processor.d.ts +1 -1
- package/dist/lib/processors/mutate-processor.d.ts.map +1 -1
- package/dist/lib/processors/validate-processor.d.ts +1 -1
- package/dist/lib/processors/validate-processor.d.ts.map +1 -1
- package/dist/lib/processors/watch-processor.d.ts.map +1 -1
- package/dist/lib/telemetry/metrics.d.ts.map +1 -1
- package/dist/lib/types.d.ts +45 -0
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib.js +2008 -1990
- package/dist/lib.js.map +4 -4
- package/package.json +16 -13
- package/src/cli/build.helpers.ts +28 -13
- package/src/cli/build.ts +65 -65
- package/src/cli/deploy.ts +32 -26
- package/src/cli/init/index.ts +2 -2
- package/src/cli/init/templates.ts +6 -5
- package/src/cli/init/walkthrough.ts +1 -1
- package/src/lib/assets/assets.ts +2 -2
- package/src/lib/assets/index.ts +1 -2
- package/src/lib/assets/pods.ts +1 -1
- package/src/lib/assets/rbac.ts +1 -2
- package/src/lib/assets/webhooks.ts +1 -1
- package/src/lib/assets/yaml/overridesFile.ts +4 -6
- package/src/lib/controller/index.ts +19 -11
- package/src/lib/core/capability.ts +1 -1
- package/src/lib/core/envChecks.ts +6 -0
- package/src/lib/core/module.ts +20 -69
- package/src/lib/core/schedule.ts +2 -2
- package/src/lib/core/storage.ts +2 -1
- package/src/lib/processors/mutate-processor.ts +2 -2
- package/src/lib/processors/validate-processor.ts +1 -1
- package/src/lib/processors/watch-processor.ts +5 -3
- package/src/lib/telemetry/metrics.ts +4 -6
- package/src/lib/types.ts +48 -0
- package/src/sdk/heredoc.ts +2 -2
package/package.json
CHANGED
|
@@ -15,27 +15,26 @@
|
|
|
15
15
|
"!src/**/*.test.ts",
|
|
16
16
|
"!dist/**/*.test.d.ts*"
|
|
17
17
|
],
|
|
18
|
-
"version": "0.
|
|
18
|
+
"version": "0.45.0-nightly.1",
|
|
19
19
|
"main": "dist/lib.js",
|
|
20
20
|
"types": "dist/lib.d.ts",
|
|
21
21
|
"scripts": {
|
|
22
22
|
"ci": "npm ci",
|
|
23
23
|
"gen-data-json": "node hack/build-template-data.js",
|
|
24
24
|
"prebuild": "rm -fr dist/* && npm run gen-data-json",
|
|
25
|
-
"version": "node scripts/set-version.js",
|
|
26
25
|
"build": "tsc && node build.mjs && npm pack",
|
|
27
26
|
"build:image": "npm run build && docker buildx build --output type=docker --tag pepr:dev .",
|
|
27
|
+
"set:version": "node scripts/set-version.js",
|
|
28
28
|
"test": "npm run test:unit && npm run test:journey",
|
|
29
29
|
"test:unit": "npm run gen-data-json && jest src --coverage --detectOpenHandles --coverageDirectory=./coverage --testPathIgnorePatterns='cosign.e2e.test.ts'",
|
|
30
30
|
"test:integration": "npm run test:integration:prep && npm run test:integration:run",
|
|
31
31
|
"test:integration:prep": "./integration/prep.sh",
|
|
32
32
|
"test:integration:run": "jest --maxWorkers=4 integration",
|
|
33
33
|
"test:journey": "npm run test:journey:k3d && npm run build && npm run test:journey:image && npm run test:journey:run",
|
|
34
|
-
"test:journey:prep": "if [ ! -d ./pepr-upgrade-test ]; then git clone https://github.com/defenseunicorns/pepr-upgrade-test.git ; fi",
|
|
35
34
|
"test:journey-wasm": "npm run test:journey:k3d && npm run build && npm run test:journey:image && npm run test:journey:run-wasm",
|
|
36
35
|
"test:journey:k3d": "k3d cluster delete pepr-dev && k3d cluster create pepr-dev --k3s-arg '--debug@server:0' --wait && kubectl rollout status deployment -n kube-system",
|
|
37
36
|
"test:journey:image": "docker buildx build --output type=docker --tag pepr:dev . && k3d image import pepr:dev -c pepr-dev",
|
|
38
|
-
"test:journey:run": "jest --detectOpenHandles journey/entrypoint.test.ts && npm run test:journey:
|
|
37
|
+
"test:journey:run": "jest --detectOpenHandles journey/entrypoint.test.ts && npm run test:journey:upgrade",
|
|
39
38
|
"test:journey:run-wasm": "jest --detectOpenHandles journey/entrypoint-wasm.test.ts",
|
|
40
39
|
"test:journey:upgrade": "npm run test:journey:k3d && npm run test:journey:image && jest --detectOpenHandles journey/pepr-upgrade.test.ts",
|
|
41
40
|
"format:check": "eslint src && prettier src --check",
|
|
@@ -57,8 +56,8 @@
|
|
|
57
56
|
"sigstore": "3.0.0"
|
|
58
57
|
},
|
|
59
58
|
"devDependencies": {
|
|
60
|
-
"@commitlint/cli": "19.
|
|
61
|
-
"@commitlint/config-conventional": "19.
|
|
59
|
+
"@commitlint/cli": "19.7.1",
|
|
60
|
+
"@commitlint/config-conventional": "19.7.1",
|
|
62
61
|
"@fast-check/jest": "^2.0.1",
|
|
63
62
|
"@jest/globals": "29.7.0",
|
|
64
63
|
"@types/eslint": "9.6.1",
|
|
@@ -72,20 +71,24 @@
|
|
|
72
71
|
"husky": "^9.1.6",
|
|
73
72
|
"jest": "29.7.0",
|
|
74
73
|
"js-yaml": "^4.1.0",
|
|
74
|
+
"shellcheck": "^3.0.0",
|
|
75
75
|
"ts-jest": "29.2.5",
|
|
76
76
|
"undici": "^7.0.1"
|
|
77
77
|
},
|
|
78
|
+
"overrides": {
|
|
79
|
+
"glob": "^9.0.0"
|
|
80
|
+
},
|
|
78
81
|
"peerDependencies": {
|
|
79
|
-
"@typescript-eslint/eslint-plugin": "7.18.0",
|
|
80
|
-
"@typescript-eslint/parser": "7.18.0",
|
|
81
82
|
"@types/prompts": "2.4.9",
|
|
83
|
+
"@typescript-eslint/eslint-plugin": "8.23.0",
|
|
84
|
+
"@typescript-eslint/parser": "8.23.0",
|
|
85
|
+
"commander": "13.1.0",
|
|
86
|
+
"esbuild": "0.24.2",
|
|
82
87
|
"eslint": "8.57.0",
|
|
83
|
-
"commander": "12.1.0",
|
|
84
|
-
"esbuild": "0.24.0",
|
|
85
88
|
"node-forge": "1.3.1",
|
|
86
89
|
"prettier": "3.4.2",
|
|
87
90
|
"prompts": "2.4.2",
|
|
88
|
-
"typescript": "
|
|
89
|
-
"uuid": "11.0.
|
|
91
|
+
"typescript": "5.7.3",
|
|
92
|
+
"uuid": "11.0.5"
|
|
90
93
|
}
|
|
91
|
-
}
|
|
94
|
+
}
|
package/src/cli/build.helpers.ts
CHANGED
|
@@ -12,6 +12,34 @@ 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
14
|
|
|
15
|
+
interface ImageOptions {
|
|
16
|
+
customImage?: string;
|
|
17
|
+
registryInfo?: string;
|
|
18
|
+
peprVersion?: string;
|
|
19
|
+
registry?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Assign image string
|
|
23
|
+
* @param imageOptions CLI options for image
|
|
24
|
+
* @returns image string
|
|
25
|
+
*/
|
|
26
|
+
export function assignImage(imageOptions: ImageOptions): string {
|
|
27
|
+
const { customImage, registryInfo, peprVersion, registry } = imageOptions;
|
|
28
|
+
if (customImage) {
|
|
29
|
+
return customImage;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (registryInfo) {
|
|
33
|
+
return `${registryInfo}/custom-pepr-controller:${peprVersion}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (registry) {
|
|
37
|
+
return checkIronBankImage(registry, "", peprVersion!);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return "";
|
|
41
|
+
}
|
|
42
|
+
|
|
15
43
|
export type Reloader = (opts: BuildResult<BuildOptions>) => void | Promise<void>;
|
|
16
44
|
/**
|
|
17
45
|
* Determine the RBAC mode based on the CLI options and the module's config
|
|
@@ -114,19 +142,6 @@ export async function handleCustomImageBuild(
|
|
|
114
142
|
}
|
|
115
143
|
}
|
|
116
144
|
|
|
117
|
-
/**
|
|
118
|
-
* Disables embedding of deployment files into output module
|
|
119
|
-
* @param embed
|
|
120
|
-
* @param path
|
|
121
|
-
* @returns
|
|
122
|
-
*/
|
|
123
|
-
export function handleEmbedding(embed: boolean, path: string): void {
|
|
124
|
-
if (!embed) {
|
|
125
|
-
console.info(`✅ Module built successfully at ${path}`);
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
145
|
/**
|
|
131
146
|
* Check if the capability names are valid
|
|
132
147
|
* @param capabilities The capabilities to check
|
package/src/cli/build.ts
CHANGED
|
@@ -11,23 +11,21 @@ import { RootCmd } from "./root";
|
|
|
11
11
|
import { Option } from "commander";
|
|
12
12
|
import { parseTimeout } from "../lib/helpers";
|
|
13
13
|
import { peprFormat } from "./format";
|
|
14
|
+
import { ModuleConfig } from "../lib/types";
|
|
14
15
|
import {
|
|
15
16
|
watchForChanges,
|
|
16
17
|
determineRbacMode,
|
|
17
|
-
|
|
18
|
+
assignImage,
|
|
18
19
|
handleCustomOutputDir,
|
|
19
20
|
handleValidCapabilityNames,
|
|
20
21
|
handleCustomImageBuild,
|
|
21
|
-
checkIronBankImage,
|
|
22
22
|
validImagePullSecret,
|
|
23
23
|
generateYamlAndWriteToDisk,
|
|
24
24
|
} from "./build.helpers";
|
|
25
|
-
import { ModuleConfig } from "../lib/core/module";
|
|
26
25
|
|
|
27
26
|
const peprTS = "pepr.ts";
|
|
28
27
|
let outputDir: string = "dist";
|
|
29
28
|
export type Reloader = (opts: BuildResult<BuildOptions>) => void | Promise<void>;
|
|
30
|
-
|
|
31
29
|
export type PeprNestedFields = Pick<
|
|
32
30
|
ModuleConfig,
|
|
33
31
|
| "uuid"
|
|
@@ -64,7 +62,7 @@ type BuildModuleReturn = {
|
|
|
64
62
|
path: string;
|
|
65
63
|
cfg: PeprConfig;
|
|
66
64
|
uuid: string;
|
|
67
|
-
}
|
|
65
|
+
};
|
|
68
66
|
|
|
69
67
|
export default function (program: RootCmd): void {
|
|
70
68
|
program
|
|
@@ -97,7 +95,7 @@ export default function (program: RootCmd): void {
|
|
|
97
95
|
.addOption(
|
|
98
96
|
new Option(
|
|
99
97
|
"-v, --version <version>",
|
|
100
|
-
"The version of the Pepr image to use in the deployment manifests. Example: '0.27.3'.",
|
|
98
|
+
"DEPRECATED: The version of the Pepr image to use in the deployment manifests. Example: '0.27.3'.",
|
|
101
99
|
).conflicts(["customImage", "registryInfo"]),
|
|
102
100
|
)
|
|
103
101
|
.option(
|
|
@@ -134,68 +132,70 @@ export default function (program: RootCmd): void {
|
|
|
134
132
|
|
|
135
133
|
// Build the module
|
|
136
134
|
const buildModuleResult = await buildModule(undefined, opts.entryPoint, opts.embed);
|
|
137
|
-
if (buildModuleResult?.cfg && buildModuleResult.path && buildModuleResult.uuid) {
|
|
138
|
-
const { cfg, path, uuid } = buildModuleResult;
|
|
139
|
-
// Files to include in controller image for WASM support
|
|
140
|
-
const { includedFiles } = cfg.pepr;
|
|
141
|
-
|
|
142
|
-
let image = opts.customImage || "";
|
|
143
|
-
|
|
144
|
-
// Check if there is a custom timeout defined
|
|
145
|
-
if (opts.timeout !== undefined) {
|
|
146
|
-
cfg.pepr.webhookTimeout = opts.timeout;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
if (opts.registryInfo !== undefined) {
|
|
150
|
-
console.info(`Including ${includedFiles.length} files in controller image.`);
|
|
151
|
-
|
|
152
|
-
// for journey test to make sure the image is built
|
|
153
|
-
image = `${opts.registryInfo}/custom-pepr-controller:${cfg.pepr.peprVersion}`;
|
|
154
|
-
|
|
155
|
-
// only actually build/push if there are files to include
|
|
156
|
-
await handleCustomImageBuild(includedFiles, cfg.pepr.peprVersion, cfg.description, image);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// If building without embedding, exit after building
|
|
160
|
-
handleEmbedding(opts.embed, path);
|
|
161
|
-
|
|
162
|
-
// set the image version if provided
|
|
163
|
-
opts.version ? (cfg.pepr.peprVersion = opts.version) : null;
|
|
164
|
-
|
|
165
|
-
// Generate a secret for the module
|
|
166
|
-
const assets = new Assets(
|
|
167
|
-
{
|
|
168
|
-
...cfg.pepr,
|
|
169
|
-
appVersion: cfg.version,
|
|
170
|
-
description: cfg.description,
|
|
171
|
-
alwaysIgnore: {
|
|
172
|
-
namespaces: cfg.pepr.alwaysIgnore?.namespaces,
|
|
173
|
-
},
|
|
174
|
-
// Can override the rbacMode with the CLI option
|
|
175
|
-
rbacMode: determineRbacMode(opts, cfg),
|
|
176
|
-
},
|
|
177
|
-
path,
|
|
178
|
-
opts.withPullSecret === "" ? [] : [opts.withPullSecret],
|
|
179
|
-
);
|
|
180
135
|
|
|
181
|
-
|
|
182
|
-
|
|
136
|
+
const { cfg, path, uuid } = buildModuleResult!;
|
|
137
|
+
const image = assignImage({
|
|
138
|
+
customImage: opts.customImage,
|
|
139
|
+
registryInfo: opts.registryInfo,
|
|
140
|
+
peprVersion: cfg.pepr.peprVersion,
|
|
141
|
+
registry: opts.registry,
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
// Check if there is a custom timeout defined
|
|
145
|
+
if (opts.timeout !== undefined) {
|
|
146
|
+
cfg.pepr.webhookTimeout = opts.timeout;
|
|
147
|
+
}
|
|
183
148
|
|
|
184
|
-
|
|
185
|
-
|
|
149
|
+
if (opts.registryInfo !== undefined) {
|
|
150
|
+
console.info(`Including ${cfg.pepr.includedFiles.length} files in controller image.`);
|
|
151
|
+
// for journey test to make sure the image is built
|
|
186
152
|
|
|
187
|
-
//
|
|
188
|
-
|
|
153
|
+
// only actually build/push if there are files to include
|
|
154
|
+
await handleCustomImageBuild(
|
|
155
|
+
cfg.pepr.includedFiles,
|
|
156
|
+
cfg.pepr.peprVersion,
|
|
157
|
+
cfg.description,
|
|
158
|
+
image,
|
|
159
|
+
);
|
|
160
|
+
}
|
|
189
161
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
imagePullSecret: opts.withPullSecret,
|
|
195
|
-
zarf: opts.zarf,
|
|
196
|
-
assets,
|
|
197
|
-
});
|
|
162
|
+
// If building without embedding, exit after building
|
|
163
|
+
if (!opts.embed) {
|
|
164
|
+
console.info(`✅ Module built successfully at ${path}`);
|
|
165
|
+
return;
|
|
198
166
|
}
|
|
167
|
+
// set the image version if provided -- DEPRECATED
|
|
168
|
+
if (opts.version) cfg.pepr.peprVersion = opts.version;
|
|
169
|
+
|
|
170
|
+
// Generate a secret for the module
|
|
171
|
+
const assets = new Assets(
|
|
172
|
+
{
|
|
173
|
+
...cfg.pepr,
|
|
174
|
+
appVersion: cfg.version,
|
|
175
|
+
description: cfg.description,
|
|
176
|
+
alwaysIgnore: {
|
|
177
|
+
namespaces: cfg.pepr.alwaysIgnore?.namespaces,
|
|
178
|
+
},
|
|
179
|
+
// Can override the rbacMode with the CLI option
|
|
180
|
+
rbacMode: determineRbacMode(opts, cfg),
|
|
181
|
+
},
|
|
182
|
+
path,
|
|
183
|
+
opts.withPullSecret === "" ? [] : [opts.withPullSecret],
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
if (image !== "") assets.image = image;
|
|
187
|
+
|
|
188
|
+
// Ensure imagePullSecret is valid
|
|
189
|
+
validImagePullSecret(opts.withPullSecret);
|
|
190
|
+
|
|
191
|
+
handleValidCapabilityNames(assets.capabilities);
|
|
192
|
+
await generateYamlAndWriteToDisk({
|
|
193
|
+
uuid,
|
|
194
|
+
outputDir,
|
|
195
|
+
imagePullSecret: opts.withPullSecret,
|
|
196
|
+
zarf: opts.zarf,
|
|
197
|
+
assets,
|
|
198
|
+
});
|
|
199
199
|
});
|
|
200
200
|
}
|
|
201
201
|
|
|
@@ -218,7 +218,7 @@ export async function loadModule(entryPoint = peprTS): Promise<LoadModuleReturn>
|
|
|
218
218
|
try {
|
|
219
219
|
await fs.access(cfgPath);
|
|
220
220
|
await fs.access(entryPointPath);
|
|
221
|
-
} catch
|
|
221
|
+
} catch {
|
|
222
222
|
console.error(
|
|
223
223
|
`Could not find ${cfgPath} or ${entryPointPath} in the current directory. Please run this command from the root of your module's directory.`,
|
|
224
224
|
);
|
|
@@ -253,7 +253,7 @@ export async function buildModule(
|
|
|
253
253
|
reloader?: Reloader,
|
|
254
254
|
entryPoint = peprTS,
|
|
255
255
|
embed = true,
|
|
256
|
-
): Promise<BuildModuleReturn> {
|
|
256
|
+
): Promise<BuildModuleReturn | void> {
|
|
257
257
|
try {
|
|
258
258
|
const { cfg, modulePath, path, uuid } = await loadModule(entryPoint);
|
|
259
259
|
|
package/src/cli/deploy.ts
CHANGED
|
@@ -93,6 +93,35 @@ export async function getUserConfirmation(opts: { confirm: boolean }): Promise<b
|
|
|
93
93
|
return confirm.confirm ? true : false;
|
|
94
94
|
}
|
|
95
95
|
|
|
96
|
+
async function buildAndDeployModule(image: string, force: boolean): Promise<void> {
|
|
97
|
+
const builtModule = await buildModule();
|
|
98
|
+
if (!builtModule) {
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Generate a secret for the module
|
|
103
|
+
const webhook = new Assets(
|
|
104
|
+
{ ...builtModule.cfg.pepr, description: builtModule.cfg.description },
|
|
105
|
+
builtModule.path,
|
|
106
|
+
[],
|
|
107
|
+
);
|
|
108
|
+
webhook.image = image ?? webhook.image;
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
await webhook.deploy(deployWebhook, force, builtModule.cfg.pepr.webhookTimeout ?? 10);
|
|
112
|
+
|
|
113
|
+
// wait for capabilities to be loaded and test names
|
|
114
|
+
validateCapabilityNames(webhook.capabilities);
|
|
115
|
+
|
|
116
|
+
// Wait for the pepr-system resources to be fully up
|
|
117
|
+
await namespaceDeploymentsReady();
|
|
118
|
+
console.info(`✅ Module deployed successfully`);
|
|
119
|
+
} catch (e) {
|
|
120
|
+
console.error(`Error deploying module:`, e);
|
|
121
|
+
process.exit(1);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
96
125
|
export default function (program: RootCmd): void {
|
|
97
126
|
program
|
|
98
127
|
.command("deploy")
|
|
@@ -117,33 +146,10 @@ export default function (program: RootCmd): void {
|
|
|
117
146
|
return;
|
|
118
147
|
}
|
|
119
148
|
|
|
120
|
-
(await getUserConfirmation(opts))
|
|
121
|
-
|
|
122
|
-
const builtModule = await buildModule();
|
|
123
|
-
if (!builtModule) {
|
|
124
|
-
return;
|
|
149
|
+
if (!(await getUserConfirmation(opts))) {
|
|
150
|
+
process.exit(0);
|
|
125
151
|
}
|
|
126
152
|
|
|
127
|
-
|
|
128
|
-
const webhook = new Assets(
|
|
129
|
-
{ ...builtModule.cfg.pepr, description: builtModule.cfg.description },
|
|
130
|
-
builtModule.path,
|
|
131
|
-
[],
|
|
132
|
-
);
|
|
133
|
-
webhook.image = opts.image ?? webhook.image;
|
|
134
|
-
|
|
135
|
-
try {
|
|
136
|
-
await webhook.deploy(deployWebhook, opts.force, builtModule.cfg.pepr.webhookTimeout ?? 10);
|
|
137
|
-
|
|
138
|
-
// wait for capabilities to be loaded and test names
|
|
139
|
-
validateCapabilityNames(webhook.capabilities);
|
|
140
|
-
|
|
141
|
-
// Wait for the pepr-system resources to be fully up
|
|
142
|
-
await namespaceDeploymentsReady();
|
|
143
|
-
console.info(`✅ Module deployed successfully`);
|
|
144
|
-
} catch (e) {
|
|
145
|
-
console.error(`Error deploying module:`, e);
|
|
146
|
-
process.exit(1);
|
|
147
|
-
}
|
|
153
|
+
await buildAndDeployModule(opts.image, opts.force);
|
|
148
154
|
});
|
|
149
155
|
}
|
package/src/cli/init/index.ts
CHANGED
|
@@ -107,7 +107,7 @@ const doPostInitActions = (dirName: string): void => {
|
|
|
107
107
|
execSync("code .", {
|
|
108
108
|
stdio: "inherit",
|
|
109
109
|
});
|
|
110
|
-
} catch
|
|
111
|
-
|
|
110
|
+
} catch {
|
|
111
|
+
console.warn("VSCode was not found, IDE will not automatically open.");
|
|
112
112
|
}
|
|
113
113
|
};
|
|
@@ -6,16 +6,17 @@ import { inspect } from "util";
|
|
|
6
6
|
import { v4 as uuidv4, v5 as uuidv5 } from "uuid";
|
|
7
7
|
|
|
8
8
|
import eslintJSON from "../../templates/.eslintrc.template.json";
|
|
9
|
+
import peprSnippetsJSON from "../../templates/pepr.code-snippets.json";
|
|
9
10
|
import prettierJSON from "../../templates/.prettierrc.json";
|
|
10
11
|
import samplesJSON from "../../templates/capabilities/hello-pepr.samples.json";
|
|
11
|
-
import { gitIgnore, helloPeprTS, packageJSON, peprTS, readmeMd } from "../../templates/data.json";
|
|
12
|
-
import peprSnippetsJSON from "../../templates/pepr.code-snippets.json";
|
|
13
12
|
import settingsJSON from "../../templates/settings.json";
|
|
14
13
|
import tsConfigJSON from "../../templates/tsconfig.module.json";
|
|
15
|
-
import {
|
|
14
|
+
import { CustomLabels } from "../../lib/types";
|
|
16
15
|
import { InitOptions } from "../types";
|
|
17
|
-
import { V1PolicyRule as PolicyRule } from "@kubernetes/client-node";
|
|
18
16
|
import { OnError, RbacMode } from "./enums";
|
|
17
|
+
import { V1PolicyRule as PolicyRule } from "@kubernetes/client-node";
|
|
18
|
+
import { gitIgnore, helloPeprTS, packageJSON, peprTS, readmeMd } from "../../templates/data.json";
|
|
19
|
+
import { sanitizeName } from "./utils";
|
|
19
20
|
|
|
20
21
|
export const { dependencies, devDependencies, peerDependencies, scripts, version } = packageJSON;
|
|
21
22
|
|
|
@@ -30,7 +31,7 @@ type peprPackageJSON = {
|
|
|
30
31
|
uuid: string;
|
|
31
32
|
onError: OnError;
|
|
32
33
|
webhookTimeout: number;
|
|
33
|
-
customLabels:
|
|
34
|
+
customLabels: CustomLabels;
|
|
34
35
|
alwaysIgnore: { namespaces: string[] };
|
|
35
36
|
includedFiles: string[];
|
|
36
37
|
env: object;
|
|
@@ -38,7 +38,7 @@ export async function setName(name?: string): Promise<Answers<string>> {
|
|
|
38
38
|
await fs.access(name, fs.constants.F_OK);
|
|
39
39
|
|
|
40
40
|
return "A directory with this name already exists";
|
|
41
|
-
} catch
|
|
41
|
+
} catch {
|
|
42
42
|
return val.length > 2 || "The name must be at least 3 characters long";
|
|
43
43
|
}
|
|
44
44
|
},
|
package/src/lib/assets/assets.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import crypto from "crypto";
|
|
2
2
|
import { CapabilityExport } from "../types";
|
|
3
|
-
import { ModuleConfig } from "../
|
|
3
|
+
import { ModuleConfig } from "../types";
|
|
4
4
|
import { TLSOut, genTLS } from "../tls";
|
|
5
5
|
import { WebhookIgnore } from "../k8s";
|
|
6
6
|
import {
|
|
@@ -81,7 +81,7 @@ export class Assets {
|
|
|
81
81
|
|
|
82
82
|
allYaml = async (
|
|
83
83
|
yamlGenerationFunction: (
|
|
84
|
-
|
|
84
|
+
assets: Assets,
|
|
85
85
|
deployments: { default: V1Deployment; watch: V1Deployment | null },
|
|
86
86
|
) => Promise<string>,
|
|
87
87
|
imagePullSecret?: string,
|
package/src/lib/assets/index.ts
CHANGED
|
@@ -5,14 +5,13 @@ import { dumpYaml } from "@kubernetes/client-node";
|
|
|
5
5
|
import { kind } from "kubernetes-fluent-client";
|
|
6
6
|
import { replaceString } from "../helpers";
|
|
7
7
|
import { resolve } from "path";
|
|
8
|
-
import { ModuleConfig } from "../
|
|
8
|
+
import { ModuleConfig } from "../types";
|
|
9
9
|
|
|
10
10
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
11
11
|
export function toYaml(obj: any): string {
|
|
12
12
|
return dumpYaml(obj, { noRefs: true });
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
// Unit Test Me!!
|
|
16
15
|
export function createWebhookYaml(
|
|
17
16
|
name: string,
|
|
18
17
|
config: ModuleConfig,
|
package/src/lib/assets/pods.ts
CHANGED
|
@@ -6,7 +6,7 @@ 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 "../
|
|
9
|
+
import { ModuleConfig } from "../types";
|
|
10
10
|
import { Binding } from "../types";
|
|
11
11
|
|
|
12
12
|
/** Generate the pepr-system namespace */
|
package/src/lib/assets/rbac.ts
CHANGED
|
@@ -24,8 +24,7 @@ export function clusterRole(
|
|
|
24
24
|
const rbacMap = createRBACMap(capabilities);
|
|
25
25
|
// Generate scoped rules from rbacMap
|
|
26
26
|
const scopedRules = Object.keys(rbacMap).map(key => {
|
|
27
|
-
|
|
28
|
-
key.split("/").length < 3 ? (group = "") : (group = key.split("/")[0]);
|
|
27
|
+
const group: string = key.split("/").length < 3 ? "" : key.split("/")[0];
|
|
29
28
|
|
|
30
29
|
return {
|
|
31
30
|
apiGroups: [group],
|
|
@@ -15,7 +15,7 @@ import { Binding } from "../types";
|
|
|
15
15
|
|
|
16
16
|
export const peprIgnoreNamespaces: string[] = ["kube-system", "pepr-system"];
|
|
17
17
|
|
|
18
|
-
const validateRule = (binding: Binding, isMutateWebhook: boolean): V1RuleWithOperations | undefined => {
|
|
18
|
+
export const validateRule = (binding: Binding, isMutateWebhook: boolean): V1RuleWithOperations | undefined => {
|
|
19
19
|
const { event, kind, isMutate, isValidate } = binding;
|
|
20
20
|
|
|
21
21
|
// Skip invalid bindings based on webhook type
|
|
@@ -1,21 +1,19 @@
|
|
|
1
1
|
import { genEnv } from "../pods";
|
|
2
|
-
import { ModuleConfig } from "../../
|
|
2
|
+
import { ModuleConfig } from "../../types";
|
|
3
3
|
import { CapabilityExport } from "../../types";
|
|
4
4
|
import { dumpYaml } from "@kubernetes/client-node";
|
|
5
5
|
import { clusterRole } from "../rbac";
|
|
6
6
|
import { promises as fs } from "fs";
|
|
7
7
|
|
|
8
|
-
type
|
|
8
|
+
type ChartOverrides = {
|
|
9
9
|
apiToken: string;
|
|
10
10
|
capabilities: CapabilityExport[];
|
|
11
11
|
config: ModuleConfig;
|
|
12
12
|
hash: string;
|
|
13
13
|
name: string;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
type ChartOverrides = CommonOverrideValues & {
|
|
17
14
|
image: string;
|
|
18
15
|
};
|
|
16
|
+
|
|
19
17
|
// Helm Chart overrides file (values.yaml) generated from assets
|
|
20
18
|
export async function overridesFile(
|
|
21
19
|
{ hash, name, image, config, apiToken, capabilities }: ChartOverrides,
|
|
@@ -34,7 +32,7 @@ export async function overridesFile(
|
|
|
34
32
|
hash,
|
|
35
33
|
namespace: {
|
|
36
34
|
annotations: {},
|
|
37
|
-
labels: {
|
|
35
|
+
labels: config.customLabels?.namespace ?? {
|
|
38
36
|
"pepr.dev": "",
|
|
39
37
|
},
|
|
40
38
|
},
|
|
@@ -9,13 +9,20 @@ import { Capability } from "../core/capability";
|
|
|
9
9
|
import { MutateResponse, ValidateResponse } from "../k8s";
|
|
10
10
|
import Log from "../telemetry/logger";
|
|
11
11
|
import { metricsCollector, MetricsCollector } from "../telemetry/metrics";
|
|
12
|
-
import {
|
|
12
|
+
import { isWatchMode } from "../core/envChecks";
|
|
13
|
+
import { ModuleConfig } from "../types";
|
|
13
14
|
import { mutateProcessor } from "../processors/mutate-processor";
|
|
14
15
|
import { validateProcessor } from "../processors/validate-processor";
|
|
15
16
|
import { StoreController } from "./store";
|
|
16
17
|
import { AdmissionRequest } from "../types";
|
|
17
18
|
import { karForMutate, karForValidate, KubeAdmissionReview } from "./index.util";
|
|
18
19
|
|
|
20
|
+
export interface ControllerHooks {
|
|
21
|
+
beforeHook?: (req: AdmissionRequest) => void;
|
|
22
|
+
afterHook?: (res: MutateResponse | ValidateResponse) => void;
|
|
23
|
+
onReady?: () => void;
|
|
24
|
+
}
|
|
25
|
+
|
|
19
26
|
if (!process.env.PEPR_NODE_WARNINGS) {
|
|
20
27
|
process.removeAllListeners("warning");
|
|
21
28
|
}
|
|
@@ -39,20 +46,17 @@ export class Controller {
|
|
|
39
46
|
readonly #beforeHook?: (req: AdmissionRequest) => void;
|
|
40
47
|
readonly #afterHook?: (res: MutateResponse | ValidateResponse) => void;
|
|
41
48
|
|
|
42
|
-
constructor(
|
|
43
|
-
|
|
44
|
-
capabilities: Capability[],
|
|
45
|
-
beforeHook?: (req: AdmissionRequest) => void,
|
|
46
|
-
afterHook?: (res: MutateResponse | ValidateResponse) => void,
|
|
47
|
-
onReady?: () => void,
|
|
48
|
-
) {
|
|
49
|
+
constructor(config: ModuleConfig, capabilities: Capability[], hooks: ControllerHooks = {}) {
|
|
50
|
+
const { beforeHook, afterHook, onReady } = hooks;
|
|
49
51
|
this.#config = config;
|
|
50
52
|
this.#capabilities = capabilities;
|
|
51
53
|
|
|
52
54
|
// Initialize the Pepr store for each capability
|
|
53
55
|
new StoreController(capabilities, `pepr-${config.uuid}-store`, () => {
|
|
54
56
|
this.#bindEndpoints();
|
|
55
|
-
onReady
|
|
57
|
+
if (typeof onReady === "function") {
|
|
58
|
+
onReady();
|
|
59
|
+
}
|
|
56
60
|
Log.info("✅ Controller startup complete");
|
|
57
61
|
// Initialize the schedule store for each capability
|
|
58
62
|
new StoreController(capabilities, `pepr-${config.uuid}-schedule`, () => {
|
|
@@ -223,7 +227,9 @@ export class Controller {
|
|
|
223
227
|
Log.debug({ ...reqMetadata, request }, "Incoming request body");
|
|
224
228
|
|
|
225
229
|
// Run the before hook if it exists
|
|
226
|
-
|
|
230
|
+
if (typeof this.#beforeHook === "function") {
|
|
231
|
+
this.#beforeHook(request || {});
|
|
232
|
+
}
|
|
227
233
|
|
|
228
234
|
// Process the request
|
|
229
235
|
const response: MutateResponse | ValidateResponse[] =
|
|
@@ -233,7 +239,9 @@ export class Controller {
|
|
|
233
239
|
|
|
234
240
|
// Run the after hook if it exists
|
|
235
241
|
[response].flat().map(res => {
|
|
236
|
-
this.#afterHook
|
|
242
|
+
if (typeof this.#afterHook === "function") {
|
|
243
|
+
this.#afterHook(res);
|
|
244
|
+
}
|
|
237
245
|
Log.info({ ...reqMetadata, res }, "Check response");
|
|
238
246
|
});
|
|
239
247
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { GenericClass, GroupVersionKind, modelToGroupVersionKind } from "kubernetes-fluent-client";
|
|
5
5
|
import { pickBy } from "ramda";
|
|
6
6
|
import Log from "../telemetry/logger";
|
|
7
|
-
import { isBuildMode, isDevMode, isWatchMode } from "./
|
|
7
|
+
import { isBuildMode, isDevMode, isWatchMode } from "./envChecks";
|
|
8
8
|
import { PeprStore, Storage } from "./storage";
|
|
9
9
|
import { OnSchedule, Schedule } from "./schedule";
|
|
10
10
|
import { Event } from "../enums";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const isWatchMode = (): boolean => process.env.PEPR_WATCH_MODE === "true";
|
|
2
|
+
// Track if Pepr is running in build mode
|
|
3
|
+
|
|
4
|
+
export const isBuildMode = (): boolean => process.env.PEPR_MODE === "build";
|
|
5
|
+
|
|
6
|
+
export const isDevMode = (): boolean => process.env.PEPR_MODE === "dev";
|