init
This commit is contained in:
11
admission/Dockerfile
Normal file
11
admission/Dockerfile
Normal file
@ -0,0 +1,11 @@
|
||||
FROM python:3-alpine
|
||||
RUN pip3 install Flask
|
||||
|
||||
COPY app.py /app/app.py
|
||||
COPY tls.crt /app/
|
||||
COPY tls.key /app/
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
|
||||
WORKDIR /app
|
||||
CMD ["python", "app.py"]
|
||||
EXPOSE 443
|
||||
68
admission/app.py
Normal file
68
admission/app.py
Normal file
@ -0,0 +1,68 @@
|
||||
from flask import Flask, request, jsonify
|
||||
import json
|
||||
import base64
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/mutate', methods=['POST'])
|
||||
def mutate():
|
||||
request_info = request.get_json()
|
||||
pod = request_info['request']['object']
|
||||
uid = request_info['request']['uid']
|
||||
|
||||
patch = []
|
||||
if 'metadata' in pod and 'labels' in pod['metadata']:
|
||||
labels = pod['metadata']['labels']
|
||||
if 'env' not in labels:
|
||||
patch.append({
|
||||
"op": "add",
|
||||
"path": "/metadata/labels/env",
|
||||
"value": "training"
|
||||
})
|
||||
else:
|
||||
patch.append({
|
||||
"op": "add",
|
||||
"path": "/metadata/labels",
|
||||
"value": {"env": "training"}
|
||||
})
|
||||
|
||||
admission_response = {
|
||||
"apiVersion": "admission.k8s.io/v1",
|
||||
"kind": "AdmissionReview",
|
||||
"response": {
|
||||
"uid": uid,
|
||||
"allowed": True,
|
||||
"patch": base64.b64encode(json.dumps(patch).encode()).decode(),
|
||||
"patchType": "JSONPatch"
|
||||
}
|
||||
}
|
||||
print (admission_response)
|
||||
print (jsonify(admission_response))
|
||||
return jsonify(admission_response)
|
||||
|
||||
@app.route('/validate', methods=['POST'])
|
||||
def validate():
|
||||
request_info = request.get_json()
|
||||
pod = request_info['request']['object']
|
||||
uid = request_info['request']['uid']
|
||||
|
||||
allowed = True
|
||||
reason = ""
|
||||
admission_response = {
|
||||
"apiVersion": "admission.k8s.io/v1",
|
||||
"kind": "AdmissionReview",
|
||||
"response": {
|
||||
"uid": uid,
|
||||
"allowed": allowed
|
||||
}
|
||||
}
|
||||
|
||||
admission_response["response"]["status"] = {
|
||||
"message": reason
|
||||
}
|
||||
return jsonify(admission_response)
|
||||
|
||||
if __name__ == '__main__':
|
||||
context = ('tls.crt', 'tls.key')
|
||||
print(context)
|
||||
app.run(host='0.0.0.0', port=443, ssl_context=context)
|
||||
36
admission/commands
Normal file
36
admission/commands
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
openssl req -x509 -newkey rsa:2048 -keyout tls.key -out tls.crt \
|
||||
-subj "/CN=admission.webhook.svc" -nodes -sha256 -days 365
|
||||
|
||||
openssl req -x509 -newkey rsa:2048 -keyout tls.key -out tls.crt \
|
||||
-sha256 -days 365 -nodes -subj "/CN=admission.webhook.svc" \
|
||||
-extensions san -config <(printf "[req]\ndistinguished_name=req\n[ san ]\nsubjectAltName=DNS:admission.webhook.svc")
|
||||
|
||||
|
||||
base64 -w0 tls.crt
|
||||
|
||||
minikube start --memory 4096 --cpus 2 --ports 5000:5000
|
||||
minikube addons enable registry
|
||||
|
||||
minikube image build -t localhost:5000/admission .
|
||||
minikube image push localhost:5000/admission:latest
|
||||
|
||||
kubectl -n webhook rollout restart deployment admission
|
||||
|
||||
docker build -t ttl.sh/admission .
|
||||
docker push ttl.sh/admission
|
||||
|
||||
docker build -t localhost:5000/admission .
|
||||
docker push localhost:5000/admission
|
||||
|
||||
|
||||
kubectl apply -f k8s
|
||||
kubectl -n webhook get pods -w
|
||||
|
||||
kubectl -n controlled delete pods --all
|
||||
kubectl apply -f k8s
|
||||
kubectl -n controlled get pods --show-labels
|
||||
|
||||
|
||||
kubectl delete validatingwebhookconfigurations.admissionregistration.k8s.io sample
|
||||
kubectl delete mutatingwebhookconfigurations.admissionregistration.k8s.io sample
|
||||
5
admission/k8s/0-ns.yaml
Normal file
5
admission/k8s/0-ns.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: webhook
|
||||
|
||||
12
admission/k8s/1-svc.yaml
Normal file
12
admission/k8s/1-svc.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: admission
|
||||
namespace: webhook
|
||||
spec:
|
||||
selector:
|
||||
app: admission
|
||||
ports:
|
||||
- port: 443
|
||||
targetPort: 443
|
||||
|
||||
5
admission/k8s/100-controlled-ns.yaml
Normal file
5
admission/k8s/100-controlled-ns.yaml
Normal file
@ -0,0 +1,5 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: controlled
|
||||
|
||||
13
admission/k8s/101-pod.yaml
Normal file
13
admission/k8s/101-pod.yaml
Normal file
@ -0,0 +1,13 @@
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: demo
|
||||
namespace: controlled
|
||||
spec:
|
||||
containers:
|
||||
- name: demo
|
||||
image: ghcr.io/trion-development/echoserver:1
|
||||
resources: {}
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
|
||||
15
admission/k8s/102-pod.yaml
Normal file
15
admission/k8s/102-pod.yaml
Normal file
@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: demo-two
|
||||
namespace: controlled
|
||||
labels:
|
||||
some: value
|
||||
spec:
|
||||
containers:
|
||||
- name: demo
|
||||
image: ghcr.io/trion-development/echoserver:1
|
||||
resources: {}
|
||||
ports:
|
||||
- containerPort: 3000
|
||||
|
||||
24
admission/k8s/2-deployment.yaml
Normal file
24
admission/k8s/2-deployment.yaml
Normal file
@ -0,0 +1,24 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: admission
|
||||
namespace: webhook
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: admission
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: admission
|
||||
spec:
|
||||
containers:
|
||||
- name: app
|
||||
image: localhost:5000/admission:latest #worst practice
|
||||
# image: localhost:5000/admission:1
|
||||
resources:
|
||||
requests:
|
||||
memory: "128Mi"
|
||||
cpu: "50m"
|
||||
ports:
|
||||
- containerPort: 443
|
||||
31
admission/k8s/3-admission.yaml
Normal file
31
admission/k8s/3-admission.yaml
Normal file
@ -0,0 +1,31 @@
|
||||
apiVersion: admissionregistration.k8s.io/v1
|
||||
# kind: ValidatingWebhookConfiguration
|
||||
kind: MutatingWebhookConfiguration
|
||||
metadata:
|
||||
name: sample
|
||||
webhooks:
|
||||
- name: "sample-webhook.trion.de"
|
||||
admissionReviewVersions: [v1]
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
apiVersions: ["v1"]
|
||||
operations: ["CREATE"]
|
||||
resources: ["pods"]
|
||||
clientConfig: # url OR service
|
||||
#url: "https://outside.example.com"
|
||||
service:
|
||||
name: admission
|
||||
namespace: webhook
|
||||
path: "/mutate"
|
||||
# path: "/validate"
|
||||
port: 443
|
||||
caBundle: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURFVENDQWZtZ0F3SUJBZ0lVWFFIM0ZkdmVYQ0ZwY2k2eE5acy83bjVXeDhrd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0lERWVNQndHQTFVRUF3d1ZZV1J0YVhOemFXOXVMbmRsWW1odmIyc3VjM1pqTUI0WERUSTFNRFV5TWpFdwpNemswTlZvWERUSTJNRFV5TWpFd016azBOVm93SURFZU1Cd0dBMVVFQXd3VllXUnRhWE56YVc5dUxuZGxZbWh2CmIyc3VjM1pqTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUF2OW54VjBHMmpOSmkKbzVRemFzb1QvVkl1eTdYZityRnI3UFF6RHVnejRQVXIwakRBNmluZURvV3VSQlhXMDV3Z2tnazJzSFpiYjJNegpQYUNlZkFDUWpwOEZ5QUxMYjFOcVVjVThJajdjMEZ2Mk1HME84bXUrNXNwNUoyLyt6cWl6bGJyMFFEQnd1YU9oCmYzN28zblVFdUgyMEtJODNTMXgzOEJNNnRyOWo4ZlN2YTlselpBZTl5K25Sc1hGb1NST2xDbGRYTGJTSDBNN3IKNU96Z1JJSTQrK3JOR0N4ZTdwRndPeGxiTEJTa0VQYUJUem4wTkhnYkJ5TzJNM25FVkJwcHlsKzBBZkU1QWI2OAo0VllVM3A5U2ZrNmlSaHVRSWRCWURTTUtEQ3gwY01VWWp1YlRpZ0FadFZoaW1lQlBmZ3RIQSt5M1hvcjM3UEJLCmNHZFdXL2VXdlFJREFRQUJvME13UVRBZ0JnTlZIUkVFR1RBWGdoVmhaRzFwYzNOcGIyNHVkMlZpYUc5dmF5NXoKZG1Nd0hRWURWUjBPQkJZRUZKQlA2aU5uUDdxVkt0QVVCRTFFeEx6OVd1Y3RNQTBHQ1NxR1NJYjNEUUVCQ3dVQQpBNElCQVFCdFdLTXVYbmlVRGx2cnZVeGRHUGVPMTV5TTFRMXdnaGE5bE5laXl2NHI2NFNTWi80Q3pWV2pWVWVDCmJvU1VoeDhPV2h1VjhWbjVOM0xhemVjVmpyemdBeWM5aUoxWUMrYlVPWHpyR3RRaEhUS0liNlkwNlVRclJWOG0KVGc3RVdLM1VxV2xwcG9WcU8xYU9QYUt5T3YzK2xGOUF1dFZ6YW1MS1FjQVRMS1VmSk05dWRLRTZtS2FJQlNHVwo2eU1tRC9XWTNCeG9URi9JWWhSSjQyWmtIMGlSK2FOaStBMmN4K1ZSZUFTWEVMUVg4ZlZJSVE2M0twWmxNNHRvCnB1WFZzcG4yaktvVWlqRVJwSWNpZHlxaXVVSitNWVg0SStFUEs0aTdWZnpvaVJJRXA3TmhPUVZpaGt3dHc0Tk0KSzgrVHg0YVJsY2xPeTNBM3dqOUxmN2kxdHc3NAotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
|
||||
sideEffects: None # or NoneOnDryRun
|
||||
namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: kubernetes.io/metadata.name
|
||||
operator: In
|
||||
values:
|
||||
- controlled
|
||||
# matchLabels:
|
||||
# enforce-image: enabled
|
||||
19
admission/tls.crt
Normal file
19
admission/tls.crt
Normal file
@ -0,0 +1,19 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDETCCAfmgAwIBAgIUXQH3FdveXCFpci6xNZs/7n5Wx8kwDQYJKoZIhvcNAQEL
|
||||
BQAwIDEeMBwGA1UEAwwVYWRtaXNzaW9uLndlYmhvb2suc3ZjMB4XDTI1MDUyMjEw
|
||||
Mzk0NVoXDTI2MDUyMjEwMzk0NVowIDEeMBwGA1UEAwwVYWRtaXNzaW9uLndlYmhv
|
||||
b2suc3ZjMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv9nxV0G2jNJi
|
||||
o5QzasoT/VIuy7Xf+rFr7PQzDugz4PUr0jDA6ineDoWuRBXW05wgkgk2sHZbb2Mz
|
||||
PaCefACQjp8FyALLb1NqUcU8Ij7c0Fv2MG0O8mu+5sp5J2/+zqizlbr0QDBwuaOh
|
||||
f37o3nUEuH20KI83S1x38BM6tr9j8fSva9lzZAe9y+nRsXFoSROlCldXLbSH0M7r
|
||||
5OzgRII4++rNGCxe7pFwOxlbLBSkEPaBTzn0NHgbByO2M3nEVBppyl+0AfE5Ab68
|
||||
4VYU3p9Sfk6iRhuQIdBYDSMKDCx0cMUYjubTigAZtVhimeBPfgtHA+y3Xor37PBK
|
||||
cGdWW/eWvQIDAQABo0MwQTAgBgNVHREEGTAXghVhZG1pc3Npb24ud2ViaG9vay5z
|
||||
dmMwHQYDVR0OBBYEFJBP6iNnP7qVKtAUBE1ExLz9WuctMA0GCSqGSIb3DQEBCwUA
|
||||
A4IBAQBtWKMuXniUDlvrvUxdGPeO15yM1Q1wgha9lNeiyv4r64SSZ/4CzVWjVUeC
|
||||
boSUhx8OWhuV8Vn5N3LazecVjrzgAyc9iJ1YC+bUOXzrGtQhHTKIb6Y06UQrRV8m
|
||||
Tg7EWK3UqWlppoVqO1aOPaKyOv3+lF9AutVzamLKQcATLKUfJM9udKE6mKaIBSGW
|
||||
6yMmD/WY3BxoTF/IYhRJ42ZkH0iR+aNi+A2cx+VReASXELQX8fVIIQ63KpZlM4to
|
||||
puXVspn2jKoUijERpIcidyqiuUJ+MYX4I+EPK4i7VfzoiRIEp7NhOQVihkwtw4NM
|
||||
K8+Tx4aRlclOy3A3wj9Lf7i1tw74
|
||||
-----END CERTIFICATE-----
|
||||
28
admission/tls.key
Normal file
28
admission/tls.key
Normal file
@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC/2fFXQbaM0mKj
|
||||
lDNqyhP9Ui7Ltd/6sWvs9DMO6DPg9SvSMMDqKd4Oha5EFdbTnCCSCTawdltvYzM9
|
||||
oJ58AJCOnwXIAstvU2pRxTwiPtzQW/YwbQ7ya77mynknb/7OqLOVuvRAMHC5o6F/
|
||||
fujedQS4fbQojzdLXHfwEzq2v2Px9K9r2XNkB73L6dGxcWhJE6UKV1cttIfQzuvk
|
||||
7OBEgjj76s0YLF7ukXA7GVssFKQQ9oFPOfQ0eBsHI7YzecRUGmnKX7QB8TkBvrzh
|
||||
VhTen1J+TqJGG5Ah0FgNIwoMLHRwxRiO5tOKABm1WGKZ4E9+C0cD7Ldeivfs8Epw
|
||||
Z1Zb95a9AgMBAAECggEADqmIvlMcBoCAYAwQL0B+bUUopRJN/zTWu2dLt6nwvRKV
|
||||
D3KrwQ8DajdhQtGAd5peYDWADoBygH15CblgI2NPqPa8/wo8+KchYFp4kWLIhswL
|
||||
HAGvEMFB98AlqOlFn2RZRT+NMegB1Xjh+4J8KEmShh8P88GY8j4rlGzZIeUCrcJp
|
||||
nlVT47d02N9dJRGeRL6qZ2Dlr/4CJjhrgSAQmG6wgHsmaQtVtiAnF7y8WABvIelT
|
||||
mybzROFpq4F47io2Zc4XJioUsN1iLujUKoV2rfZ2+KarGmfGTwaYApMzWBf4V/pQ
|
||||
ZUbbEPEdzyOUecWWX/ESynAr93k7G1EeC8LTtivlqQKBgQDTJnNWMZiQt7BFss49
|
||||
QyaQzSEVFPZJekPdzETh4eZJBhGxeKce14mToLKr4xqMP4blCXBus8dC1C+cQ63J
|
||||
AZ1zcy6Nsx6rGixPJJNvuQsjXBdpyFhYSCKL+NSXzD+isODkNtcBlbjCgch59PzC
|
||||
r5yQiTAHHjr/WSs9OQZo82oa9wKBgQDomhfePhZIFUUzCek5fHTxT4upd3N6MeJe
|
||||
Dsv00ajfNEF//vm+6GyOnNz8hx9qH7cWvsGpsr7AtYB3C9DKoRKRVNidc4z9PovD
|
||||
ZjJQMeOqbOzH7FKiZMrGiJuyYSYB96Mr8tTR7jRBNeBX/3R+ll/aYnYIJZrnnUPX
|
||||
KeijWRpa6wKBgH2m7AvnB7tXFHblqQWb6F9TMtSw3L9tGuXqoTMqkzfxfKX3/rvD
|
||||
2AMaJjlTtICxbTzvGRFHutRyIMMFI23yoBgL+zAn36BCuwt94J8jpxUrwGMa7jfa
|
||||
9XQGZ7zNtzDBwZMNb3Vp+8EEKqEowSG6D5mTihkyTDmYfrq4LLBX6lSRAoGBAKeW
|
||||
lsnerAkloiUi5/IuVMeky3i/gukw1et098id4vFm4iaJnIHLTqP2K1abOKwqy6zM
|
||||
phZRnhSU8UlUrwu/v/QMUMIpBhVUojiYAno7Z9BcCMIG6Ibu3hbrSFremhbiyKMa
|
||||
o/HZkbbGTay5dsLaL5fWRzqZdaGZcs6s+FvxEAcfAoGBAJvfkqvwQ2UadVLNltsl
|
||||
ygFdaGZNyRKUS+KQitOjltKXgebL2ZYk4eCWqwCDhjWKwdPHJkq1fGjBED9yYVVG
|
||||
ORRNqvPh3E2HLhnG4efQLObN++FsZC5roC5wZDm0fjwJfLgfBP4kuBy18CKZs27f
|
||||
JtSwkRdyLwGjiM1IY0UHR/8/
|
||||
-----END PRIVATE KEY-----
|
||||
Reference in New Issue
Block a user