Skip to content

Commit

Permalink
wip pdf consumer
Browse files Browse the repository at this point in the history
  • Loading branch information
northdpole committed Nov 12, 2023
1 parent 7c3e656 commit 2bb7508
Show file tree
Hide file tree
Showing 6 changed files with 331 additions and 0 deletions.
50 changes: 50 additions & 0 deletions components/consumers/pdf/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
subinclude(
"//build/defs:buildkit",
"///k8s//build/defs:k8s",
"//build/defs:dracon",
)

go_binary(
name = "pdf",
srcs = [
"main.go",
],
static = True,
deps = [
"//api/proto/v1",
"//components/consumers",
"//pkg/enumtransformers",
"//pkg/templating",
"//third_party/go/google.golang.org/protobuf",
"//third_party/go/github.com/aws/aws-sdk-go",
"//third_party/go/github.com/playwright-community/playwright-go",
],
)

# buildkit_distroless_image(
# name = "image",
# srcs = [":pdf"],
# visibility = [
# "//examples/...",
# ],
# )

buildkit_image(
name = "image",
srcs = [
":pdf",
],
dockerfile = "Dockerfile",
visibility = [
"//examples/...",
],
)

dracon_component(
name = "pdf",
images = [
":image",
],
task = "task.yaml",
visibility = ["//examples/pipelines/..."],
)
10 changes: 10 additions & 0 deletions components/consumers/pdf/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM golang:latest

WORKDIR /playwright
RUN go mod init github.com/ocurity/pdf-consumer &&\
go get -u github.com/playwright-community/playwright-go &&\
go run github.com/playwright-community/playwright-go/cmd/playwright@latest install --with-deps

ENV PATH="${PATH}:/go/pkg/mod/github.com/playwright-community"
COPY components/consumers/pdf/pdf /pdf
ENTRYPOINT ["/pdf"]
20 changes: 20 additions & 0 deletions components/consumers/pdf/default.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<h1>{{.PageTitle}}</h1>
{{range .EnrichedLaunchToolResponses}}
<h2>{{$.OriginalResults.ScanInfo.ScanUuid}} - {{$.OriginalResults.ToolName}}</h2>
<ul>
{{range $.Issues}}
<h3>{{$.RawIssue.Target}}</h3>
<li>
<h4>{{$.RawIssue.Title}}</h4>
<p>{{$.RawIssue.FirstSeen}} </p>
<p>{{$.RawIssue.Count}} </p>
<p>{{$.RawIssue.FalsePositive}} </p>
<p>{{$.RawIssue.UpdatedAt}} </p>
{{ range $key,$element := .Annotations }}
<p><b>{{$key}}</b>:{{$element}}</p>
{{end}}
</li>
{{end}}
</ul>

{{end}}
80 changes: 80 additions & 0 deletions components/consumers/pdf/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# DO NOT EDIT. Code generated by:
# github.com/ocurity/dracon//build/tools/kustomize-component-generator.

apiVersion: kustomize.config.k8s.io/v1alpha1
kind: Component
resources:
- task.yaml
patches:
# Add the Task to the Tekton Pipeline.
- patch: |
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: unused
spec:
workspaces:
- name: source-code-ws
tasks:
- name: consumer-elasticsearch
taskRef:
name: consumer-elasticsearch
workspaces:
- name: source-code-ws
workspace: source-code-ws
params:
- name: consumer-elasticsearch-url
value: $(params.consumer-elasticsearch-url)
- name: consumer-elasticsearch-description-template
value: $(params.consumer-elasticsearch-description-template)
params:
- name: consumer-elasticsearch-url
type: string
default: http://dracon-es-http.dracon.svc:9200
- name: consumer-elasticsearch-description-template
type: string
default: ""
target:
kind: Pipeline
# Add anchors to Task.
- patch: |
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: consumer-elasticsearch
labels:
v1.dracon.ocurity.com/component: consumer
spec:
params:
- name: anchors
type: array
description: A list of tasks that this task depends on using their anchors.
default: []
results:
- name: anchor
description: An anchor to allow other tasks to depend on this task.
steps:
- name: anchor
image: docker.io/busybox:1.35.0
script: echo "$(context.task.name)" > "$(results.anchor.path)"
target:
kind: Task
name: consumer-elasticsearch
# If we have an enricher-aggregator task in the pipeline (added by the
# enricher-aggregator component), make the consumer depend on the completion of
# it.
- patch: |
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: unused
spec:
tasks:
- name: consumer-elasticsearch
params:
- name: anchors
value:
- $(tasks.enricher-aggregator.results.anchor)
target:
kind: Pipeline
annotationSelector: v1.dracon.ocurity.com/has-enricher-aggregator=true
120 changes: 120 additions & 0 deletions components/consumers/pdf/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package main

