新增learn-kubernetes(https://github.com/yyong-brs/learn-kubernetes)相关文件
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
FROM node:10.19.0-slim AS builder
|
||||
|
||||
WORKDIR /src
|
||||
COPY src/package.json .
|
||||
RUN npm install
|
||||
|
||||
# app
|
||||
FROM node:10.19.0-slim
|
||||
|
||||
EXPOSE 8080
|
||||
ENV PORT="8080" \
|
||||
USE_HTTPS="false"
|
||||
|
||||
CMD ["node", "server.js"]
|
||||
|
||||
WORKDIR /app
|
||||
COPY --from=builder /src/node_modules/ /app/node_modules/
|
||||
COPY src/ .
|
||||
@@ -0,0 +1,5 @@
|
||||
## Credits
|
||||
|
||||
Validation: https://github.com/kelseyhightower/denyenv-validating-admission-webhook
|
||||
|
||||
Mutation: https://github.com/nsubrahm/k8s-mutating-webhook
|
||||
@@ -0,0 +1,14 @@
|
||||
const { format, transports } = require('winston');
|
||||
var logConfig = module.exports = {};
|
||||
|
||||
logConfig.options = {
|
||||
format: format.combine(
|
||||
format.splat(),
|
||||
format.simple()
|
||||
),
|
||||
transports: [
|
||||
new transports.Console({
|
||||
level: 'info'
|
||||
})
|
||||
]
|
||||
};
|
||||
@@ -0,0 +1,5 @@
|
||||
const winston = require('winston');
|
||||
var logConfig = require('./config/logConfig');
|
||||
|
||||
const logger = winston.createLogger(logConfig.options);
|
||||
exports.Logger = logger;
|
||||
@@ -0,0 +1,40 @@
|
||||
const base64 = require('js-base64').Base64;
|
||||
const log = require("./log");
|
||||
|
||||
function post(req, res, next) {
|
||||
log.Logger.debug("** POST /mutate called");
|
||||
|
||||
var admissionRequest = req.body;
|
||||
var object = admissionRequest.request.object;
|
||||
log.Logger.info(`Mutating object; request UID: ${admissionRequest.request.uid}`);
|
||||
|
||||
var admissionReview = {
|
||||
apiVersion: admissionRequest.apiVersion,
|
||||
kind: admissionRequest.kind,
|
||||
response: {
|
||||
uid: admissionRequest.request.uid,
|
||||
allowed: true
|
||||
}
|
||||
}
|
||||
|
||||
if (object.spec.hasOwnProperty("securityContext") &&
|
||||
object.spec.securityContext.hasOwnProperty("runAsNonRoot")) {
|
||||
log.Logger.info("- runAsNonRoot specified - no patch");
|
||||
}
|
||||
else {
|
||||
let jsonPatch = [{
|
||||
op: "add",
|
||||
path: "/spec/securityContext/runAsNonRoot",
|
||||
value: true
|
||||
}];
|
||||
admissionReview.response.patch = base64.encode(JSON.stringify(jsonPatch));
|
||||
admissionReview.response.patchType = "JSONPatch"
|
||||
log.Logger.info("- added runAsNonRoot patch");
|
||||
}
|
||||
|
||||
res.send(200, admissionReview);
|
||||
log.Logger.info(`Mutated request UID: ${admissionRequest.request.uid}`);
|
||||
next();
|
||||
}
|
||||
|
||||
module.exports = { post }
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "admission-webhook",
|
||||
"version": "1.0.0",
|
||||
"main": "server.js",
|
||||
"author": "kiamol",
|
||||
"dependencies": {
|
||||
"js-base64": "^2.5.1",
|
||||
"restify": "8.5.1",
|
||||
"winston": "3.3.3"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
const restify = require("restify");
|
||||
const fs = require("fs");
|
||||
|
||||
const log = require("./log");
|
||||
const validate = require('./validate');
|
||||
const mutate = require('./mutate');
|
||||
|
||||
if (process.env.USE_HTTPS=="true") {
|
||||
var https_options = {
|
||||
key: fs.readFileSync('/run/secrets/tls/tls.key'),
|
||||
certificate: fs.readFileSync('/run/secrets/tls/tls.crt')
|
||||
};
|
||||
var server = restify.createServer(https_options);
|
||||
}
|
||||
else {
|
||||
var server = restify.createServer();
|
||||
}
|
||||
server.use(restify.plugins.bodyParser());
|
||||
|
||||
server.post("/validate", validate.post);
|
||||
server.post("/mutate", mutate.post);
|
||||
|
||||
server.listen(process.env.PORT, function() {
|
||||
log.Logger.info("%s listening at %s", server.name, server.url);
|
||||
});
|
||||
@@ -0,0 +1,42 @@
|
||||
const log = require("./log");
|
||||
|
||||
function post(req, res, next) {
|
||||
log.Logger.debug("** POST /validate called");
|
||||
|
||||
var admissionRequest = req.body;
|
||||
var object = admissionRequest.request.object;
|
||||
log.Logger.info(`Validating object; request UID: ${admissionRequest.request.uid}`);
|
||||
|
||||
var admissionResponse = {
|
||||
uid: admissionRequest.request.uid,
|
||||
allowed: false
|
||||
};
|
||||
|
||||
if (object.spec.hasOwnProperty("automountServiceAccountToken")) {
|
||||
admissionResponse.allowed = (object.spec.automountServiceAccountToken == false);
|
||||
}
|
||||
else {
|
||||
log.Logger.info("- no automountServiceAccountToken");
|
||||
}
|
||||
|
||||
if (!admissionResponse.allowed) {
|
||||
admissionResponse.status = {
|
||||
status: 'Failure',
|
||||
message: "automountServiceAccountToken must be set to false",
|
||||
reason: "automountServiceAccountToken must be set to false",
|
||||
code: 400
|
||||
}
|
||||
}
|
||||
|
||||
var admissionReview = {
|
||||
apiVersion: admissionRequest.apiVersion,
|
||||
kind: admissionRequest.kind,
|
||||
response: admissionResponse
|
||||
}
|
||||
|
||||
res.send(200, admissionReview);
|
||||
log.Logger.info(`Validated request UID: ${admissionRequest.request.uid}`);
|
||||
next();
|
||||
}
|
||||
|
||||
module.exports = { post }
|
||||
@@ -0,0 +1,7 @@
|
||||
version: "3.7"
|
||||
|
||||
services:
|
||||
ch16-admission-webhook:
|
||||
image: kiamol/ch16-admission-webhook
|
||||
build:
|
||||
context: ./admission-webhook
|
||||
Reference in New Issue
Block a user