From c8607d742f80a5d40458902a1da7b33e44c0a0db Mon Sep 17 00:00:00 2001 From: Kent Rancourt Date: Mon, 21 Mar 2022 19:13:24 -0400 Subject: [PATCH] ci: scan images (#1875) Signed-off-by: Kent Rancourt --- .brigade/brigade.ts | 90 +++++++++++++++++++++++++++++++++++++++++---- Makefile | 8 ++++ 2 files changed, 91 insertions(+), 7 deletions(-) diff --git a/.brigade/brigade.ts b/.brigade/brigade.ts index ff945a868..5e2ea4764 100644 --- a/.brigade/brigade.ts +++ b/.brigade/brigade.ts @@ -132,6 +132,40 @@ class BuildImageJob extends JobWithSource { } } +class ScanJob extends MakeTargetJob { + constructor(image: string, event: Event) { + const env = {} + const secrets = event.project.secrets + if (secrets.unstableImageRegistry) { + env["DOCKER_REGISTRY"] = secrets.unstableImageRegistry + } + if (secrets.unstableImageRegistryOrg) { + env["DOCKER_ORG"] = secrets.unstableImageRegistryOrg + } + super(`scan-${image}`, [`scan-${image}`], dockerClientImg, event, env) + this.fallible = true + } +} + +class PublishSBOMJob extends MakeTargetJob { + constructor(image: string, event: Event, version: string) { + const secrets = event.project.secrets + const env = { + "GITHUB_ORG": secrets.githubOrg, + "GITHUB_REPO": secrets.githubRepo, + "GITHUB_TOKEN": secrets.githubToken, + "VERSION": version + } + if (secrets.stableImageRegistry) { + env["DOCKER_REGISTRY"] = secrets.stableImageRegistry + } + if (secrets.stableImageRegistryOrg) { + env["DOCKER_ORG"] = secrets.stableImageRegistryOrg + } + super(`publish-sbom-${image}`, [`publish-sbom-${image}`], dockerClientImg, event, env) + } +} + // A map of all jobs. When a ci:job_requested event wants to re-run a single // job, this allows us to easily find that job by name. const jobs: {[key: string]: (event: Event, version?: string) => Job } = {} @@ -202,42 +236,84 @@ const buildArtemisJob = (event: Event, version?: string) => { } jobs[buildArtemisJobName] = buildArtemisJob +const scanArtemisJobName = "scan-artemis" +const scanArtemisJob = (event: Event) => { + return new ScanJob("artemis", event) +} +jobs[scanArtemisJobName] = scanArtemisJob + const buildAPIServerJobName = "build-apiserver" const buildAPIServerJob = (event: Event, version?: string) => { return new BuildImageJob("apiserver", event, version) } jobs[buildAPIServerJobName] = buildAPIServerJob +const scanAPIServerJobName = "scan-apiserver" +const scanAPIServerJob = (event: Event) => { + return new ScanJob("apiserver", event) +} +jobs[scanAPIServerJobName] = scanAPIServerJob + const buildGitInitializerJobName = "build-git-initializer" const buildGitInitializerJob = (event: Event, version?: string) => { return new BuildImageJob("git-initializer", event, version) } jobs[buildGitInitializerJobName] = buildGitInitializerJob +const scanGitInitializerJobName = "scan-git-initializer" +const scanGitInitializerJob = (event: Event) => { + return new ScanJob("git-initializer", event) +} +jobs[scanGitInitializerJobName] = scanGitInitializerJob + const buildLoggerLinuxJobName = "build-logger" const buildLoggerLinuxJob = (event: Event, version?: string) => { return new BuildImageJob("logger", event, version) } jobs[buildLoggerLinuxJobName] = buildLoggerLinuxJob +const scanLoggerLinuxJobName = "scan-logger" +const scanLoggerLinuxJob = (event: Event) => { + return new ScanJob("logger", event) +} +jobs[scanLoggerLinuxJobName] = scanLoggerLinuxJob + const buildObserverJobName = "build-observer" const buildObserverJob = (event: Event, version?: string) => { return new BuildImageJob("observer", event, version) } jobs[buildObserverJobName] = buildObserverJob +const scanObserverJobName = "scan-observer" +const scanObserverJob = (event: Event) => { + return new ScanJob("observer", event) +} +jobs[scanObserverJobName] = scanObserverJob + const buildSchedulerJobName = "build-scheduler" const buildSchedulerJob = (event: Event, version?: string) => { return new BuildImageJob("scheduler", event, version) } jobs[buildSchedulerJobName] = buildSchedulerJob +const scanSchedulerJobName = "scan-scheduler" +const scanSchedulerJob = (event: Event) => { + return new ScanJob("scheduler", event) +} +jobs[scanSchedulerJobName] = scanSchedulerJob + const buildWorkerJobName = "build-worker" const buildWorkerJob = (event: Event, version?: string) => { return new BuildImageJob("worker", event, version) } jobs[buildWorkerJobName] = buildWorkerJob +const scanWorkerJobName = "scan-worker" +const scanWorkerJob = (event: Event) => { + return new ScanJob("worker", event) +} +jobs[scanWorkerJobName] = scanWorkerJob + const buildBrigadierJobName = "build-brigadier" const buildBrigadierJob = (event: Event) => { return new MakeTargetJob(buildBrigadierJobName, ["build-brigadier"], jsImg, event) @@ -347,13 +423,13 @@ events.on("brigade.sh/github", "ci:pipeline_requested", async event => { validateExamplesJob(event) ), new ConcurrentGroup( // Build everything - buildArtemisJob(event), - buildAPIServerJob(event), - buildGitInitializerJob(event), - buildLoggerLinuxJob(event), - buildObserverJob(event), - buildSchedulerJob(event), - buildWorkerJob(event), + new SerialGroup(buildArtemisJob(event), scanArtemisJob(event)), + new SerialGroup(buildAPIServerJob(event), scanAPIServerJob(event)), + new SerialGroup(buildGitInitializerJob(event), scanGitInitializerJob(event)), + new SerialGroup(buildLoggerLinuxJob(event), scanLoggerLinuxJob(event)), + new SerialGroup(buildObserverJob(event), scanObserverJob(event)), + new SerialGroup(buildSchedulerJob(event), scanSchedulerJob(event)), + new SerialGroup(buildWorkerJob(event), scanWorkerJob(event)), buildBrigadierJob(event), buildCLIJob(event) ), diff --git a/Makefile b/Makefile index f95cdd88e..3e8e0b3bd 100644 --- a/Makefile +++ b/Makefile @@ -338,6 +338,14 @@ build-cli: ../scripts/build-cli.sh \ ' +################################################################################ +# Image security # +################################################################################ + +.PHONY: scan-% +scan-%: + grype $(DOCKER_IMAGE_PREFIX)$*:$(IMMUTABLE_DOCKER_TAG) -f medium + ################################################################################ # Publish # ################################################################################