diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 50b78aa..5befc9d 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -12,6 +12,7 @@ on: - 'PH-196/*' - 'PH-198/*' - 'PH-201/*' + - 'PH-205/*' pull_request: branches: - main diff --git a/go.mod b/go.mod index 0733185..06ccc2e 100644 --- a/go.mod +++ b/go.mod @@ -50,7 +50,7 @@ require ( github.com/dustinkirkland/golang-petname v0.0.0-20240428194347-eebcea082ee0 github.com/go-chi/chi/v5 v5.2.3 github.com/go-git/go-git/v5 v5.16.3 - github.com/metraction/handwheel v0.0.3 + github.com/metraction/handwheel v0.0.4 github.com/otiai10/copy v1.14.1 github.com/prometheus/client_golang v1.23.2 github.com/theory/jsonpath v0.10.2 diff --git a/go.sum b/go.sum index 0f94622..85f2c98 100644 --- a/go.sum +++ b/go.sum @@ -202,8 +202,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-sqlite3 v1.14.32 h1:JD12Ag3oLy1zQA+BNn74xRgaBbdhbNIDYvQUEuuErjs= github.com/mattn/go-sqlite3 v1.14.32/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= -github.com/metraction/handwheel v0.0.3 h1:Gyw38RnqzJzwMMYw5EBJ4XDXnGvPz8CF0cOZkXT3RIk= -github.com/metraction/handwheel v0.0.3/go.mod h1:Yh3ep7n59UXW8m9hMIuEzJ+T72Z6pVoO6hDFx94+A6M= +github.com/metraction/handwheel v0.0.4 h1:dHacUX93NMZoFXH39bUQdmb/fHNYfJFNeqdtlY94tjY= +github.com/metraction/handwheel v0.0.4/go.mod h1:Yh3ep7n59UXW8m9hMIuEzJ+T72Z6pVoO6hDFx94+A6M= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= diff --git a/helm/pharos/templates/configmap.yaml b/helm/pharos/templates/configmap.yaml index fc40f49..350fd4e 100644 --- a/helm/pharos/templates/configmap.yaml +++ b/helm/pharos/templates/configmap.yaml @@ -8,14 +8,14 @@ data: .pharos.yaml: | {{- if .Values.redis.enabled }} redis: - dsn: {{ .Release.Namespace }}-redis.{{ .Release.Namespace }}.svc.cluster.local:6379 + dsn: {{ .Release.Name }}-redis.{{ .Release.Namespace }}.svc.cluster.local:6379 {{- else }} redis: dsn: {{ .Values.externalRedis.host | default "localhost" }}:{{ .Values.externalRedis.port | default 6379 }} {{- end }} {{- if .Values.redis.enabled }} scanner: - cacheEndpoint: redis://{{ .Release.Namespace }}-redis.{{ .Release.Namespace }}.svc.cluster.local:6379 + cacheEndpoint: redis://{{ .Release.Name }}-redis.{{ .Release.Namespace }}.svc.cluster.local:6379 {{- else }} scanner: cacheEndpoint: redis://{{ .Values.externalRedis.host | default "localhost" }}:{{ .Values.externalRedis.port | default 6379 }} diff --git a/helm/pharos/templates/deployment-reporter.yaml b/helm/pharos/templates/deployment-reporter.yaml index db8b40a..63290f4 100644 --- a/helm/pharos/templates/deployment-reporter.yaml +++ b/helm/pharos/templates/deployment-reporter.yaml @@ -48,6 +48,10 @@ spec: value: {{ .Values.prometheus.query }} - name: PHAROS_PROMETHEUS_INTERVAL value: {{ .Values.prometheus.interval }} + {{- if .Values.prometheus.contextLabels}} + - name: PHAROS_PROMETHEUS_CONTEXTLABELS + value: {{ .Values.prometheus.contextLabels | quote }} + {{- end }} - name: PHAROS_PROMETHEUS_NAMESPACE valueFrom: fieldRef: diff --git a/helm/pharos/values.yaml b/helm/pharos/values.yaml index 32bdbc5..6b64a73 100644 --- a/helm/pharos/values.yaml +++ b/helm/pharos/values.yaml @@ -221,7 +221,7 @@ prometheus: query: 'kube_pod_container_info{}' # -- Interval for scanning images interval: 10m - # -- Context labels to add to the Prometheus context + # -- Context labels to add to the Prometheus context, separate by comma contextLabels: "namespace" # -- Time to live for the scan results, defaults to 12 hours ttl: "12h" diff --git a/pkg/grype/grype.go b/pkg/grype/grype.go index f23df6c..65b4074 100644 --- a/pkg/grype/grype.go +++ b/pkg/grype/grype.go @@ -178,11 +178,11 @@ func (rx *GrypeScanner) VulnScanSbom(sbom []byte) (grypetype.GrypeScanType, []by rx.wgDbUpdate.Wait() // wait in case of running db update - ctx, cancel := context.WithTimeout(context.Background(), rx.ScanTimeout) + ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5) defer cancel() elapsed := utils.ElapsedFunc() - cmd := exec.Command(rx.ScannerBin, "-o", "json") // cyclonedx-json has no "fixed" state ;-( + cmd := exec.CommandContext(ctx, rx.ScannerBin, "-o", "json") // cyclonedx-json has no "fixed" state ;-( cmd.Stdin = bytes.NewReader(sbom) cmd.Stdout = &stdout cmd.Stderr = &stderr diff --git a/pkg/grype/grype_scan.go b/pkg/grype/grype_scan.go index 23e4d38..4ef7e8b 100644 --- a/pkg/grype/grype_scan.go +++ b/pkg/grype/grype_scan.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "time" "github.com/dustin/go-humanize" "github.com/metraction/pharos/internal/integrations/cache" @@ -43,7 +44,9 @@ func ScanImage(task model.PharosScanTask, scanEngine *GrypeScanner, kvc *cache.P return lo.Substring(digest, 0, 39) + ".grype.sbom" } - ctx := context.Background() + ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5) + defer cancel() + var sbomEngine *syft.SyftSbomCreator result.ScanTask.Status = "get-digest" diff --git a/pkg/grype/helper.go b/pkg/grype/helper.go index c91ee58..18af352 100644 --- a/pkg/grype/helper.go +++ b/pkg/grype/helper.go @@ -2,6 +2,7 @@ package grype import ( "bytes" + "context" "encoding/json" "fmt" "os" @@ -75,7 +76,9 @@ func GrypeExeOutput[T any](cmd *exec.Cmd) (T, error) { // check grype binary version func GetScannerVersion(scannerBin string) (string, error) { - cmd := exec.Command(scannerBin, "version", "-o", "json") + ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5) + defer cancel() + cmd := exec.CommandContext(ctx, scannerBin, "version", "-o", "json") cmd.Env = append(cmd.Env, "GRYPE_CHECK_FOR_APP_UPDATE=false") result, err := GrypeExeOutput[GrypeVersion](cmd) @@ -88,7 +91,9 @@ func GetScannerVersion(scannerBin string) (string, error) { // check grype local database status, update DbState func GetDatabaseStatus(scannerBin string, targetDir string) (string, time.Time, error) { - cmd := exec.Command(scannerBin, "db", "status", "-o", "json") + ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5) + defer cancel() + cmd := exec.CommandContext(ctx, scannerBin, "db", "status", "-o", "json") cmd.Env = append(cmd.Env, "GRYPE_CHECK_FOR_APP_UPDATE=false") cmd.Env = append(cmd.Env, "GRYPE_DB_CACHE_DIR="+targetDir) @@ -102,7 +107,9 @@ func GetDatabaseStatus(scannerBin string, targetDir string) (string, time.Time, // check if local db in targetDir requires an update func GrypeUpdateRequired(scannerBin, targetDir string) bool { - cmd := exec.Command(scannerBin, "db", "check", "-o", "json") + ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5) + defer cancel() + cmd := exec.CommandContext(ctx, scannerBin, "db", "check", "-o", "json") cmd.Env = append(cmd.Env, "GRYPE_CHECK_FOR_APP_UPDATE=false") cmd.Env = append(cmd.Env, "GRYPE_DB_CACHE_DIR="+targetDir) @@ -118,7 +125,9 @@ func GetGrypeUpdate(scannerBin, targetDir string) error { // do update var stdout, stderr bytes.Buffer - cmd := exec.Command(scannerBin, "db", "update", "--quiet") + ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5) + defer cancel() + cmd := exec.CommandContext(ctx, scannerBin, "db", "update", "--quiet") cmd.Env = append(cmd.Env, "GRYPE_CHECK_FOR_APP_UPDATE=false") cmd.Env = append(cmd.Env, "GRYPE_DB_CACHE_DIR="+targetDir) cmd.Stdout = &stdout @@ -137,7 +146,9 @@ func GrypeTestScan(scannerBin, targetDir string) error { var stdout, stderr bytes.Buffer - cmd := exec.Command(scannerBin, "-o", "json") + ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5) + defer cancel() + cmd := exec.CommandContext(ctx, scannerBin, "-o", "json") cmd.Stdin = bytes.NewReader(sampleSbom) cmd.Stdout = &stdout cmd.Stderr = &stderr diff --git a/pkg/images/digest.go b/pkg/images/digest.go index 8b4ff74..757225b 100644 --- a/pkg/images/digest.go +++ b/pkg/images/digest.go @@ -1,11 +1,13 @@ package images import ( + "context" "crypto/tls" "encoding/json" "fmt" "net/http" "strings" + "time" "github.com/google/go-containerregistry/pkg/authn" "github.com/google/go-containerregistry/pkg/name" @@ -44,7 +46,11 @@ func GetImageDigests(task model.PharosScanTask) (string, string, string, error) digest := sbom.Source.Metadata.Digests[0].Algorithm + ":" + sbom.Source.Metadata.Digests[0].Value return digest, digest, "", nil } + ctx, cancel := context.WithTimeout(context.Background(), time.Minute*1) + defer cancel() + var options []remote.Option + options = append(options, remote.WithContext(ctx)) platform := task.Platform // TODO: Empty platform -> default? What if @sha:.. is given, so no platform needed ref, err := name.ParseReference(task.ImageSpec) diff --git a/pkg/model/loader_grype.go b/pkg/model/loader_grype.go index db768ef..436095f 100644 --- a/pkg/model/loader_grype.go +++ b/pkg/model/loader_grype.go @@ -44,12 +44,6 @@ func (rx *PharosScanResult) LoadGrypeImageScan(sbom syfttype.SyftSbomType, scan rx.Image.IndexDigest = "" } } // TODO: check if this is correct, but we use this for now. - if rx.Image.IndexDigest == "" { - rx.Image.IndexDigest = "not applicable" - } - if rx.Image.ManifestDigest == "" { - rx.Image.ManifestDigest = "not applicable" - } rx.Image.ArchName = target.Architecture rx.Image.ArchOS = target.OS diff --git a/pkg/syft/syft.go b/pkg/syft/syft.go index a79409e..b5680fd 100644 --- a/pkg/syft/syft.go +++ b/pkg/syft/syft.go @@ -76,7 +76,7 @@ func (rx *SyftSbomCreator) CreateSbom(task model.PharosScanTask, format string) var err error var stdout, stderr bytes.Buffer - ctx, cancel := context.WithTimeout(context.Background(), rx.Timeout) + ctx, cancel := context.WithTimeout(context.Background(), time.Minute*5) defer cancel() // fail if image is not provided @@ -85,7 +85,7 @@ func (rx *SyftSbomCreator) CreateSbom(task model.PharosScanTask, format string) } // note: empty platform is OK elapsed := utils.ElapsedFunc() - cmd := exec.Command(rx.SyftBin, "scan", "registry:"+task.ImageSpec, "--platform", task.Platform, "-o", format) + cmd := exec.CommandContext(ctx, rx.SyftBin, "scan", "registry:"+task.ImageSpec, "--platform", task.Platform, "-o", format) cmd.Stdout = &stdout cmd.Stderr = &stderr diff --git a/testdata/payload.json b/testdata/payload.json index 9e64663..f6813ce 100644 --- a/testdata/payload.json +++ b/testdata/payload.json @@ -1,7 +1,12 @@ { "meta": { - "test": { - "foo": "bar" + "namespaces": { + "traefik-external": { + "exposure": "external" + }, + "kube-system":{ + "exposure": "internal" + } } }, "payload": {