import (
"bytes"
"flag"
"fmt"
"html/template"
"log"
"os"
"path/filepath"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3/s3manager"
"github.com/ocurity/dracon/components/consumers"
playwright "github.com/playwright-community/playwright-go"
)

var (
bucket string
region string
reportTemplate string
)

func main() {
flag.StringVar(&bucket, "bucket", "", "s3 bucket name")
flag.StringVar(&region, "region", "", "s3 bucket region")
flag.StringVar(&reportTemplate, "template", "", "report html template location")

if err := consumers.ParseFlags(); err != nil {
log.Fatal(err)
}
var responses any
if consumers.Raw {
r, err := consumers.LoadToolResponse()
if err != nil {
log.Fatal("could not load raw results, file malformed: ", err)
}
responses = r
} else {
r, err := consumers.LoadEnrichedToolResponse()
if err != nil {
log.Fatal("could not load enriched results, file malformed: ", err)
}
responses = r
}

result := buildPdf(responses)
sendToS3(result, bucket, region)
}

func sendToS3(filename, bucket, region string) {
sess, err := session.NewSession(&aws.Config{
Region: aws.String(region),
},
)
if err != nil {
log.Fatalf("Unable to acquire AWS session in region %s, check your credentials", region)
}
data, err := os.ReadFile(filename)
if err != nil {
panic(err)
}
uploader := s3manager.NewUploader(sess)
_, err = uploader.Upload(&s3manager.UploadInput{
Bucket: aws.String(bucket),
Key: aws.String(filename),
Body: bytes.NewReader(data),
})
if err != nil {
log.Fatalf("Unable to upload %q to %q, %v", filename, bucket, err)
}

fmt.Printf("Successfully uploaded %q to %q\n", filename, bucket)
}

func assertErrorToNilf(message string, err error) {
if err != nil {
log.Fatalf(message, err)
}
}

func buildPdf(data any) string {
tmpl := template.Must(template.ParseFiles("layout.html"))

currentPath, err := os.Getwd()
if err != nil {
panic(err)
}
f, err := os.OpenFile(filepath.Join(currentPath, "report.html"), os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0600)
if err != nil {
panic(err)
}
defer f.Close()
tmpl.Execute(f, data)

pw, err := playwright.Run()
assertErrorToNilf("could not launch playwright: %w", err)

browser, err := pw.Chromium.Launch()
assertErrorToNilf("could not launch Chromium: %w", err)

context, err := browser.NewContext()
assertErrorToNilf("could not create context: %w", err)

page, err := context.NewPage()
assertErrorToNilf("could not create page: %w", err)

_, err = page.Goto(fmt.Sprintf("file:///%s", filepath.Join(currentPath, "report.html")))
assertErrorToNilf("could not goto: %w", err)

_, err = page.PDF(playwright.PagePdfOptions{
Path: playwright.String(filepath.Join(currentPath, "report.pdf")),
})
assertErrorToNilf("could not create PDF: %w", err)
assertErrorToNilf("could not close browser: %w", browser.Close())
assertErrorToNilf("could not stop Playwright: %w", pw.Stop())

return filepath.Join(currentPath, "report.pdf")
}
51 changes: 51 additions & 0 deletions components/consumers/pdf/task.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
---
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: consumer-pdf
labels:
v1.dracon.ocurity.com/component: consumer
spec:
volumes:
- name: scratch
emptyDir: {}
params:
- name: consumer-pdf-s3-access-key-id
type: string
- name: consumer-pdf-s3-secret-access-key
type: string
- name: consumer-pdf-s3-bucket-name
type: string
- name: consumer-pdf-s3-bucket-region
type: string
- name: consumer-pdf-template-location
type: string
default: ""

workspaces:
- name: source-code-ws
description: The workspace containing the source-code to scan.
steps:
- name: run-consumer
imagePullPolicy: IfNotPresent
image: ghcr.io/ocurity/dracon/components/consumers/pdf/image:latest
env:
- name: AWS_ACCESS_KEY_ID
value: "$(params.consumer-aws-s3-access-key-id)"
- name: AWS_SECRET_ACCESS_KEY
value: "$(params.consumer-aws-s3-secret-access-key)"
command: ["/app/components/consumers/aws-s3/aws-s3"]
args:
[
"-in",
"$(workspaces.source-code-ws.path)/.dracon/enrichers/",
"-bucket",
"$(params.consumer-aws-s3-bucket-name)",
"-region",
"$(params.consumer-aws-s3-bucket-region)",
"-template",
"$(params.consumer-pdf-template-location)",
]
volumeMounts:
- mountPath: /scratch
name: scratch

0 comments on commit 2bb7508

Please sign in to comment.