pepr 0.1.25 → 0.1.26
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/pepr-cli.js +76 -45
- package/dist/pepr-core.js +93 -32
- package/package.json +1 -2
- package/src/lib/capability.ts +0 -8
- package/src/lib/controller.ts +92 -0
- package/src/lib/filter.ts +1 -4
- package/src/lib/module.ts +19 -29
package/dist/pepr-cli.js
CHANGED
|
@@ -13,12 +13,12 @@ var zlib = require('zlib');
|
|
|
13
13
|
var forge = require('node-forge');
|
|
14
14
|
var prompt = require('prompts');
|
|
15
15
|
var child_process = require('child_process');
|
|
16
|
+
var chokidar = require('chokidar');
|
|
16
17
|
var util = require('util');
|
|
17
18
|
var uuid = require('uuid');
|
|
18
19
|
var commander = require('commander');
|
|
19
|
-
var chokidar = require('chokidar');
|
|
20
20
|
|
|
21
|
-
var version = "0.1.
|
|
21
|
+
var version = "0.1.26";
|
|
22
22
|
|
|
23
23
|
// SPDX-License-Identifier: Apache-2.0
|
|
24
24
|
// SPDX-FileCopyrightText: 2023-Present The Pepr Authors
|
|
@@ -806,9 +806,9 @@ function dev (program) {
|
|
|
806
806
|
process.exit(0);
|
|
807
807
|
}
|
|
808
808
|
// Build the module
|
|
809
|
-
const { cfg, path } = await buildModule(opts.dir);
|
|
809
|
+
const { cfg, path: path$1 } = await buildModule(opts.dir);
|
|
810
810
|
// Read the compiled module code
|
|
811
|
-
const code = await fs.promises.readFile(path, { encoding: "utf-8" });
|
|
811
|
+
const code = await fs.promises.readFile(path$1, { encoding: "utf-8" });
|
|
812
812
|
// Generate a secret for the module
|
|
813
813
|
const webhook = new Webhook({
|
|
814
814
|
...cfg.pepr,
|
|
@@ -820,6 +820,25 @@ function dev (program) {
|
|
|
820
820
|
try {
|
|
821
821
|
await webhook.deploy(code);
|
|
822
822
|
types.logger.info(`Module deployed successfully`);
|
|
823
|
+
const moduleFiles = path.resolve(opts.dir, "**", "*.ts");
|
|
824
|
+
const watcher = chokidar.watch(moduleFiles);
|
|
825
|
+
const peprTS = path.resolve(opts.dir, "pepr.ts");
|
|
826
|
+
let program;
|
|
827
|
+
// Run the module once to start the server
|
|
828
|
+
runDev(peprTS);
|
|
829
|
+
// Watch for changes
|
|
830
|
+
watcher.on("ready", () => {
|
|
831
|
+
types.logger.info(`Watching for changes in ${moduleFiles}`);
|
|
832
|
+
watcher.on("all", async (event, path) => {
|
|
833
|
+
types.logger.debug({ event, path }, "File changed");
|
|
834
|
+
// Kill the running process
|
|
835
|
+
if (program) {
|
|
836
|
+
program.kill("SIGKILL");
|
|
837
|
+
}
|
|
838
|
+
// Start the process again
|
|
839
|
+
program = runDev(peprTS);
|
|
840
|
+
});
|
|
841
|
+
});
|
|
823
842
|
}
|
|
824
843
|
catch (e) {
|
|
825
844
|
types.logger.error(`Error deploying module: ${e}`);
|
|
@@ -827,6 +846,28 @@ function dev (program) {
|
|
|
827
846
|
}
|
|
828
847
|
});
|
|
829
848
|
}
|
|
849
|
+
function runDev(path) {
|
|
850
|
+
try {
|
|
851
|
+
const program = child_process.spawn("./node_modules/.bin/ts-node", [path], {
|
|
852
|
+
env: {
|
|
853
|
+
...process.env,
|
|
854
|
+
SSL_KEY_PATH: "insecure-tls.key",
|
|
855
|
+
SSL_CERT_PATH: "insecure-tls.crt",
|
|
856
|
+
},
|
|
857
|
+
});
|
|
858
|
+
program.stdout.on("data", data => console.log(data.toString()));
|
|
859
|
+
program.stderr.on("data", data => console.error(data.toString()));
|
|
860
|
+
program.on("close", code => {
|
|
861
|
+
types.logger.info(`Process exited with code ${code}`);
|
|
862
|
+
});
|
|
863
|
+
return program;
|
|
864
|
+
}
|
|
865
|
+
catch (e) {
|
|
866
|
+
types.logger.debug(e);
|
|
867
|
+
types.logger.error(`Error running module: ${e}`);
|
|
868
|
+
process.exit(1);
|
|
869
|
+
}
|
|
870
|
+
}
|
|
830
871
|
|
|
831
872
|
// SPDX-License-Identifier: Apache-2.0
|
|
832
873
|
/**
|
|
@@ -883,28 +924,18 @@ function genPeprTS() {
|
|
|
883
924
|
path: "pepr.ts",
|
|
884
925
|
data: `import { PeprModule } from "pepr";
|
|
885
926
|
import cfg from "./package.json";
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
// This initializes the Pepr module with the configuration from package.json
|
|
889
|
-
export const { ProcessRequest, Register } = new PeprModule(cfg);
|
|
927
|
+
import { HelloPepr } from "./capabilities/hello-pepr";
|
|
890
928
|
|
|
891
929
|
/**
|
|
892
|
-
*
|
|
893
|
-
* This
|
|
894
|
-
* \`pepr new <capability name>\`
|
|
895
|
-
*
|
|
896
|
-
* Example:
|
|
897
|
-
* import { Capability1 } from "./capabilities/capability1";
|
|
898
|
-
* import { Capability2 } from "./capabilities/capability2";
|
|
899
|
-
*
|
|
900
|
-
* Capability1(Register);
|
|
901
|
-
* Capability2(Register);
|
|
902
|
-
*
|
|
903
|
-
* Uncomment the line below and the import above to use the hello-pepr demo capability
|
|
930
|
+
* This is the main entrypoint for the Pepr module. It is the file that is run when the module is started.
|
|
931
|
+
* This is where you register your configurations and capabilities with the module.
|
|
904
932
|
*/
|
|
933
|
+
new PeprModule(cfg, [
|
|
934
|
+
// "HelloPepr" is a demo capability that is included with Pepr. You can remove it if you want.
|
|
935
|
+
HelloPepr,
|
|
905
936
|
|
|
906
|
-
//
|
|
907
|
-
|
|
937
|
+
// Your additional capabilities go here
|
|
938
|
+
]);
|
|
908
939
|
`,
|
|
909
940
|
};
|
|
910
941
|
}
|
|
@@ -1009,14 +1040,15 @@ const capabilityHelloPeprTS = {
|
|
|
1009
1040
|
path: "hello-pepr.ts",
|
|
1010
1041
|
data: `import { Capability, a } from "pepr";
|
|
1011
1042
|
|
|
1012
|
-
const
|
|
1043
|
+
export const HelloPepr = new Capability({
|
|
1013
1044
|
name: "hello-pepr",
|
|
1014
1045
|
description: "A simple example capability to show how things work.",
|
|
1015
1046
|
namespaces: ["pepr-demo"],
|
|
1016
1047
|
});
|
|
1017
1048
|
|
|
1018
|
-
|
|
1019
|
-
|
|
1049
|
+
// Use the 'When' function to create a new Capability Action
|
|
1050
|
+
const { When } = HelloPepr;
|
|
1051
|
+
|
|
1020
1052
|
/**
|
|
1021
1053
|
* This is a single Capability Action. They can be in the same file or put imported from other files.
|
|
1022
1054
|
* In this exmaple, when a ConfigMap is created with the name \`example-1\`, then add a label and annotation.
|
|
@@ -1079,27 +1111,26 @@ When(a.ConfigMap)
|
|
|
1079
1111
|
const capabilitySnippet = {
|
|
1080
1112
|
path: "pepr.code-snippets",
|
|
1081
1113
|
data: `{
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
}
|
|
1114
|
+
"Create a new Pepr capability": {
|
|
1115
|
+
"prefix": "create pepr capability",
|
|
1116
|
+
"body": [
|
|
1117
|
+
"import { Capability, a } from 'pepr';",
|
|
1118
|
+
"",
|
|
1119
|
+
"export const $\{TM_FILENAME_BASE/(.*)/$\{1:/pascalcase}/} = new Capability({",
|
|
1120
|
+
"\tname: '$\{TM_FILENAME_BASE}',",
|
|
1121
|
+
"\tdescription: '$\{1:A brief description of this capability.}',",
|
|
1122
|
+
"\tnamespaces: [$\{2:}],",
|
|
1123
|
+
"});",
|
|
1124
|
+
"",
|
|
1125
|
+
"// Use the 'When' function to create a new Capability Action",
|
|
1126
|
+
"const { When } = $\{TM_FILENAME_BASE/(.*)/$\{1:/pascalcase}/};",
|
|
1127
|
+
"",
|
|
1128
|
+
"// When(a.<Kind>).Is<Event>().Then(change => change.<changes>",
|
|
1129
|
+
"When($\{3:})"
|
|
1130
|
+
],
|
|
1131
|
+
"description": "Creates a new Pepr capability with a specified description, and optional namespaces, and adds a When statement for the specified value."
|
|
1101
1132
|
}
|
|
1102
|
-
|
|
1133
|
+
}`,
|
|
1103
1134
|
};
|
|
1104
1135
|
|
|
1105
1136
|
// SPDX-License-Identifier: Apache-2.0
|
package/dist/pepr-core.js
CHANGED
|
@@ -4,6 +4,9 @@
|
|
|
4
4
|
var dist = require('@kubernetes/client-node/dist');
|
|
5
5
|
var types = require('./types-1709b44f.js');
|
|
6
6
|
var R = require('ramda');
|
|
7
|
+
var express = require('express');
|
|
8
|
+
var fs = require('fs');
|
|
9
|
+
var https = require('https');
|
|
7
10
|
var fastJsonPatch = require('fast-json-patch');
|
|
8
11
|
|
|
9
12
|
function _interopNamespaceDefault(e) {
|
|
@@ -535,13 +538,6 @@ class Capability {
|
|
|
535
538
|
// Currently everything is considered a mutation
|
|
536
539
|
this._mutateOrValidate = types.HookPhase.mutate;
|
|
537
540
|
this._bindings = [];
|
|
538
|
-
/**
|
|
539
|
-
* The Register method is used to register a capability with the Pepr runtime. This method is
|
|
540
|
-
* called in the order that the capabilities should be executed.
|
|
541
|
-
*
|
|
542
|
-
* @param callback the state register method to call, passing the capability as an argument
|
|
543
|
-
*/
|
|
544
|
-
this.Register = (register) => register(this);
|
|
545
541
|
/**
|
|
546
542
|
* The When method is used to register a capability action to be executed when a Kubernetes resource is
|
|
547
543
|
* processed by Pepr. The action will be executed if the resource matches the specified kind and any
|
|
@@ -640,19 +636,16 @@ function shouldSkipRequest(binding, req) {
|
|
|
640
636
|
const { namespaces, labels, annotations } = binding.filters;
|
|
641
637
|
const { metadata } = req.object;
|
|
642
638
|
if (kind !== req.kind.kind) {
|
|
643
|
-
types.logger.debug(`${req.kind.kind} does not match ${kind}`);
|
|
644
639
|
return true;
|
|
645
640
|
}
|
|
646
641
|
if (group && group !== req.kind.group) {
|
|
647
|
-
types.logger.debug(`${req.kind.group} does not match ${group}`);
|
|
648
642
|
return true;
|
|
649
643
|
}
|
|
650
644
|
if (version && version !== req.kind.version) {
|
|
651
|
-
types.logger.debug(`${req.kind.version} does not match ${version}`);
|
|
652
645
|
return true;
|
|
653
646
|
}
|
|
654
647
|
if (namespaces.length && !namespaces.includes(req.namespace || "")) {
|
|
655
|
-
types.logger.debug(
|
|
648
|
+
types.logger.debug("Namespace does not match");
|
|
656
649
|
return true;
|
|
657
650
|
}
|
|
658
651
|
for (const [key, value] of Object.entries(labels)) {
|
|
@@ -848,38 +841,106 @@ function processor(config, capabilities, req) {
|
|
|
848
841
|
return response;
|
|
849
842
|
}
|
|
850
843
|
|
|
844
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
845
|
+
// Load SSL certificate and key
|
|
846
|
+
const options = {
|
|
847
|
+
key: fs.readFileSync(process.env.SSL_KEY_PATH || "/etc/certs/tls.key"),
|
|
848
|
+
cert: fs.readFileSync(process.env.SSL_CERT_PATH || "/etc/certs/tls.crt"),
|
|
849
|
+
};
|
|
850
|
+
class Controller {
|
|
851
|
+
constructor(config, capabilities) {
|
|
852
|
+
this.config = config;
|
|
853
|
+
this.capabilities = capabilities;
|
|
854
|
+
this.app = express();
|
|
855
|
+
/** Start the webhook server */
|
|
856
|
+
this.startServer = (port) => {
|
|
857
|
+
// Create HTTPS server
|
|
858
|
+
https.createServer(options, this.app).listen(port, () => {
|
|
859
|
+
console.log(`Server listening on port ${port}`);
|
|
860
|
+
});
|
|
861
|
+
};
|
|
862
|
+
this.logger = (req, res, next) => {
|
|
863
|
+
const startTime = Date.now();
|
|
864
|
+
res.on("finish", () => {
|
|
865
|
+
const now = new Date().toISOString();
|
|
866
|
+
const elapsedTime = Date.now() - startTime;
|
|
867
|
+
const message = `[${now}] ${req.method} ${req.originalUrl} - ${res.statusCode} - ${elapsedTime} ms\n`;
|
|
868
|
+
res.statusCode >= 400 ? console.error(message) : console.info(message);
|
|
869
|
+
});
|
|
870
|
+
next();
|
|
871
|
+
};
|
|
872
|
+
this.healthz = (req, res) => {
|
|
873
|
+
try {
|
|
874
|
+
res.send("OK");
|
|
875
|
+
}
|
|
876
|
+
catch (err) {
|
|
877
|
+
console.error(err);
|
|
878
|
+
res.status(500).send("Internal Server Error");
|
|
879
|
+
}
|
|
880
|
+
};
|
|
881
|
+
this.mutate = (req, res) => {
|
|
882
|
+
try {
|
|
883
|
+
const name = req.body?.request?.name || "";
|
|
884
|
+
const namespace = req.body?.request?.namespace || "";
|
|
885
|
+
const gvk = req.body?.request?.kind || { group: "", version: "", kind: "" };
|
|
886
|
+
console.log(`Mutate request: ${gvk.group}/${gvk.version}/${gvk.kind}`);
|
|
887
|
+
name && console.log(` ${namespace}/${name}\n`);
|
|
888
|
+
// @todo: make this actually do something
|
|
889
|
+
const response = processor(this.config, this.capabilities, req.body.request);
|
|
890
|
+
console.debug(response);
|
|
891
|
+
// Send a no prob bob response
|
|
892
|
+
res.send({
|
|
893
|
+
apiVersion: "admission.k8s.io/v1",
|
|
894
|
+
kind: "AdmissionReview",
|
|
895
|
+
response: {
|
|
896
|
+
uid: req.body.request.uid,
|
|
897
|
+
allowed: true,
|
|
898
|
+
},
|
|
899
|
+
});
|
|
900
|
+
}
|
|
901
|
+
catch (err) {
|
|
902
|
+
console.error(err);
|
|
903
|
+
res.status(500).send("Internal Server Error");
|
|
904
|
+
}
|
|
905
|
+
};
|
|
906
|
+
// Middleware for logging requests
|
|
907
|
+
this.app.use(this.logger);
|
|
908
|
+
// Middleware for parsing JSON
|
|
909
|
+
this.app.use(express.json());
|
|
910
|
+
// Health check endpoint
|
|
911
|
+
this.app.get("/healthz", this.healthz);
|
|
912
|
+
// Mutate endpoint
|
|
913
|
+
this.app.post("/mutate", this.mutate);
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
|
|
851
917
|
// SPDX-License-Identifier: Apache-2.0
|
|
852
918
|
const alwaysIgnore = {
|
|
853
919
|
namespaces: ["kube-system", "pepr-system"],
|
|
854
920
|
labels: [{ "pepr.dev": "ignore" }],
|
|
855
921
|
};
|
|
856
922
|
class PeprModule {
|
|
857
|
-
get kinds() {
|
|
858
|
-
return this._kinds;
|
|
859
|
-
}
|
|
860
|
-
get UUID() {
|
|
861
|
-
return this._config.uuid;
|
|
862
|
-
}
|
|
863
923
|
/**
|
|
864
924
|
* Create a new Pepr runtime
|
|
865
925
|
*
|
|
866
926
|
* @param config The configuration for the Pepr runtime
|
|
867
927
|
*/
|
|
868
|
-
constructor({ description, pepr }) {
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
this.
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
928
|
+
constructor({ description, pepr }, capabilities = [], deferStart = false) {
|
|
929
|
+
const config = R.mergeDeepWith(R.concat, pepr, alwaysIgnore);
|
|
930
|
+
config.description = description;
|
|
931
|
+
this._controller = new Controller(config, capabilities);
|
|
932
|
+
if (!deferStart) {
|
|
933
|
+
this.start();
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
/**
|
|
937
|
+
* Start the Pepr runtime manually.
|
|
938
|
+
* Normally this is called automatically when the Pepr module is instantiated, but can be called manually if `deferStart` is set to `true` in the constructor.
|
|
939
|
+
*
|
|
940
|
+
* @param port
|
|
941
|
+
*/
|
|
942
|
+
start(port = 3000) {
|
|
943
|
+
this._controller.startServer(port);
|
|
883
944
|
}
|
|
884
945
|
}
|
|
885
946
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pepr",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.26",
|
|
4
4
|
"description": "Kubernetes application engine",
|
|
5
5
|
"author": "Defense Unicorns",
|
|
6
6
|
"homepage": "https://github.com/defenseunicorns/pepr",
|
|
@@ -41,7 +41,6 @@
|
|
|
41
41
|
"@rollup/plugin-node-resolve": "^15.0.1",
|
|
42
42
|
"@rollup/plugin-typescript": "^11.0.0",
|
|
43
43
|
"@types/ramda": "^0.28.23",
|
|
44
|
-
"body-parser": "^1.20.2",
|
|
45
44
|
"chokidar": "^3.5.3",
|
|
46
45
|
"commander": "^10.0.0",
|
|
47
46
|
"express": "^4.18.2",
|
package/src/lib/capability.ts
CHANGED
|
@@ -58,14 +58,6 @@ export class Capability implements CapabilityCfg {
|
|
|
58
58
|
logger.debug(cfg);
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
-
/**
|
|
62
|
-
* The Register method is used to register a capability with the Pepr runtime. This method is
|
|
63
|
-
* called in the order that the capabilities should be executed.
|
|
64
|
-
*
|
|
65
|
-
* @param callback the state register method to call, passing the capability as an argument
|
|
66
|
-
*/
|
|
67
|
-
Register = (register: (capability: Capability) => void) => register(this);
|
|
68
|
-
|
|
69
61
|
/**
|
|
70
62
|
* The When method is used to register a capability action to be executed when a Kubernetes resource is
|
|
71
63
|
* processed by Pepr. The action will be executed if the resource matches the specified kind and any
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// SPDX-FileCopyrightText: 2023-Present The Pepr Authors
|
|
3
|
+
|
|
4
|
+
import express from "express";
|
|
5
|
+
import fs from "fs";
|
|
6
|
+
import https from "https";
|
|
7
|
+
import { ModuleConfig } from "./types";
|
|
8
|
+
import { Capability } from "./capability";
|
|
9
|
+
import { processor } from "./processor";
|
|
10
|
+
|
|
11
|
+
// Load SSL certificate and key
|
|
12
|
+
const options = {
|
|
13
|
+
key: fs.readFileSync(process.env.SSL_KEY_PATH || "/etc/certs/tls.key"),
|
|
14
|
+
cert: fs.readFileSync(process.env.SSL_CERT_PATH || "/etc/certs/tls.crt"),
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export class Controller {
|
|
18
|
+
private readonly app = express();
|
|
19
|
+
|
|
20
|
+
constructor(private readonly config: ModuleConfig, private readonly capabilities: Capability[]) {
|
|
21
|
+
// Middleware for logging requests
|
|
22
|
+
this.app.use(this.logger);
|
|
23
|
+
|
|
24
|
+
// Middleware for parsing JSON
|
|
25
|
+
this.app.use(express.json());
|
|
26
|
+
|
|
27
|
+
// Health check endpoint
|
|
28
|
+
this.app.get("/healthz", this.healthz);
|
|
29
|
+
|
|
30
|
+
// Mutate endpoint
|
|
31
|
+
this.app.post("/mutate", this.mutate);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Start the webhook server */
|
|
35
|
+
public startServer = (port: number) => {
|
|
36
|
+
// Create HTTPS server
|
|
37
|
+
https.createServer(options, this.app).listen(port, () => {
|
|
38
|
+
console.log(`Server listening on port ${port}`);
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
private logger = (req: express.Request, res: express.Response, next: express.NextFunction) => {
|
|
43
|
+
const startTime = Date.now();
|
|
44
|
+
|
|
45
|
+
res.on("finish", () => {
|
|
46
|
+
const now = new Date().toISOString();
|
|
47
|
+
const elapsedTime = Date.now() - startTime;
|
|
48
|
+
const message = `[${now}] ${req.method} ${req.originalUrl} - ${res.statusCode} - ${elapsedTime} ms\n`;
|
|
49
|
+
|
|
50
|
+
res.statusCode >= 400 ? console.error(message) : console.info(message);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
next();
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
private healthz = (req: express.Request, res: express.Response) => {
|
|
57
|
+
try {
|
|
58
|
+
res.send("OK");
|
|
59
|
+
} catch (err) {
|
|
60
|
+
console.error(err);
|
|
61
|
+
res.status(500).send("Internal Server Error");
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
private mutate = (req: express.Request, res: express.Response) => {
|
|
66
|
+
try {
|
|
67
|
+
const name = req.body?.request?.name || "";
|
|
68
|
+
const namespace = req.body?.request?.namespace || "";
|
|
69
|
+
const gvk = req.body?.request?.kind || { group: "", version: "", kind: "" };
|
|
70
|
+
|
|
71
|
+
console.log(`Mutate request: ${gvk.group}/${gvk.version}/${gvk.kind}`);
|
|
72
|
+
name && console.log(` ${namespace}/${name}\n`);
|
|
73
|
+
|
|
74
|
+
// @todo: make this actually do something
|
|
75
|
+
const response = processor(this.config, this.capabilities, req.body.request);
|
|
76
|
+
console.debug(response);
|
|
77
|
+
|
|
78
|
+
// Send a no prob bob response
|
|
79
|
+
res.send({
|
|
80
|
+
apiVersion: "admission.k8s.io/v1",
|
|
81
|
+
kind: "AdmissionReview",
|
|
82
|
+
response: {
|
|
83
|
+
uid: req.body.request.uid,
|
|
84
|
+
allowed: true,
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
} catch (err) {
|
|
88
|
+
console.error(err);
|
|
89
|
+
res.status(500).send("Internal Server Error");
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
package/src/lib/filter.ts
CHANGED
|
@@ -18,22 +18,19 @@ export function shouldSkipRequest(binding: Binding, req: Request) {
|
|
|
18
18
|
const { metadata } = req.object;
|
|
19
19
|
|
|
20
20
|
if (kind !== req.kind.kind) {
|
|
21
|
-
logger.debug(`${req.kind.kind} does not match ${kind}`);
|
|
22
21
|
return true;
|
|
23
22
|
}
|
|
24
23
|
|
|
25
24
|
if (group && group !== req.kind.group) {
|
|
26
|
-
logger.debug(`${req.kind.group} does not match ${group}`);
|
|
27
25
|
return true;
|
|
28
26
|
}
|
|
29
27
|
|
|
30
28
|
if (version && version !== req.kind.version) {
|
|
31
|
-
logger.debug(`${req.kind.version} does not match ${version}`);
|
|
32
29
|
return true;
|
|
33
30
|
}
|
|
34
31
|
|
|
35
32
|
if (namespaces.length && !namespaces.includes(req.namespace || "")) {
|
|
36
|
-
logger.debug(
|
|
33
|
+
logger.debug("Namespace does not match");
|
|
37
34
|
return true;
|
|
38
35
|
}
|
|
39
36
|
|
package/src/lib/module.ts
CHANGED
|
@@ -3,9 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
import R from "ramda";
|
|
5
5
|
import { Capability } from "./capability";
|
|
6
|
-
import {
|
|
7
|
-
import logger from "./logger";
|
|
8
|
-
import { processor } from "./processor";
|
|
6
|
+
import { Controller } from "./controller";
|
|
9
7
|
import { ModuleConfig } from "./types";
|
|
10
8
|
|
|
11
9
|
const alwaysIgnore = {
|
|
@@ -19,39 +17,31 @@ export type PackageJSON = {
|
|
|
19
17
|
};
|
|
20
18
|
|
|
21
19
|
export class PeprModule {
|
|
22
|
-
private
|
|
23
|
-
private _state: Capability[] = [];
|
|
24
|
-
private _kinds: GroupVersionKind[] = [];
|
|
25
|
-
|
|
26
|
-
get kinds(): GroupVersionKind[] {
|
|
27
|
-
return this._kinds;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
get UUID(): string {
|
|
31
|
-
return this._config.uuid;
|
|
32
|
-
}
|
|
20
|
+
private _controller: Controller;
|
|
33
21
|
|
|
34
22
|
/**
|
|
35
23
|
* Create a new Pepr runtime
|
|
36
24
|
*
|
|
37
25
|
* @param config The configuration for the Pepr runtime
|
|
38
26
|
*/
|
|
39
|
-
constructor({ description, pepr }: PackageJSON) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
Register = (capability: Capability) => {
|
|
45
|
-
logger.info(`Registering capability ${capability.name}`);
|
|
27
|
+
constructor({ description, pepr }: PackageJSON, capabilities: Capability[] = [], deferStart = false) {
|
|
28
|
+
const config: ModuleConfig = R.mergeDeepWith(R.concat, pepr, alwaysIgnore);
|
|
29
|
+
config.description = description;
|
|
46
30
|
|
|
47
|
-
|
|
48
|
-
this._kinds = capability.bindings.map(({ kind }) => kind);
|
|
31
|
+
this._controller = new Controller(config, capabilities);
|
|
49
32
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
33
|
+
if (!deferStart) {
|
|
34
|
+
this.start();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
53
37
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Start the Pepr runtime manually.
|
|
40
|
+
* Normally this is called automatically when the Pepr module is instantiated, but can be called manually if `deferStart` is set to `true` in the constructor.
|
|
41
|
+
*
|
|
42
|
+
* @param port
|
|
43
|
+
*/
|
|
44
|
+
start(port = 3000) {
|
|
45
|
+
this._controller.startServer(port);
|
|
46
|
+
}
|
|
57
47
|
}
|