pepr 0.1.19 → 0.1.21
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/pepr-cli.js +115 -250
- package/dist/pepr-core.js +898 -0
- package/dist/types-672dd6e4.js +163 -0
- package/package.json +5 -4
- package/src/lib/k8s/tls.ts +59 -38
- package/src/lib/k8s/webhook.ts +2 -3
- package/tsconfig.json +3 -0
- package/dist/pepr-cli.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Pepr
|
|
2
2
|
|
|
3
|
-
<img align="right" width="
|
|
3
|
+
<img align="right" width="40%" src=".images/pepr.png" />
|
|
4
4
|
|
|
5
5
|
Pepr is an open-source project that helps IT Ops teams of all skill levels manage and modify resources in a Kubernetes (K8s) cluster using TypeScript. Kubernetes simplifies the management of multiple computers working together to run and scale applications. Pepr acts as a smart assistant, automatically changing or validating parts of the system as needed.
|
|
6
6
|
|
package/dist/pepr-cli.js
CHANGED
|
@@ -7,6 +7,7 @@ var typescript = require('@rollup/plugin-typescript');
|
|
|
7
7
|
var fs = require('fs');
|
|
8
8
|
var path = require('path');
|
|
9
9
|
var rollup = require('rollup');
|
|
10
|
+
var types = require('./types-672dd6e4.js');
|
|
10
11
|
require('@kubernetes/client-node/dist');
|
|
11
12
|
require('ramda');
|
|
12
13
|
require('fast-json-patch');
|
|
@@ -20,7 +21,7 @@ var uuid = require('uuid');
|
|
|
20
21
|
var commander = require('commander');
|
|
21
22
|
var chokidar = require('chokidar');
|
|
22
23
|
|
|
23
|
-
var version = "0.1.
|
|
24
|
+
var version = "0.1.21";
|
|
24
25
|
|
|
25
26
|
// SPDX-License-Identifier: Apache-2.0
|
|
26
27
|
// SPDX-FileCopyrightText: 2023-Present The Pepr Authors
|
|
@@ -90,207 +91,66 @@ const banner = `[107;40m[38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;
|
|
|
90
91
|
[38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m [38;5;016m
|
|
91
92
|
[0m`;
|
|
92
93
|
|
|
93
|
-
|
|
94
|
-
// SPDX-FileCopyrightText: 2023-Present The Pepr Authors
|
|
95
|
-
/**
|
|
96
|
-
* Enumeration representing different logging levels.
|
|
97
|
-
*/
|
|
98
|
-
var LogLevel;
|
|
99
|
-
(function (LogLevel) {
|
|
100
|
-
LogLevel[LogLevel["debug"] = 0] = "debug";
|
|
101
|
-
LogLevel[LogLevel["info"] = 1] = "info";
|
|
102
|
-
LogLevel[LogLevel["warn"] = 2] = "warn";
|
|
103
|
-
LogLevel[LogLevel["error"] = 3] = "error";
|
|
104
|
-
})(LogLevel || (LogLevel = {}));
|
|
105
|
-
var ConsoleColors;
|
|
106
|
-
(function (ConsoleColors) {
|
|
107
|
-
ConsoleColors["Reset"] = "\u001B[0m";
|
|
108
|
-
ConsoleColors["Bright"] = "\u001B[1m";
|
|
109
|
-
ConsoleColors["Dim"] = "\u001B[2m";
|
|
110
|
-
ConsoleColors["Underscore"] = "\u001B[4m";
|
|
111
|
-
ConsoleColors["Blink"] = "\u001B[5m";
|
|
112
|
-
ConsoleColors["Reverse"] = "\u001B[7m";
|
|
113
|
-
ConsoleColors["Hidden"] = "\u001B[8m";
|
|
114
|
-
ConsoleColors["FgBlack"] = "\u001B[30m";
|
|
115
|
-
ConsoleColors["FgRed"] = "\u001B[31m";
|
|
116
|
-
ConsoleColors["FgGreen"] = "\u001B[32m";
|
|
117
|
-
ConsoleColors["FgYellow"] = "\u001B[33m";
|
|
118
|
-
ConsoleColors["FgBlue"] = "\u001B[34m";
|
|
119
|
-
ConsoleColors["FgMagenta"] = "\u001B[35m";
|
|
120
|
-
ConsoleColors["FgCyan"] = "\u001B[36m";
|
|
121
|
-
ConsoleColors["FgWhite"] = "\u001B[37m";
|
|
122
|
-
ConsoleColors["BgBlack"] = "\u001B[40m";
|
|
123
|
-
ConsoleColors["BgRed"] = "\u001B[41m";
|
|
124
|
-
ConsoleColors["BgGreen"] = "\u001B[42m";
|
|
125
|
-
ConsoleColors["BgYellow"] = "\u001B[43m";
|
|
126
|
-
ConsoleColors["BgBlue"] = "\u001B[44m";
|
|
127
|
-
ConsoleColors["BgMagenta"] = "\u001B[45m";
|
|
128
|
-
ConsoleColors["BgCyan"] = "\u001B[46m";
|
|
129
|
-
ConsoleColors["BgWhite"] = "\u001B[47m";
|
|
130
|
-
})(ConsoleColors || (ConsoleColors = {}));
|
|
94
|
+
const caName = "Pepr Ephemeral CA";
|
|
131
95
|
/**
|
|
132
|
-
*
|
|
133
|
-
*/
|
|
134
|
-
class Logger {
|
|
135
|
-
/**
|
|
136
|
-
* Create a new logger instance.
|
|
137
|
-
* @param logLevel - The minimum log level to log messages for.
|
|
138
|
-
*/
|
|
139
|
-
constructor(logLevel) {
|
|
140
|
-
this._logLevel = logLevel;
|
|
141
|
-
}
|
|
142
|
-
/**
|
|
143
|
-
* Change the log level of the logger.
|
|
144
|
-
* @param logLevel - The log level to log the message at.
|
|
145
|
-
*/
|
|
146
|
-
SetLogLevel(logLevel) {
|
|
147
|
-
this._logLevel = LogLevel[logLevel];
|
|
148
|
-
this.debug(`Log level set to ${logLevel}`);
|
|
149
|
-
}
|
|
150
|
-
/**
|
|
151
|
-
* Log a debug message.
|
|
152
|
-
* @param message - The message to log.
|
|
153
|
-
*/
|
|
154
|
-
debug(message, prefix) {
|
|
155
|
-
this.log(LogLevel.debug, message, prefix);
|
|
156
|
-
}
|
|
157
|
-
/**
|
|
158
|
-
* Log an info message.
|
|
159
|
-
* @param message - The message to log.
|
|
160
|
-
*/
|
|
161
|
-
info(message, prefix) {
|
|
162
|
-
this.log(LogLevel.info, message, prefix);
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Log a warning message.
|
|
166
|
-
* @param message - The message to log.
|
|
167
|
-
*/
|
|
168
|
-
warn(message, prefix) {
|
|
169
|
-
this.log(LogLevel.warn, message, prefix);
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* Log an error message.
|
|
173
|
-
* @param message - The message to log.
|
|
174
|
-
*/
|
|
175
|
-
error(message, prefix) {
|
|
176
|
-
this.log(LogLevel.error, message, prefix);
|
|
177
|
-
}
|
|
178
|
-
/**
|
|
179
|
-
* Log a message at the specified log level.
|
|
180
|
-
* @param logLevel - The log level of the message.
|
|
181
|
-
* @param message - The message to log.
|
|
182
|
-
*/
|
|
183
|
-
log(logLevel, message, callerPrefix = "") {
|
|
184
|
-
const color = {
|
|
185
|
-
[LogLevel.debug]: ConsoleColors.FgBlack,
|
|
186
|
-
[LogLevel.info]: ConsoleColors.FgCyan,
|
|
187
|
-
[LogLevel.warn]: ConsoleColors.FgYellow,
|
|
188
|
-
[LogLevel.error]: ConsoleColors.FgRed,
|
|
189
|
-
};
|
|
190
|
-
if (logLevel >= this._logLevel) {
|
|
191
|
-
// Prefix the message with the colored log level.
|
|
192
|
-
let prefix = "[" + LogLevel[logLevel] + "]\t" + callerPrefix;
|
|
193
|
-
prefix = this.colorize(prefix, color[logLevel]);
|
|
194
|
-
// If the message is not a string, use the debug method to log the object.
|
|
195
|
-
if (typeof message !== "string") {
|
|
196
|
-
console.log(prefix);
|
|
197
|
-
console.debug("%o", message);
|
|
198
|
-
}
|
|
199
|
-
else {
|
|
200
|
-
console.log(prefix + "\t" + message);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
colorize(text, color) {
|
|
205
|
-
return color + text + ConsoleColors.Reset;
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
var Log = new Logger(LogLevel.info);
|
|
209
|
-
|
|
210
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
211
|
-
// SPDX-FileCopyrightText: 2023-Present The Pepr Authors
|
|
212
|
-
var Operation;
|
|
213
|
-
(function (Operation) {
|
|
214
|
-
Operation["CREATE"] = "CREATE";
|
|
215
|
-
Operation["UPDATE"] = "UPDATE";
|
|
216
|
-
Operation["DELETE"] = "DELETE";
|
|
217
|
-
Operation["CONNECT"] = "CONNECT";
|
|
218
|
-
})(Operation || (Operation = {}));
|
|
219
|
-
|
|
220
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
221
|
-
// SPDX-FileCopyrightText: 2023-Present The Pepr Authors
|
|
222
|
-
/**
|
|
223
|
-
* The behavior of this module when an error occurs.
|
|
224
|
-
*/
|
|
225
|
-
var ErrorBehavior;
|
|
226
|
-
(function (ErrorBehavior) {
|
|
227
|
-
ErrorBehavior["ignore"] = "ignore";
|
|
228
|
-
ErrorBehavior["audit"] = "audit";
|
|
229
|
-
ErrorBehavior["reject"] = "reject";
|
|
230
|
-
})(ErrorBehavior || (ErrorBehavior = {}));
|
|
231
|
-
/**
|
|
232
|
-
* The phase of the Kubernetes admission webhook that the capability is registered for.
|
|
96
|
+
* Generates a self-signed CA and server certificate with Subject Alternative Names (SANs) for the K8s webhook.
|
|
233
97
|
*
|
|
234
|
-
*
|
|
98
|
+
* @param {string} name - The name to use for the server certificate's Common Name and SAN DNS entry.
|
|
99
|
+
* @returns {TLSOut} - An object containing the Base64-encoded CA, server certificate, and server private key.
|
|
235
100
|
*/
|
|
236
|
-
var HookPhase;
|
|
237
|
-
(function (HookPhase) {
|
|
238
|
-
HookPhase["mutate"] = "mutate";
|
|
239
|
-
HookPhase["valdiate"] = "validate";
|
|
240
|
-
})(HookPhase || (HookPhase = {}));
|
|
241
|
-
/**
|
|
242
|
-
* The type of Kubernetes mutating webhook event ethat the capability action is registered for.
|
|
243
|
-
*/
|
|
244
|
-
var Event;
|
|
245
|
-
(function (Event) {
|
|
246
|
-
Event["Create"] = "create";
|
|
247
|
-
Event["Update"] = "update";
|
|
248
|
-
Event["Delete"] = "delete";
|
|
249
|
-
Event["CreateOrUpdate"] = "createOrUpdate";
|
|
250
|
-
})(Event || (Event = {}));
|
|
251
|
-
|
|
252
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
253
101
|
function genTLS(name) {
|
|
254
|
-
// Generate a new CA key pair
|
|
102
|
+
// Generate a new CA key pair and create a self-signed CA certificate
|
|
255
103
|
const caKeys = forge.pki.rsa.generateKeyPair(2048);
|
|
256
|
-
const caCert =
|
|
257
|
-
caCert.
|
|
258
|
-
caCert.serialNumber = "01";
|
|
259
|
-
caCert.validity.notBefore = new Date();
|
|
260
|
-
caCert.validity.notAfter = new Date();
|
|
261
|
-
caCert.validity.notAfter.setFullYear(caCert.validity.notBefore.getFullYear() + 1);
|
|
262
|
-
const caAttrs = [
|
|
104
|
+
const caCert = genCert(caKeys, caName, [{ name: "commonName", value: caName }]);
|
|
105
|
+
caCert.setExtensions([
|
|
263
106
|
{
|
|
264
|
-
name: "
|
|
265
|
-
|
|
107
|
+
name: "basicConstraints",
|
|
108
|
+
cA: true,
|
|
266
109
|
},
|
|
267
|
-
];
|
|
268
|
-
caCert.setSubject(caAttrs);
|
|
269
|
-
caCert.setIssuer(caAttrs);
|
|
270
|
-
caCert.sign(caKeys.privateKey, forge.md.sha256.create());
|
|
271
|
-
// Generate a new key pair
|
|
272
|
-
const keys = forge.pki.rsa.generateKeyPair(2048);
|
|
273
|
-
const cert = forge.pki.createCertificate();
|
|
274
|
-
cert.publicKey = keys.publicKey;
|
|
275
|
-
cert.serialNumber = "01";
|
|
276
|
-
cert.validity.notBefore = new Date();
|
|
277
|
-
cert.validity.notAfter = new Date();
|
|
278
|
-
cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1);
|
|
279
|
-
const attrs = [
|
|
280
110
|
{
|
|
281
|
-
name: "
|
|
282
|
-
|
|
111
|
+
name: "keyUsage",
|
|
112
|
+
keyCertSign: true,
|
|
113
|
+
digitalSignature: true,
|
|
114
|
+
nonRepudiation: true,
|
|
115
|
+
keyEncipherment: true,
|
|
116
|
+
dataEncipherment: true,
|
|
283
117
|
},
|
|
284
|
-
];
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
//
|
|
118
|
+
]);
|
|
119
|
+
// Generate a new server key pair and create a server certificate signed by the CA
|
|
120
|
+
const serverKeys = forge.pki.rsa.generateKeyPair(2048);
|
|
121
|
+
const serverCert = genCert(serverKeys, `${name}.pepr-system.svc`, caCert.subject.attributes);
|
|
122
|
+
// Sign both certificates with the CA private key
|
|
123
|
+
caCert.sign(caKeys.privateKey, forge.md.sha256.create());
|
|
124
|
+
serverCert.sign(caKeys.privateKey, forge.md.sha256.create());
|
|
125
|
+
// Convert the keys and certificates to PEM format and Base64-encode them
|
|
289
126
|
const ca = Buffer.from(forge.pki.certificateToPem(caCert)).toString("base64");
|
|
290
|
-
const key = Buffer.from(forge.pki.privateKeyToPem(
|
|
291
|
-
const crt = Buffer.from(forge.pki.certificateToPem(
|
|
127
|
+
const key = Buffer.from(forge.pki.privateKeyToPem(serverKeys.privateKey)).toString("base64");
|
|
128
|
+
const crt = Buffer.from(forge.pki.certificateToPem(serverCert)).toString("base64");
|
|
292
129
|
return { ca, key, crt };
|
|
293
130
|
}
|
|
131
|
+
function genCert(key, name, issuer) {
|
|
132
|
+
const crt = forge.pki.createCertificate();
|
|
133
|
+
crt.publicKey = key.publicKey;
|
|
134
|
+
crt.serialNumber = "01";
|
|
135
|
+
crt.validity.notBefore = new Date();
|
|
136
|
+
crt.validity.notAfter = new Date();
|
|
137
|
+
crt.validity.notAfter.setFullYear(crt.validity.notBefore.getFullYear() + 1);
|
|
138
|
+
// Add SANs to the server certificate
|
|
139
|
+
crt.setExtensions([
|
|
140
|
+
{
|
|
141
|
+
name: "subjectAltName",
|
|
142
|
+
altNames: [
|
|
143
|
+
{
|
|
144
|
+
type: 2,
|
|
145
|
+
value: name,
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
},
|
|
149
|
+
]);
|
|
150
|
+
// Set the server certificate's issuer to the CA
|
|
151
|
+
crt.setIssuer(issuer);
|
|
152
|
+
return crt;
|
|
153
|
+
}
|
|
294
154
|
|
|
295
155
|
// SPDX-License-Identifier: Apache-2.0
|
|
296
156
|
const peprIgnore = {
|
|
@@ -301,7 +161,6 @@ const peprIgnore = {
|
|
|
301
161
|
class Webhook {
|
|
302
162
|
constructor(config) {
|
|
303
163
|
this.config = config;
|
|
304
|
-
this.ns = "pepr-system";
|
|
305
164
|
this.name = `pepr-${config.uuid}`;
|
|
306
165
|
this.image = `ghcr.io/defenseunicorns/pepr/controller:${config.version}`;
|
|
307
166
|
// Generate the ephemeral tls things
|
|
@@ -423,7 +282,7 @@ class Webhook {
|
|
|
423
282
|
apiGroups: ["*"],
|
|
424
283
|
apiVersions: ["*"],
|
|
425
284
|
operations: ["CREATE", "UPDATE", "DELETE"],
|
|
426
|
-
resources: ["
|
|
285
|
+
resources: ["*/*"],
|
|
427
286
|
},
|
|
428
287
|
],
|
|
429
288
|
// @todo: track side effects state
|
|
@@ -587,7 +446,7 @@ class Webhook {
|
|
|
587
446
|
return resources.map(r => clientNode.dumpYaml(r, { noRefs: true })).join("---\n");
|
|
588
447
|
}
|
|
589
448
|
async deploy(code) {
|
|
590
|
-
Log.info("Establishing connection to Kubernetes");
|
|
449
|
+
types.Log.info("Establishing connection to Kubernetes");
|
|
591
450
|
const namespace = "pepr-system";
|
|
592
451
|
// Deploy the resources using the k8s API
|
|
593
452
|
const kubeConfig = new clientNode.KubeConfig();
|
|
@@ -598,104 +457,104 @@ class Webhook {
|
|
|
598
457
|
const admissionApi = kubeConfig.makeApiClient(clientNode.AdmissionregistrationV1Api);
|
|
599
458
|
const ns = this.namespace();
|
|
600
459
|
try {
|
|
601
|
-
Log.info("Checking for namespace");
|
|
460
|
+
types.Log.info("Checking for namespace");
|
|
602
461
|
await coreV1Api.readNamespace(namespace);
|
|
603
462
|
}
|
|
604
463
|
catch (e) {
|
|
605
|
-
Log.debug(e.body);
|
|
606
|
-
Log.info("Creating namespace");
|
|
464
|
+
types.Log.debug(e.body);
|
|
465
|
+
types.Log.info("Creating namespace");
|
|
607
466
|
await coreV1Api.createNamespace(ns);
|
|
608
467
|
}
|
|
609
468
|
const wh = this.mutatingWebhook();
|
|
610
469
|
try {
|
|
611
|
-
Log.info("Creating mutating webhook");
|
|
470
|
+
types.Log.info("Creating mutating webhook");
|
|
612
471
|
await admissionApi.createMutatingWebhookConfiguration(wh);
|
|
613
472
|
}
|
|
614
473
|
catch (e) {
|
|
615
|
-
Log.debug(e.body);
|
|
616
|
-
Log.info("Removing and re-creating mutating webhook");
|
|
474
|
+
types.Log.debug(e.body);
|
|
475
|
+
types.Log.info("Removing and re-creating mutating webhook");
|
|
617
476
|
await admissionApi.deleteMutatingWebhookConfiguration(wh.metadata.name);
|
|
618
477
|
await admissionApi.createMutatingWebhookConfiguration(wh);
|
|
619
478
|
}
|
|
620
479
|
const crb = this.clusterRoleBinding();
|
|
621
480
|
try {
|
|
622
|
-
Log.info("Creating cluster role binding");
|
|
481
|
+
types.Log.info("Creating cluster role binding");
|
|
623
482
|
await rbacApi.createClusterRoleBinding(crb);
|
|
624
483
|
}
|
|
625
484
|
catch (e) {
|
|
626
|
-
Log.debug(e.body);
|
|
627
|
-
Log.info("Removing and re-creating cluster role binding");
|
|
485
|
+
types.Log.debug(e.body);
|
|
486
|
+
types.Log.info("Removing and re-creating cluster role binding");
|
|
628
487
|
await rbacApi.deleteClusterRoleBinding(crb.metadata.name);
|
|
629
488
|
await rbacApi.createClusterRoleBinding(crb);
|
|
630
489
|
}
|
|
631
490
|
const cr = this.clusterRole();
|
|
632
491
|
try {
|
|
633
|
-
Log.info("Creating cluster role");
|
|
492
|
+
types.Log.info("Creating cluster role");
|
|
634
493
|
await rbacApi.createClusterRole(cr);
|
|
635
494
|
}
|
|
636
495
|
catch (e) {
|
|
637
|
-
Log.debug(e.body);
|
|
638
|
-
Log.info("Removing and re-creating the cluster role");
|
|
496
|
+
types.Log.debug(e.body);
|
|
497
|
+
types.Log.info("Removing and re-creating the cluster role");
|
|
639
498
|
try {
|
|
640
499
|
await rbacApi.deleteClusterRole(cr.metadata.name);
|
|
641
500
|
await rbacApi.createClusterRole(cr);
|
|
642
501
|
}
|
|
643
502
|
catch (e) {
|
|
644
|
-
Log.debug(e.body);
|
|
503
|
+
types.Log.debug(e.body);
|
|
645
504
|
}
|
|
646
505
|
}
|
|
647
506
|
const sa = this.serviceAccount();
|
|
648
507
|
try {
|
|
649
|
-
Log.info("Creating service account");
|
|
508
|
+
types.Log.info("Creating service account");
|
|
650
509
|
await coreV1Api.createNamespacedServiceAccount(namespace, sa);
|
|
651
510
|
}
|
|
652
511
|
catch (e) {
|
|
653
|
-
Log.debug(e.body);
|
|
654
|
-
Log.info("Removing and re-creating service account");
|
|
512
|
+
types.Log.debug(e.body);
|
|
513
|
+
types.Log.info("Removing and re-creating service account");
|
|
655
514
|
await coreV1Api.deleteNamespacedServiceAccount(sa.metadata.name, namespace);
|
|
656
515
|
await coreV1Api.createNamespacedServiceAccount(namespace, sa);
|
|
657
516
|
}
|
|
658
517
|
const mod = this.moduleSecret(code);
|
|
659
518
|
try {
|
|
660
|
-
Log.info("Creating module secret");
|
|
519
|
+
types.Log.info("Creating module secret");
|
|
661
520
|
await coreV1Api.createNamespacedSecret(namespace, mod);
|
|
662
521
|
}
|
|
663
522
|
catch (e) {
|
|
664
|
-
Log.debug(e.body);
|
|
665
|
-
Log.info("Removing and re-creating module secret");
|
|
523
|
+
types.Log.debug(e.body);
|
|
524
|
+
types.Log.info("Removing and re-creating module secret");
|
|
666
525
|
await coreV1Api.deleteNamespacedSecret(mod.metadata.name, namespace);
|
|
667
526
|
await coreV1Api.createNamespacedSecret(namespace, mod);
|
|
668
527
|
}
|
|
669
528
|
const svc = this.service();
|
|
670
529
|
try {
|
|
671
|
-
Log.info("Creating service");
|
|
530
|
+
types.Log.info("Creating service");
|
|
672
531
|
await coreV1Api.createNamespacedService(namespace, svc);
|
|
673
532
|
}
|
|
674
533
|
catch (e) {
|
|
675
|
-
Log.debug(e.body);
|
|
676
|
-
Log.info("Removing and re-creating service");
|
|
534
|
+
types.Log.debug(e.body);
|
|
535
|
+
types.Log.info("Removing and re-creating service");
|
|
677
536
|
await coreV1Api.deleteNamespacedService(svc.metadata.name, namespace);
|
|
678
537
|
await coreV1Api.createNamespacedService(namespace, svc);
|
|
679
538
|
}
|
|
680
539
|
const tls = this.tlsSecret();
|
|
681
540
|
try {
|
|
682
|
-
Log.info("Creating TLS secret");
|
|
541
|
+
types.Log.info("Creating TLS secret");
|
|
683
542
|
await coreV1Api.createNamespacedSecret(namespace, tls);
|
|
684
543
|
}
|
|
685
544
|
catch (e) {
|
|
686
|
-
Log.debug(e.body);
|
|
687
|
-
Log.info("Removing and re-creating TLS secret");
|
|
545
|
+
types.Log.debug(e.body);
|
|
546
|
+
types.Log.info("Removing and re-creating TLS secret");
|
|
688
547
|
await coreV1Api.deleteNamespacedSecret(tls.metadata.name, namespace);
|
|
689
548
|
await coreV1Api.createNamespacedSecret(namespace, tls);
|
|
690
549
|
}
|
|
691
550
|
const dep = this.deployment();
|
|
692
551
|
try {
|
|
693
|
-
Log.info("Creating deployment");
|
|
552
|
+
types.Log.info("Creating deployment");
|
|
694
553
|
await appsApi.createNamespacedDeployment(namespace, dep);
|
|
695
554
|
}
|
|
696
555
|
catch (e) {
|
|
697
|
-
Log.debug(e.body);
|
|
698
|
-
Log.info("Removing and re-creating deployment");
|
|
556
|
+
types.Log.debug(e.body);
|
|
557
|
+
types.Log.info("Removing and re-creating deployment");
|
|
699
558
|
await appsApi.deleteNamespacedDeployment(dep.metadata.name, namespace);
|
|
700
559
|
await appsApi.createNamespacedDeployment(namespace, dep);
|
|
701
560
|
}
|
|
@@ -725,8 +584,8 @@ function build (program) {
|
|
|
725
584
|
const zarf = webhook.zarfYaml(yamlFile);
|
|
726
585
|
await fs.promises.writeFile(yamlPath, yaml);
|
|
727
586
|
await fs.promises.writeFile(zarfPath, zarf);
|
|
728
|
-
Log.debug(`Module compiled successfully at ${path$1}`);
|
|
729
|
-
Log.info(`K8s resource for the module saved to ${yamlPath}`);
|
|
587
|
+
types.Log.debug(`Module compiled successfully at ${path$1}`);
|
|
588
|
+
types.Log.info(`K8s resource for the module saved to ${yamlPath}`);
|
|
730
589
|
});
|
|
731
590
|
}
|
|
732
591
|
const externalLibs = [
|
|
@@ -785,8 +644,8 @@ async function buildModule(moduleDir) {
|
|
|
785
644
|
}
|
|
786
645
|
catch (e) {
|
|
787
646
|
// On any other error, exit with a non-zero exit code
|
|
788
|
-
Log.debug(e);
|
|
789
|
-
Log.error(e.message);
|
|
647
|
+
types.Log.debug(e);
|
|
648
|
+
types.Log.error(e.message);
|
|
790
649
|
process.exit(1);
|
|
791
650
|
}
|
|
792
651
|
}
|
|
@@ -810,16 +669,20 @@ function deploy (program) {
|
|
|
810
669
|
.command("deploy")
|
|
811
670
|
.description("Deploy a Pepr Module")
|
|
812
671
|
.option("-d, --dir [directory]", "Pepr module directory", ".")
|
|
672
|
+
.option("-i, --image [image]", "Override the image tag")
|
|
673
|
+
.option("-f, --force", "Force redeployment")
|
|
813
674
|
.action(async (opts) => {
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
675
|
+
if (!opts.force) {
|
|
676
|
+
// Prompt the user to confirm
|
|
677
|
+
const confirm = await prompt.prompt({
|
|
678
|
+
type: "confirm",
|
|
679
|
+
name: "confirm",
|
|
680
|
+
message: "This will remove and redeploy the module. Continue?",
|
|
681
|
+
});
|
|
682
|
+
// Exit if the user doesn't confirm
|
|
683
|
+
if (!confirm.confirm) {
|
|
684
|
+
process.exit(0);
|
|
685
|
+
}
|
|
823
686
|
}
|
|
824
687
|
// Build the module
|
|
825
688
|
const { cfg, path } = await buildModule(opts.dir);
|
|
@@ -830,12 +693,15 @@ function deploy (program) {
|
|
|
830
693
|
...cfg.pepr,
|
|
831
694
|
description: cfg.description,
|
|
832
695
|
});
|
|
696
|
+
if (opts.image) {
|
|
697
|
+
webhook.image = opts.image;
|
|
698
|
+
}
|
|
833
699
|
try {
|
|
834
700
|
await webhook.deploy(code);
|
|
835
|
-
Log.info(`Module deployed successfully`);
|
|
701
|
+
types.Log.info(`Module deployed successfully`);
|
|
836
702
|
}
|
|
837
703
|
catch (e) {
|
|
838
|
-
Log.error(`Error deploying module: ${e}`);
|
|
704
|
+
types.Log.error(`Error deploying module: ${e}`);
|
|
839
705
|
process.exit(1);
|
|
840
706
|
}
|
|
841
707
|
});
|
|
@@ -1140,23 +1006,23 @@ function walkthrough() {
|
|
|
1140
1006
|
const askErrorBehavior = {
|
|
1141
1007
|
type: "select",
|
|
1142
1008
|
name: "errorBehavior",
|
|
1143
|
-
validate: val => ErrorBehavior[val],
|
|
1009
|
+
validate: val => types.ErrorBehavior[val],
|
|
1144
1010
|
message: "How do you want Pepr to handle errors encountered during K8s operations?",
|
|
1145
1011
|
choices: [
|
|
1146
1012
|
{
|
|
1147
1013
|
title: "Ignore",
|
|
1148
|
-
value: ErrorBehavior.ignore,
|
|
1014
|
+
value: types.ErrorBehavior.ignore,
|
|
1149
1015
|
description: "Pepr will continue processing and generate an entry in the Pepr Controller log.",
|
|
1150
1016
|
selected: true,
|
|
1151
1017
|
},
|
|
1152
1018
|
{
|
|
1153
1019
|
title: "Log an audit event",
|
|
1154
|
-
value: ErrorBehavior.audit,
|
|
1020
|
+
value: types.ErrorBehavior.audit,
|
|
1155
1021
|
description: "Pepr will continue processing and generate an entry in the Pepr Controller log as well as an audit event in the cluster.",
|
|
1156
1022
|
},
|
|
1157
1023
|
{
|
|
1158
1024
|
title: "Reject the operation",
|
|
1159
|
-
value: ErrorBehavior.reject,
|
|
1025
|
+
value: types.ErrorBehavior.reject,
|
|
1160
1026
|
description: "Pepr will reject the operation and return an error to the client.",
|
|
1161
1027
|
},
|
|
1162
1028
|
],
|
|
@@ -1224,8 +1090,8 @@ function init (program) {
|
|
|
1224
1090
|
console.log(`Open VSCode or your editor of choice in ${dirName} to get started!`);
|
|
1225
1091
|
}
|
|
1226
1092
|
catch (e) {
|
|
1227
|
-
Log.debug(e);
|
|
1228
|
-
Log.error(e.message);
|
|
1093
|
+
types.Log.debug(e);
|
|
1094
|
+
types.Log.error(e.message);
|
|
1229
1095
|
process.exit(1);
|
|
1230
1096
|
}
|
|
1231
1097
|
}
|
|
@@ -1238,7 +1104,7 @@ class RootCmd extends commander.Command {
|
|
|
1238
1104
|
const cmd = new commander.Command(name);
|
|
1239
1105
|
cmd.option("-l, --log-level [level]", "Log level: debug, info, warn, error", "info");
|
|
1240
1106
|
cmd.hook("preAction", run => {
|
|
1241
|
-
Log.SetLogLevel(run.opts().logLevel);
|
|
1107
|
+
types.Log.SetLogLevel(run.opts().logLevel);
|
|
1242
1108
|
});
|
|
1243
1109
|
return cmd;
|
|
1244
1110
|
}
|
|
@@ -1253,15 +1119,15 @@ function test (program) {
|
|
|
1253
1119
|
.option("-d, --dir [directory]", "Pepr module directory", ".")
|
|
1254
1120
|
.option("-w, --watch", "Watch for changes and re-run the test")
|
|
1255
1121
|
.action(async (opts) => {
|
|
1256
|
-
Log.info("Test Module");
|
|
1122
|
+
types.Log.info("Test Module");
|
|
1257
1123
|
await buildAndTest(opts.dir);
|
|
1258
1124
|
if (opts.watch) {
|
|
1259
1125
|
const moduleFiles = path.resolve(opts.dir, "**", "*.ts");
|
|
1260
1126
|
const watcher = chokidar.watch(moduleFiles);
|
|
1261
1127
|
watcher.on("ready", () => {
|
|
1262
|
-
Log.info(`Watching for changes in ${moduleFiles}`);
|
|
1128
|
+
types.Log.info(`Watching for changes in ${moduleFiles}`);
|
|
1263
1129
|
watcher.on("all", async (event, path) => {
|
|
1264
|
-
Log.debug({ event, path }, "File changed");
|
|
1130
|
+
types.Log.debug({ event, path }, "File changed");
|
|
1265
1131
|
await buildAndTest(opts.dir);
|
|
1266
1132
|
});
|
|
1267
1133
|
});
|
|
@@ -1270,15 +1136,15 @@ function test (program) {
|
|
|
1270
1136
|
}
|
|
1271
1137
|
async function buildAndTest(dir) {
|
|
1272
1138
|
const { path } = await buildModule(dir);
|
|
1273
|
-
Log.info(`Module built successfully at ${path}`);
|
|
1139
|
+
types.Log.info(`Module built successfully at ${path}`);
|
|
1274
1140
|
try {
|
|
1275
1141
|
const { stdout, stderr } = await exec(`node ${path}`);
|
|
1276
1142
|
console.log(stdout);
|
|
1277
1143
|
console.log(stderr);
|
|
1278
1144
|
}
|
|
1279
1145
|
catch (e) {
|
|
1280
|
-
Log.debug(e);
|
|
1281
|
-
Log.error(`Error running module: ${e}`);
|
|
1146
|
+
types.Log.debug(e);
|
|
1147
|
+
types.Log.error(`Error running module: ${e}`);
|
|
1282
1148
|
process.exit(1);
|
|
1283
1149
|
}
|
|
1284
1150
|
}
|
|
@@ -1300,4 +1166,3 @@ capability(program);
|
|
|
1300
1166
|
test(program);
|
|
1301
1167
|
deploy(program);
|
|
1302
1168
|
program.parse();
|
|
1303
|
-
//# sourceMappingURL=pepr-cli.js.map
|