chore(trivy): update trivy version and enforce OCI compliant repo names in local image storage (#1068)
1. chore(trivy): update trivy library version The trivy team switched github.com/urfave/cli for viper so there are some other code changes as well. Since we don't use github.com/urfave/cli directly in our software we needed to add a tools.go in order for "go mod tidy" to not delete it. See this pattern explained in: - https://github.com/99designs/gqlgen#quick-start - https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module - https://github.com/go-modules-by-example/index/blob/master/010_tools/README.md#walk-through The jobs using "go get -u" have been updated to use "go install", since go get modifies the go.mod by upgrading some of the packages, but downgrading trivy to an older version with broken dependencies 2. fix(storage) Update local storage to ignore folder names not compliant with dist spec Also updated trivy to download the DB and cache results under the rootDir/_trivy folder 3. fix(s3): one of the s3 tests was missing the skipIt call This caused a failure when running locally without s3 being available 4. make sure the offline scanning is enabled, and zot only downloads the trivy DB on the regular schedule, and doesn't download the DB on every image scan ci: increase build and test timeout as tests are reaching the limit more often Signed-off-by: Andrei Aaron <aaaron@luxoft.com>
This commit is contained in:
parent
9294ebb0ec
commit
fac1d1d05d
2
.github/workflows/ci-cd.yml
vendored
2
.github/workflows/ci-cd.yml
vendored
@ -87,7 +87,7 @@ jobs:
|
||||
AWS_ACCESS_KEY_ID: fake
|
||||
AWS_SECRET_ACCESS_KEY: fake
|
||||
- name: Run build and test
|
||||
timeout-minutes: 60
|
||||
timeout-minutes: 70
|
||||
run: |
|
||||
echo "Building for $OS:$ARCH"
|
||||
cd $GITHUB_WORKSPACE
|
||||
|
2
.github/workflows/cluster.yaml
vendored
2
.github/workflows/cluster.yaml
vendored
@ -34,7 +34,7 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd $GITHUB_WORKSPACE
|
||||
go get -u github.com/swaggo/swag/cmd/swag
|
||||
go install github.com/swaggo/swag/cmd/swag
|
||||
go mod download
|
||||
sudo apt-get update
|
||||
sudo apt-get -y install rpm uidmap
|
||||
|
2
.github/workflows/ecosystem-tools.yaml
vendored
2
.github/workflows/ecosystem-tools.yaml
vendored
@ -23,7 +23,7 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd $GITHUB_WORKSPACE
|
||||
go get -u github.com/swaggo/swag/cmd/swag
|
||||
go install github.com/swaggo/swag/cmd/swag
|
||||
go mod download
|
||||
sudo apt-get update
|
||||
sudo apt-get install libgpgme-dev libassuan-dev libbtrfs-dev libdevmapper-dev pkg-config rpm uidmap
|
||||
|
@ -45,7 +45,7 @@ var (
|
||||
ErrEmptyValue = errors.New("cache: empty value")
|
||||
ErrEmptyRepoList = errors.New("search: no repository found")
|
||||
ErrCVESearchDisabled = errors.New("search: CVE search is disabled")
|
||||
ErrInvalidRepositoryName = errors.New("routes: not a repository name")
|
||||
ErrInvalidRepositoryName = errors.New("repository: not a valid repository name")
|
||||
ErrSyncMissingCatalog = errors.New("sync: couldn't fetch upstream registry's catalog")
|
||||
ErrMethodNotSupported = errors.New("storage: method not supported")
|
||||
ErrInvalidMetric = errors.New("metrics: invalid metric func")
|
||||
|
169
go.mod
169
go.mod
@ -7,7 +7,7 @@ require (
|
||||
github.com/Masterminds/semver v1.5.0
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
|
||||
github.com/apex/log v1.9.0
|
||||
github.com/aquasecurity/trivy-db v0.0.0-20210916043317-726b7b72a47b
|
||||
github.com/aquasecurity/trivy-db v0.0.0-20220627104749-930461748b63
|
||||
github.com/bmatcuk/doublestar/v4 v4.6.0
|
||||
github.com/briandowns/spinner v1.20.0
|
||||
github.com/chartmuseum/auth v0.5.0
|
||||
@ -42,7 +42,6 @@ require (
|
||||
github.com/spf13/viper v1.14.0
|
||||
github.com/stretchr/testify v1.8.1
|
||||
github.com/swaggo/swag v1.8.9
|
||||
github.com/urfave/cli/v2 v2.23.7
|
||||
github.com/vektah/gqlparser/v2 v2.5.1
|
||||
go.etcd.io/bbolt v1.3.6
|
||||
golang.org/x/crypto v0.5.0
|
||||
@ -51,7 +50,7 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/aquasecurity/trivy v0.0.0-00010101000000-000000000000
|
||||
github.com/aquasecurity/trivy v0.35.0
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodb v1.18.0
|
||||
github.com/containers/image/v5 v5.23.0
|
||||
github.com/gobwas/glob v0.2.3
|
||||
@ -62,9 +61,102 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/CycloneDX/cyclonedx-go v0.6.0 // indirect
|
||||
github.com/MakeNowJust/heredoc v1.0.0 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.1.1 // indirect
|
||||
github.com/Masterminds/sprig/v3 v3.2.2 // indirect
|
||||
github.com/Masterminds/squirrel v1.5.3 // indirect
|
||||
github.com/Microsoft/hcsshim v0.9.4 // indirect
|
||||
github.com/alecthomas/chroma v0.10.0 // indirect
|
||||
github.com/aquasecurity/defsec v0.82.0 // indirect
|
||||
github.com/aquasecurity/memoryfs v1.4.4 // indirect
|
||||
github.com/aquasecurity/table v1.8.0 // indirect
|
||||
github.com/aquasecurity/tml v0.6.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/dynamodbstreams v1.14.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ebs v1.15.19 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.63.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.21 // indirect
|
||||
github.com/chai2010/gettext-go v1.0.2 // indirect
|
||||
github.com/containerd/cgroups v1.0.4 // indirect
|
||||
github.com/containerd/containerd v1.6.8 // indirect
|
||||
github.com/containerd/continuity v0.3.0 // indirect
|
||||
github.com/containerd/fifo v1.0.0 // indirect
|
||||
github.com/containerd/ttrpc v1.1.1-0.20220420014843-944ef4a40df3 // indirect
|
||||
github.com/dlclark/regexp2 v1.4.0 // indirect
|
||||
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
|
||||
github.com/docker/libnetwork v0.8.0-dev.2.0.20200917202933-d0951081b35f // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.8.0 // indirect
|
||||
github.com/evanphx/json-patch v5.6.0+incompatible // indirect
|
||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d // indirect
|
||||
github.com/go-errors/errors v1.0.1 // indirect
|
||||
github.com/go-gorp/gorp/v3 v3.0.2 // indirect
|
||||
github.com/gogo/googleapis v1.4.1 // indirect
|
||||
github.com/google/gnostic v0.5.7-v3refs // indirect
|
||||
github.com/google/licenseclassifier/v2 v2.0.0-pre6 // indirect
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
|
||||
github.com/gosuri/uitable v0.0.4 // indirect
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
|
||||
github.com/jmoiron/sqlx v1.3.5 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect
|
||||
github.com/liamg/iamgo v0.0.9 // indirect
|
||||
github.com/liamg/jfather v0.0.7 // indirect
|
||||
github.com/liamg/memoryfs v1.4.3 // indirect
|
||||
github.com/lib/pq v1.10.6 // indirect
|
||||
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de // indirect
|
||||
github.com/lunixbochs/struc v0.0.0-20200707160740-784aaebc1d40 // indirect
|
||||
github.com/masahiro331/go-disk v0.0.0-20220919035250-c8da316f91ac // indirect
|
||||
github.com/masahiro331/go-ebs-file v0.0.0-20221125181850-09c63351e38c // indirect
|
||||
github.com/masahiro331/go-ext4-filesystem v0.0.0-20221016160854-4b40d7ee6193 // indirect
|
||||
github.com/masahiro331/go-vmdk-parser v0.0.0-20221124162251-5eeffd974e5a // indirect
|
||||
github.com/masahiro331/go-xfs-filesystem v0.0.0-20221127135739-051c25f1becd // indirect
|
||||
github.com/microsoft/go-rustaudit v0.0.0-20220808201409-204dfee52032 // indirect
|
||||
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
|
||||
github.com/moby/locker v1.0.1 // indirect
|
||||
github.com/moby/spdystream v0.2.0 // indirect
|
||||
github.com/moby/sys/signal v0.7.0 // indirect
|
||||
github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
|
||||
github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00 // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/opencontainers/selinux v1.10.2 // indirect
|
||||
github.com/owenrumney/go-sarif/v2 v2.1.2 // indirect
|
||||
github.com/package-url/packageurl-go v0.1.1-0.20220203205134-d70459300c8a // indirect
|
||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
||||
github.com/rubenv/sql-migrate v1.1.2 // indirect
|
||||
github.com/russross/blackfriday v1.6.0 // indirect
|
||||
github.com/samber/lo v1.33.0 // indirect
|
||||
github.com/shopspring/decimal v1.2.0 // indirect
|
||||
github.com/spdx/tools-golang v0.3.0 // indirect
|
||||
github.com/tetratelabs/wazero v1.0.0-pre.3 // indirect
|
||||
github.com/urfave/cli/v2 v2.8.1 // indirect
|
||||
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||
github.com/xlab/treeprint v1.1.0 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
|
||||
helm.sh/helm/v3 v3.10.0 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.25.0 // indirect
|
||||
k8s.io/apiserver v0.25.0 // indirect
|
||||
k8s.io/cli-runtime v0.25.3 // indirect
|
||||
k8s.io/component-base v0.25.3 // indirect
|
||||
k8s.io/kubectl v0.25.3 // indirect
|
||||
lukechampine.com/uint128 v1.1.1 // indirect
|
||||
modernc.org/cc/v3 v3.36.0 // indirect
|
||||
modernc.org/ccgo/v3 v3.16.6 // indirect
|
||||
modernc.org/libc v1.16.7 // indirect
|
||||
modernc.org/mathutil v1.4.1 // indirect
|
||||
modernc.org/memory v1.1.1 // indirect
|
||||
modernc.org/opt v0.1.1 // indirect
|
||||
modernc.org/sqlite v1.17.3 // indirect
|
||||
modernc.org/strutil v1.1.1 // indirect
|
||||
modernc.org/token v1.0.0 // indirect
|
||||
oras.land/oras-go v1.2.0 // indirect
|
||||
sigs.k8s.io/kustomize/api v0.12.1 // indirect
|
||||
sigs.k8s.io/kustomize/kyaml v0.13.9 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
@ -88,10 +180,9 @@ require (
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20220621081337-cb9428e4ac1e // indirect
|
||||
github.com/BurntSushi/toml v1.2.1 // indirect
|
||||
github.com/GoogleCloudPlatform/docker-credential-gcr v1.5.0 // indirect
|
||||
github.com/GoogleCloudPlatform/docker-credential-gcr v2.0.5+incompatible // indirect
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
|
||||
github.com/Microsoft/go-winio v0.6.0 // indirect
|
||||
github.com/OneOfOne/xxhash v1.2.8 // indirect
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20220407094043-a94812496cf5 // indirect
|
||||
@ -99,7 +190,7 @@ require (
|
||||
github.com/VividCortex/ewma v1.2.0 // indirect
|
||||
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d // indirect
|
||||
github.com/acomagu/bufpipe v1.0.3 // indirect
|
||||
github.com/agext/levenshtein v1.2.2 // indirect
|
||||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/agnivade/levenshtein v1.1.1 // indirect
|
||||
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.4 // indirect
|
||||
github.com/alibabacloud-go/cr-20160607 v1.0.1 // indirect
|
||||
@ -114,15 +205,13 @@ require (
|
||||
github.com/aliyun/credentials-go v1.2.3 // indirect
|
||||
github.com/apparentlymart/go-cidr v1.1.0 // indirect
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||
github.com/aquasecurity/fanal v0.0.0-20211005172059-69527b46560c // indirect
|
||||
github.com/aquasecurity/go-dep-parser v0.0.0-20210919151457-76db061b9305 // indirect
|
||||
github.com/aquasecurity/go-dep-parser v0.0.0-20221114145626-35ef808901e8 // indirect
|
||||
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce // indirect
|
||||
github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798 // indirect
|
||||
github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46 // indirect
|
||||
github.com/aquasecurity/go-version v0.0.0-20210121072130-637058cfe492 // indirect
|
||||
github.com/aquasecurity/tfsec v0.58.11 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
|
||||
github.com/aws/aws-sdk-go v1.44.114
|
||||
github.com/aws/aws-sdk-go v1.44.136
|
||||
github.com/aws/aws-sdk-go-v2 v1.17.3
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.8
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.8 // indirect
|
||||
@ -131,7 +220,7 @@ require (
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.27 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.28 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ecr v1.15.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ecr v1.17.18 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.12.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.12.0 // indirect
|
||||
@ -145,12 +234,12 @@ require (
|
||||
github.com/bgentry/speakeasy v0.1.0 // indirect
|
||||
github.com/blang/semver v3.5.1+incompatible // indirect
|
||||
github.com/bmatcuk/doublestar v1.3.4 // indirect
|
||||
github.com/caarlos0/env/v6 v6.0.0 // indirect
|
||||
github.com/caarlos0/env/v6 v6.10.1 // indirect
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.3 // indirect
|
||||
github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.2 // indirect
|
||||
github.com/cheggaaa/pb/v3 v3.0.3 // indirect
|
||||
github.com/cheggaaa/pb/v3 v3.1.0 // indirect
|
||||
github.com/chrismellard/docker-credential-acr-env v0.0.0-20220119192733-fe33c00cee21 // indirect
|
||||
github.com/clbanning/mxj/v2 v2.5.6 // indirect
|
||||
github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 // indirect
|
||||
@ -205,9 +294,8 @@ require (
|
||||
github.com/go-pkgz/expirable-cache v0.0.3 // indirect
|
||||
github.com/go-playground/locales v0.14.0 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.11.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.11.1 // indirect
|
||||
github.com/go-redis/redis/v8 v8.11.5 // indirect
|
||||
github.com/go-restruct/restruct v0.0.0-20191227155143-5734170a48a1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
|
||||
@ -219,7 +307,6 @@ require (
|
||||
github.com/google/btree v1.1.2 // indirect
|
||||
github.com/google/certificate-transparency-go v1.1.3 // indirect
|
||||
github.com/google/go-cmp v0.5.9 // indirect
|
||||
github.com/google/go-github/v33 v33.0.0 // indirect
|
||||
github.com/google/go-github/v45 v45.2.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
@ -227,7 +314,6 @@ require (
|
||||
github.com/google/wire v0.5.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.6.0 // indirect
|
||||
github.com/googleapis/gnostic v0.5.5 // indirect
|
||||
github.com/googleapis/go-type-adapters v1.0.0 // indirect
|
||||
github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
@ -237,7 +323,7 @@ require (
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-getter v1.5.2 // indirect
|
||||
github.com/hashicorp/go-getter v1.6.2 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.1 // indirect
|
||||
github.com/hashicorp/go-safetemp v1.0.0 // indirect
|
||||
@ -245,10 +331,10 @@ require (
|
||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.4
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.10.1 // indirect
|
||||
github.com/hashicorp/hcl/v2 v2.14.1 // indirect
|
||||
github.com/huandu/xstrings v1.3.2 // indirect
|
||||
github.com/imdario/mergo v0.3.13 // indirect
|
||||
github.com/in-toto/in-toto-golang v0.3.4-0.20220709202702-fa494aaa0add // indirect
|
||||
github.com/in-toto/in-toto-golang v0.5.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.0.1 // indirect
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
|
||||
github.com/jedisct1/go-minisign v0.0.0-20211028175153-1c139d1cc84b // indirect
|
||||
@ -263,8 +349,8 @@ require (
|
||||
github.com/klauspost/pgzip v1.2.5 // indirect
|
||||
github.com/knqyf263/go-apk-version v0.0.0-20200609155635-041fdbb8563f // indirect
|
||||
github.com/knqyf263/go-deb-version v0.0.0-20190517075300-09fca494f03d // indirect
|
||||
github.com/knqyf263/go-rpm-version v0.0.0-20170716094938-74609b86c936 // indirect
|
||||
github.com/knqyf263/go-rpmdb v0.0.0-20210911072402-73bd0ce46c49 // indirect
|
||||
github.com/knqyf263/go-rpm-version v0.0.0-20220614171824-631e686d1075 // indirect
|
||||
github.com/knqyf263/go-rpmdb v0.0.0-20221030142135-919c8a52f04f // indirect
|
||||
github.com/knqyf263/nested v0.0.1 // indirect
|
||||
github.com/leodido/go-urn v1.2.1 // indirect
|
||||
github.com/letsencrypt/boulder v0.0.0-20220929215747-76583552c2be // indirect
|
||||
@ -279,9 +365,9 @@ require (
|
||||
github.com/mitchellh/copystructure v1.2.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.0 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/moby/buildkit v0.8.1 // indirect
|
||||
github.com/moby/buildkit v0.10.4 // indirect
|
||||
github.com/moby/sys/mountinfo v0.6.2 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
@ -292,9 +378,9 @@ require (
|
||||
github.com/oklog/ulid v1.3.1 // indirect
|
||||
github.com/open-policy-agent/opa v0.45.0 // indirect
|
||||
github.com/opencontainers/runc v1.1.4 // indirect
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417 // indirect
|
||||
github.com/opencontainers/runtime-spec v1.0.3-0.20220311020903-6969a0a09ab1 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/owenrumney/squealer v0.2.28 // indirect
|
||||
github.com/owenrumney/squealer v1.0.1-0.20220510063705-c0be93f0edea // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
@ -313,7 +399,7 @@ require (
|
||||
github.com/sergi/go-diff v1.2.0 // indirect
|
||||
github.com/shibumi/go-pathspec v1.3.0 // indirect
|
||||
github.com/sigstore/fulcio v0.6.0 // indirect
|
||||
github.com/sigstore/rekor v0.12.1-0.20220915152154-4bb6f441c1b2 // indirect
|
||||
github.com/sigstore/rekor v1.0.0 // indirect
|
||||
github.com/sigstore/sigstore v1.4.4 // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect
|
||||
@ -337,9 +423,8 @@ require (
|
||||
github.com/titanous/rocacheck v0.0.0-20171023193734-afe73141d399 // indirect
|
||||
github.com/tjfoc/gmsm v1.3.2 // indirect
|
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect
|
||||
github.com/tmccombs/hcl2json v0.3.1 // indirect
|
||||
github.com/transparency-dev/merkle v0.0.1 // indirect
|
||||
github.com/twitchtv/twirp v8.1.0+incompatible // indirect
|
||||
github.com/twitchtv/twirp v8.1.2+incompatible // indirect
|
||||
github.com/ulikunitz/xz v0.5.10 // indirect
|
||||
github.com/urfave/cli v1.22.7 // indirect
|
||||
github.com/vbatts/go-mtree v0.5.0 // indirect
|
||||
@ -350,9 +435,8 @@ require (
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // indirect
|
||||
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
|
||||
github.com/yashtewari/glob-intersection v0.1.0 // indirect
|
||||
github.com/zclconf/go-cty v1.9.1 // indirect
|
||||
github.com/zclconf/go-cty v1.10.0 // indirect
|
||||
github.com/zclconf/go-cty-yaml v1.0.2 // indirect
|
||||
github.com/zeebo/errs v1.2.2 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.6.0-alpha.0 // indirect
|
||||
@ -369,7 +453,7 @@ require (
|
||||
go.mongodb.org/mongo-driver v1.10.0 // indirect
|
||||
go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect
|
||||
go.opencensus.io v0.23.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.29.0 // indirect
|
||||
go.opentelemetry.io/otel v1.7.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0 // indirect
|
||||
@ -389,7 +473,7 @@ require (
|
||||
golang.org/x/term v0.4.0 // indirect
|
||||
golang.org/x/text v0.6.0 // indirect
|
||||
golang.org/x/time v0.0.0-20220922220347-f3bd1da661af // indirect
|
||||
golang.org/x/tools v0.1.12 // indirect
|
||||
golang.org/x/tools v0.2.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/api v0.102.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
@ -403,23 +487,20 @@ require (
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/api v0.23.5 // indirect
|
||||
k8s.io/apimachinery v0.23.5 // indirect
|
||||
k8s.io/client-go v0.23.5 // indirect
|
||||
k8s.io/klog/v2 v2.60.1-0.20220317184644-43cc75f9ae89 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20220124234850-424119656bbf // indirect
|
||||
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
|
||||
k8s.io/api v0.25.3 // indirect
|
||||
k8s.io/apimachinery v0.25.3 // indirect
|
||||
k8s.io/client-go v0.25.3 // indirect
|
||||
k8s.io/klog/v2 v2.70.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1 // indirect
|
||||
k8s.io/utils v0.0.0-20220728103510-ee6ede2d64ed // indirect
|
||||
oras.land/oras-go/v2 v2.0.0-rc.3 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
|
||||
sigs.k8s.io/release-utils v0.7.3 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.1 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
)
|
||||
|
||||
replace (
|
||||
github.com/aquasecurity/fanal => github.com/project-zot/fanal v0.0.0-20211007194926-d0c577a014df
|
||||
github.com/aquasecurity/trivy => github.com/project-zot/trivy v0.9.2-0.20211013001708-27408aa50da3
|
||||
github.com/aquasecurity/trivy-db => github.com/project-zot/trivy-db v0.0.0-20211007191113-44f7e57b689c
|
||||
github.com/containers/image/v5 => github.com/anuvu/image/v5 v5.0.0-20220520105616-e594853d6471
|
||||
github.com/hashicorp/go-getter => github.com/hashicorp/go-getter v1.6.1
|
||||
github.com/open-policy-agent/opa => github.com/open-policy-agent/opa v0.44.0
|
||||
|
@ -6117,7 +6117,7 @@ func TestInjectTooManyOpenFiles(t *testing.T) {
|
||||
|
||||
func TestGCSignaturesAndUntaggedManifests(t *testing.T) {
|
||||
Convey("Make controller", t, func() {
|
||||
repoName := "testrepo"
|
||||
repoName := "testrepo" //nolint:goconst
|
||||
tag := "0.0.1"
|
||||
|
||||
port := test.GetFreePort()
|
||||
@ -6369,7 +6369,7 @@ func TestGCSignaturesAndUntaggedManifests(t *testing.T) {
|
||||
|
||||
func TestPeriodicGC(t *testing.T) {
|
||||
Convey("Periodic gc enabled for default store", t, func() {
|
||||
repoName := "testRepo"
|
||||
repoName := "testrepo" //nolint:goconst
|
||||
|
||||
port := test.GetFreePort()
|
||||
conf := config.New()
|
||||
@ -6445,7 +6445,7 @@ func TestPeriodicGC(t *testing.T) {
|
||||
})
|
||||
|
||||
Convey("Periodic gc error", t, func() {
|
||||
repoName := "testRepo"
|
||||
repoName := "testrepo" //nolint:goconst
|
||||
|
||||
port := test.GetFreePort()
|
||||
conf := config.New()
|
||||
@ -6505,7 +6505,7 @@ func TestSearchRoutes(t *testing.T) {
|
||||
cm.StartAndWait(port)
|
||||
defer cm.StopServer()
|
||||
|
||||
repoName := "testrepo"
|
||||
repoName := "testrepo" //nolint:goconst
|
||||
inaccessibleRepo := "inaccessible"
|
||||
|
||||
cfg, layers, manifest, err := test.GetImageComponents(10000)
|
||||
|
@ -36,6 +36,7 @@ import (
|
||||
"zotregistry.io/zot/pkg/extensions/sync"
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
repoDBUpdate "zotregistry.io/zot/pkg/meta/repodb/update"
|
||||
zreg "zotregistry.io/zot/pkg/regexp"
|
||||
localCtx "zotregistry.io/zot/pkg/requestcontext"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
"zotregistry.io/zot/pkg/test" //nolint:goimports
|
||||
@ -73,34 +74,34 @@ func (rh *RouteHandler) SetupRoutes() {
|
||||
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#endpoints
|
||||
prefixedRouter := rh.c.Router.PathPrefix(constants.RoutePrefix).Subrouter()
|
||||
{
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/tags/list", NameRegexp.String()),
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/tags/list", zreg.NameRegexp.String()),
|
||||
rh.ListTags).Methods(allowedMethods("GET")...)
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/manifests/{reference}", NameRegexp.String()),
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/manifests/{reference}", zreg.NameRegexp.String()),
|
||||
rh.CheckManifest).Methods(allowedMethods("HEAD")...)
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/manifests/{reference}", NameRegexp.String()),
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/manifests/{reference}", zreg.NameRegexp.String()),
|
||||
rh.GetManifest).Methods(allowedMethods("GET")...)
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/manifests/{reference}", NameRegexp.String()),
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/manifests/{reference}", zreg.NameRegexp.String()),
|
||||
rh.UpdateManifest).Methods("PUT")
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/manifests/{reference}", NameRegexp.String()),
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/manifests/{reference}", zreg.NameRegexp.String()),
|
||||
rh.DeleteManifest).Methods("DELETE")
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/{digest}", NameRegexp.String()),
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/{digest}", zreg.NameRegexp.String()),
|
||||
rh.CheckBlob).Methods("HEAD")
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/{digest}", NameRegexp.String()),
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/{digest}", zreg.NameRegexp.String()),
|
||||
rh.GetBlob).Methods("GET")
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/{digest}", NameRegexp.String()),
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/{digest}", zreg.NameRegexp.String()),
|
||||
rh.DeleteBlob).Methods("DELETE")
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/", NameRegexp.String()),
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/", zreg.NameRegexp.String()),
|
||||
rh.CreateBlobUpload).Methods("POST")
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/{session_id}", NameRegexp.String()),
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/{session_id}", zreg.NameRegexp.String()),
|
||||
rh.GetBlobUpload).Methods("GET")
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/{session_id}", NameRegexp.String()),
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/{session_id}", zreg.NameRegexp.String()),
|
||||
rh.PatchBlobUpload).Methods("PATCH")
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/{session_id}", NameRegexp.String()),
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/{session_id}", zreg.NameRegexp.String()),
|
||||
rh.UpdateBlobUpload).Methods("PUT")
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/{session_id}", NameRegexp.String()),
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/blobs/uploads/{session_id}", zreg.NameRegexp.String()),
|
||||
rh.DeleteBlobUpload).Methods("DELETE")
|
||||
// support for OCI artifact references
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/referrers/{digest}", NameRegexp.String()),
|
||||
prefixedRouter.HandleFunc(fmt.Sprintf("/{name:%s}/referrers/{digest}", zreg.NameRegexp.String()),
|
||||
rh.GetReferrers).Methods(allowedMethods("GET")...)
|
||||
prefixedRouter.HandleFunc(constants.ExtCatalogPrefix,
|
||||
rh.ListRepositories).Methods(allowedMethods("GET")...)
|
||||
@ -112,7 +113,7 @@ func (rh *RouteHandler) SetupRoutes() {
|
||||
|
||||
// support for ORAS artifact reference types (alpha 1) - image signature use case
|
||||
rh.c.Router.HandleFunc(fmt.Sprintf("%s/{name:%s}/manifests/{digest}/referrers",
|
||||
constants.ArtifactSpecRoutePrefix, NameRegexp.String()), rh.GetOrasReferrers).Methods("GET")
|
||||
constants.ArtifactSpecRoutePrefix, zreg.NameRegexp.String()), rh.GetOrasReferrers).Methods("GET")
|
||||
|
||||
// swagger
|
||||
debug.SetupSwaggerRoutes(rh.c.Config, rh.c.Router, rh.c.Log)
|
||||
|
@ -1298,7 +1298,7 @@ func TestScrub(t *testing.T) {
|
||||
|
||||
dir := t.TempDir()
|
||||
|
||||
repoName := "badIndex"
|
||||
repoName := "badindex"
|
||||
|
||||
repo, err := os.MkdirTemp(dir, repoName)
|
||||
if err != nil {
|
||||
|
@ -555,8 +555,13 @@ func TestRepoListWithNewestImage(t *testing.T) {
|
||||
ShouldBeGreaterThan,
|
||||
0,
|
||||
)
|
||||
// This really depends on the test data, but with the current test images it's CRITICAL
|
||||
So(vulnerabilities.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
if repo.Name == "zot-cve-test" {
|
||||
// This really depends on the test data, but with the current test image it's HIGH
|
||||
So(vulnerabilities.MaxSeverity, ShouldEqual, "HIGH")
|
||||
} else if repo.Name == "zot-test" {
|
||||
// This really depends on the test data, but with the current test image it's CRITICAL
|
||||
So(vulnerabilities.MaxSeverity, ShouldEqual, "CRITICAL")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -1,20 +1,19 @@
|
||||
package trivy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"path"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
|
||||
"github.com/aquasecurity/trivy/pkg/commands/artifact"
|
||||
"github.com/aquasecurity/trivy/pkg/commands/operation"
|
||||
"github.com/aquasecurity/trivy/pkg/flag"
|
||||
"github.com/aquasecurity/trivy/pkg/types"
|
||||
regTypes "github.com/google/go-containerregistry/pkg/v1/types"
|
||||
godigest "github.com/opencontainers/go-digest"
|
||||
ispec "github.com/opencontainers/image-spec/specs-go/v1"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
zerr "zotregistry.io/zot/errors"
|
||||
"zotregistry.io/zot/pkg/extensions/search/common"
|
||||
@ -24,51 +23,44 @@ import (
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
)
|
||||
|
||||
type trivyCtx struct {
|
||||
Input string
|
||||
Ctx *cli.Context
|
||||
}
|
||||
const dbRepository = "ghcr.io/aquasecurity/trivy-db"
|
||||
|
||||
// newTrivyContext set some trivy configuration value and return a context.
|
||||
func newTrivyContext(dir string) *trivyCtx {
|
||||
tCtx := &trivyCtx{}
|
||||
// getNewScanOptions sets trivy configuration values for our scans and returns them as
|
||||
// a trivy Options structure.
|
||||
func getNewScanOptions(dir string) *flag.Options {
|
||||
scanOptions := flag.Options{
|
||||
GlobalOptions: flag.GlobalOptions{
|
||||
CacheDir: dir,
|
||||
},
|
||||
ScanOptions: flag.ScanOptions{
|
||||
SecurityChecks: []string{types.SecurityCheckVulnerability},
|
||||
OfflineScan: true,
|
||||
},
|
||||
VulnerabilityOptions: flag.VulnerabilityOptions{
|
||||
VulnType: []string{types.VulnTypeOS, types.VulnTypeLibrary},
|
||||
},
|
||||
DBOptions: flag.DBOptions{
|
||||
DBRepository: dbRepository,
|
||||
SkipDBUpdate: true,
|
||||
},
|
||||
ReportOptions: flag.ReportOptions{
|
||||
Format: "table",
|
||||
Severities: []dbTypes.Severity{
|
||||
dbTypes.SeverityUnknown,
|
||||
dbTypes.SeverityLow,
|
||||
dbTypes.SeverityMedium,
|
||||
dbTypes.SeverityHigh,
|
||||
dbTypes.SeverityCritical,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
app := &cli.App{}
|
||||
|
||||
flagSet := &flag.FlagSet{}
|
||||
|
||||
var cacheDir string
|
||||
|
||||
flagSet.StringVar(&cacheDir, "cache-dir", dir, "")
|
||||
|
||||
var vuln string
|
||||
|
||||
flagSet.StringVar(&vuln, "vuln-type", strings.Join([]string{types.VulnTypeOS, types.VulnTypeLibrary}, ","), "")
|
||||
|
||||
var severity string
|
||||
|
||||
flagSet.StringVar(&severity, "severity", strings.Join(dbTypes.SeverityNames, ","), "")
|
||||
|
||||
flagSet.StringVar(&tCtx.Input, "input", "", "")
|
||||
|
||||
var securityCheck string
|
||||
|
||||
flagSet.StringVar(&securityCheck, "security-checks", types.SecurityCheckVulnerability, "")
|
||||
|
||||
var reportFormat string
|
||||
|
||||
flagSet.StringVar(&reportFormat, "format", "table", "")
|
||||
|
||||
ctx := cli.NewContext(app, flagSet, nil)
|
||||
|
||||
tCtx.Ctx = ctx
|
||||
|
||||
return tCtx
|
||||
return &scanOptions
|
||||
}
|
||||
|
||||
type cveTrivyController struct {
|
||||
DefaultCveConfig *trivyCtx
|
||||
SubCveConfig map[string]*trivyCtx
|
||||
DefaultCveConfig *flag.Options
|
||||
SubCveConfig map[string]*flag.Options
|
||||
}
|
||||
|
||||
type Scanner struct {
|
||||
@ -85,25 +77,27 @@ func NewScanner(storeController storage.StoreController,
|
||||
) *Scanner {
|
||||
cveController := cveTrivyController{}
|
||||
|
||||
subCveConfig := make(map[string]*trivyCtx)
|
||||
subCveConfig := make(map[string]*flag.Options)
|
||||
|
||||
if storeController.DefaultStore != nil {
|
||||
imageStore := storeController.DefaultStore
|
||||
|
||||
rootDir := imageStore.RootDir()
|
||||
|
||||
ctx := newTrivyContext(rootDir)
|
||||
cacheDir := path.Join(rootDir, "_trivy")
|
||||
opts := getNewScanOptions(cacheDir)
|
||||
|
||||
cveController.DefaultCveConfig = ctx
|
||||
cveController.DefaultCveConfig = opts
|
||||
}
|
||||
|
||||
if storeController.SubStore != nil {
|
||||
for route, storage := range storeController.SubStore {
|
||||
rootDir := storage.RootDir()
|
||||
|
||||
ctx := newTrivyContext(rootDir)
|
||||
cacheDir := path.Join(rootDir, "_trivy")
|
||||
opts := getNewScanOptions(cacheDir)
|
||||
|
||||
subCveConfig[route] = ctx
|
||||
subCveConfig[route] = opts
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,33 +113,58 @@ func NewScanner(storeController storage.StoreController,
|
||||
}
|
||||
}
|
||||
|
||||
func (scanner Scanner) getTrivyContext(image string) *trivyCtx {
|
||||
func (scanner Scanner) getTrivyOptions(image string) flag.Options {
|
||||
// Split image to get route prefix
|
||||
prefixName := common.GetRoutePrefix(image)
|
||||
|
||||
var tCtx *trivyCtx
|
||||
var opts flag.Options
|
||||
|
||||
var ok bool
|
||||
|
||||
var rootDir string
|
||||
|
||||
// Get corresponding CVE trivy config, if no sub cve config present that means its default
|
||||
tCtx, ok = scanner.cveController.SubCveConfig[prefixName]
|
||||
_, ok = scanner.cveController.SubCveConfig[prefixName]
|
||||
if ok {
|
||||
opts = *scanner.cveController.SubCveConfig[prefixName]
|
||||
|
||||
imgStore := scanner.storeController.SubStore[prefixName]
|
||||
|
||||
rootDir = imgStore.RootDir()
|
||||
} else {
|
||||
tCtx = scanner.cveController.DefaultCveConfig
|
||||
opts = *scanner.cveController.DefaultCveConfig
|
||||
|
||||
imgStore := scanner.storeController.DefaultStore
|
||||
|
||||
rootDir = imgStore.RootDir()
|
||||
}
|
||||
|
||||
tCtx.Input = path.Join(rootDir, image)
|
||||
opts.ScanOptions.Target = path.Join(rootDir, image)
|
||||
opts.ImageOptions.Input = path.Join(rootDir, image)
|
||||
|
||||
return tCtx
|
||||
return opts
|
||||
}
|
||||
|
||||
func (scanner Scanner) runTrivy(opts flag.Options) (types.Report, error) {
|
||||
ctx := context.Background()
|
||||
|
||||
runner, err := artifact.NewRunner(ctx, opts)
|
||||
if err != nil {
|
||||
return types.Report{}, err
|
||||
}
|
||||
defer runner.Close(ctx)
|
||||
|
||||
report, err := runner.ScanImage(ctx, opts)
|
||||
if err != nil {
|
||||
return types.Report{}, err
|
||||
}
|
||||
|
||||
report, err = runner.Filter(ctx, opts, report)
|
||||
if err != nil {
|
||||
return types.Report{}, err
|
||||
}
|
||||
|
||||
return report, nil
|
||||
}
|
||||
|
||||
func (scanner Scanner) IsImageFormatScannable(image string) (bool, error) {
|
||||
@ -208,10 +227,9 @@ func (scanner Scanner) ScanImage(image string) (map[string]cvemodel.CVE, error)
|
||||
|
||||
scanner.log.Debug().Str("image", image).Msg("scanning image")
|
||||
|
||||
tCtx := scanner.getTrivyContext(image)
|
||||
|
||||
scanner.dbLock.Lock()
|
||||
report, err := artifact.TrivyImageRun(tCtx.Ctx)
|
||||
opts := scanner.getTrivyOptions(image)
|
||||
report, err := scanner.runTrivy(opts)
|
||||
scanner.dbLock.Unlock()
|
||||
|
||||
if err != nil { //nolint: wsl
|
||||
@ -288,7 +306,7 @@ func (scanner Scanner) UpdateDB() error {
|
||||
defer scanner.dbLock.Unlock()
|
||||
|
||||
if scanner.storeController.DefaultStore != nil {
|
||||
dbDir := scanner.storeController.DefaultStore.RootDir()
|
||||
dbDir := path.Join(scanner.storeController.DefaultStore.RootDir(), "_trivy")
|
||||
|
||||
err := scanner.updateDB(dbDir)
|
||||
if err != nil {
|
||||
@ -298,7 +316,9 @@ func (scanner Scanner) UpdateDB() error {
|
||||
|
||||
if scanner.storeController.SubStore != nil {
|
||||
for _, storage := range scanner.storeController.SubStore {
|
||||
err := scanner.updateDB(storage.RootDir())
|
||||
dbDir := path.Join(storage.RootDir(), "_trivy")
|
||||
|
||||
err := scanner.updateDB(dbDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -313,7 +333,7 @@ func (scanner Scanner) UpdateDB() error {
|
||||
func (scanner Scanner) updateDB(dbDir string) error {
|
||||
scanner.log.Debug().Msgf("Download Trivy DB to destination dir: %s", dbDir)
|
||||
|
||||
err := operation.DownloadDB("dev", dbDir, false, false, false)
|
||||
err := operation.DownloadDB("dev", dbDir, dbRepository, false, false, false)
|
||||
if err != nil {
|
||||
scanner.log.Error().Err(err).Msgf("Error downloading Trivy DB to destination dir: %s", dbDir)
|
||||
|
||||
|
@ -102,19 +102,23 @@ func TestMultipleStoragePath(t *testing.T) {
|
||||
img1 := "a/test/image1:tag1"
|
||||
img2 := "b/test/image2:tag2"
|
||||
|
||||
ctx := scanner.getTrivyContext(img0)
|
||||
So(ctx.Input, ShouldEqual, path.Join(firstStore.RootDir(), img0))
|
||||
opts := scanner.getTrivyOptions(img0)
|
||||
So(opts.ScanOptions.Target, ShouldEqual, path.Join(firstStore.RootDir(), img0))
|
||||
|
||||
ctx = scanner.getTrivyContext(img1)
|
||||
So(ctx.Input, ShouldEqual, path.Join(secondStore.RootDir(), img1))
|
||||
opts = scanner.getTrivyOptions(img1)
|
||||
So(opts.ScanOptions.Target, ShouldEqual, path.Join(secondStore.RootDir(), img1))
|
||||
|
||||
ctx = scanner.getTrivyContext(img2)
|
||||
So(ctx.Input, ShouldEqual, path.Join(thirdStore.RootDir(), img2))
|
||||
opts = scanner.getTrivyOptions(img2)
|
||||
So(opts.ScanOptions.Target, ShouldEqual, path.Join(thirdStore.RootDir(), img2))
|
||||
|
||||
generateTestImage(storeController, img0)
|
||||
generateTestImage(storeController, img1)
|
||||
generateTestImage(storeController, img2)
|
||||
|
||||
// Download DB since DB download on scan is disabled
|
||||
err = scanner.UpdateDB()
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// Scanning image in default store
|
||||
cveMap, err := scanner.ScanImage(img0)
|
||||
So(err, ShouldBeNil)
|
||||
@ -152,3 +156,65 @@ func TestMultipleStoragePath(t *testing.T) {
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestTrivyLibraryErrors(t *testing.T) {
|
||||
Convey("Test trivy API errors", t, func() {
|
||||
// Create temporary directory
|
||||
rootDir := t.TempDir()
|
||||
|
||||
err := test.CopyFiles("../../../../../test/data/zot-test", path.Join(rootDir, "zot-test"))
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
log := log.NewLogger("debug", "")
|
||||
metrics := monitoring.NewMetricsServer(false, log)
|
||||
|
||||
conf := config.New()
|
||||
conf.Extensions = &extconf.ExtensionConfig{}
|
||||
conf.Extensions.Lint = &extconf.LintConfig{}
|
||||
|
||||
// Create ImageStore
|
||||
store := local.NewImageStore(rootDir, false, storage.DefaultGCDelay, false, false, log, metrics, nil, nil)
|
||||
|
||||
storeController := storage.StoreController{}
|
||||
storeController.DefaultStore = store
|
||||
|
||||
repoDB, err := bolt.NewBoltDBWrapper(bolt.DBParameters{
|
||||
RootDir: rootDir,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = repodb.SyncRepoDB(repoDB, storeController, log)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
scanner := NewScanner(storeController, repoDB, log)
|
||||
|
||||
// Download DB since DB download on scan is disabled
|
||||
err = scanner.UpdateDB()
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
img := "zot-test:0.0.1"
|
||||
|
||||
// Scanning image with correct options
|
||||
opts := scanner.getTrivyOptions(img)
|
||||
_, err = scanner.runTrivy(opts)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// Scanning image with incorrect cache options
|
||||
// to trigger runner initialization errors
|
||||
opts.CacheOptions.CacheBackend = "redis://asdf!$%&!*)("
|
||||
_, err = scanner.runTrivy(opts)
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
// Scanning image with invalid input to trigger a scanner error
|
||||
opts = scanner.getTrivyOptions("nonexisting_image:0.0.1")
|
||||
_, err = scanner.runTrivy(opts)
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
// Scanning image with incorrect report options
|
||||
// to trigger report filtering errors
|
||||
opts = scanner.getTrivyOptions(img)
|
||||
opts.ReportOptions.IgnorePolicy = "invalid file path"
|
||||
_, err = scanner.runTrivy(opts)
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package api
|
||||
package regexp
|
||||
|
||||
import "regexp"
|
||||
|
||||
@ -26,6 +26,10 @@ var (
|
||||
NameRegexp = expression(
|
||||
nameComponentRegexp,
|
||||
optional(repeated(literal(`/`), nameComponentRegexp)))
|
||||
|
||||
// FullNameRegexp is the format which matches the full string of the
|
||||
// name component of reference.
|
||||
FullNameRegexp = expression(match("^"), NameRegexp, match("$"))
|
||||
)
|
||||
|
||||
// match compiles the string to a regular expression.
|
@ -31,6 +31,7 @@ import (
|
||||
"zotregistry.io/zot/pkg/common"
|
||||
"zotregistry.io/zot/pkg/extensions/monitoring"
|
||||
zlog "zotregistry.io/zot/pkg/log"
|
||||
zreg "zotregistry.io/zot/pkg/regexp"
|
||||
"zotregistry.io/zot/pkg/scheduler"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
"zotregistry.io/zot/pkg/storage/cache"
|
||||
@ -154,6 +155,12 @@ func (is *ImageStoreLocal) initRepo(name string) error {
|
||||
return zerr.ErrInvalidRepositoryName
|
||||
}
|
||||
|
||||
if !zreg.FullNameRegexp.MatchString(name) {
|
||||
is.log.Error().Str("repo", name).Msg("invalid repository name")
|
||||
|
||||
return zerr.ErrInvalidRepositoryName
|
||||
}
|
||||
|
||||
// create "blobs" subdir
|
||||
err := ensureDir(path.Join(repoDir, "blobs"), is.log)
|
||||
if err != nil {
|
||||
@ -221,6 +228,10 @@ func (is *ImageStoreLocal) ValidateRepo(name string) (bool, error) {
|
||||
// https://github.com/opencontainers/image-spec/blob/master/image-layout.md#content
|
||||
// at least, expect at least 3 entries - ["blobs", "oci-layout", "index.json"]
|
||||
// and an additional/optional BlobUploadDir in each image store
|
||||
if !zreg.FullNameRegexp.MatchString(name) {
|
||||
return false, zerr.ErrInvalidRepositoryName
|
||||
}
|
||||
|
||||
dir := path.Join(is.rootDir, name)
|
||||
if !is.DirExists(dir) {
|
||||
return false, zerr.ErrRepoNotFound
|
||||
|
@ -30,6 +30,7 @@ import (
|
||||
"zotregistry.io/zot/pkg/log"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
"zotregistry.io/zot/pkg/storage/cache"
|
||||
storageConstants "zotregistry.io/zot/pkg/storage/constants"
|
||||
"zotregistry.io/zot/pkg/storage/local"
|
||||
"zotregistry.io/zot/pkg/test"
|
||||
)
|
||||
@ -1326,6 +1327,11 @@ func TestNegativeCases(t *testing.T) {
|
||||
// Init repo should fail if repo is invalid UTF-8
|
||||
err = imgStore.InitRepo("hi \255")
|
||||
So(err, ShouldNotBeNil)
|
||||
|
||||
// Init repo should fail if repo name does not match spec
|
||||
err = imgStore.InitRepo("_trivy")
|
||||
So(err, ShouldNotBeNil)
|
||||
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
|
||||
})
|
||||
|
||||
Convey("Invalid validate repo", t, func(c C) {
|
||||
@ -1430,7 +1436,7 @@ func TestNegativeCases(t *testing.T) {
|
||||
So(func() { _, _ = imgStore.ValidateRepo("test") }, ShouldPanic)
|
||||
}
|
||||
|
||||
err = os.Chmod(dir, 0o755) // remove all perms
|
||||
err = os.Chmod(dir, 0o755) // add perms
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -2483,10 +2489,53 @@ func TestValidateRepo(t *testing.T) {
|
||||
_, err = imgStore.ValidateRepo("test-dir")
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
|
||||
Convey("Get error when repo name is not compliant with repo spec", t, func() {
|
||||
dir := t.TempDir()
|
||||
|
||||
log := log.Logger{Logger: zerolog.New(os.Stdout)}
|
||||
metrics := monitoring.NewMetricsServer(false, log)
|
||||
cacheDriver, _ := storage.Create("boltdb", cache.BoltDBDriverParameters{
|
||||
RootDir: dir,
|
||||
Name: "cache",
|
||||
UseRelPaths: true,
|
||||
}, log)
|
||||
imgStore := local.NewImageStore(dir, true, storage.DefaultGCDelay,
|
||||
true, true, log, metrics, nil, cacheDriver)
|
||||
|
||||
_, err := imgStore.ValidateRepo(".")
|
||||
So(err, ShouldNotBeNil)
|
||||
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
|
||||
|
||||
_, err = imgStore.ValidateRepo("..")
|
||||
So(err, ShouldNotBeNil)
|
||||
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
|
||||
|
||||
err = os.Mkdir(path.Join(dir, "_test-dir"), 0o755)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
_, err = imgStore.ValidateRepo("_test-dir")
|
||||
So(err, ShouldNotBeNil)
|
||||
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
|
||||
|
||||
err = os.Mkdir(path.Join(dir, ".test-dir"), 0o755)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
_, err = imgStore.ValidateRepo(".test-dir")
|
||||
So(err, ShouldNotBeNil)
|
||||
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
|
||||
|
||||
err = os.Mkdir(path.Join(dir, "-test-dir"), 0o755)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
_, err = imgStore.ValidateRepo("-test-dir")
|
||||
So(err, ShouldNotBeNil)
|
||||
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetRepositoriesError(t *testing.T) {
|
||||
Convey("Get error when returning relative path", t, func() {
|
||||
func TestGetRepositories(t *testing.T) {
|
||||
Convey("Verify errors and repos returned by GetRepositories()", t, func() {
|
||||
dir := t.TempDir()
|
||||
|
||||
log := log.Logger{Logger: zerolog.New(os.Stdout)}
|
||||
@ -2500,15 +2549,178 @@ func TestGetRepositoriesError(t *testing.T) {
|
||||
true, true, log, metrics, nil, cacheDriver,
|
||||
)
|
||||
|
||||
// create valid directory with permissions
|
||||
err := os.Mkdir(path.Join(dir, "test-dir"), 0o755)
|
||||
// Create valid directory with permissions
|
||||
err := os.Mkdir(path.Join(dir, "test-dir"), 0o755) //nolint: gosec
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = os.WriteFile(path.Join(dir, "test-dir/test-file"), []byte("this is test file"), 0o000)
|
||||
err = os.WriteFile(path.Join(dir, "test-dir/test-file"), []byte("this is test file"), 0o755) //nolint: gosec
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
_, err = imgStore.GetRepositories()
|
||||
// Folder is not a repo as it is missing the requires files/subfolder
|
||||
repos, err := imgStore.GetRepositories()
|
||||
So(err, ShouldBeNil)
|
||||
So(len(repos), ShouldEqual, 0)
|
||||
|
||||
il := ispec.ImageLayout{Version: ispec.ImageLayoutVersion}
|
||||
layoutFileContent, err := json.Marshal(il)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// Folder becomes a repo after the missing content is added
|
||||
err = os.Mkdir(path.Join(dir, "test-dir", "blobs"), 0o755) //nolint: gosec
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = os.Mkdir(path.Join(dir, "test-dir", storageConstants.BlobUploadDir), 0o755) //nolint: gosec
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = os.WriteFile(path.Join(dir, "test-dir", "index.json"), []byte{}, 0o755) //nolint: gosec
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = os.WriteFile(path.Join(dir, "test-dir", ispec.ImageLayoutFile), layoutFileContent, 0o755) //nolint: gosec
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// Verify the new repo is turned
|
||||
repos, err = imgStore.GetRepositories()
|
||||
So(err, ShouldBeNil)
|
||||
So(len(repos), ShouldEqual, 1)
|
||||
So(repos[0], ShouldEqual, "test-dir")
|
||||
|
||||
// create directory starting with underscore, which is not OCI a dist spec compliant repo name
|
||||
// [a-z0-9]+([._-][a-z0-9]+)*(/[a-z0-9]+([._-][a-z0-9]+)*)*
|
||||
err = os.MkdirAll(path.Join(dir, "_trivy", "db"), 0o755)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = os.WriteFile(path.Join(dir, "_trivy", "db", "trivy.db"), []byte("this is test file"), 0o755) //nolint: gosec
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// Folder with invalid name is not a repo as it is missing the requires files/subfolder
|
||||
repos, err = imgStore.GetRepositories()
|
||||
So(err, ShouldBeNil)
|
||||
So(len(repos), ShouldEqual, 1)
|
||||
So(repos[0], ShouldEqual, "test-dir")
|
||||
|
||||
// Add missing content to folder with invalid name
|
||||
err = os.Mkdir(path.Join(dir, "_trivy", "blobs"), 0o755) //nolint: gosec
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = os.Mkdir(path.Join(dir, "_trivy", storageConstants.BlobUploadDir), 0o755) //nolint: gosec
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = os.WriteFile(path.Join(dir, "_trivy", "index.json"), []byte{}, 0o755) //nolint: gosec
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = os.WriteFile(path.Join(dir, "_trivy", ispec.ImageLayoutFile), layoutFileContent, 0o755) //nolint: gosec
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// Folder with invalid name doesn't become a repo after the missing content is added
|
||||
repos, err = imgStore.GetRepositories()
|
||||
So(err, ShouldBeNil)
|
||||
t.Logf("repos %v", repos)
|
||||
So(len(repos), ShouldEqual, 1)
|
||||
So(repos[0], ShouldEqual, "test-dir")
|
||||
|
||||
// Rename folder with invalid name to a valid one
|
||||
err = os.Rename(path.Join(dir, "_trivy"), path.Join(dir, "test-dir-2"))
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// Verify both repos are now visible
|
||||
repos, err = imgStore.GetRepositories()
|
||||
So(err, ShouldBeNil)
|
||||
t.Logf("repos %v", repos)
|
||||
So(len(repos), ShouldEqual, 2)
|
||||
So(repos, ShouldContain, "test-dir")
|
||||
So(repos, ShouldContain, "test-dir-2")
|
||||
})
|
||||
|
||||
Convey("Verify GetRepositories() doesn't return '.' when having an oci layout as root directory ", t, func() {
|
||||
dir := t.TempDir()
|
||||
|
||||
log := log.Logger{Logger: zerolog.New(os.Stdout)}
|
||||
metrics := monitoring.NewMetricsServer(false, log)
|
||||
cacheDriver, _ := storage.Create("boltdb", cache.BoltDBDriverParameters{
|
||||
RootDir: dir,
|
||||
Name: "cache",
|
||||
UseRelPaths: true,
|
||||
}, log)
|
||||
|
||||
imgStore := local.NewImageStore(dir, true, storage.DefaultGCDelay,
|
||||
true, true, log, metrics, nil, cacheDriver,
|
||||
)
|
||||
|
||||
// Root dir does not contain repos
|
||||
repos, err := imgStore.GetRepositories()
|
||||
So(err, ShouldBeNil)
|
||||
So(len(repos), ShouldEqual, 0)
|
||||
|
||||
// Configure root directory as an oci layout
|
||||
err = os.Mkdir(path.Join(dir, "blobs"), 0o755) //nolint: gosec
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = os.Mkdir(path.Join(dir, storageConstants.BlobUploadDir), 0o755) //nolint: gosec
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = os.WriteFile(path.Join(dir, "index.json"), []byte{}, 0o755) //nolint: gosec
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
il := ispec.ImageLayout{Version: ispec.ImageLayoutVersion}
|
||||
layoutFileContent, err := json.Marshal(il)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = os.WriteFile(path.Join(dir, ispec.ImageLayoutFile), layoutFileContent, 0o755) //nolint: gosec
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// Verify root directory is not returned as a repo
|
||||
repos, err = imgStore.GetRepositories()
|
||||
So(err, ShouldBeNil)
|
||||
t.Logf("repos %v", repos)
|
||||
So(len(repos), ShouldEqual, 0)
|
||||
})
|
||||
|
||||
Convey("Verify GetRepositories() doesn't return '..'", t, func() {
|
||||
dir := t.TempDir()
|
||||
|
||||
rootDir := path.Join(dir, "rootDir")
|
||||
err := os.Mkdir(rootDir, 0o755)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
log := log.Logger{Logger: zerolog.New(os.Stdout)}
|
||||
metrics := monitoring.NewMetricsServer(false, log)
|
||||
cacheDriver, _ := storage.Create("boltdb", cache.BoltDBDriverParameters{
|
||||
RootDir: rootDir,
|
||||
Name: "cache",
|
||||
UseRelPaths: true,
|
||||
}, log)
|
||||
|
||||
imgStore := local.NewImageStore(rootDir, true, storage.DefaultGCDelay,
|
||||
true, true, log, metrics, nil, cacheDriver,
|
||||
)
|
||||
|
||||
// Root dir does not contain repos
|
||||
repos, err := imgStore.GetRepositories()
|
||||
So(err, ShouldBeNil)
|
||||
So(len(repos), ShouldEqual, 0)
|
||||
|
||||
// Configure parent of root directory as an oci layout
|
||||
err = os.Mkdir(path.Join(dir, "blobs"), 0o755) //nolint: gosec
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = os.Mkdir(path.Join(dir, storageConstants.BlobUploadDir), 0o755) //nolint: gosec
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = os.WriteFile(path.Join(dir, "index.json"), []byte{}, 0o755) //nolint: gosec
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
il := ispec.ImageLayout{Version: ispec.ImageLayoutVersion}
|
||||
layoutFileContent, err := json.Marshal(il)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = os.WriteFile(path.Join(dir, ispec.ImageLayoutFile), layoutFileContent, 0o755) //nolint: gosec
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
// Verify root directory is not returned as a repo
|
||||
repos, err = imgStore.GetRepositories()
|
||||
So(err, ShouldBeNil)
|
||||
t.Logf("repos %v", repos)
|
||||
So(len(repos), ShouldEqual, 0)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ import (
|
||||
zerr "zotregistry.io/zot/errors"
|
||||
"zotregistry.io/zot/pkg/extensions/monitoring"
|
||||
zlog "zotregistry.io/zot/pkg/log"
|
||||
zreg "zotregistry.io/zot/pkg/regexp"
|
||||
"zotregistry.io/zot/pkg/scheduler"
|
||||
"zotregistry.io/zot/pkg/storage"
|
||||
"zotregistry.io/zot/pkg/storage/cache"
|
||||
@ -122,6 +123,12 @@ func (is *ObjectStorage) Unlock(lockStart *time.Time) {
|
||||
func (is *ObjectStorage) initRepo(name string) error {
|
||||
repoDir := path.Join(is.rootDir, name)
|
||||
|
||||
if !zreg.FullNameRegexp.MatchString(name) {
|
||||
is.log.Error().Str("repo", name).Msg("invalid repository name")
|
||||
|
||||
return zerr.ErrInvalidRepositoryName
|
||||
}
|
||||
|
||||
// "oci-layout" file - create if it doesn't exist
|
||||
ilPath := path.Join(repoDir, ispec.ImageLayoutFile)
|
||||
if _, err := is.store.Stat(context.Background(), ilPath); err != nil {
|
||||
@ -176,6 +183,10 @@ func (is *ObjectStorage) InitRepo(name string) error {
|
||||
|
||||
// ValidateRepo validates that the repository layout is complaint with the OCI repo layout.
|
||||
func (is *ObjectStorage) ValidateRepo(name string) (bool, error) {
|
||||
if !zreg.FullNameRegexp.MatchString(name) {
|
||||
return false, zerr.ErrInvalidRepositoryName
|
||||
}
|
||||
|
||||
// https://github.com/opencontainers/image-spec/blob/master/image-layout.md#content
|
||||
// at least, expect at least 3 entries - ["blobs", "oci-layout", "index.json"]
|
||||
// and an additional/optional BlobUploadDir in each image store
|
||||
|
@ -386,8 +386,8 @@ func TestStorageDriverStatFunction(t *testing.T) {
|
||||
3) the returned storageDriver.FileInfo will report that isDir() is true.
|
||||
*/
|
||||
Convey("Validate storageDriver.Stat() and isDir() functions with zot storage API", t, func(c C) {
|
||||
repo1 := "repo/testImageA"
|
||||
repo2 := "repo/testImage"
|
||||
repo1 := "repo/testimagea"
|
||||
repo2 := "repo/testimage"
|
||||
|
||||
So(imgStore, ShouldNotBeNil)
|
||||
|
||||
@ -446,6 +446,8 @@ func TestStorageDriverStatFunction(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetOrasAndOCIReferrers(t *testing.T) {
|
||||
skipIt(t)
|
||||
|
||||
repo := "zot-test"
|
||||
|
||||
uuid, err := guuid.NewV4()
|
||||
@ -655,6 +657,50 @@ func TestNegativeCasesObjectsStorage(t *testing.T) {
|
||||
storeDriver, imgStore, _ := createObjectsStore(testDir, tdir, true)
|
||||
defer cleanupStorage(storeDriver, testDir)
|
||||
|
||||
Convey("Invalid repo name", func(c C) {
|
||||
// Validate repo should fail if repo name does not match spec
|
||||
_, err := imgStore.ValidateRepo(".")
|
||||
So(err, ShouldNotBeNil)
|
||||
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
|
||||
|
||||
_, err = imgStore.ValidateRepo("..")
|
||||
So(err, ShouldNotBeNil)
|
||||
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
|
||||
|
||||
_, err = imgStore.ValidateRepo("_test-dir")
|
||||
So(err, ShouldNotBeNil)
|
||||
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
|
||||
|
||||
_, err = imgStore.ValidateRepo(".test-dir")
|
||||
So(err, ShouldNotBeNil)
|
||||
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
|
||||
|
||||
_, err = imgStore.ValidateRepo("-test-dir")
|
||||
So(err, ShouldNotBeNil)
|
||||
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
|
||||
|
||||
// Init repo should fail if repo name does not match spec
|
||||
err = imgStore.InitRepo(".")
|
||||
So(err, ShouldNotBeNil)
|
||||
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
|
||||
|
||||
err = imgStore.InitRepo("..")
|
||||
So(err, ShouldNotBeNil)
|
||||
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
|
||||
|
||||
err = imgStore.InitRepo("_test-dir")
|
||||
So(err, ShouldNotBeNil)
|
||||
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
|
||||
|
||||
err = imgStore.InitRepo(".test-dir")
|
||||
So(err, ShouldNotBeNil)
|
||||
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
|
||||
|
||||
err = imgStore.InitRepo("-test-dir")
|
||||
So(err, ShouldNotBeNil)
|
||||
So(errors.Is(err, zerr.ErrInvalidRepositoryName), ShouldBeTrue)
|
||||
})
|
||||
|
||||
Convey("Invalid validate repo", func(c C) {
|
||||
So(imgStore.InitRepo(testImage), ShouldBeNil)
|
||||
objects, err := storeDriver.List(context.Background(), path.Join(imgStore.RootDir(), testImage))
|
||||
|
@ -149,6 +149,11 @@ func CopyFiles(sourceDir, destDir string) error {
|
||||
destFilePath := path.Join(destDir, file.Name())
|
||||
|
||||
if file.IsDir() {
|
||||
if strings.HasPrefix(file.Name(), "_") {
|
||||
// Some tests create the trivy related folders under test/_trivy
|
||||
continue
|
||||
}
|
||||
|
||||
if err = CopyFiles(sourceFilePath, destFilePath); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -283,7 +288,7 @@ func WaitTillServerReady(url string) {
|
||||
|
||||
func WaitTillTrivyDBDownloadStarted(rootDir string) {
|
||||
for {
|
||||
if _, err := os.Stat(path.Join(rootDir, "trivy.db")); err == nil {
|
||||
if _, err := os.Stat(path.Join(rootDir, "_trivy", "db", "trivy.db")); err == nil {
|
||||
break
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,47 @@ func TestCopyFiles(t *testing.T) {
|
||||
err = test.CopyFiles(dir, os.TempDir())
|
||||
So(err, ShouldNotBeNil)
|
||||
})
|
||||
Convey("sourceDir contains a folder starting with invalid characters", t, func() {
|
||||
srcDir := t.TempDir()
|
||||
dstDir := t.TempDir()
|
||||
|
||||
err := os.MkdirAll(path.Join(srcDir, "_trivy", "db"), 0o755)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = os.MkdirAll(path.Join(srcDir, "test-index"), 0o755)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
filePathTrivy := path.Join(srcDir, "_trivy", "db", "trivy.db")
|
||||
err = os.WriteFile(filePathTrivy, []byte("some dummy file content"), 0o644) //nolint: gosec
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var index ispec.Index
|
||||
content, err := json.Marshal(index)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = os.WriteFile(path.Join(srcDir, "test-index", "index.json"), content, 0o644) //nolint: gosec
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = test.CopyFiles(srcDir, dstDir)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
_, err = os.Stat(path.Join(dstDir, "_trivy", "db", "trivy.db"))
|
||||
So(err, ShouldNotBeNil)
|
||||
So(os.IsNotExist(err), ShouldBeTrue)
|
||||
|
||||
_, err = os.Stat(path.Join(dstDir, "test-index", "index.json"))
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestGetOciLayoutDigests(t *testing.T) {
|
||||
|
Loading…
Reference in New Issue
Block a user