Skip to content

Commit

Permalink
Feat: add aqua trivy as trivy operator (#572)
Browse files Browse the repository at this point in the history
Signed-off-by: FogDong <[email protected]>

Signed-off-by: FogDong <[email protected]>
  • Loading branch information
FogDong authored Dec 26, 2022
1 parent 1d8cd2c commit e7ae082
Show file tree
Hide file tree
Showing 11 changed files with 165 additions and 170 deletions.
62 changes: 23 additions & 39 deletions addons/trivy-operator/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# description
- This addon provides a vulnerability scanner that continuously scans containers deployed in a Kubernetes cluster.
- More Info is here: https://github.com/devopstales/trivy-operator/blob/main/README.md
- For detail, please checkout [AquaSecurity Trivy Operator](https://github.com/aquasecurity/trivy-operator).

## Install

Expand Down Expand Up @@ -30,18 +30,7 @@ local ─┬─ - ─── Namespace/trivy-system
Status: stored artifact for revision 'd120de77328f9ccbaaf5bfe8737220cac718bf34e98493d63b94ae20a4d0b92d'
```

Create a new namespace for image-scan or use your exist namespace:

```shell
vela env init image-scan --namespace image-scan
```

Set the scan label for your namespace:

```shell
vela env set image-scan --labels trivy-operator-validation=true
vela env set image-scan --labels trivy-scan=true
```
Aqua Trivy Operator will scan all the workloads in the cluster.

Apply an application to scan your image, following application will first deploy a `webservice` with a risky image, then scan the image and send the image result with notification.

Expand All @@ -52,14 +41,14 @@ apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: example
namespace: image-scan
namespace: default
spec:
components:
- name: frontend
type: webservice
properties:
port: 8000
image: docker.io/nginxinc/nginx-unprivileged:latest
image: fogdong/simple-web-demo:v1
workflow:
steps:
- name: apply-comp
Expand All @@ -72,7 +61,8 @@ spec:
- name: image-scan-result
valueFrom: result.message
properties:
image: docker.io/nginxinc/nginx-unprivileged:latest
resource:
name: frontend
- name: notification
type: notification
inputs:
Expand All @@ -82,7 +72,7 @@ spec:
properties:
slack:
url:
value: <slack-url>
value: <your slack>
```

Deploy this application:
Expand All @@ -97,10 +87,10 @@ Checkout the application status:
$ vela status example
About:
Name: example
Namespace: image-scan
Created at: 2022-11-04 12:04:10 +0800 CST
Status: running
Name: example
Namespace: default
Created at: 2022-12-22 16:12:11 +0800 CST
Status: running
Workflow:
Expand All @@ -109,46 +99,40 @@ Workflow:
Suspend: false
Terminated: false
Steps
- id: dr6vd9i5dz
- id: z26279ngn1
name: apply-comp
type: apply-component
phase: succeeded
- id: skvs1l1m9z
phase: succeeded
- id: 92xcnw1dvc
name: image-scan
type: trivy-check
phase: succeeded
- id: 3gvsx3bsc9
phase: succeeded
- id: i64nsj12sg
name: notification
type: notification
phase: succeeded
phase: succeeded
Services:
- Name: frontend
Cluster: local Namespace: image-scan
- Name: frontend
Cluster: local Namespace: default
Type: webservice
Healthy Ready:1/1
No trait applied
```

All the steps are successful! Trivy-operator will scan the image and send the result with CVE info to your slack channel like:

![](../../examples/trivy-operator/trivy.png)
![](../../examples/trivy-operator/aqua-trivy.png)

## More

If you want to check out the scan data in raw, you can check the metrics of trivy:
If you want to check out the scan data in raw, you can check the `vuln` in the cluster:

```shell
kubectl port-forward service/trivy-system-trivy-system-helm-trivy-operator 9999:9115 -n trivy-system
Forwarding from 127.0.0.1:9999 -> 9115
Forwarding from [::1]:9999 -> 9115

curl -s http://localhost:9115/metrics | grep trivy_vulnerabilities

curl -s http://localhost:9115/metrics | grep ac_vulnerabilities
kubectl get vuln
```

## Reference

https://github.com/devopstales/trivy-operator
https://github.com/aquasecurity/trivy-operator
116 changes: 116 additions & 0 deletions addons/trivy-operator/definitions/aqua-trivy.cue
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import (
"vela/op"
"strings"
"encoding/yaml"
)

"trivy-check": {
type: "workflow-step"
annotations: {
"definition.oam.dev/example-url": "https://raw.githubusercontent.com/kubevela/catalog/master/examples/trivy-operator/trivy-check-example.yaml"
}
labels: {}
description: ""
}
template: {
findResource: op.#Steps & {
resourceType: *parameter.resource.kind | string
resourceName: *parameter.resource.name | string
if parameter.resource.kind == "Deployment" {
deployment: op.#Read & {
value: {
apiVersion: "apps/v1"
kind: "Deployment"
metadata: {
name: parameter.resource.name
namespace: context.namespace
}
}
}
rs: op.#List & {
resource: {
apiVersion: "apps/v1"
kind: "ReplicaSet"
}
filter: {
namespace: context.namespace
matchingLabels: deployment.value.spec.selector.matchLabels
}
}
resourceType: "ReplicaSet"
if rs.list != _|_ {
if rs.list.items != _|_ {
if len(rs.list.items) > 0 {
resourceName: rs.list.items[0].metadata.name
}
}
}
}
}

findVulns: op.#Steps & {
scanPod: op.#List & {
resource: {
apiVersion: "v1"
kind: "Pod"
}
filter: {
namespace: "trivy-system"
matchingLabels: {
"trivy-operator.resource.kind": findResource.resourceType
"trivy-operator.resource.name": findResource.resourceName
}
}
}
wait: op.#ConditionalWait & {
continue: len(scanPod.list.items) == 0
}
vulns: op.#List & {
resource: {
apiVersion: "aquasecurity.github.io/v1alpha1"
kind: "VulnerabilityReport"
}
filter: {
namespace: context.namespace
matchingLabels: {
"trivy-operator.resource.kind": findResource.resourceType
"trivy-operator.resource.name": findResource.resourceName
}
}
}
}

trivyLevel: strings.Join(parameter.level, ",")
result: {
report: {...}
if findVulns.vulns.list != _|_ && findVulns.vulns.list.items != _|_ for v in findVulns.vulns.list.items {
report: "\(v.report.artifact.repository):\(v.report.artifact.tag)": {
summary: v.report.summary
if parameter.showDetail {
details: [ for vul in v.report.vulnerabilities if strings.Contains(trivyLevel, vul.severity) {
"\(vul.severity) \(vul.vulnerabilityID)": {
link: vul.primaryLink
title: vul.title
resource: vul.resource
}
}]
}
}
}

if len(report) > 0 {
message: "Trivy Scan Result: \n\n" + yaml.Marshal(report)
}
if len(report) == 0 {
message: "No processed trivy scanning job found for \(findResource.resourceType) \(findResource.resourceName)"
}
}
parameter: {
level: *["CRITICAL"] | [...string]
showDetail: *true | bool
resource: {
kind: *"Deployment" | "StatefulSet" | "ReplicaSet" | "Job" | "Pod" | "DaemonSet" | string
name: string
}
}
}
69 changes: 0 additions & 69 deletions addons/trivy-operator/definitions/trivy.cue

This file was deleted.

3 changes: 1 addition & 2 deletions addons/trivy-operator/metadata.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: trivy-operator
version: 2.3.2
version: 2.3.3
description: Kubernetes Operator based on the open-source container vulnerability scanner Trivy
icon: https://raw.githubusercontent.com/devopstales/helm-charts/main/icons/trivy.png
url: https://github.com/devopstales/trivy-operator
Expand All @@ -9,6 +9,5 @@ tags:

dependencies:
- name: fluxcd
- name: prometheus-server

invisible: false
16 changes: 2 additions & 14 deletions addons/trivy-operator/parameter.cue
Original file line number Diff line number Diff line change
@@ -1,19 +1,7 @@
parameter: {
//+usage=Deploy to specified clusters. Leave empty to deploy to all clusters.
// +usage=Deploy to specified clusters. Leave empty to deploy to all clusters.
clusters?: [...string]

//+usage=Namespace to deploy to, defaults to cert-manager
// +usage=Namespace to deploy to, defaults to cert-manager
namespace: *"trivy-system" | string

// +usage=Specify image including image repository address and image name to use for the trivy-operator
"repository": *"devopstales/trivy-operator" | string

// +usage=Specify image tag to use for the trivy-operator
"tag": *"2.4.1" | string

// +usage=Specify if persistent storage (pv) is enabled or not, no persistent storage when false
"enabled": *false | bool

// +usage=Specify the crontab for trivy-operator to scanning image in labled namespace
"crontab": *"*/5 * * * *" | string
}
18 changes: 18 additions & 0 deletions addons/trivy-operator/resources/aqua-trivy-service.cue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package main

aquaTrivyHelm: {
name: "aqua-trivy-system-helm"
dependsOn: ["trivy-system-ns"]
type: "helm"

properties: {
repoType: "helm"
url: "https://aquasecurity.github.io/helm-charts"
chart: "trivy-operator"
version: "0.9.1"
targetNamespace: parameter.namespace
values: {
trivy: ignoreUnfixed: true
}
}
}
Loading

0 comments on commit e7ae082

Please sign in to comment.