Skip to content

Commit e1f821a

Browse files
Admission webhook implementation (#25)
* wip: adding addmission webhook * wip: first dummy version working * wip: version2 working demo - but it takes alot of time * configured the trivy server using k8s deployment/svc way * updated the backend to use trivy client * wip: tested the almost everything - its working Signed-off-by: Rahul Vishwakarma <[email protected]> * wip: added cert in .gitignore Signed-off-by: Rahul Vishwakarma <[email protected]> * wip: added BYPASS_CVE_DENIED as env for bypassing fail on CVE Signed-off-by: Rahul Vishwakarma <[email protected]> * wip: improved the bit of log formatting Signed-off-by: Rahul Vishwakarma <[email protected]> --------- Signed-off-by: Rahul Vishwakarma <[email protected]>
1 parent 7da563b commit e1f821a

30 files changed

+762
-61
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,6 @@ vendor\
44
.idea
55
.DS_Store
66
vendor
7-
.env
7+
.env
8+
results.json
9+
certs

Dockerfile

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,53 @@
1-
# Build stage
1+
# =========================
2+
# Build Stage
3+
# =========================
24
FROM golang:1.24 AS builder
35

46
WORKDIR /app
57

8+
# Download dependencies
69
COPY go.mod go.sum ./
710
RUN go mod download
811

12+
# Copy the source code
913
COPY . .
1014
ARG TARGETARCH=amd64
11-
#RUN go build -o k8s-custom-controller
15+
16+
# Build the Go binary
1217
RUN CGO_ENABLED=0 GOOS=linux GOARCH=$TARGETARCH go build -o backend main.go
1318

1419

15-
# Final stage
16-
FROM alpine:latest
17-
RUN apk --no-cache add ca-certificates
20+
# =========================
21+
# Final Stage with Trivy
22+
# =========================
23+
FROM alpine:3.20
24+
25+
# Install required packages
26+
RUN apk --no-cache add \
27+
ca-certificates \
28+
curl \
29+
bash \
30+
tar \
31+
gzip \
32+
libc6-compat
33+
34+
# Install Trivy (static binary)
35+
ENV TRIVY_VERSION=0.55.2
36+
RUN curl -sfL https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz \
37+
| tar zx -C /usr/local/bin/ trivy
38+
39+
# Verify installation
40+
RUN trivy --version
41+
1842
WORKDIR /root/
43+
44+
# Copy the Go binary
1945
COPY --from=builder /app/backend .
2046

2147
# Allow access to Kubernetes API via a volume mount for kubeconfig
2248
VOLUME ["/root/.kube"]
49+
50+
# Expose webhook port
2351
EXPOSE 8000
52+
2453
CMD ["./backend"]

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
APP_NAME = k8s-custom-controller
22
DOCKER_USER = manzilrahul
3-
VERSION ?= 1.0.5
3+
VERSION ?= 1.0.15
44
IMAGE_NAME = $(DOCKER_USER)/$(APP_NAME)
55

66
# 🖼️ Logo banner

chart/templates/role.yaml

Lines changed: 0 additions & 8 deletions
This file was deleted.

chart/templates/rolebinding.yaml

Lines changed: 0 additions & 12 deletions
This file was deleted.

chart/templates/service.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ spec:
88
type: {{ .Values.service.type }}
99
ports:
1010
- port: {{ .Values.service.port }}
11-
targetPort: http
11+
targetPort: 8000 #http
1212
protocol: TCP
1313
name: http
1414
selector:

chart/values.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ image:
1111
# This sets the pull policy for images.
1212
pullPolicy: IfNotPresent
1313
# Overrides the image tag whose default is the chart appVersion.
14-
tag: "1.0.5"
14+
tag: "latest" # 1.0.9
1515

1616
# This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
1717
imagePullSecrets: []
@@ -55,7 +55,8 @@ service:
5555
# This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types
5656
type: NodePort
5757
# This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports
58-
port: 8000
58+
# port: 8000
59+
port: 443
5960

6061
# This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/
6162
ingress:

controller/controller.go

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,9 @@ func (c *controller) processItem() bool {
7575
}
7676
err = c.syncDeployment(namespace, name)
7777
if err != nil {
78+
fmt.Println("────────────────────────────────────────────────────")
7879
fmt.Printf("sync deployment, %s\n", err.Error())
80+
fmt.Println("────────────────────────────────────────────────────")
7981
return false
8082
}
8183
return true
@@ -117,12 +119,16 @@ func (c *controller) syncDeployment(ns, name string) error {
117119

118120
_, err = c.clientset.CoreV1().Services(ns).Create(ctx, &service, metav1.CreateOptions{})
119121
if err != nil {
122+
fmt.Println("────────────────────────────────────────────────────")
120123
fmt.Printf("sync deployment, %s\n", err.Error())
124+
fmt.Println("────────────────────────────────────────────────────")
121125
}
122126

123127
err = c.createIngress(ns, name)
124128
if err != nil {
129+
fmt.Println("────────────────────────────────────────────────────")
125130
fmt.Printf("sync deployment, %s\n", err.Error())
131+
fmt.Println("────────────────────────────────────────────────────")
126132
}
127133
return nil
128134
}
@@ -193,18 +199,17 @@ func depLabels(dep appsv1.Deployment) map[string]string {
193199
func (c *controller) handleAdd(obj interface{}) {
194200
deployment, ok := obj.(*appsv1.Deployment)
195201
if !ok {
196-
fmt.Println("\n Not a Deployment")
202+
fmt.Println("\n Not a Deployment object")
197203
return
198204
}
199205

200-
fmt.Printf("Deployment Added:\n")
201-
fmt.Printf("Name: %s\n", deployment.Name)
202-
203-
fmt.Printf("ADDED: Name=%s, Namespace=%s, UID=%s, Created=%s\n",
204-
deployment.Name,
205-
deployment.Namespace,
206-
string(deployment.UID),
207-
deployment.CreationTimestamp)
206+
fmt.Println("────────────────────────────────────────────────────")
207+
fmt.Println("📦 Deployment Added")
208+
fmt.Printf("🔤 Name: %s\n", deployment.Name)
209+
fmt.Printf("📂 Namespace: %s\n", deployment.Namespace)
210+
fmt.Printf("🆔 UID: %s\n", deployment.UID)
211+
fmt.Printf("🕓 Created: %s\n", deployment.CreationTimestamp.UTC().Format("2006-01-02 15:04:05 MST"))
212+
fmt.Println("────────────────────────────────────────────────────")
208213

209214
c.queue.Add(obj)
210215
}
@@ -213,17 +218,17 @@ func (c *controller) handleAdd(obj interface{}) {
213218
func (c *controller) handleDel(obj interface{}) {
214219
deployment, ok := obj.(*appsv1.Deployment)
215220
if !ok {
216-
fmt.Println("\n Not a Deployment")
221+
fmt.Println("\n Not a Deployment")
217222
return
218223
}
219-
fmt.Printf("Deployment Deleted:\n")
220-
fmt.Printf("Name: %s\n", deployment.Name)
221224

222-
fmt.Printf("DELETED: Name=%s, Namespace=%s, UID=%s, Created=%s\n",
223-
deployment.Name,
224-
deployment.Namespace,
225-
string(deployment.UID),
226-
deployment.CreationTimestamp)
225+
fmt.Println("────────────────────────────────────────────────────")
226+
fmt.Println("📦 Deployment DELETED")
227+
fmt.Printf("🔤 Name: %s\n", deployment.Name)
228+
fmt.Printf("📂 Namespace: %s\n", deployment.Namespace)
229+
fmt.Printf("🆔 UID: %s\n", deployment.UID)
230+
fmt.Printf("🕓 Deleted: %s\n", deployment.CreationTimestamp.UTC().Format("2006-01-02 15:04:05 MST"))
231+
fmt.Println("────────────────────────────────────────────────────")
227232

228233
//c.queue.Add(obj)
229234
}

docs/how-to-install.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
```bash
2+
# create cluster
3+
# Install cert-manager
4+
# add trivy - k apply -f docs/trivy-manifest/deployment.yml and then same for svc
5+
# k apply -f manifest/k8s-controller-webhook.yaml (it contain everything, cert, tls secrets)
6+
# add cluster permission for list, watch, create, get
7+
# k apply -f manifest/cluster-permission.yaml
8+
```

docs/trivy-docs.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
```bash
2+
kubectl exec -it <your-controller-pod> -- nslookup trivy-server-service.default.svc
3+
kubectl exec -it <your-controller-pod> -- curl http://trivy-server-service.default.svc:8080/healthz
4+
5+
---
6+
kubectl exec -it k8s-custom-controller-5c7d47fdb7-69757 -- curl http://trivy-server-service.default.svc:8080/healthz
7+
ok
8+
---
9+
k exec -it k8s-custom-controller-5c7d47fdb7-69757 -- bash
10+
k8s-custom-controller-5c7d47fdb7-69757:/etc# cat resolv.conf
11+
search example1.svc.cluster.local svc.cluster.local cluster.local
12+
nameserver 10.96.0.10
13+
options ndots:5
14+
```
15+

0 commit comments

Comments
 (0)