Skip to content

Commit

Permalink
fix #332 by updating the pdf consumer to work with the rest of the pr…
Browse files Browse the repository at this point in the history
…oject
  • Loading branch information
northdpole committed Sep 4, 2024
1 parent 9c207f8 commit b1e2162
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 33 deletions.
26 changes: 17 additions & 9 deletions components/consumers/pdf/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
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
# Stage 2: Build
FROM golang:1.22 as builder

ENV PATH="${PATH}:/go/pkg/mod/github.com/playwright-community"
COPY components/consumers/pdf/pdf /playwright/pdf
COPY components/consumers/pdf/default.html /playwright/default.html
ENTRYPOINT ["/playwright/pdf"]
# Install playwright cli with right version for later use
RUN go install github.com/playwright-community/playwright-go/cmd/playwright@latest

# Stage 3: Final
FROM ubuntu:oracular
COPY --from=builder /go/bin/playwright /
RUN apt-get update && apt-get install -y ca-certificates tzdata \
# Install dependencies and all browsers (or specify one)
&& /playwright install chromium --with-deps \
&& rm -rf /var/lib/apt/lists/*

COPY components/consumers/pdf/pdf /application/pdf
COPY components/consumers/pdf/default.html /application/default.html
WORKDIR /application
ENTRYPOINT ["/application/pdf"]
22 changes: 22 additions & 0 deletions components/consumers/pdf/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
.PHONY: container publish

CONTAINER_REPO=
DRACON_VERSION=
SOURCE_CODE_REPO=
PRODUCER_AGGREGATOR_BASE_IMAGE=$(shell test -e .custom_image && cat .custom_image || echo "scratch")

DOCKER=docker

container:
$(eval workdir:=$(shell mktemp -d /tmp/pdf.XXXXXX))
mkdir -p ${workdir}/components/consumers && \
cp -r ../../../bin/components/consumers/pdf ${workdir}/components/consumers && \
cp default.html ${workdir}/components/consumers/pdf && \
$(DOCKER) build --tag $(CONTAINER_REPO)/components/consumers/pdf:$(DRACON_VERSION) \
--file Dockerfile \
$$([ "${SOURCE_CODE_REPO}" != "" ] && echo "--label=org.opencontainers.image.source=${SOURCE_CODE_REPO}" ) \
${workdir} 1>&2 && \
rm -rf ${workdir}

publish:
$(DOCKER) push $(CONTAINER_REPO)/components/consumers/pdf:$(DRACON_VERSION) 1>&2
58 changes: 36 additions & 22 deletions components/consumers/pdf/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ import (
"fmt"
"html/template"
"log"
"log/slog"
"os"
"path/filepath"
"strings"

"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/go-errors/errors"
playwright "github.com/playwright-community/playwright-go"

"github.com/ocurity/dracon/components/consumers"
Expand Down Expand Up @@ -52,27 +55,27 @@ func main() {
}
responses = r
}
result, err := buildPdf(responses)
result, pdfBytes, err := buildPdf(responses)
if err != nil {
log.Fatal(err)
}

if err = sendToS3(result, bucket, region); err != nil {
if err = sendToS3(result, bucket, region, pdfBytes); err != nil {
log.Fatal(err)
}
}

func sendToS3(filename, bucket, region string) error {
func sendToS3(filename, bucket, region string, pdfBytes []byte) error {
sess, err := session.NewSession(&aws.Config{Region: aws.String(region)})
if err != nil {
return fmt.Errorf("unable to start session with AWS API: %w", err)
return errors.Errorf("unable to start session with AWS API: %w", err)
}

// filename is statically defined above
//#nosec:G304
data, err := os.ReadFile(filename) //#nosec:G304
if err != nil {
return fmt.Errorf("could not open file: %w", err)
return errors.Errorf("could not open file: %w", err)
}

uploader := s3manager.NewUploader(sess)
Expand All @@ -82,68 +85,79 @@ func sendToS3(filename, bucket, region string) error {
Body: bytes.NewReader(data),
})
if err != nil {
return fmt.Errorf("unable to upload %q to %q: %w", filename, bucket, err)
return errors.Errorf("unable to upload %s to %s: %w", filename, bucket, err)
}

fmt.Printf("Successfully uploaded %q to %q\n", filename, bucket)
pdfFilename := strings.Replace(filename, ".html", "", -1) + ".pdf"
_, err = uploader.Upload(&s3manager.UploadInput{
Bucket: aws.String(bucket),
Key: aws.String(pdfFilename),
Body: bytes.NewReader(pdfBytes),
})
if err != nil {
return errors.Errorf("unable to upload %s to %s: %w", filename, bucket, err)
}

slog.Info("uploaded", "filename", filename, "pdf filename", pdfFilename, "to", "bucket", bucket, "successfully")
return nil
}

func buildPdf(data any) (string, error) {
func buildPdf(data any) (string, []byte, error) {
tmpl := template.Must(template.ParseFiles("default.html"))
cleanupRun := func(msg string, cleanup func() error) {
if err := cleanup(); err != nil {
log.Printf(msg, err)
slog.Error(msg, "error", err)
}
}

currentPath, err := os.Getwd()
if err != nil {
return "", fmt.Errorf("could not get current working directory: %w", err)
return "", nil, errors.Errorf("could not get current working directory: %w", err)
}

reportHTMLPath := filepath.Join(currentPath, "report.html")
//#nosec: G304
f, err := os.OpenFile(reportHTMLPath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0o600) //#nosec: G304
if err != nil {
return "", fmt.Errorf("could not open report.html: %w", err)
return "", nil, errors.Errorf("could not open report.html: %w", err)
}
defer cleanupRun("could not close file: %w", f.Close)

if err = tmpl.Execute(f, data); err != nil {
return "", fmt.Errorf("could not apply data to template: %w", err)
return "", nil, errors.Errorf("could not apply data to template: %w", err)
}

pw, err := playwright.Run()
if err != nil {
return "", fmt.Errorf("could not launch playwright: %w", err)
return "", nil, errors.Errorf("could not launch playwright: %w", err)
}
defer cleanupRun("could not stop Playwrigh: %w", pw.Stop)
defer cleanupRun("could not stop Playwright: %w", pw.Stop)

browser, err := pw.Chromium.Launch()
if err != nil {
return "", fmt.Errorf("could not launch Chromium: %w", err)
return "", nil, errors.Errorf("could not launch Chromium: %w", err)
}
defer cleanupRun("could not close browser: %w", browser.Close)

context, err := browser.NewContext()
if err != nil {
return "", fmt.Errorf("could not create context: %w", err)
return "", nil, errors.Errorf("could not create context: %w", err)
}

page, err := context.NewPage()
if err != nil {
return "", fmt.Errorf("could not create page: %w", err)
return "", nil, errors.Errorf("could not create page: %w", err)
}

reportPage := fmt.Sprintf("file:///%s", reportHTMLPath)
if _, err = page.Goto(reportPage); err != nil {
return "", fmt.Errorf("could not goto page %s in the browser: %w", reportPage, err)
return "", nil, errors.Errorf("could not goto page %s in the browser: %w", reportPage, err)
}

_, err = page.PDF(playwright.PagePdfOptions{
pdfBytes, err := page.PDF(playwright.PagePdfOptions{
Path: playwright.String(reportHTMLPath),
})
if err != nil {
return "", nil, errors.Errorf("could not generate pdf from page %s, err: %w", reportPage, err)

return reportHTMLPath, err
}
return reportHTMLPath, pdfBytes, err
}
4 changes: 2 additions & 2 deletions components/consumers/pdf/task.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ spec:
type: string
- name: consumer-pdf-template-location
type: string
default: "/playwright/default.html"
default: "/application/default.html"

workspaces:
- name: output
Expand All @@ -35,7 +35,7 @@ spec:
value: "$(params.consumer-pdf-s3-access-key-id)"
- name: AWS_SECRET_ACCESS_KEY
value: "$(params.consumer-pdf-s3-secret-access-key)"
command: ["/playwright/pdf"]
command: ["/application/pdf"]
args:
[
"-in",
Expand Down

0 comments on commit b1e2162

Please sign in to comment.