From 1207620234281a7c8e4f4ff8d28ebce08d4ce656 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nils=20Gustav=20Str=C3=A5b=C3=B8?= <65334626+nilsgstrabo@users.noreply.github.com> Date: Thu, 13 Jun 2024 15:30:39 +0200 Subject: [PATCH] add platform argument when scanning images (#70) --- .github/workflows/build-push.yml | 2 +- .github/workflows/deploy-database.yml | 2 +- .github/workflows/pr.yml | 16 +- Dockerfile | 4 +- README.md | 2 +- charts/radix-vulnerability-scanner/Chart.yaml | 4 +- go.mod | 80 +++++--- go.sum | 191 +++++++++++------- pkg/handler/handler.go | 15 +- pkg/handler/handler_test.go | 22 +- pkg/imageworker/worker.go | 23 ++- pkg/imageworker/worker_test.go | 16 +- pkg/observe/radixdeployment.go | 20 +- pkg/observe/radixdeployment_test.go | 46 ++++- pkg/scan/mock/scanner.go | 8 +- pkg/scan/scanner.go | 2 +- pkg/scan/snyk.go | 10 +- pkg/scan/snyk_test.go | 26 ++- 18 files changed, 303 insertions(+), 186 deletions(-) diff --git a/.github/workflows/build-push.yml b/.github/workflows/build-push.yml index 58a5595..f1ad38c 100644 --- a/.github/workflows/build-push.yml +++ b/.github/workflows/build-push.yml @@ -43,7 +43,7 @@ jobs: - uses: actions/checkout@v4 if: matrix.target.ref == github.ref - - uses: azure/login@v1 + - uses: azure/login@v2 if: matrix.target.ref == github.ref with: client-id: ${{matrix.target.client-id}} diff --git a/.github/workflows/deploy-database.yml b/.github/workflows/deploy-database.yml index ecef1a4..7a387b3 100644 --- a/.github/workflows/deploy-database.yml +++ b/.github/workflows/deploy-database.yml @@ -49,7 +49,7 @@ jobs: - uses: actions/checkout@v4 if: matrix.target.ref == github.ref - - uses: azure/login@v1 + - uses: azure/login@v2 if: matrix.target.ref == github.ref with: client-id: ${{matrix.target.client-id}} diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index aa3eb88..197553f 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -22,25 +22,25 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 2 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version-file: 'go.mod' - name: Install dependencies run: go mod download - - name: Install GolangCI Lint - run: curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.55.2 - - name: golangci-lint - run: golangci-lint run --timeout=30m --max-same-issues=0 --out-format=github-actions + uses: golangci/golangci-lint-action@v6 + with: + version: v1.59.1 + args: --timeout=30m --max-same-issues=0 test: name: Unit Test runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v4 + - uses: actions/setup-go@v5 with: - go-version: '1.21' + go-version-file: 'go.mod' - name: Install dependencies run: go mod download - name: Run Tests diff --git a/Dockerfile b/Dockerfile index 5386a84..e06bc3c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.21-alpine3.18 as builder +FROM golang:1.22-alpine3.20 as builder RUN apk update && \ apk add --no-cache gcc musl-dev @@ -17,7 +17,7 @@ RUN CGO_ENABLED=0 GOOS=linux go build -ldflags "-s -w" -a -installsuffix cgo -o # Install SNYK FROM alpine:3 as tools -ADD https://github.com/snyk/snyk/releases/download/v1.1286.1/snyk-alpine / +ADD https://github.com/snyk/snyk/releases/download/v1.1291.1/snyk-alpine / RUN chmod +x /snyk-alpine # Run scanner diff --git a/README.md b/README.md index 0d575dc..b9d1cc3 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Every command line argument can be specified as an environment variable by prefi ## Developing -You need Go (>=1.21) installed. Make sure GOPATH and GOROOT are properly set up. Clone the repo into your GOPATH and run go mod download +You need Go (>=1.22) installed. Make sure GOPATH and GOROOT are properly set up. Clone the repo into your GOPATH and run go mod download ## Contribution diff --git a/charts/radix-vulnerability-scanner/Chart.yaml b/charts/radix-vulnerability-scanner/Chart.yaml index 13156be..ed86091 100644 --- a/charts/radix-vulnerability-scanner/Chart.yaml +++ b/charts/radix-vulnerability-scanner/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: radix-vulnerability-scanner description: Scan images in RadixDeployments for vulnerabilities kubeVersion: ">=1.24.0" -appVersion: 1.1.3 -version: 1.2.0 +appVersion: 1.2.0 +version: 1.3.0 sources: - https://github.com/equinor/radix-vulnerability-scanner maintainers: diff --git a/go.mod b/go.mod index fdce278..ce87cad 100644 --- a/go.mod +++ b/go.mod @@ -1,40 +1,45 @@ module github.com/equinor/radix-vulnerability-scanner -go 1.21 +go 1.22.0 -toolchain go1.21.0 +toolchain go1.22.4 require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1 - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 - github.com/containerd/containerd v1.7.14 + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0 + github.com/containerd/containerd v1.7.18 github.com/equinor/radix-common v1.9.2 - github.com/equinor/radix-operator v1.50.2 + github.com/equinor/radix-operator v1.56.0 github.com/golang-jwt/jwt/v5 v5.2.1 github.com/golang/mock v1.6.0 - github.com/microsoft/go-mssqldb v1.7.0 + github.com/microsoft/go-mssqldb v1.7.2 github.com/mitchellh/mapstructure v1.5.0 github.com/robfig/cron/v3 v3.0.1 - github.com/rs/zerolog v1.32.0 + github.com/rs/zerolog v1.33.0 github.com/spf13/pflag v1.0.5 - github.com/spf13/viper v1.18.2 + github.com/spf13/viper v1.19.0 github.com/stretchr/testify v1.9.0 - golang.org/x/oauth2 v0.15.0 + golang.org/x/oauth2 v0.21.0 gorm.io/driver/sqlserver v1.5.3 - gorm.io/gorm v1.25.7 - k8s.io/api v0.29.0 - k8s.io/apimachinery v0.29.0 - k8s.io/client-go v0.29.0 - k8s.io/utils v0.0.0-20240102154912-e7106e64919e + gorm.io/gorm v1.25.10 + k8s.io/api v0.30.1 + k8s.io/apimachinery v0.30.1 + k8s.io/client-go v0.30.1 + k8s.io/utils v0.0.0-20240310230437-4693a0247e57 ) require ( dario.cat/mergo v1.0.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1 // indirect - github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/cert-manager/cert-manager v1.14.2 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/evanphx/json-patch v5.7.0+incompatible // indirect + github.com/emicklei/go-restful/v3 v3.11.2 // indirect + github.com/evanphx/json-patch v5.8.1+incompatible // indirect + github.com/evanphx/json-patch/v5 v5.9.0 // indirect + github.com/expr-lang/expr v1.15.8 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-openapi/jsonpointer v0.20.2 // indirect @@ -43,7 +48,8 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/gofuzz v1.2.0 // indirect @@ -54,19 +60,26 @@ require ( github.com/jinzhu/now v1.1.5 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/kedacore/keda/v2 v2.13.1 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect - github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.70.0 // indirect + github.com/prometheus-operator/prometheus-operator/pkg/client v0.70.0 // indirect + github.com/prometheus/client_golang v1.19.0 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.53.0 // indirect + github.com/prometheus/procfs v0.12.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect @@ -75,22 +88,27 @@ require ( github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/exp v0.0.0-20231226003508-02704c960a9b // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/crypto v0.24.0 // indirect + golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/term v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect - google.golang.org/appengine v1.6.8 // indirect + gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/protobuf v1.33.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/klog/v2 v2.110.1 // indirect - k8s.io/kube-openapi v0.0.0-20240103051144-eec4567ac022 // indirect + k8s.io/apiextensions-apiserver v0.30.1 // indirect + k8s.io/klog/v2 v2.120.1 // indirect + k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect + knative.dev/pkg v0.0.0-20240116073220-b488e7be5902 // indirect + sigs.k8s.io/controller-runtime v0.18.2 // indirect + sigs.k8s.io/gateway-api v1.0.0 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/secrets-store-csi-driver v1.4.0 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/go.sum b/go.sum index 6b70489..3184576 100644 --- a/go.sum +++ b/go.sum @@ -1,19 +1,20 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0/go.mod h1:ON4tFdPTwRcgWEaVDrN3584Ef+b7GgSJaXxe5fW9t4M= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.0/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.6.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.1/go.mod h1:bjGvMhVMb+EEm3VRNQawDMUyMMjo+S5ewNjflkep/0Q= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1 h1:lGlwhPtrX6EVml1hO0ivjkUxsSyl4dsiw9qcA1k/3IQ= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.1/go.mod h1:RKUqNu35KJYcVG/fqTRqmuXJZYNhYkBrnC/hX7yGbTA= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 h1:E+OJmp2tPvt1W+amx48v1eqbjDYsgN+RzP4q16yV5eM= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1/go.mod h1:a6xsAQUZg+VsS3TJ05SRp524Hs4pZ/AeFSr5ENf0Yjo= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.3.0/go.mod h1:OQeznEEkTZ9OrhHJoDD8ZDq51FHgXjqtP9z6bEwBq9U= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1 h1:sO0/P7g68FrryJzljemN+6GTssUXdANk6aJ7T1ZxnsQ= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.1/go.mod h1:h8hyGFDsU5HMivxiS2iYFZsgDbU9OnnJ163x5UGVKYo= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0 h1:U2rTu3Ef+7w9FHKIAXM6ZyqF3UOWJZ12zIm8zECAFfg= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= github.com/Azure/azure-sdk-for-go/sdk/internal v1.1.2/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= github.com/Azure/azure-sdk-for-go/sdk/internal v1.2.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0/go.mod h1:okt5dMMTOFjX/aovMlrjvvXoPMBVSPzk9185BT0+eZM= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1 h1:6oNBlSdi1QqM1PNW7FPA6xOGA5UNsXnkaYZz9vdPGhA= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.1/go.mod h1:s4kgfzA0covAXNicZHDMN58jExvcng2mC/DepXiF1EI= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0 h1:jBQA3cKT4L2rWMpgE7Yt3Hwh2aUj8KXjIGLxjHeYNNo= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.8.0/go.mod h1:4OG6tQ9EOP/MT0NMjDlRzWoVFxfu9rN9B2X+tlSVktg= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0/go.mod h1:Q28U+75mpCaSCDowNEmhIo/rmgdkqmkmzI7N6TGR4UY= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1 h1:MyVTgWR8qd/Jw1Le0NZebGBUCLbtak3bJ3z1OlqZBpw= github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.1/go.mod h1:GpPjLhVR9dnUoJMyHWSPy71xY9/lcmpzIPZXmF0FCVY= @@ -22,33 +23,43 @@ github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0 h1:D3occ github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.0.0/go.mod h1:bTSOgj05NGRuHHhQwAdPnYr9TOdNmKlZTgGLL6nyAdI= github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o= github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= -github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1 h1:DzHpqpoJVaCgOUdVHxE8QB52S6NiVdDQvGlny1qvPqA= -github.com/AzureAD/microsoft-authentication-library-for-go v1.2.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= -github.com/containerd/containerd v1.7.14 h1:H/XLzbnGuenZEGK+v0RkwTdv2u1QFAruMe5N0GNPJwA= -github.com/containerd/containerd v1.7.14/go.mod h1:YMC9Qt5yzNqXx/fO4j/5yYVIHXSRrlB3H7sxkUTvspg= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= +github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/cert-manager/cert-manager v1.14.2 h1:C/uci6yxiCRO04PWomBbSX+T4JT58FIIpDj5SZ6Ks6I= +github.com/cert-manager/cert-manager v1.14.2/go.mod h1:pik7K6jXfgh++lfVJ/i1HzEnDluSUtTVLXSHikj8Lho= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/containerd/containerd v1.7.18 h1:jqjZTQNfXGoEaZdW1WwPU0RqSn1Bm2Ay/KJPUuO8nao= +github.com/containerd/containerd v1.7.18/go.mod h1:IYEk9/IO6wAPUz2bCMVUbsfXjzw5UNP5fLz4PsUygQ4= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= -github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= -github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.11.2 h1:1onLa9DcsMYO9P+CXaL0dStDqQ2EHHXLiz+BtnqkLAU= +github.com/emicklei/go-restful/v3 v3.11.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/equinor/radix-common v1.9.2 h1:pOYN/mSAoPe6KO/Nvudfd5DUETbLv4nLTLzFPr62ADw= github.com/equinor/radix-common v1.9.2/go.mod h1:ekn86U68NT4ccSdt3GT+ukpiclzfuhr96a7zBJKv/jw= -github.com/equinor/radix-operator v1.50.2 h1:xa5kPUN77QT6QJq9+DJzF/ic2c7AJcl4KKztky38sdc= -github.com/equinor/radix-operator v1.50.2/go.mod h1:rl8Tbor0wvKfol67nd/p72MRh0iDTClGeQ2HcMRG/LQ= -github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= -github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/equinor/radix-operator v1.56.0 h1:XNlloJ0/oy4AyKGFySpbatHqVYkydsf5/Oj9gcfZ+Kg= +github.com/equinor/radix-operator v1.56.0/go.mod h1:0KwN3ZEACZWhHrJZIuSxVYVeHhFgUBaRoeDyGiAljRs= +github.com/evanphx/json-patch v5.8.1+incompatible h1:2toJaoe7/rNa1zpeQx0UnVEjqk6z2ecyA20V/zg8vTU= +github.com/evanphx/json-patch v5.8.1+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= +github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/expr-lang/expr v1.15.8 h1:FL8+d3rSSP4tmK9o+vKfSMqqpGL8n15pEPiHcnBpxoI= +github.com/expr-lang/expr v1.15.8/go.mod h1:uCkhfG+x7fcZ5A5sXHKuQ07jGZRl6J0FCAaf2k4PtVQ= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= github.com/go-openapi/jsonpointer v0.20.2 h1:mQc3nmndL8ZBzStEo3JYF8wzmeWffDH4VbXz58sAx6Q= github.com/go-openapi/jsonpointer v0.20.2/go.mod h1:bHen+N0u1KEO3YlmqOjTT9Adn1RfD91Ar825/PuiRVs= github.com/go-openapi/jsonreference v0.20.4 h1:bKlDxQxQJgwpUSgOENiMPzCTBVuc7vTdXSSgNeAhojU= @@ -69,23 +80,22 @@ github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0kt github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42 h1:dHLYa5D8/Ta0aLR2XcPsrkpAgGeFs6thhMcQK0oQ0n8= +github.com/google/pprof v0.0.0-20231229205709-960ae82b1e42/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -111,6 +121,8 @@ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8Hm github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kedacore/keda/v2 v2.13.1 h1:8y4Mp4iWyiqHoedVT3q2g5xvWDe494TRH3sUCZPpn/o= +github.com/kedacore/keda/v2 v2.13.1/go.mod h1:AZTRgxWpK5/6pq+DqJ15y3Bl/C8sl9C7tUVF4phzGDQ= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -126,11 +138,12 @@ github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/microsoft/go-mssqldb v1.6.0/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU= -github.com/microsoft/go-mssqldb v1.7.0 h1:sgMPW0HA6Ihd37Yx0MzHyKD726C2kY/8KJsQtXHNaAs= -github.com/microsoft/go-mssqldb v1.7.0/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA= +github.com/microsoft/go-mssqldb v1.7.2 h1:CHkFJiObW7ItKTJfHo1QX7QBBD1iV+mn1eOyRP3b/PA= +github.com/microsoft/go-mssqldb v1.7.2/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -142,14 +155,15 @@ github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3P github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.13.0 h1:0jY9lJquiL8fcf3M4LAXN5aMlS/b2BV86HFFPCPMgE4= -github.com/onsi/ginkgo/v2 v2.13.0/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= -github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg= -github.com/onsi/gomega v1.29.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= +github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= +github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk= +github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= -github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= @@ -158,13 +172,25 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.70.0 h1:CFTvpkpVP4EXXZuaZuxpikAoma8xVha/IZKMDc9lw+Y= +github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.70.0/go.mod h1:npfc20mPOAu7ViOVnATVMbI7PoXvW99EzgJVqkAomIQ= +github.com/prometheus-operator/prometheus-operator/pkg/client v0.70.0 h1:PpdpJDS1MyMSLILG+Y0hgzVQ3tu6qEkRD0gR/UuvSZk= +github.com/prometheus-operator/prometheus-operator/pkg/client v0.70.0/go.mod h1:4I5Rt6iIu95JBYYaDYA+Er+YBfUwIq9Pwh5TEoBmawg= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= +github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= +github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= -github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8= +github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= @@ -177,8 +203,8 @@ github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= -github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= +github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= +github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= @@ -200,8 +226,12 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= +go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -210,15 +240,17 @@ golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58 golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/exp v0.0.0-20231226003508-02704c960a9b h1:kLiC65FbiHWFAOu+lxwNPujcsl8VYyTYYEZnsOO1WK4= -golang.org/x/exp v0.0.0-20231226003508-02704c960a9b/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3 h1:hNQpMuAJe5CtcUqCXaWga3FHu+kQvCqcsoVaQgSV60o= +golang.org/x/exp v0.0.0-20240112132812-db7319d0e0e3/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -233,16 +265,18 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= -golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -260,26 +294,25 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -289,16 +322,14 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM= -golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= +gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -319,22 +350,32 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/sqlserver v1.5.3 h1:rjupPS4PVw+rjJkfvr8jn2lJ8BMhT4UW5FwuJY0P3Z0= gorm.io/driver/sqlserver v1.5.3/go.mod h1:B+CZ0/7oFJ6tAlefsKoyxdgDCXJKSgwS2bMOQZT0I00= gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= -gorm.io/gorm v1.25.7 h1:VsD6acwRjz2zFxGO50gPO6AkNs7KKnvfzUjHQhZDz/A= -gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= -k8s.io/api v0.29.0 h1:NiCdQMY1QOp1H8lfRyeEf8eOwV6+0xA6XEE44ohDX2A= -k8s.io/api v0.29.0/go.mod h1:sdVmXoz2Bo/cb77Pxi71IPTSErEW32xa4aXwKH7gfBA= -k8s.io/apimachinery v0.29.0 h1:+ACVktwyicPz0oc6MTMLwa2Pw3ouLAfAon1wPLtG48o= -k8s.io/apimachinery v0.29.0/go.mod h1:eVBxQ/cwiJxH58eK/jd/vAk4mrxmVlnpBH5J2GbMeis= -k8s.io/client-go v0.29.0 h1:KmlDtFcrdUzOYrBhXHgKw5ycWzc3ryPX5mQe0SkG3y8= -k8s.io/client-go v0.29.0/go.mod h1:yLkXH4HKMAywcrD82KMSmfYg2DlE8mepPR4JGSo5n38= -k8s.io/klog/v2 v2.110.1 h1:U/Af64HJf7FcwMcXyKm2RPM22WZzyR7OSpYj5tg3cL0= -k8s.io/klog/v2 v2.110.1/go.mod h1:YGtd1984u+GgbuZ7e08/yBuAfKLSO0+uR1Fhi6ExXjo= -k8s.io/kube-openapi v0.0.0-20240103051144-eec4567ac022 h1:avRdiaB03v88Mfvum2S3BBwkNuTlmuar4LlfO9Hajko= -k8s.io/kube-openapi v0.0.0-20240103051144-eec4567ac022/go.mod h1:sIV51WBTkZrlGOJMCDZDA1IaPBUDTulPpD4y7oe038k= -k8s.io/utils v0.0.0-20240102154912-e7106e64919e h1:eQ/4ljkx21sObifjzXwlPKpdGLrCfRziVtos3ofG/sQ= -k8s.io/utils v0.0.0-20240102154912-e7106e64919e/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +gorm.io/gorm v1.25.10 h1:dQpO+33KalOA+aFYGlK+EfxcI5MbO7EP2yYygwh9h+s= +gorm.io/gorm v1.25.10/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= +k8s.io/api v0.30.1 h1:kCm/6mADMdbAxmIh0LBjS54nQBE+U4KmbCfIkF5CpJY= +k8s.io/api v0.30.1/go.mod h1:ddbN2C0+0DIiPntan/bye3SW3PdwLa11/0yqwvuRrJM= +k8s.io/apiextensions-apiserver v0.30.1 h1:4fAJZ9985BmpJG6PkoxVRpXv9vmPUOVzl614xarePws= +k8s.io/apiextensions-apiserver v0.30.1/go.mod h1:R4GuSrlhgq43oRY9sF2IToFh7PVlF1JjfWdoG3pixk4= +k8s.io/apimachinery v0.30.1 h1:ZQStsEfo4n65yAdlGTfP/uSHMQSoYzU/oeEbkmF7P2U= +k8s.io/apimachinery v0.30.1/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= +k8s.io/client-go v0.30.1 h1:uC/Ir6A3R46wdkgCV3vbLyNOYyCJ8oZnjtJGKfytl/Q= +k8s.io/client-go v0.30.1/go.mod h1:wrAqLNs2trwiCH/wxxmT/x3hKVH9PuV0GGW0oDoHVqc= +k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= +k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/utils v0.0.0-20240310230437-4693a0247e57 h1:gbqbevonBh57eILzModw6mrkbwM0gQBEuevE/AaBsHY= +k8s.io/utils v0.0.0-20240310230437-4693a0247e57/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +knative.dev/pkg v0.0.0-20240116073220-b488e7be5902 h1:H6+JJN23fhwYWCHY1339sY6uhIyoUwDy1a8dN233fdk= +knative.dev/pkg v0.0.0-20240116073220-b488e7be5902/go.mod h1:NYk8mMYoLkO7CQWnNkti4YGGnvLxN6MIDbUvtgeo0C0= +sigs.k8s.io/controller-runtime v0.18.2 h1:RqVW6Kpeaji67CY5nPEfRz6ZfFMk0lWQlNrLqlNpx+Q= +sigs.k8s.io/controller-runtime v0.18.2/go.mod h1:tuAt1+wbVsXIT8lPtk5RURxqAnq7xkpv2Mhttslg7Hw= +sigs.k8s.io/gateway-api v1.0.0 h1:iPTStSv41+d9p0xFydll6d7f7MOBGuqXM6p2/zVYMAs= +sigs.k8s.io/gateway-api v1.0.0/go.mod h1:4cUgr0Lnp5FZ0Cdq8FdRwCvpiWws7LVhLHGIudLlf4c= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/secrets-store-csi-driver v1.4.0 h1:R9JVcKOs11fEuiOLlH1BWMeyb6WYzvElRVkq1BWJkr4= +sigs.k8s.io/secrets-store-csi-driver v1.4.0/go.mod h1:RjFTqJzIV6/howouY0llU0iMbldSEt3nc2MGFOL6gko= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= diff --git a/pkg/handler/handler.go b/pkg/handler/handler.go index 83e1457..8060add 100644 --- a/pkg/handler/handler.go +++ b/pkg/handler/handler.go @@ -20,7 +20,7 @@ type ( // Handler interface Handler interface { - Handle(ctx context.Context, imageName string, dockerConfig dockercfg.Config) error + Handle(ctx context.Context, imageName, platform string, dockerConfig dockercfg.Config) error } // Option configuration for vulnerability scanner @@ -65,26 +65,27 @@ func New(scanner scan.Scanner, repository db.Repository, opts ...Option) Handler } // Handle scans an image and stores the result -func (s *imageVulnerabilityScanner) Handle(ctx context.Context, imageName string, dockerConfig dockercfg.Config) error { +func (s *imageVulnerabilityScanner) Handle(ctx context.Context, imageName, platform string, dockerConfig dockercfg.Config) error { // TODO: use https://github.com/go-redsync/redsync for distributed locking // As long as we run the scanner as a single pod/replica and with a single worker "thread" // we don't need to worry about locking // Locking is required if we run multiple workers and/or multiple replicas // and we need to ensure that an image is not concurrently processed by two workers/replicas + logger := log.With().Str("pkg", "handler").Str("image", imageName).Str("platform", platform).Logger() if skipScan, err := s.isLastScanWithinRescanThreshold(ctx, imageName); err != nil { return err } else if skipScan { - log.Info().Str("pkg", "handler").Str("image", imageName).Msgf("skipping scan of image, recently scanned") + logger.Info().Msgf("skipping scan of image, recently scanned") return nil } - log.Info().Str("pkg", "handler").Str("image", imageName).Msgf("scanning image") + logger.Info().Msgf("scanning image") scanCtx, cancel := context.WithTimeout(ctx, s.scanTimeout) defer cancel() - scanResult, err := s.scanner.Scan(scanCtx, imageName, dockerConfig) + scanResult, err := s.scanner.Scan(scanCtx, imageName, platform, dockerConfig) if err != nil { - log.Warn().Str("pkg", "handler").Str("image", imageName).Err(err).Msgf("error scanning image") + logger.Warn().Err(err).Msgf("error scanning image") } scanSuccess := err == nil vulnerabilitiesBulk := []db.VulnerabilityBulkDto{} @@ -133,7 +134,7 @@ func (s *imageVulnerabilityScanner) Handle(ctx context.Context, imageName string dbCtx, cancel := context.WithTimeout(ctx, 30*time.Second) defer cancel() - log.Info().Str("pkg", "handler").Str("image", imageName).Msgf("storing scan results for image") + logger.Info().Msgf("storing scan results for image") return s.repository.RegisterImageScan(dbCtx, imageName, baseImage, time.Now(), scanSuccess, vulnerabilitiesBulk, identifiersBulk, referencesBulk) } diff --git a/pkg/handler/handler_test.go b/pkg/handler/handler_test.go index b215c46..463b575 100644 --- a/pkg/handler/handler_test.go +++ b/pkg/handler/handler_test.go @@ -57,7 +57,7 @@ func (s *scanTestSuite) Test_MustNotScanWhenLastScanWithinMaxAge() { image := "image:latest" s.repo.EXPECT().GetLastImageScan(gomock.Any(), image).Return(&db.ImageScanDto{ScanTime: time.Now()}, nil).Times(1) sut := New(s.scanner, s.repo, WithRescanAge(time.Minute)) - err := sut.Handle(context.TODO(), image, dockercfg.Config{}) + err := sut.Handle(context.TODO(), image, "foo", dockercfg.Config{}) s.Require().NoError(err) } @@ -66,22 +66,22 @@ func (s *scanTestSuite) Test_MustNotScanWhenGetLastImageScanReturnsError() { expectedErr := errors.New("any error") s.repo.EXPECT().GetLastImageScan(gomock.Any(), image).Return(nil, expectedErr).Times(1) sut := New(s.scanner, s.repo, WithRescanAge(time.Minute)) - err := sut.Handle(context.TODO(), image, dockercfg.Config{}) + err := sut.Handle(context.TODO(), image, "foo", dockercfg.Config{}) s.ErrorIs(err, expectedErr) } func (s *scanTestSuite) Test_MustScanWhenLastScanExceedMaxAge() { scanResult := &scan.ScanResult{} s.repo.EXPECT().GetLastImageScan(gomock.Any(), gomock.Any()).Return(&db.ImageScanDto{ScanTime: time.Now().Add(-1 * time.Hour)}, nil).Times(1) - s.scanner.EXPECT().Scan(gomock.Any(), gomock.Any(), gomock.Any()).Return(scanResult, nil).Times(1) + s.scanner.EXPECT().Scan(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(scanResult, nil).Times(1) s.repo.EXPECT().RegisterImageScan(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(1) sut := New(s.scanner, s.repo, WithRescanAge(time.Minute)) - err := sut.Handle(context.TODO(), "foo", dockercfg.Config{}) + err := sut.Handle(context.TODO(), "foo", "bar", dockercfg.Config{}) s.Require().NoError(err) } func (s *scanTestSuite) Test_SuccessfulScanStoresScanResults() { - image := "image:latest" + image, platform := "image:latest", "anyplatform" dockerCfg := dockercfg.Config{Auths: dockercfg.AuthMap{"any": {}}} scanResult := &scan.ScanResult{ Docker: scan.DockerInfo{BaseImage: s.stringPtr("baseimage")}, @@ -137,10 +137,10 @@ func (s *scanTestSuite) Test_SuccessfulScanStoresScanResults() { }() s.repo.EXPECT().GetLastImageScan(gomock.Any(), image).Return(&db.ImageScanDto{ScanTime: time.Now().Add(-1 * time.Hour)}, nil).Times(1) - s.scanner.EXPECT().Scan(gomock.Any(), image, dockerCfg).Return(scanResult, nil).Times(1) + s.scanner.EXPECT().Scan(gomock.Any(), image, platform, dockerCfg).Return(scanResult, nil).Times(1) s.repo.EXPECT().RegisterImageScan(gomock.Any(), image, scanResult.Docker.BaseImage, skewTimeNowMatcher{skewFrom: -5 * time.Second, skewTo: 5 * time.Second}, true, gomock.InAnyOrder(expectedVulnerabilities), gomock.InAnyOrder(expectedIdentifiers), gomock.InAnyOrder(expectedReferences)).Return(nil).Times(1) sut := New(s.scanner, s.repo, WithRescanAge(time.Minute)) - err := sut.Handle(context.TODO(), image, dockerCfg) + err := sut.Handle(context.TODO(), image, platform, dockerCfg) s.Require().NoError(err) } @@ -148,20 +148,20 @@ func (s *scanTestSuite) Test_FailedScanStoresScanFailed() { image := "image:latest" s.repo.EXPECT().GetLastImageScan(gomock.Any(), image).Return(&db.ImageScanDto{ScanTime: time.Now().Add(-1 * time.Hour)}, nil).Times(1) - s.scanner.EXPECT().Scan(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("any error")).Times(1) + s.scanner.EXPECT().Scan(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, errors.New("any error")).Times(1) s.repo.EXPECT().RegisterImageScan(gomock.Any(), image, gomock.Any(), skewTimeNowMatcher{skewFrom: -5 * time.Second, skewTo: 5 * time.Second}, false, []db.VulnerabilityBulkDto{}, []db.VulnerabilityIdentifierBulkDto{}, []db.VulnerabilityReferenceBulkDto{}).Return(nil).Times(1) sut := New(s.scanner, s.repo, WithRescanAge(time.Minute)) - err := sut.Handle(context.TODO(), image, dockercfg.Config{}) + err := sut.Handle(context.TODO(), image, "foo", dockercfg.Config{}) s.Require().NoError(err) } func (s *scanTestSuite) Test_FailingToStoreScanResultsReturnsError() { expectedErr := errors.New("any error") s.repo.EXPECT().GetLastImageScan(gomock.Any(), gomock.Any()).Return(&db.ImageScanDto{ScanTime: time.Now().Add(-1 * time.Hour)}, nil).Times(1) - s.scanner.EXPECT().Scan(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) + s.scanner.EXPECT().Scan(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, nil).Times(1) s.repo.EXPECT().RegisterImageScan(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(expectedErr).Times(1) sut := New(s.scanner, s.repo, WithRescanAge(time.Minute)) - err := sut.Handle(context.TODO(), "anyimage", dockercfg.Config{}) + err := sut.Handle(context.TODO(), "foo", "bar", dockercfg.Config{}) s.ErrorIs(err, expectedErr) } diff --git a/pkg/imageworker/worker.go b/pkg/imageworker/worker.go index 3aeeab3..5d8a682 100644 --- a/pkg/imageworker/worker.go +++ b/pkg/imageworker/worker.go @@ -43,7 +43,7 @@ func New(handler handler.Handler) *Worker { // Receive implementation of Observer func (w *Worker) Receive(obj observe.ImageInfo) { - log.Info().Str("pkg", "imageworker").Str("image", obj.ImageName).Msg("enqueuing image") + log.Info().Str("pkg", "imageworker").Str("image", obj.ImageName).Str("platform", obj.Platform).Msg("enqueuing image") w.queue.Add(&obj) } @@ -61,16 +61,16 @@ func (w *Worker) Start(workers uint, stop <-chan struct{}) error { w.running = false }() - for i := uint(0); i < workers; i++ { - go func(id uint) { - w.worker(id, stop) - }(i) + for range workers { + go func() { + w.worker(stop) + }() } return nil } -func (w *Worker) worker(id uint, stop <-chan struct{}) { +func (w *Worker) worker(stop <-chan struct{}) { ctx, cancel := utils.ContextForChannel(stop) defer cancel() @@ -91,18 +91,21 @@ func (w *Worker) processNextItem(ctx context.Context) bool { func (w *Worker) processItem(ctx context.Context, item any) { defer w.queue.Done(item) + logger := log.With().Str("pkg", "imageworker") if image, ok := item.(*observe.ImageInfo); ok { - log.Info().Str("pkg", "imageworker").Str("image", image.ImageName).Msg("processing image") - if err := w.handler.Handle(ctx, image.ImageName, image.DockerConfig); err != nil { + logger := logger.Str("image", image.ImageName).Str("platform", image.Platform).Logger() + logger.Info().Msg("processing image") + + if err := w.handler.Handle(ctx, image.ImageName, image.Platform, image.DockerConfig); err != nil { requeues := w.queue.NumRequeues(image) if requeues < maxNumberOfRequeues { - log.Info().Str("pkg", "imageworker").Str("image", image.ImageName).Err(err).Msgf("requeuing scan of image (attempt %d of %d) due to error", requeues+1, maxNumberOfRequeues) + log.Info().Err(err).Msgf("requeuing scan of image (attempt %d of %d) due to error", requeues+1, maxNumberOfRequeues) w.queue.AddRateLimited(item) return } else { w.queue.Forget(item) - log.Error().Str("pkg", "imageworker").Str("image", image.ImageName).Err(err).Msgf("scan failed for image after %d retries", requeues) + log.Error().Err(err).Msgf("scan failed for image after %d retries", requeues) return } } diff --git a/pkg/imageworker/worker_test.go b/pkg/imageworker/worker_test.go index f5f600f..42a9294 100644 --- a/pkg/imageworker/worker_test.go +++ b/pkg/imageworker/worker_test.go @@ -46,8 +46,8 @@ type mockHandler struct { mock.Mock } -func (f *mockHandler) Handle(ctx context.Context, image string, dockerConfig dockercfg.Config) error { - args := f.Called(ctx, image, dockerConfig) +func (f *mockHandler) Handle(ctx context.Context, image, platform string, dockerConfig dockercfg.Config) error { + args := f.Called(ctx, image, platform, dockerConfig) return args.Error(0) } @@ -84,14 +84,14 @@ func Test_WorkerProcessImageWithSuccess(t *testing.T) { imageSubject.AttachObserver(sut) // Handle image with no error - imageInfo := observe.ImageInfo{ImageName: "image:tag", DockerConfig: dockercfg.Config{Auths: dockercfg.AuthMap{"any": {}}}} + imageInfo := observe.ImageInfo{ImageName: "image:tag", Platform: "anyplatform", DockerConfig: dockercfg.Config{Auths: dockercfg.AuthMap{"any": {}}}} queue.On("Add", &imageInfo).Times(1) queue.On("Get").Times(1).Return(&imageInfo, false) // First call to get returns image queue.On("Get").Times(1).Return("", true) // Second call to get (in loop) returns shutdown true queue.On("ShuttingDown").Times(1).Return(false) queue.On("Done", &imageInfo).Times(1) queue.On("Forget", &imageInfo).Times(1) - imgHandler.On("Handle", mock.Anything, imageInfo.ImageName, imageInfo.DockerConfig).Times(1).Return(nil) + imgHandler.On("Handle", mock.Anything, imageInfo.ImageName, imageInfo.Platform, imageInfo.DockerConfig).Times(1).Return(nil) imageSubject.Next(imageInfo) time.Sleep(100 * time.Millisecond) // Sleep to let worker go-routines process the queue @@ -109,7 +109,7 @@ func Test_WorkerProcessImageWithError(t *testing.T) { imageSubject.AttachObserver(sut) // Handle image with no error - imageInfo := observe.ImageInfo{ImageName: "image:tag"} + imageInfo := observe.ImageInfo{ImageName: "image:tag", Platform: "anyplatform"} queue.On("Add", &imageInfo).Times(1) queue.On("Get").Times(1).Return(&imageInfo, false) // First call to get returns image queue.On("Get").Times(1).Return("", true) // Second call to get (in loop) returns shutdown true @@ -117,7 +117,7 @@ func Test_WorkerProcessImageWithError(t *testing.T) { queue.On("Done", &imageInfo).Times(1) queue.On("NumRequeues", &imageInfo).Times(1).Return(2) queue.On("AddRateLimited", &imageInfo).Times(1) - imgHandler.On("Handle", mock.Anything, imageInfo.ImageName, mock.Anything).Times(1).Return(errors.New("any error")) + imgHandler.On("Handle", mock.Anything, imageInfo.ImageName, imageInfo.Platform, mock.Anything).Times(1).Return(errors.New("any error")) imageSubject.Next(imageInfo) time.Sleep(100 * time.Millisecond) // Sleep to let worker go-routines process the queue @@ -135,7 +135,7 @@ func Test_WorkerProcessImageWithError_MaxRequeuesExceeded(t *testing.T) { imageSubject.AttachObserver(sut) // Handle image with no error - imageInfo := observe.ImageInfo{ImageName: "image:tag"} + imageInfo := observe.ImageInfo{ImageName: "image:tag", Platform: "anyplatform"} queue.On("Add", &imageInfo).Times(1) queue.On("Get").Times(1).Return(&imageInfo, false) // First call to get returns image queue.On("Get").Times(1).Return("", true) // Second call to get (in loop) returns shutdown true @@ -143,7 +143,7 @@ func Test_WorkerProcessImageWithError_MaxRequeuesExceeded(t *testing.T) { queue.On("ShuttingDown").Times(1).Return(false) queue.On("NumRequeues", &imageInfo).Times(1).Return(maxNumberOfRequeues) queue.On("Forget", &imageInfo).Times(1) - imghandler.On("Handle", mock.Anything, imageInfo.ImageName, mock.Anything).Times(1).Return(errors.New("any error")) + imghandler.On("Handle", mock.Anything, imageInfo.ImageName, imageInfo.Platform, mock.Anything).Times(1).Return(errors.New("any error")) imageSubject.Next(imageInfo) time.Sleep(100 * time.Millisecond) // Sleep to let worker go-routines process the queue diff --git a/pkg/observe/radixdeployment.go b/pkg/observe/radixdeployment.go index b056fff..c30205d 100644 --- a/pkg/observe/radixdeployment.go +++ b/pkg/observe/radixdeployment.go @@ -7,6 +7,7 @@ import ( "github.com/equinor/radix-operator/pkg/apis/defaults" v1 "github.com/equinor/radix-operator/pkg/apis/radix/v1" + "github.com/equinor/radix-operator/pkg/apis/utils" "github.com/equinor/radix-vulnerability-scanner/pkg/dockercfg" "github.com/rs/zerolog/log" corev1 "k8s.io/api/core/v1" @@ -18,6 +19,7 @@ type ( // ImageInfo is sent to observers of RadixDeploymentContainerImageMapper ImageInfo struct { ImageName string + Platform string DockerConfig dockercfg.Config } @@ -45,11 +47,11 @@ func (m *RadixDeploymentContainerImageMapper) Receive(rd *v1.RadixDeployment) { } for _, c := range rd.Spec.Components { - m.notifyObservers(ImageInfo{ImageName: c.GetImage(), DockerConfig: dockerConfig}) + m.notifyObservers(m.buildImageInfo(&c, dockerConfig)) } for _, c := range rd.Spec.Jobs { - m.notifyObservers(ImageInfo{ImageName: c.GetImage(), DockerConfig: dockerConfig}) + m.notifyObservers(m.buildImageInfo(&c, dockerConfig)) } } @@ -72,6 +74,20 @@ func (m *RadixDeploymentContainerImageMapper) readDockerConfigJSON(namespace str return cfg, nil } +func (m *RadixDeploymentContainerImageMapper) buildImageInfo(c v1.RadixCommonDeployComponent, dockerCfg dockercfg.Config) ImageInfo { + return ImageInfo{ + ImageName: c.GetImage(), + Platform: m.parsePlatformForComponent(c), + DockerConfig: dockerCfg, + } +} +func (*RadixDeploymentContainerImageMapper) parsePlatformForComponent(c v1.RadixCommonDeployComponent) string { + architecture := utils.GetArchitectureFromRuntime(c.GetRuntime()) + if len(architecture) == 0 { + return "" + } + return fmt.Sprintf("linux/%s", architecture) +} func (m *RadixDeploymentListMapper) Receive(rds []*v1.RadixDeployment) { for _, rd := range rds { diff --git a/pkg/observe/radixdeployment_test.go b/pkg/observe/radixdeployment_test.go index f4929a6..cb33478 100644 --- a/pkg/observe/radixdeployment_test.go +++ b/pkg/observe/radixdeployment_test.go @@ -35,17 +35,16 @@ func Test_RadixDeploymentContainerImageMapperWithDockerAuthSecret(t *testing.T) sut.Receive(&v1.RadixDeployment{ ObjectMeta: metav1.ObjectMeta{Namespace: namespace}, Spec: v1.RadixDeploymentSpec{ - Components: []v1.RadixDeployComponent{{Image: "c1"}, {Image: "c2"}}, - Jobs: []v1.RadixDeployJobComponent{{Image: "j1"}, {Image: "j2"}}, - ImagePullSecrets: []corev1.LocalObjectReference{{Name: "secretname"}}, + Components: []v1.RadixDeployComponent{{Image: "c1"}, {Image: "c2"}}, + Jobs: []v1.RadixDeployJobComponent{{Image: "j1"}, {Image: "j2"}}, }}) assert.ElementsMatch(t, []ImageInfo{ - {ImageName: "c1", DockerConfig: dockerConfig}, - {ImageName: "c2", DockerConfig: dockerConfig}, - {ImageName: "j1", DockerConfig: dockerConfig}, - {ImageName: "j2", DockerConfig: dockerConfig}, + {ImageName: "c1", Platform: "linux/amd64", DockerConfig: dockerConfig}, + {ImageName: "c2", Platform: "linux/amd64", DockerConfig: dockerConfig}, + {ImageName: "j1", Platform: "linux/amd64", DockerConfig: dockerConfig}, + {ImageName: "j2", Platform: "linux/amd64", DockerConfig: dockerConfig}, }, receivedImages) } @@ -60,11 +59,36 @@ func Test_RadixDeploymentContainerImageMapperWithoutDockerAuthSecret(t *testing. sut.Receive(&v1.RadixDeployment{ ObjectMeta: metav1.ObjectMeta{Namespace: namespace}, Spec: v1.RadixDeploymentSpec{ - Components: []v1.RadixDeployComponent{{Image: "c1"}, {Image: "c2"}}, - Jobs: []v1.RadixDeployJobComponent{{Image: "j1"}, {Image: "j2"}}, - ImagePullSecrets: []corev1.LocalObjectReference{{Name: "secretname"}}, + Components: []v1.RadixDeployComponent{{Image: "c1"}, {Image: "c2"}}, + Jobs: []v1.RadixDeployJobComponent{{Image: "j1"}, {Image: "j2"}}, }}) - assert.ElementsMatch(t, []ImageInfo{{ImageName: "c1"}, {ImageName: "c2"}, {ImageName: "j1"}, {ImageName: "j2"}}, receivedImages) + assert.ElementsMatch(t, []ImageInfo{ + {ImageName: "c1", Platform: "linux/amd64"}, + {ImageName: "c2", Platform: "linux/amd64"}, + {ImageName: "j1", Platform: "linux/amd64"}, + {ImageName: "j2", Platform: "linux/amd64"}, + }, receivedImages) +} + +func Test_RadixDeploymentContainerImageMapperWithRuntime(t *testing.T) { + namespace := "anynamespace" + var receivedImages []ImageInfo + fakeObserver := fakeImageInfoObserver{OnReceive: func(receivedObj ImageInfo) { receivedImages = append(receivedImages, receivedObj) }} + kubeClient := kubefake.NewSimpleClientset() + sut := &RadixDeploymentContainerImageMapper{KubeClient: kubeClient} + sut.AttachObserver(&fakeObserver) + sut.Receive(&v1.RadixDeployment{ + ObjectMeta: metav1.ObjectMeta{Namespace: namespace}, + Spec: v1.RadixDeploymentSpec{ + Components: []v1.RadixDeployComponent{{Image: "c1"}, {Image: "c2", Runtime: &v1.Runtime{Architecture: "otherarch"}}}, + Jobs: []v1.RadixDeployJobComponent{{Image: "j1"}, {Image: "j2", Runtime: &v1.Runtime{Architecture: "otherarch"}}}, + }}) + assert.ElementsMatch(t, []ImageInfo{ + {ImageName: "c1", Platform: "linux/amd64"}, + {ImageName: "c2", Platform: "linux/otherarch"}, + {ImageName: "j1", Platform: "linux/amd64"}, + {ImageName: "j2", Platform: "linux/otherarch"}, + }, receivedImages) } func Test_RadixDeploymentListMapper(t *testing.T) { diff --git a/pkg/scan/mock/scanner.go b/pkg/scan/mock/scanner.go index 26fea13..5948b34 100644 --- a/pkg/scan/mock/scanner.go +++ b/pkg/scan/mock/scanner.go @@ -37,16 +37,16 @@ func (m *MockScanner) EXPECT() *MockScannerMockRecorder { } // Scan mocks base method. -func (m *MockScanner) Scan(ctx context.Context, image string, dockerConfig dockercfg.Config) (*scan.ScanResult, error) { +func (m *MockScanner) Scan(ctx context.Context, image, platform string, dockerConfig dockercfg.Config) (*scan.ScanResult, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Scan", ctx, image, dockerConfig) + ret := m.ctrl.Call(m, "Scan", ctx, image, platform, dockerConfig) ret0, _ := ret[0].(*scan.ScanResult) ret1, _ := ret[1].(error) return ret0, ret1 } // Scan indicates an expected call of Scan. -func (mr *MockScannerMockRecorder) Scan(ctx, image, dockerConfig interface{}) *gomock.Call { +func (mr *MockScannerMockRecorder) Scan(ctx, image, platform, dockerConfig interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Scan", reflect.TypeOf((*MockScanner)(nil).Scan), ctx, image, dockerConfig) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Scan", reflect.TypeOf((*MockScanner)(nil).Scan), ctx, image, platform, dockerConfig) } diff --git a/pkg/scan/scanner.go b/pkg/scan/scanner.go index c787dd6..6cd2d25 100644 --- a/pkg/scan/scanner.go +++ b/pkg/scan/scanner.go @@ -9,5 +9,5 @@ import ( // Scanner defines methods for scanning Docker images for vulnerabilities type Scanner interface { // Scan scans a Docker image for vulnerabilities - Scan(ctx context.Context, image string, dockerConfig dockercfg.Config) (*ScanResult, error) + Scan(ctx context.Context, image, platform string, dockerConfig dockercfg.Config) (*ScanResult, error) } diff --git a/pkg/scan/snyk.go b/pkg/scan/snyk.go index 8cfdf78..fe5a945 100644 --- a/pkg/scan/snyk.go +++ b/pkg/scan/snyk.go @@ -40,8 +40,8 @@ func NewSnykScanner(executor executor.Executor, opts ...SnykOption) *SnykScanner return scanner } -func (s *SnykScanner) Scan(ctx context.Context, image string, dockerConfig dockercfg.Config) (*ScanResult, error) { - logger := log.Ctx(ctx).With().Str("pkg", "scan").Str("image", image).Logger() +func (s *SnykScanner) Scan(ctx context.Context, image, platform string, dockerConfig dockercfg.Config) (*ScanResult, error) { + logger := log.Ctx(ctx).With().Str("pkg", "scan").Str("image", image).Str("platform", platform).Logger() ctx = logger.WithContext(ctx) auths := append(s.commonDockerAuths, &dockerConfig) var credArgs []string @@ -67,6 +67,10 @@ func (s *SnykScanner) Scan(ctx context.Context, image string, dockerConfig docke logger.Debug().Msg("scanning image") testArgs := []string{"container", "test", "--json", image} + if len(platform) > 0 { + testArgs = append(testArgs, fmt.Sprintf("--platform=%s", platform)) + } + var testArgsWithCreds []string testArgsWithCreds = append(testArgsWithCreds, testArgs...) testArgsWithCreds = append(testArgsWithCreds, credArgs...) @@ -90,7 +94,7 @@ func (s *SnykScanner) Scan(ctx context.Context, image string, dockerConfig docke logger.Debug().Msg("scanning image again without creds") buf = &bytes.Buffer{} err = scanFn(ctx, testArgs, buf) - logger.Trace().Stringer("result", buf).Strs("args", testArgsWithCreds).Err(err).Msg("retry scan completed") + logger.Trace().Stringer("result", buf).Strs("args", testArgs).Err(err).Msg("retry scan completed") if err != nil { logger.Warn().Stringer("stdout", buf).Msg("scan failed") return nil, err diff --git a/pkg/scan/snyk_test.go b/pkg/scan/snyk_test.go index 5e16e78..e984692 100644 --- a/pkg/scan/snyk_test.go +++ b/pkg/scan/snyk_test.go @@ -52,12 +52,11 @@ func (s *SnykTestSuite) Test_SnykScanImageWithCommonAuthEntry() { sut := NewSnykScanner(s.executor, WithAuthProvider(s.authprovider)) - _, err := sut.Scan(context.Background(), "my.registry.com/image:tag", dockercfg.Config{}) + _, err := sut.Scan(context.Background(), "my.registry.com/image:tag", "", dockercfg.Config{}) assert.NoError(s.T(), err) } func (s *SnykTestSuite) Test_SnykScanImageWithNoCommonAuthEntryButWithArgumentAuth() { - expectedArgs := []string{"container", "test", "--json", "my.registry.com/image:tag", "--username=anotheruser", "--password=anotherpwd"} s.executor.EXPECT(). Execute(gomock.Any(), "snyk", expectedArgs, gomock.Any()). @@ -67,7 +66,7 @@ func (s *SnykTestSuite) Test_SnykScanImageWithNoCommonAuthEntryButWithArgumentAu sut := NewSnykScanner(s.executor, WithAuthProvider(dockercfg.Config{})) extraCfg := &dockercfg.Config{Auths: dockercfg.AuthMap{"my.registry.com": {Username: "anotheruser", Password: "anotherpwd"}}} - _, actualErr := sut.Scan(context.Background(), "my.registry.com/image:tag", *extraCfg) + _, actualErr := sut.Scan(context.Background(), "my.registry.com/image:tag", "", *extraCfg) assert.NoError(s.T(), actualErr) } @@ -82,7 +81,7 @@ func (s *SnykTestSuite) Test_SnykScanImageAuthArgFailsShouldRetryWithoutAuth() { sut := NewSnykScanner(s.executor, WithAuthProvider(dockerCfg)) extraConfig := dockercfg.Config{Auths: dockercfg.AuthMap{"my.registry.com": {Username: "anotheruser", Password: "anotherpwd"}}} - _, actualErr := sut.Scan(context.Background(), "my.registry.com/image:tag", extraConfig) + _, actualErr := sut.Scan(context.Background(), "my.registry.com/image:tag", "", extraConfig) s.NoError(actualErr) } @@ -92,7 +91,18 @@ func (s *SnykTestSuite) Test_SnykScanImageWithNoAuthEntry() { s.executor.EXPECT().Execute(gomock.Any(), "snyk", expectedArgs, gomock.Any()).Do(s.fakeWriter(emptyObj)).Return(nil).Times(1) sut := NewSnykScanner(s.executor, WithAuthProvider(dockerCfg)) - _, actualErr := sut.Scan(context.Background(), "my.registry.com/image:tag", dockercfg.Config{}) + _, actualErr := sut.Scan(context.Background(), "my.registry.com/image:tag", "", dockercfg.Config{}) + + s.NoError(actualErr) +} + +func (s *SnykTestSuite) Test_SnykScanImageWithPlatform() { + dockerCfg := dockercfg.Config{Auths: dockercfg.AuthMap{"another.registry.com": {Username: "someuser", Password: "somepwd"}}} + expectedArgs := []string{"container", "test", "--json", "my.registry.com/image:tag", "--platform=anyplatformarg"} + s.executor.EXPECT().Execute(gomock.Any(), "snyk", expectedArgs, gomock.Any()).Do(s.fakeWriter(emptyObj)).Return(nil).Times(1) + sut := NewSnykScanner(s.executor, WithAuthProvider(dockerCfg)) + + _, actualErr := sut.Scan(context.Background(), "my.registry.com/image:tag", "anyplatformarg", dockercfg.Config{}) s.NoError(actualErr) } @@ -101,7 +111,7 @@ func (s *SnykTestSuite) Test_SnykScanImageWithInvalidImageStringReturnsError() { dockerCfg := dockercfg.Config{Auths: dockercfg.AuthMap{"any.registry.com": {Username: "someuser", Password: "somepwd"}}} s.executor.EXPECT().Execute(gomock.Any(), "snyk", gomock.Any(), gomock.Any()).Times(0) sut := NewSnykScanner(s.executor, WithAuthProvider(dockerCfg)) - _, actualErr := sut.Scan(context.Background(), "my.registry.com/:image:tag", dockercfg.Config{}) + _, actualErr := sut.Scan(context.Background(), "my.registry.com/:image:tag", "", dockercfg.Config{}) s.Error(actualErr) } @@ -111,7 +121,7 @@ func (s *SnykTestSuite) Test_SnykScanErrorFromExecutorReturned() { expectedErr := errors.New("any error") s.executor.EXPECT().Execute(gomock.Any(), "snyk", gomock.Any(), gomock.Any()).Return(expectedErr).Times(1) sut := NewSnykScanner(s.executor, WithAuthProvider(dockerCfg)) - _, actualErr := sut.Scan(context.Background(), "my.registry.com/image:test", dockercfg.Config{}) + _, actualErr := sut.Scan(context.Background(), "my.registry.com/image:test", "", dockercfg.Config{}) s.ErrorIs(expectedErr, actualErr) } @@ -125,7 +135,7 @@ func (s *SnykTestSuite) Test_SnykScanStdOutFromExecutorUnmarshalled() { s.executor.EXPECT().Execute(gomock.Any(), "snyk", gomock.Any(), gomock.Any()).Do(s.fakeWriter(expectedResults)).Return(nil).Times(1) sut := NewSnykScanner(s.executor, WithAuthProvider(dockerCfg)) - actualScanResult, actualErr := sut.Scan(context.Background(), "my.registry.com/image:test", dockercfg.Config{}) + actualScanResult, actualErr := sut.Scan(context.Background(), "my.registry.com/image:test", "", dockercfg.Config{}) s.NoError(actualErr) s.Equal(expectedResults, *actualScanResult) }