From d19c7d9f292759848aa77109357b405a64716c78 Mon Sep 17 00:00:00 2001 From: Teppei Fukuda Date: Mon, 31 Jul 2023 14:27:36 +0300 Subject: [PATCH] feat(repo): support local repositories (#4890) * feat(repo): support local repositories * fix tests * test: fix client/server tests * docs: update * test: add fs tests * test: do not update golden files if overridden * docs: remove a comment about fs deprecation --- docs/docs/target/git-repository.md | 236 ------------------ docs/docs/target/repository.md | 155 ++++++++++++ docs/getting-started/coverage.md | 2 +- docs/getting-started/faq.md | 2 + integration/client_server_test.go | 24 +- integration/docker_engine_test.go | 2 +- integration/integration_test.go | 5 +- integration/module_test.go | 3 +- integration/{fs_test.go => repo_test.go} | 130 ++++++---- integration/standalone_tar_test.go | 6 +- integration/testdata/cocoapods.json.golden | 4 +- .../testdata/composer.lock.json.golden | 4 +- integration/testdata/conan.json.golden | 4 +- .../testdata/conda-cyclonedx.json.golden | 2 +- integration/testdata/conda-spdx.json.golden | 12 +- .../dockerfile-custom-policies.json.golden | 4 +- ...dockerfile-namespace-exception.json.golden | 4 +- .../dockerfile-rule-exception.json.golden | 4 +- integration/testdata/dockerfile.json.golden | 4 +- .../dockerfile_file_pattern.json.golden | 4 +- integration/testdata/dotnet.json.golden | 4 +- .../{fs => repo}/cocoapods/Podfile.lock | 0 .../{fs => repo}/composer/composer.json | 0 .../{fs => repo}/composer/composer.lock | 0 .../fixtures/{fs => repo}/conan/conan.lock | 0 .../conda-meta/openssl-1.1.1q-h7f8727e_0.json | 0 .../conda-meta/pip-22.2.2-py38h06a4308_0.json | 0 .../{fs => repo}/custom-policy/Dockerfile | 0 .../custom-policy/policy/bar.rego | 0 .../custom-policy/policy/foo.rego | 0 .../{fs => repo}/dockerfile/Dockerfile | 0 .../dockerfile_file_pattern/Customfile | 0 .../dotnet/datacollector.deps.json | 0 .../fixtures/{fs => repo}/gomod/go.mod | 0 .../fixtures/{fs => repo}/gomod/go.sum | 0 .../fixtures/{fs => repo}/gomod/submod/go.mod | 0 .../fixtures/{fs => repo}/gomod/submod/go.sum | 3 +- .../{fs => repo}/gomod/submod2/go.mod | 0 .../{fs => repo}/gomod/submod2/go.sum | 0 .../{fs => repo}/gradle/gradle.lockfile | 0 .../{fs => repo}/helm/testchart.tar.gz | Bin .../{fs => repo}/helm_badname/Chart.yaml | 0 .../{fs => repo}/helm_testchart/.helmignore | 0 .../{fs => repo}/helm_testchart/Chart.yaml | 0 .../helm_testchart/templates/NOTES.txt | 0 .../helm_testchart/templates/_helpers.tpl | 0 .../helm_testchart/templates/deployment.yaml | 0 .../helm_testchart/templates/hpa.yaml | 0 .../helm_testchart/templates/ingress.yaml | 0 .../helm_testchart/templates/service.yaml | 0 .../templates/serviceaccount.yaml | 0 .../templates/tests/test-connection.yaml | 0 .../{fs => repo}/helm_testchart/values.yaml | 0 .../{fs => repo}/helm_values/values.yaml | 0 .../fixtures/{fs => repo}/mixlock/mix.lock | 0 .../namespace-exception/Dockerfile | 0 .../namespace-exception/policy/exception.rego | 0 .../npm/node_modules/jquery/package.json | 0 .../npm/node_modules/promise/package.json | 0 .../npm/node_modules/react-is/package.json | 0 .../npm/node_modules/react/package.json | 0 .../npm/node_modules/redux/package.json | 0 .../npm/node_modules/z-lock/package.json | 0 .../{fs => repo}/npm/package-lock.json | 0 .../{fs => repo}/nuget/packages.lock.json | 0 .../{fs => repo}/pip/requirements.txt | 0 .../fixtures/{fs => repo}/pipenv/Pipfile.lock | 0 .../fixtures/{fs => repo}/pnpm/pnpm-lock.yaml | 0 .../fixtures/{fs => repo}/poetry/poetry.lock | 0 .../{fs => repo}/poetry/pyproject.toml | 0 .../fixtures/{fs => repo}/pom/pom.xml | 0 .../{fs => repo}/pubspec/pubspec.lock | 0 .../{fs => repo}/rule-exception/Dockerfile | 0 .../rule-exception/policy/exception.rego | 0 .../fixtures/{fs => repo}/secrets/deploy.sh | 0 .../{fs => repo}/secrets/trivy-secret.yaml | 0 .../fixtures/{fs => repo}/yarn/package.json | 0 .../fixtures/{fs => repo}/yarn/yarn.lock | 0 integration/testdata/gomod-skip.json.golden | 4 +- integration/testdata/gomod.json.golden | 4 +- integration/testdata/gradle.json.golden | 4 +- integration/testdata/helm.json.golden | 4 +- integration/testdata/helm_badname.json.golden | 4 +- .../testdata/helm_testchart.json.golden | 4 +- .../helm_testchart.overridden.json.golden | 4 +- integration/testdata/mix.lock.json.golden | 4 +- integration/testdata/npm-with-dev.json.golden | 4 +- integration/testdata/npm.json.golden | 4 +- integration/testdata/nuget.json.golden | 4 +- integration/testdata/pip.json.golden | 4 +- integration/testdata/pipenv.json.golden | 4 +- integration/testdata/pnpm.json.golden | 4 +- integration/testdata/poetry.json.golden | 4 +- integration/testdata/pom.json.golden | 4 +- integration/testdata/pubspec.lock.json.golden | 4 +- integration/testdata/secrets.json.golden | 4 +- integration/testdata/yarn.json.golden | 4 +- integration/vm_test.go | 2 +- mkdocs.yml | 2 +- pkg/commands/artifact/wire_gen.go | 6 +- pkg/fanal/artifact/{remote => repo}/git.go | 124 ++++++--- .../artifact/{remote => repo}/git_test.go | 39 +-- .../{remote => repo}/testdata/test.git/HEAD | 0 .../{remote => repo}/testdata/test.git/config | 0 .../0d/8bf3f07c3970b3e38c2cfb1c619cb86fae76d2 | 0 .../1c/1d7deed649fbecd66fab423ccd9d001bf9ff91 | Bin .../27/aaec53f92314d9438a53c703f169d2cbf5001a | Bin .../5e/fb9bc29c482e023e40e0a2b3b7e49cec842034 | Bin .../6a/c152fe2b87cb5e243414df71790a32912e778d | 0 .../c0/42cd14d2b999cade090785af47e9f8b8e342ff | Bin .../c9/06fc4a94762f8a2c77c718947143d16e4e9ec7 | Bin .../d7/937c5f0ce7f2054e4e3be65ab3cd0f9462dc1b | Bin .../e2/4866d1d31ddffdb27fbcf583d5deb4386d5145 | Bin .../e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 | Bin .../f4/836be6497e83e13dc0cfbce7e6b973b1ea511d | Bin .../testdata/test.git/refs/heads/master | 0 .../testdata/test.git/refs/heads/valid-branch | 0 .../testdata/test.git/refs/tags/v1.0.0 | 0 pkg/fanal/types/artifact.go | 14 +- pkg/sbom/cyclonedx/marshal.go | 2 +- pkg/sbom/cyclonedx/marshal_test.go | 2 +- pkg/sbom/spdx/marshal.go | 2 +- pkg/sbom/spdx/marshal_test.go | 2 +- pkg/scanner/scan.go | 11 +- 124 files changed, 454 insertions(+), 446 deletions(-) delete mode 100644 docs/docs/target/git-repository.md create mode 100644 docs/docs/target/repository.md rename integration/{fs_test.go => repo_test.go} (72%) rename integration/testdata/fixtures/{fs => repo}/cocoapods/Podfile.lock (100%) rename integration/testdata/fixtures/{fs => repo}/composer/composer.json (100%) rename integration/testdata/fixtures/{fs => repo}/composer/composer.lock (100%) rename integration/testdata/fixtures/{fs => repo}/conan/conan.lock (100%) rename integration/testdata/fixtures/{fs => repo}/conda/miniconda3/envs/testenv/conda-meta/openssl-1.1.1q-h7f8727e_0.json (100%) rename integration/testdata/fixtures/{fs => repo}/conda/miniconda3/envs/testenv/conda-meta/pip-22.2.2-py38h06a4308_0.json (100%) rename integration/testdata/fixtures/{fs => repo}/custom-policy/Dockerfile (100%) rename integration/testdata/fixtures/{fs => repo}/custom-policy/policy/bar.rego (100%) rename integration/testdata/fixtures/{fs => repo}/custom-policy/policy/foo.rego (100%) rename integration/testdata/fixtures/{fs => repo}/dockerfile/Dockerfile (100%) rename integration/testdata/fixtures/{fs => repo}/dockerfile_file_pattern/Customfile (100%) rename integration/testdata/fixtures/{fs => repo}/dotnet/datacollector.deps.json (100%) rename integration/testdata/fixtures/{fs => repo}/gomod/go.mod (100%) rename integration/testdata/fixtures/{fs => repo}/gomod/go.sum (100%) rename integration/testdata/fixtures/{fs => repo}/gomod/submod/go.mod (100%) rename integration/testdata/fixtures/{fs => repo}/gomod/submod/go.sum (85%) rename integration/testdata/fixtures/{fs => repo}/gomod/submod2/go.mod (100%) rename integration/testdata/fixtures/{fs => repo}/gomod/submod2/go.sum (100%) rename integration/testdata/fixtures/{fs => repo}/gradle/gradle.lockfile (100%) rename integration/testdata/fixtures/{fs => repo}/helm/testchart.tar.gz (100%) rename integration/testdata/fixtures/{fs => repo}/helm_badname/Chart.yaml (100%) rename integration/testdata/fixtures/{fs => repo}/helm_testchart/.helmignore (100%) rename integration/testdata/fixtures/{fs => repo}/helm_testchart/Chart.yaml (100%) rename integration/testdata/fixtures/{fs => repo}/helm_testchart/templates/NOTES.txt (100%) rename integration/testdata/fixtures/{fs => repo}/helm_testchart/templates/_helpers.tpl (100%) rename integration/testdata/fixtures/{fs => repo}/helm_testchart/templates/deployment.yaml (100%) rename integration/testdata/fixtures/{fs => repo}/helm_testchart/templates/hpa.yaml (100%) rename integration/testdata/fixtures/{fs => repo}/helm_testchart/templates/ingress.yaml (100%) rename integration/testdata/fixtures/{fs => repo}/helm_testchart/templates/service.yaml (100%) rename integration/testdata/fixtures/{fs => repo}/helm_testchart/templates/serviceaccount.yaml (100%) rename integration/testdata/fixtures/{fs => repo}/helm_testchart/templates/tests/test-connection.yaml (100%) rename integration/testdata/fixtures/{fs => repo}/helm_testchart/values.yaml (100%) rename integration/testdata/fixtures/{fs => repo}/helm_values/values.yaml (100%) rename integration/testdata/fixtures/{fs => repo}/mixlock/mix.lock (100%) rename integration/testdata/fixtures/{fs => repo}/namespace-exception/Dockerfile (100%) rename integration/testdata/fixtures/{fs => repo}/namespace-exception/policy/exception.rego (100%) rename integration/testdata/fixtures/{fs => repo}/npm/node_modules/jquery/package.json (100%) rename integration/testdata/fixtures/{fs => repo}/npm/node_modules/promise/package.json (100%) rename integration/testdata/fixtures/{fs => repo}/npm/node_modules/react-is/package.json (100%) rename integration/testdata/fixtures/{fs => repo}/npm/node_modules/react/package.json (100%) rename integration/testdata/fixtures/{fs => repo}/npm/node_modules/redux/package.json (100%) rename integration/testdata/fixtures/{fs => repo}/npm/node_modules/z-lock/package.json (100%) rename integration/testdata/fixtures/{fs => repo}/npm/package-lock.json (100%) rename integration/testdata/fixtures/{fs => repo}/nuget/packages.lock.json (100%) rename integration/testdata/fixtures/{fs => repo}/pip/requirements.txt (100%) rename integration/testdata/fixtures/{fs => repo}/pipenv/Pipfile.lock (100%) rename integration/testdata/fixtures/{fs => repo}/pnpm/pnpm-lock.yaml (100%) rename integration/testdata/fixtures/{fs => repo}/poetry/poetry.lock (100%) rename integration/testdata/fixtures/{fs => repo}/poetry/pyproject.toml (100%) rename integration/testdata/fixtures/{fs => repo}/pom/pom.xml (100%) rename integration/testdata/fixtures/{fs => repo}/pubspec/pubspec.lock (100%) rename integration/testdata/fixtures/{fs => repo}/rule-exception/Dockerfile (100%) rename integration/testdata/fixtures/{fs => repo}/rule-exception/policy/exception.rego (100%) rename integration/testdata/fixtures/{fs => repo}/secrets/deploy.sh (100%) rename integration/testdata/fixtures/{fs => repo}/secrets/trivy-secret.yaml (100%) rename integration/testdata/fixtures/{fs => repo}/yarn/package.json (100%) rename integration/testdata/fixtures/{fs => repo}/yarn/yarn.lock (100%) rename pkg/fanal/artifact/{remote => repo}/git.go (64%) rename pkg/fanal/artifact/{remote => repo}/git_test.go (88%) rename pkg/fanal/artifact/{remote => repo}/testdata/test.git/HEAD (100%) rename pkg/fanal/artifact/{remote => repo}/testdata/test.git/config (100%) rename pkg/fanal/artifact/{remote => repo}/testdata/test.git/objects/0d/8bf3f07c3970b3e38c2cfb1c619cb86fae76d2 (100%) rename pkg/fanal/artifact/{remote => repo}/testdata/test.git/objects/1c/1d7deed649fbecd66fab423ccd9d001bf9ff91 (100%) rename pkg/fanal/artifact/{remote => repo}/testdata/test.git/objects/27/aaec53f92314d9438a53c703f169d2cbf5001a (100%) rename pkg/fanal/artifact/{remote => repo}/testdata/test.git/objects/5e/fb9bc29c482e023e40e0a2b3b7e49cec842034 (100%) rename pkg/fanal/artifact/{remote => repo}/testdata/test.git/objects/6a/c152fe2b87cb5e243414df71790a32912e778d (100%) rename pkg/fanal/artifact/{remote => repo}/testdata/test.git/objects/c0/42cd14d2b999cade090785af47e9f8b8e342ff (100%) rename pkg/fanal/artifact/{remote => repo}/testdata/test.git/objects/c9/06fc4a94762f8a2c77c718947143d16e4e9ec7 (100%) rename pkg/fanal/artifact/{remote => repo}/testdata/test.git/objects/d7/937c5f0ce7f2054e4e3be65ab3cd0f9462dc1b (100%) rename pkg/fanal/artifact/{remote => repo}/testdata/test.git/objects/e2/4866d1d31ddffdb27fbcf583d5deb4386d5145 (100%) rename pkg/fanal/artifact/{remote => repo}/testdata/test.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 (100%) rename pkg/fanal/artifact/{remote => repo}/testdata/test.git/objects/f4/836be6497e83e13dc0cfbce7e6b973b1ea511d (100%) rename pkg/fanal/artifact/{remote => repo}/testdata/test.git/refs/heads/master (100%) rename pkg/fanal/artifact/{remote => repo}/testdata/test.git/refs/heads/valid-branch (100%) rename pkg/fanal/artifact/{remote => repo}/testdata/test.git/refs/tags/v1.0.0 (100%) diff --git a/docs/docs/target/git-repository.md b/docs/docs/target/git-repository.md deleted file mode 100644 index c3b4d6b9397e..000000000000 --- a/docs/docs/target/git-repository.md +++ /dev/null @@ -1,236 +0,0 @@ -# Git Repository - -Scan your remote git repositories for - -- Vulnerabilities -- Misconfigurations -- Secrets -- Licenses - -By default, vulnerability and secret scanning are enabled, and you can configure that with `--scanners`. - -```bash -$ trivy repo [YOUR_REPO_URL] -``` - -## Scanners -### Vulnerabilities -It is enabled by default. -Trivy will look for vulnerabilities based on lock files such as Gemfile.lock and package-lock.json. -See [here](../scanner/vulnerability/index.md) for the detail. - -``` -$ trivy repo https://github.com/knqyf263/trivy-ci-test -``` - -
-Result - -``` -2021-03-09T15:04:19.003+0200 INFO Detecting cargo vulnerabilities... -2021-03-09T15:04:19.005+0200 INFO Detecting pipenv vulnerabilities... - -Cargo.lock -========== -Total: 7 (UNKNOWN: 7, LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 0) - -+----------+-------------------+----------+-------------------+------------------------------+---------------------------------------------+ -| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | -+----------+-------------------+----------+-------------------+------------------------------+---------------------------------------------+ -| ammonia | RUSTSEC-2019-0001 | UNKNOWN | 1.9.0 | >= 2.1.0 | Uncontrolled recursion leads | -| | | | | | to abort in HTML serialization | -| | | | | | -->rustsec.org/advisories/RUSTSEC-2019-0001 | -+----------+-------------------+ +-------------------+------------------------------+---------------------------------------------+ -| openssl | RUSTSEC-2016-0001 | | 0.8.3 | >= 0.9.0 | SSL/TLS MitM vulnerability | -| | | | | | due to insecure defaults | -| | | | | | -->rustsec.org/advisories/RUSTSEC-2016-0001 | -+----------+-------------------+ +-------------------+------------------------------+---------------------------------------------+ -| smallvec | RUSTSEC-2018-0018 | | 0.6.9 | >= 0.6.13 | smallvec creates uninitialized | -| | | | | | value of any type | -| | | | | | -->rustsec.org/advisories/RUSTSEC-2018-0018 | -+ +-------------------+ + +------------------------------+---------------------------------------------+ -| | RUSTSEC-2019-0009 | | | >= 0.6.10 | Double-free and use-after-free | -| | | | | | in SmallVec::grow() | -| | | | | | -->rustsec.org/advisories/RUSTSEC-2019-0009 | -+ +-------------------+ + + +---------------------------------------------+ -| | RUSTSEC-2019-0012 | | | | Memory corruption in SmallVec::grow() | -| | | | | | -->rustsec.org/advisories/RUSTSEC-2019-0012 | -+ +-------------------+ + +------------------------------+---------------------------------------------+ -| | RUSTSEC-2021-0003 | | | >= 0.6.14, < 1.0.0, >= 1.6.1 | Buffer overflow in SmallVec::insert_many | -| | | | | | -->rustsec.org/advisories/RUSTSEC-2021-0003 | -+----------+-------------------+ +-------------------+------------------------------+---------------------------------------------+ -| tempdir | RUSTSEC-2018-0017 | | 0.3.7 | | `tempdir` crate has been | -| | | | | | deprecated; use `tempfile` instead | -| | | | | | -->rustsec.org/advisories/RUSTSEC-2018-0017 | -+----------+-------------------+----------+-------------------+------------------------------+---------------------------------------------+ - -Pipfile.lock -============ -Total: 20 (UNKNOWN: 3, LOW: 0, MEDIUM: 7, HIGH: 5, CRITICAL: 5) - -+---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ -| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | -+---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ -| django | CVE-2019-19844 | CRITICAL | 2.0.9 | 3.0.1, 2.2.9, 1.11.27 | Django: crafted email address | -| | | | | | allows account takeover | -| | | | | | -->avd.aquasec.com/nvd/cve-2019-19844 | -+ +------------------+ + +------------------------+---------------------------------------+ -| | CVE-2020-7471 | | | 3.0.3, 2.2.10, 1.11.28 | django: potential SQL injection | -| | | | | | via StringAgg(delimiter) | -| | | | | | -->avd.aquasec.com/nvd/cve-2020-7471 | -+ +------------------+----------+ +------------------------+---------------------------------------+ -| | CVE-2019-6975 | HIGH | | 2.1.6, 2.0.11, 1.11.19 | python-django: memory exhaustion in | -| | | | | | django.utils.numberformat.format() | -| | | | | | -->avd.aquasec.com/nvd/cve-2019-6975 | -+ +------------------+ + +------------------------+---------------------------------------+ -| | CVE-2020-9402 | | | 3.0.4, 2.2.11, 1.11.29 | django: potential SQL injection | -| | | | | | via "tolerance" parameter in | -| | | | | | GIS functions and aggregates... | -| | | | | | -->avd.aquasec.com/nvd/cve-2020-9402 | -+ +------------------+----------+ +------------------------+---------------------------------------+ -| | CVE-2019-3498 | MEDIUM | | 2.1.5, 2.0.10, 1.11.18 | python-django: Content spoofing | -| | | | | | via URL path in default 404 page | -| | | | | | -->avd.aquasec.com/nvd/cve-2019-3498 | -+ +------------------+ + +------------------------+---------------------------------------+ -| | CVE-2020-13254 | | | 3.0.7, 2.2.13 | django: potential data leakage | -| | | | | | via malformed memcached keys | -| | | | | | -->avd.aquasec.com/nvd/cve-2020-13254 | -+ +------------------+ + + +---------------------------------------+ -| | CVE-2020-13596 | | | | django: possible XSS via | -| | | | | | admin ForeignKeyRawIdWidget | -| | | | | | -->avd.aquasec.com/nvd/cve-2020-13596 | -+---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ -| django-cors-headers | pyup.io-37132 | UNKNOWN | 2.5.2 | 3.0.0 | In django-cors-headers | -| | | | | | version 3.0.0, | -| | | | | | ``CORS_ORIGIN_WHITELIST`` | -| | | | | | requires URI schemes, and | -| | | | | | optionally ports. This... | -+---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ -| djangorestframework | CVE-2020-25626 | MEDIUM | 3.9.2 | 3.11.2 | django-rest-framework: XSS | -| | | | | | Vulnerability in API viewer | -| | | | | | -->avd.aquasec.com/nvd/cve-2020-25626 | -+---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ -| httplib2 | CVE-2021-21240 | HIGH | 0.12.1 | 0.19.0 | python-httplib2: Regular | -| | | | | | expression denial of | -| | | | | | service via malicious header | -| | | | | | -->avd.aquasec.com/nvd/cve-2021-21240 | -+ +------------------+----------+ +------------------------+---------------------------------------+ -| | CVE-2020-11078 | MEDIUM | | 0.18.0 | python-httplib2: CRLF injection | -| | | | | | via an attacker controlled | -| | | | | | unescaped part of uri for... | -| | | | | | -->avd.aquasec.com/nvd/cve-2020-11078 | -+ +------------------+----------+ + +---------------------------------------+ -| | pyup.io-38303 | UNKNOWN | | | Httplib2 0.18.0 is an | -| | | | | | important security update to | -| | | | | | patch a CWE-93 CRLF... | -+---------------------+------------------+ +-------------------+------------------------+---------------------------------------+ -| jinja2 | pyup.io-39525 | | 2.10.1 | 2.11.3 | This affects the package | -| | | | | | jinja2 from 0.0.0 and before | -| | | | | | 2.11.3. The ReDOS... | -+---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ -| py | CVE-2020-29651 | HIGH | 1.8.0 | | python-py: ReDoS in the py.path.svnwc | -| | | | | | component via malicious input | -| | | | | | to blame functionality... | -| | | | | | -->avd.aquasec.com/nvd/cve-2020-29651 | -+---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ -| pyyaml | CVE-2019-20477 | CRITICAL | 5.1 | | PyYAML: command execution | -| | | | | | through python/object/apply | -| | | | | | constructor in FullLoader | -| | | | | | -->avd.aquasec.com/nvd/cve-2019-20477 | -+ +------------------+ + +------------------------+---------------------------------------+ -| | CVE-2020-14343 | | | 5.4 | PyYAML: incomplete | -| | | | | | fix for CVE-2020-1747 | -| | | | | | -->avd.aquasec.com/nvd/cve-2020-14343 | -+ +------------------+ + +------------------------+---------------------------------------+ -| | CVE-2020-1747 | | | 5.3.1 | PyYAML: arbitrary command | -| | | | | | execution through python/object/new | -| | | | | | when FullLoader is used | -| | | | | | -->avd.aquasec.com/nvd/cve-2020-1747 | -+---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ -| urllib3 | CVE-2019-11324 | HIGH | 1.24.1 | 1.24.2 | python-urllib3: Certification | -| | | | | | mishandle when error should be thrown | -| | | | | | -->avd.aquasec.com/nvd/cve-2019-11324 | -+ +------------------+----------+ +------------------------+---------------------------------------+ -| | CVE-2019-11236 | MEDIUM | | | python-urllib3: CRLF injection | -| | | | | | due to not encoding the | -| | | | | | '\r\n' sequence leading to... | -| | | | | | -->avd.aquasec.com/nvd/cve-2019-11236 | -+ +------------------+ + +------------------------+---------------------------------------+ -| | CVE-2020-26137 | | | 1.25.9 | python-urllib3: CRLF injection | -| | | | | | via HTTP request method | -| | | | | | -->avd.aquasec.com/nvd/cve-2020-26137 | -+---------------------+------------------+----------+-------------------+------------------------+---------------------------------------+ -``` - -
- -### Misconfigurations -It is disabled by default and can be enabled with `--scanners config`. -See [here](../scanner/misconfiguration/index.md) for the detail. - -```shell -$ trivy repo --scanners config [YOUR_REPO_URL] -``` - -### Secrets -It is enabled by default. -See [here](../scanner/secret.md) for the detail. - -```shell -$ trivy repo [YOUR_REPO_URL] -``` - -### Licenses -It is disabled by default. -See [here](../scanner/license.md) for the detail. - -```shell -$ trivy repo --scanners license [YOUR_REPO_URL] -``` - -## SBOM generation -Trivy can generate SBOM for git repositories. -See [here](../supply-chain/sbom.md) for the detail. - -## References -### Scanning a Branch - -Pass a `--branch` argument with a valid branch name on the remote repository provided: - -``` -$ trivy repo --branch -``` - -### Scanning upto a Commit - -Pass a `--commit` argument with a valid commit hash on the remote repository provided: - -``` -$ trivy repo --commit -``` - -### Scanning a Tag - -Pass a `--tag` argument with a valid tag on the remote repository provided: - -``` -$ trivy repo --tag -``` - -### Scanning Private Repositories -In order to scan private GitHub or GitLab repositories, the environment variable `GITHUB_TOKEN` or `GITLAB_TOKEN` must be set, respectively, with a valid token that has access to the private repository being scanned. - -The `GITHUB_TOKEN` environment variable will take precedence over `GITLAB_TOKEN`, so if a private GitLab repository will be scanned, then `GITHUB_TOKEN` must be unset. - -You can find how to generate your GitHub Token in the following [GitHub documentation.](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) - -For example: - -``` -$ export GITHUB_TOKEN="your_private_github_token" -$ trivy repo -$ -$ # or -$ export GITLAB_TOKEN="your_private_gitlab_token" -$ trivy repo -``` diff --git a/docs/docs/target/repository.md b/docs/docs/target/repository.md new file mode 100644 index 000000000000..e4f99052dbf2 --- /dev/null +++ b/docs/docs/target/repository.md @@ -0,0 +1,155 @@ +# Code Repository + +Scan your local or remote code repositories for + +- Vulnerabilities +- Misconfigurations +- Secrets +- Licenses + +By default, vulnerability and secret scanning are enabled, and you can configure that with `--scanners`. + +```bash +$ trivy repo (REPO_PATH | REPO_URL) +``` + +For example, you can scan a local repository as below. + +```bash +$ trivy repo ./ +``` + +It's also possible to scan a single file. + +``` +$ trivy repo ./trivy-ci-test/Pipfile.lock +``` + +To scan remote code repositories, you need to specify the URL. + +```bash +$ trivy repo https://github.com/aquasecurity/trivy-ci-test +``` + +## Rationale +`trivy repo` is designed to scan code repositories, and it is intended to be used for scanning local/remote repositories in your machine or in your CI environment. +Therefore, unlike container/VM image scanning, it targets lock files such as package-lock.json and does not target artifacts like JAR files, binary files, etc. +See [here](../scanner/vulnerability/language/index.md) for the detail. + +## Scanners +### Vulnerabilities +It is enabled by default. +Trivy will look for vulnerabilities based on lock files such as Gemfile.lock and package-lock.json. +See [here](../scanner/vulnerability/index.md) for the detail. + +``` +$ trivy repo ~/src/github.com/aquasecurity/trivy-ci-test +``` + +
+Result + +``` +2020-06-01T17:06:58.652+0300 WARN OS is not detected and vulnerabilities in OS packages are not detected. +2020-06-01T17:06:58.652+0300 INFO Detecting pipenv vulnerabilities... +2020-06-01T17:06:58.691+0300 INFO Detecting cargo vulnerabilities... + +Pipfile.lock +============ +Total: 10 (UNKNOWN: 2, LOW: 0, MEDIUM: 6, HIGH: 2, CRITICAL: 0) + ++---------------------+------------------+----------+-------------------+------------------------+------------------------------------+ +| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION | TITLE | ++---------------------+------------------+----------+-------------------+------------------------+------------------------------------+ +| django | CVE-2020-7471 | HIGH | 2.0.9 | 3.0.3, 2.2.10, 1.11.28 | django: potential | +| | | | | | SQL injection via | +| | | | | | StringAgg(delimiter) | ++ +------------------+----------+ +------------------------+------------------------------------+ +| | CVE-2019-19844 | MEDIUM | | 3.0.1, 2.2.9, 1.11.27 | Django: crafted email address | +| | | | | | allows account takeover | ++ +------------------+ + +------------------------+------------------------------------+ +| | CVE-2019-3498 | | | 2.1.5, 2.0.10, 1.11.18 | python-django: Content | +| | | | | | spoofing via URL path in | +| | | | | | default 404 page | ++ +------------------+ + +------------------------+------------------------------------+ +| | CVE-2019-6975 | | | 2.1.6, 2.0.11, 1.11.19 | python-django: | +| | | | | | memory exhaustion in | +| | | | | | django.utils.numberformat.format() | ++---------------------+------------------+----------+-------------------+------------------------+------------------------------------+ +... +``` + +
+ +### Misconfigurations +It is disabled by default and can be enabled with `--scanners config`. +See [here](../scanner/misconfiguration/index.md) for the detail. + +```shell +$ trivy repo --scanners config [YOUR_REPO_URL] +``` + +### Secrets +It is enabled by default. +See [here](../scanner/secret.md) for the detail. + +```shell +$ trivy repo [YOUR_REPO_URL] +``` + +### Licenses +It is disabled by default. +See [here](../scanner/license.md) for the detail. + +```shell +$ trivy repo --scanners license [YOUR_REPO_URL] +``` + +## SBOM generation +Trivy can generate SBOM for code repositories. +See [here](../supply-chain/sbom.md) for the detail. + +## References +The following flags and environmental variables are available for remote git repositories. + +### Scanning a Branch + +Pass a `--branch` argument with a valid branch name on the remote repository provided: + +``` +$ trivy repo --branch +``` + +### Scanning upto a Commit + +Pass a `--commit` argument with a valid commit hash on the remote repository provided: + +``` +$ trivy repo --commit +``` + +### Scanning a Tag + +Pass a `--tag` argument with a valid tag on the remote repository provided: + +``` +$ trivy repo --tag +``` + +### Scanning Private Repositories +In order to scan private GitHub or GitLab repositories, the environment variable `GITHUB_TOKEN` or `GITLAB_TOKEN` must be set, respectively, with a valid token that has access to the private repository being scanned. + +The `GITHUB_TOKEN` environment variable will take precedence over `GITLAB_TOKEN`, so if a private GitLab repository will be scanned, then `GITHUB_TOKEN` must be unset. + +You can find how to generate your GitHub Token in the following [GitHub documentation.](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) + +For example: + +``` +$ export GITHUB_TOKEN="your_private_github_token" +$ trivy repo + +# or +$ export GITLAB_TOKEN="your_private_gitlab_token" +$ trivy repo +``` diff --git a/docs/getting-started/coverage.md b/docs/getting-started/coverage.md index 47b1f06b47ca..81c6a2b662ff 100644 --- a/docs/getting-started/coverage.md +++ b/docs/getting-started/coverage.md @@ -55,4 +55,4 @@ Trivy reads IaC & configuration languages for the purpose of misconfiguration de - Azure ARM Template - Helm Chart -For more information about checks [see here](../docs/misconfiguration/policy/builtin.md). +For more information about checks [see here](../docs/scanner/misconfiguration/policy/builtin.md). diff --git a/docs/getting-started/faq.md b/docs/getting-started/faq.md index 02614613db89..4652aab42ec5 100644 --- a/docs/getting-started/faq.md +++ b/docs/getting-started/faq.md @@ -21,3 +21,5 @@ See [here](../docs/configuration/reporting.md#converting). ### How to run Trivy under air-gapped environment? See [here](../docs/advanced/air-gap.md). +### Why `trivy fs` and `trivy repo` does not scan JAR files for vulnerabilities? +See [here](../docs/target/repository.md#rationale). diff --git a/integration/client_server_test.go b/integration/client_server_test.go index 53dfd468aae6..b7144d53c72e 100644 --- a/integration/client_server_test.go +++ b/integration/client_server_test.go @@ -236,21 +236,21 @@ func TestClientServer(t *testing.T) { golden: "testdata/busybox-with-lockfile.json.golden", }, { - name: "scan pox.xml with fs command in client/server mode", + name: "scan pox.xml with repo command in client/server mode", args: csArgs{ - Command: "fs", + Command: "repo", RemoteAddrOption: "--server", - Target: "testdata/fixtures/fs/pom/", + Target: "testdata/fixtures/repo/pom/", }, golden: "testdata/pom.json.golden", }, { - name: "scan sample.pem with fs command in client/server mode", + name: "scan sample.pem with repo command in client/server mode", args: csArgs{ - Command: "fs", + Command: "repo", RemoteAddrOption: "--server", - secretConfig: "testdata/fixtures/fs/secrets/trivy-secret.yaml", - Target: "testdata/fixtures/fs/secrets/", + secretConfig: "testdata/fixtures/repo/secrets/trivy-secret.yaml", + Target: "testdata/fixtures/repo/secrets/", }, golden: "testdata/secrets.json.golden", }, @@ -279,7 +279,7 @@ func TestClientServer(t *testing.T) { err := execute(osArgs) require.NoError(t, err) - compareReports(t, c.golden, outputFile) + compareReports(t, c.golden, outputFile, nil) }) } } @@ -328,11 +328,11 @@ func TestClientServerWithFormat(t *testing.T) { { name: "scan secrets with ASFF template", args: csArgs{ - Command: "fs", + Command: "repo", RemoteAddrOption: "--server", Format: "template", TemplatePath: "@../contrib/asff.tpl", - Target: "testdata/fixtures/fs/secrets/", + Target: "testdata/fixtures/repo/secrets/", }, golden: "testdata/secrets.asff.golden", }, @@ -501,7 +501,7 @@ func TestClientServerWithToken(t *testing.T) { } require.NoError(t, err, c.name) - compareReports(t, c.golden, outputFile) + compareReports(t, c.golden, outputFile, nil) }) } } @@ -528,7 +528,7 @@ func TestClientServerWithRedis(t *testing.T) { err := execute(osArgs) require.NoError(t, err) - compareReports(t, golden, outputFile) + compareReports(t, golden, outputFile, nil) }) // Terminate the Redis container diff --git a/integration/docker_engine_test.go b/integration/docker_engine_test.go index 75a9d3c6ace3..c69f6d34a0a7 100644 --- a/integration/docker_engine_test.go +++ b/integration/docker_engine_test.go @@ -285,7 +285,7 @@ func TestDockerEngine(t *testing.T) { assert.NoError(t, err, tt.name) // check for vulnerability output info - compareReports(t, tt.golden, output) + compareReports(t, tt.golden, output, nil) // cleanup _, err = cli.ImageRemove(ctx, tt.input, api.ImageRemoveOptions{ diff --git a/integration/integration_test.go b/integration/integration_test.go index 5559da4f8fa3..65fb3a36578f 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -199,9 +199,12 @@ func execute(osArgs []string) error { return app.Execute() } -func compareReports(t *testing.T, wantFile, gotFile string) { +func compareReports(t *testing.T, wantFile, gotFile string, override func(*types.Report)) { want := readReport(t, wantFile) got := readReport(t, gotFile) + if override != nil { + override(&want) + } assert.Equal(t, want, got) } diff --git a/integration/module_test.go b/integration/module_test.go index 0f4f650e8aa3..c2fd3928922b 100644 --- a/integration/module_test.go +++ b/integration/module_test.go @@ -1,4 +1,5 @@ //go:build module_integration + package integration import ( @@ -70,7 +71,7 @@ func TestModule(t *testing.T) { }() // Compare want and got - compareReports(t, tt.golden, outputFile) + compareReports(t, tt.golden, outputFile, nil) }) } } diff --git a/integration/fs_test.go b/integration/repo_test.go similarity index 72% rename from integration/fs_test.go rename to integration/repo_test.go index 61a1cf49ac85..a736d8f20d00 100644 --- a/integration/fs_test.go +++ b/integration/repo_test.go @@ -1,5 +1,4 @@ //go:build integration -// +build integration package integration @@ -12,13 +11,14 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/types" ) -func TestFilesystem(t *testing.T) { +// TestRepository tests `trivy repo` with the local code repositories +func TestRepository(t *testing.T) { type args struct { scanner types.Scanner - severity []string ignoreIDs []string policyPaths []string namespaces []string @@ -35,15 +35,16 @@ func TestFilesystem(t *testing.T) { includeDevDeps bool } tests := []struct { - name string - args args - golden string + name string + args args + golden string + override func(*types.Report) }{ { name: "gomod", args: args{ scanner: types.VulnerabilityScanner, - input: "testdata/fixtures/fs/gomod", + input: "testdata/fixtures/repo/gomod", }, golden: "testdata/gomod.json.golden", }, @@ -51,8 +52,8 @@ func TestFilesystem(t *testing.T) { name: "gomod with skip files", args: args{ scanner: types.VulnerabilityScanner, - input: "testdata/fixtures/fs/gomod", - skipFiles: []string{"testdata/fixtures/fs/gomod/submod2/go.mod"}, + input: "testdata/fixtures/repo/gomod", + skipFiles: []string{"testdata/fixtures/repo/gomod/submod2/go.mod"}, }, golden: "testdata/gomod-skip.json.golden", }, @@ -60,8 +61,8 @@ func TestFilesystem(t *testing.T) { name: "gomod with skip dirs", args: args{ scanner: types.VulnerabilityScanner, - input: "testdata/fixtures/fs/gomod", - skipDirs: []string{"testdata/fixtures/fs/gomod/submod2"}, + input: "testdata/fixtures/repo/gomod", + skipDirs: []string{"testdata/fixtures/repo/gomod/submod2"}, }, golden: "testdata/gomod-skip.json.golden", }, @@ -69,7 +70,7 @@ func TestFilesystem(t *testing.T) { name: "npm", args: args{ scanner: types.VulnerabilityScanner, - input: "testdata/fixtures/fs/npm", + input: "testdata/fixtures/repo/npm", listAllPkgs: true, }, golden: "testdata/npm.json.golden", @@ -78,7 +79,7 @@ func TestFilesystem(t *testing.T) { name: "npm with dev deps", args: args{ scanner: types.VulnerabilityScanner, - input: "testdata/fixtures/fs/npm", + input: "testdata/fixtures/repo/npm", listAllPkgs: true, includeDevDeps: true, }, @@ -88,7 +89,7 @@ func TestFilesystem(t *testing.T) { name: "yarn", args: args{ scanner: types.VulnerabilityScanner, - input: "testdata/fixtures/fs/yarn", + input: "testdata/fixtures/repo/yarn", listAllPkgs: true, }, golden: "testdata/yarn.json.golden", @@ -97,7 +98,7 @@ func TestFilesystem(t *testing.T) { name: "pnpm", args: args{ scanner: types.VulnerabilityScanner, - input: "testdata/fixtures/fs/pnpm", + input: "testdata/fixtures/repo/pnpm", }, golden: "testdata/pnpm.json.golden", }, @@ -106,7 +107,7 @@ func TestFilesystem(t *testing.T) { args: args{ scanner: types.VulnerabilityScanner, listAllPkgs: true, - input: "testdata/fixtures/fs/pip", + input: "testdata/fixtures/repo/pip", }, golden: "testdata/pip.json.golden", }, @@ -115,7 +116,7 @@ func TestFilesystem(t *testing.T) { args: args{ scanner: types.VulnerabilityScanner, listAllPkgs: true, - input: "testdata/fixtures/fs/pipenv", + input: "testdata/fixtures/repo/pipenv", }, golden: "testdata/pipenv.json.golden", }, @@ -124,7 +125,7 @@ func TestFilesystem(t *testing.T) { args: args{ scanner: types.VulnerabilityScanner, listAllPkgs: true, - input: "testdata/fixtures/fs/poetry", + input: "testdata/fixtures/repo/poetry", }, golden: "testdata/poetry.json.golden", }, @@ -132,7 +133,7 @@ func TestFilesystem(t *testing.T) { name: "pom", args: args{ scanner: types.VulnerabilityScanner, - input: "testdata/fixtures/fs/pom", + input: "testdata/fixtures/repo/pom", }, golden: "testdata/pom.json.golden", }, @@ -140,7 +141,7 @@ func TestFilesystem(t *testing.T) { name: "gradle", args: args{ scanner: types.VulnerabilityScanner, - input: "testdata/fixtures/fs/gradle", + input: "testdata/fixtures/repo/gradle", }, golden: "testdata/gradle.json.golden", }, @@ -149,7 +150,7 @@ func TestFilesystem(t *testing.T) { args: args{ scanner: types.VulnerabilityScanner, listAllPkgs: true, - input: "testdata/fixtures/fs/conan", + input: "testdata/fixtures/repo/conan", }, golden: "testdata/conan.json.golden", }, @@ -158,7 +159,7 @@ func TestFilesystem(t *testing.T) { args: args{ scanner: types.VulnerabilityScanner, listAllPkgs: true, - input: "testdata/fixtures/fs/nuget", + input: "testdata/fixtures/repo/nuget", }, golden: "testdata/nuget.json.golden", }, @@ -167,7 +168,7 @@ func TestFilesystem(t *testing.T) { args: args{ scanner: types.VulnerabilityScanner, listAllPkgs: true, - input: "testdata/fixtures/fs/dotnet", + input: "testdata/fixtures/repo/dotnet", }, golden: "testdata/dotnet.json.golden", }, @@ -176,7 +177,7 @@ func TestFilesystem(t *testing.T) { args: args{ scanner: types.VulnerabilityScanner, listAllPkgs: true, - input: "testdata/fixtures/fs/cocoapods", + input: "testdata/fixtures/repo/cocoapods", }, golden: "testdata/cocoapods.json.golden", }, @@ -185,7 +186,7 @@ func TestFilesystem(t *testing.T) { args: args{ scanner: types.VulnerabilityScanner, listAllPkgs: true, - input: "testdata/fixtures/fs/pubspec", + input: "testdata/fixtures/repo/pubspec", }, golden: "testdata/pubspec.lock.json.golden", }, @@ -194,7 +195,7 @@ func TestFilesystem(t *testing.T) { args: args{ scanner: types.VulnerabilityScanner, listAllPkgs: true, - input: "testdata/fixtures/fs/mixlock", + input: "testdata/fixtures/repo/mixlock", }, golden: "testdata/mix.lock.json.golden", }, @@ -203,7 +204,7 @@ func TestFilesystem(t *testing.T) { args: args{ scanner: types.VulnerabilityScanner, listAllPkgs: true, - input: "testdata/fixtures/fs/composer", + input: "testdata/fixtures/repo/composer", }, golden: "testdata/composer.lock.json.golden", }, @@ -211,7 +212,7 @@ func TestFilesystem(t *testing.T) { name: "dockerfile", args: args{ scanner: types.MisconfigScanner, - input: "testdata/fixtures/fs/dockerfile", + input: "testdata/fixtures/repo/dockerfile", namespaces: []string{"testing"}, }, golden: "testdata/dockerfile.json.golden", @@ -220,7 +221,7 @@ func TestFilesystem(t *testing.T) { name: "dockerfile with custom file pattern", args: args{ scanner: types.MisconfigScanner, - input: "testdata/fixtures/fs/dockerfile_file_pattern", + input: "testdata/fixtures/repo/dockerfile_file_pattern", namespaces: []string{"testing"}, filePatterns: []string{"dockerfile:Customfile"}, }, @@ -230,8 +231,8 @@ func TestFilesystem(t *testing.T) { name: "dockerfile with rule exception", args: args{ scanner: types.MisconfigScanner, - policyPaths: []string{"testdata/fixtures/fs/rule-exception/policy"}, - input: "testdata/fixtures/fs/rule-exception", + policyPaths: []string{"testdata/fixtures/repo/rule-exception/policy"}, + input: "testdata/fixtures/repo/rule-exception", }, golden: "testdata/dockerfile-rule-exception.json.golden", }, @@ -239,8 +240,8 @@ func TestFilesystem(t *testing.T) { name: "dockerfile with namespace exception", args: args{ scanner: types.MisconfigScanner, - policyPaths: []string{"testdata/fixtures/fs/namespace-exception/policy"}, - input: "testdata/fixtures/fs/namespace-exception", + policyPaths: []string{"testdata/fixtures/repo/namespace-exception/policy"}, + input: "testdata/fixtures/repo/namespace-exception", }, golden: "testdata/dockerfile-namespace-exception.json.golden", }, @@ -248,9 +249,9 @@ func TestFilesystem(t *testing.T) { name: "dockerfile with custom policies", args: args{ scanner: types.MisconfigScanner, - policyPaths: []string{"testdata/fixtures/fs/custom-policy/policy"}, + policyPaths: []string{"testdata/fixtures/repo/custom-policy/policy"}, namespaces: []string{"user"}, - input: "testdata/fixtures/fs/custom-policy", + input: "testdata/fixtures/repo/custom-policy", }, golden: "testdata/dockerfile-custom-policies.json.golden", }, @@ -258,7 +259,7 @@ func TestFilesystem(t *testing.T) { name: "tarball helm chart scanning with builtin policies", args: args{ scanner: types.MisconfigScanner, - input: "testdata/fixtures/fs/helm", + input: "testdata/fixtures/repo/helm", }, golden: "testdata/helm.json.golden", }, @@ -266,7 +267,7 @@ func TestFilesystem(t *testing.T) { name: "helm chart directory scanning with builtin policies", args: args{ scanner: types.MisconfigScanner, - input: "testdata/fixtures/fs/helm_testchart", + input: "testdata/fixtures/repo/helm_testchart", }, golden: "testdata/helm_testchart.json.golden", }, @@ -274,7 +275,7 @@ func TestFilesystem(t *testing.T) { name: "helm chart directory scanning with value overrides using set", args: args{ scanner: types.MisconfigScanner, - input: "testdata/fixtures/fs/helm_testchart", + input: "testdata/fixtures/repo/helm_testchart", helmSet: []string{"securityContext.runAsUser=0"}, }, golden: "testdata/helm_testchart.overridden.json.golden", @@ -283,8 +284,8 @@ func TestFilesystem(t *testing.T) { name: "helm chart directory scanning with value overrides using value file", args: args{ scanner: types.MisconfigScanner, - input: "testdata/fixtures/fs/helm_testchart", - helmValuesFile: []string{"testdata/fixtures/fs/helm_values/values.yaml"}, + input: "testdata/fixtures/repo/helm_testchart", + helmValuesFile: []string{"testdata/fixtures/repo/helm_values/values.yaml"}, }, golden: "testdata/helm_testchart.overridden.json.golden", }, @@ -292,7 +293,7 @@ func TestFilesystem(t *testing.T) { name: "helm chart directory scanning with builtin policies and non string Chart name", args: args{ scanner: types.MisconfigScanner, - input: "testdata/fixtures/fs/helm_badname", + input: "testdata/fixtures/repo/helm_badname", }, golden: "testdata/helm_badname.json.golden", }, @@ -300,8 +301,8 @@ func TestFilesystem(t *testing.T) { name: "secrets", args: args{ scanner: "vuln,secret", - input: "testdata/fixtures/fs/secrets", - secretConfig: "testdata/fixtures/fs/secrets/trivy-secret.yaml", + input: "testdata/fixtures/repo/secrets", + secretConfig: "testdata/fixtures/repo/secrets/trivy-secret.yaml", }, golden: "testdata/secrets.json.golden", }, @@ -310,7 +311,7 @@ func TestFilesystem(t *testing.T) { args: args{ command: "rootfs", format: "cyclonedx", - input: "testdata/fixtures/fs/conda", + input: "testdata/fixtures/repo/conda", }, golden: "testdata/conda-cyclonedx.json.golden", }, @@ -319,10 +320,37 @@ func TestFilesystem(t *testing.T) { args: args{ command: "rootfs", format: "spdx-json", - input: "testdata/fixtures/fs/conda", + input: "testdata/fixtures/repo/conda", }, golden: "testdata/conda-spdx.json.golden", }, + { + name: "gomod with fs subcommand", + args: args{ + command: "fs", + scanner: types.VulnerabilityScanner, + input: "testdata/fixtures/repo/gomod", + skipFiles: []string{"testdata/fixtures/repo/gomod/submod2/go.mod"}, + }, + golden: "testdata/gomod-skip.json.golden", + override: func(report *types.Report) { + report.ArtifactType = ftypes.ArtifactFilesystem + }, + }, + { + name: "dockerfile with fs subcommand", + args: args{ + command: "fs", + scanner: types.MisconfigScanner, + policyPaths: []string{"testdata/fixtures/repo/custom-policy/policy"}, + namespaces: []string{"user"}, + input: "testdata/fixtures/repo/custom-policy", + }, + golden: "testdata/dockerfile-custom-policies.json.golden", + override: func(report *types.Report) { + report.ArtifactType = ftypes.ArtifactFilesystem + }, + }, } // Set up testing DB @@ -334,7 +362,7 @@ func TestFilesystem(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - command := "fs" + command := "repo" if tt.args.command != "" { command = tt.args.command } @@ -372,10 +400,6 @@ func TestFilesystem(t *testing.T) { } } - if len(tt.args.severity) != 0 { - osArgs = append(osArgs, "--severity", strings.Join(tt.args.severity, ",")) - } - if len(tt.args.ignoreIDs) != 0 { trivyIgnore := ".trivyignore" err := os.WriteFile(trivyIgnore, []byte(strings.Join(tt.args.ignoreIDs, "\n")), 0444) @@ -415,7 +439,7 @@ func TestFilesystem(t *testing.T) { // Setup the output file outputFile := filepath.Join(t.TempDir(), "output.json") - if *update { + if *update && tt.override == nil { outputFile = tt.golden } @@ -434,7 +458,7 @@ func TestFilesystem(t *testing.T) { osArgs = append(osArgs, "--output", outputFile) osArgs = append(osArgs, tt.args.input) - // Run "trivy fs" + // Run "trivy repo" err := execute(osArgs) require.NoError(t, err) @@ -445,7 +469,7 @@ func TestFilesystem(t *testing.T) { case "spdx-json": compareSpdxJson(t, tt.golden, outputFile) case "json": - compareReports(t, tt.golden, outputFile) + compareReports(t, tt.golden, outputFile, tt.override) default: require.Fail(t, "invalid format", "format: %s", format) } diff --git a/integration/standalone_tar_test.go b/integration/standalone_tar_test.go index 4bb391712e6e..570acef48bd8 100644 --- a/integration/standalone_tar_test.go +++ b/integration/standalone_tar_test.go @@ -418,7 +418,7 @@ func TestTar(t *testing.T) { require.NoError(t, err) // Compare want and got - compareReports(t, tt.golden, outputFile) + compareReports(t, tt.golden, outputFile, nil) }) } } @@ -513,7 +513,7 @@ func TestTarWithEnv(t *testing.T) { require.NoError(t, err) // Compare want and got - compareReports(t, tt.golden, outputFile) + compareReports(t, tt.golden, outputFile, nil) }) } } @@ -588,7 +588,7 @@ cache: require.NoError(t, err) // Compare want and got - compareReports(t, tt.golden, outputFile) + compareReports(t, tt.golden, outputFile, nil) }) } } diff --git a/integration/testdata/cocoapods.json.golden b/integration/testdata/cocoapods.json.golden index 34a5838f72ce..5d66b7a6786a 100644 --- a/integration/testdata/cocoapods.json.golden +++ b/integration/testdata/cocoapods.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/cocoapods", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/cocoapods", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/composer.lock.json.golden b/integration/testdata/composer.lock.json.golden index 88a7c4203f8d..0b5947077c42 100644 --- a/integration/testdata/composer.lock.json.golden +++ b/integration/testdata/composer.lock.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/composer", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/composer", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/conan.json.golden b/integration/testdata/conan.json.golden index b7be6556c1b6..33040c5bd2d8 100644 --- a/integration/testdata/conan.json.golden +++ b/integration/testdata/conan.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/conan", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/conan", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/conda-cyclonedx.json.golden b/integration/testdata/conda-cyclonedx.json.golden index 94a52ee3e0f3..7523d4132ae2 100644 --- a/integration/testdata/conda-cyclonedx.json.golden +++ b/integration/testdata/conda-cyclonedx.json.golden @@ -15,7 +15,7 @@ "component": { "bom-ref": "cd0ebb00-5c53-4b82-a3f7-271add663c51", "type": "application", - "name": "testdata/fixtures/fs/conda", + "name": "testdata/fixtures/repo/conda", "properties": [ { "name": "aquasecurity:trivy:SchemaVersion", diff --git a/integration/testdata/conda-spdx.json.golden b/integration/testdata/conda-spdx.json.golden index 2afefc508e65..59f288a94527 100644 --- a/integration/testdata/conda-spdx.json.golden +++ b/integration/testdata/conda-spdx.json.golden @@ -2,8 +2,8 @@ "spdxVersion": "SPDX-2.3", "dataLicense": "CC0-1.0", "SPDXID": "SPDXRef-DOCUMENT", - "name": "testdata/fixtures/fs/conda", - "documentNamespace": "http://aquasecurity.github.io/trivy/filesystem/testdata/fixtures/fs/conda-2738b2fe-b40c-4ecb-b8ae-5b3cc4cbc004", + "name": "testdata/fixtures/repo/conda", + "documentNamespace": "http://aquasecurity.github.io/trivy/filesystem/testdata/fixtures/repo/conda-08df146c-0996-4718-8648-b2a45769ab79", "creationInfo": { "licenseListVersion": "", "creators": [ @@ -58,8 +58,8 @@ "primaryPackagePurpose": "LIBRARY" }, { - "name": "testdata/fixtures/fs/conda", - "SPDXID": "SPDXRef-Filesystem-6e0ac6a0fab50ab4", + "name": "testdata/fixtures/repo/conda", + "SPDXID": "SPDXRef-Filesystem-2e2426fd0f2580ef", "downloadLocation": "NONE", "copyrightText": "", "attributionTexts": [ @@ -95,11 +95,11 @@ "relationships": [ { "spdxElementId": "SPDXRef-DOCUMENT", - "relatedSpdxElement": "SPDXRef-Filesystem-6e0ac6a0fab50ab4", + "relatedSpdxElement": "SPDXRef-Filesystem-2e2426fd0f2580ef", "relationshipType": "DESCRIBES" }, { - "spdxElementId": "SPDXRef-Filesystem-6e0ac6a0fab50ab4", + "spdxElementId": "SPDXRef-Filesystem-2e2426fd0f2580ef", "relatedSpdxElement": "SPDXRef-Application-ee5ef1aa4ac89125", "relationshipType": "CONTAINS" }, diff --git a/integration/testdata/dockerfile-custom-policies.json.golden b/integration/testdata/dockerfile-custom-policies.json.golden index 8c39a79c5a82..cbe02296668c 100644 --- a/integration/testdata/dockerfile-custom-policies.json.golden +++ b/integration/testdata/dockerfile-custom-policies.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/custom-policy", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/custom-policy", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/dockerfile-namespace-exception.json.golden b/integration/testdata/dockerfile-namespace-exception.json.golden index 63ae3d86eced..0f3427d8c289 100644 --- a/integration/testdata/dockerfile-namespace-exception.json.golden +++ b/integration/testdata/dockerfile-namespace-exception.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/namespace-exception", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/namespace-exception", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/dockerfile-rule-exception.json.golden b/integration/testdata/dockerfile-rule-exception.json.golden index b152252c66d3..1507a4af950f 100644 --- a/integration/testdata/dockerfile-rule-exception.json.golden +++ b/integration/testdata/dockerfile-rule-exception.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/rule-exception", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/rule-exception", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/dockerfile.json.golden b/integration/testdata/dockerfile.json.golden index 0b753f0fe55a..4dc5cb289f74 100644 --- a/integration/testdata/dockerfile.json.golden +++ b/integration/testdata/dockerfile.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/dockerfile", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/dockerfile", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/dockerfile_file_pattern.json.golden b/integration/testdata/dockerfile_file_pattern.json.golden index 01734f42b507..c50361b7934f 100644 --- a/integration/testdata/dockerfile_file_pattern.json.golden +++ b/integration/testdata/dockerfile_file_pattern.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/dockerfile_file_pattern", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/dockerfile_file_pattern", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/dotnet.json.golden b/integration/testdata/dotnet.json.golden index 7a765f6fc578..a822c8940c72 100644 --- a/integration/testdata/dotnet.json.golden +++ b/integration/testdata/dotnet.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/dotnet", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/dotnet", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/fixtures/fs/cocoapods/Podfile.lock b/integration/testdata/fixtures/repo/cocoapods/Podfile.lock similarity index 100% rename from integration/testdata/fixtures/fs/cocoapods/Podfile.lock rename to integration/testdata/fixtures/repo/cocoapods/Podfile.lock diff --git a/integration/testdata/fixtures/fs/composer/composer.json b/integration/testdata/fixtures/repo/composer/composer.json similarity index 100% rename from integration/testdata/fixtures/fs/composer/composer.json rename to integration/testdata/fixtures/repo/composer/composer.json diff --git a/integration/testdata/fixtures/fs/composer/composer.lock b/integration/testdata/fixtures/repo/composer/composer.lock similarity index 100% rename from integration/testdata/fixtures/fs/composer/composer.lock rename to integration/testdata/fixtures/repo/composer/composer.lock diff --git a/integration/testdata/fixtures/fs/conan/conan.lock b/integration/testdata/fixtures/repo/conan/conan.lock similarity index 100% rename from integration/testdata/fixtures/fs/conan/conan.lock rename to integration/testdata/fixtures/repo/conan/conan.lock diff --git a/integration/testdata/fixtures/fs/conda/miniconda3/envs/testenv/conda-meta/openssl-1.1.1q-h7f8727e_0.json b/integration/testdata/fixtures/repo/conda/miniconda3/envs/testenv/conda-meta/openssl-1.1.1q-h7f8727e_0.json similarity index 100% rename from integration/testdata/fixtures/fs/conda/miniconda3/envs/testenv/conda-meta/openssl-1.1.1q-h7f8727e_0.json rename to integration/testdata/fixtures/repo/conda/miniconda3/envs/testenv/conda-meta/openssl-1.1.1q-h7f8727e_0.json diff --git a/integration/testdata/fixtures/fs/conda/miniconda3/envs/testenv/conda-meta/pip-22.2.2-py38h06a4308_0.json b/integration/testdata/fixtures/repo/conda/miniconda3/envs/testenv/conda-meta/pip-22.2.2-py38h06a4308_0.json similarity index 100% rename from integration/testdata/fixtures/fs/conda/miniconda3/envs/testenv/conda-meta/pip-22.2.2-py38h06a4308_0.json rename to integration/testdata/fixtures/repo/conda/miniconda3/envs/testenv/conda-meta/pip-22.2.2-py38h06a4308_0.json diff --git a/integration/testdata/fixtures/fs/custom-policy/Dockerfile b/integration/testdata/fixtures/repo/custom-policy/Dockerfile similarity index 100% rename from integration/testdata/fixtures/fs/custom-policy/Dockerfile rename to integration/testdata/fixtures/repo/custom-policy/Dockerfile diff --git a/integration/testdata/fixtures/fs/custom-policy/policy/bar.rego b/integration/testdata/fixtures/repo/custom-policy/policy/bar.rego similarity index 100% rename from integration/testdata/fixtures/fs/custom-policy/policy/bar.rego rename to integration/testdata/fixtures/repo/custom-policy/policy/bar.rego diff --git a/integration/testdata/fixtures/fs/custom-policy/policy/foo.rego b/integration/testdata/fixtures/repo/custom-policy/policy/foo.rego similarity index 100% rename from integration/testdata/fixtures/fs/custom-policy/policy/foo.rego rename to integration/testdata/fixtures/repo/custom-policy/policy/foo.rego diff --git a/integration/testdata/fixtures/fs/dockerfile/Dockerfile b/integration/testdata/fixtures/repo/dockerfile/Dockerfile similarity index 100% rename from integration/testdata/fixtures/fs/dockerfile/Dockerfile rename to integration/testdata/fixtures/repo/dockerfile/Dockerfile diff --git a/integration/testdata/fixtures/fs/dockerfile_file_pattern/Customfile b/integration/testdata/fixtures/repo/dockerfile_file_pattern/Customfile similarity index 100% rename from integration/testdata/fixtures/fs/dockerfile_file_pattern/Customfile rename to integration/testdata/fixtures/repo/dockerfile_file_pattern/Customfile diff --git a/integration/testdata/fixtures/fs/dotnet/datacollector.deps.json b/integration/testdata/fixtures/repo/dotnet/datacollector.deps.json similarity index 100% rename from integration/testdata/fixtures/fs/dotnet/datacollector.deps.json rename to integration/testdata/fixtures/repo/dotnet/datacollector.deps.json diff --git a/integration/testdata/fixtures/fs/gomod/go.mod b/integration/testdata/fixtures/repo/gomod/go.mod similarity index 100% rename from integration/testdata/fixtures/fs/gomod/go.mod rename to integration/testdata/fixtures/repo/gomod/go.mod diff --git a/integration/testdata/fixtures/fs/gomod/go.sum b/integration/testdata/fixtures/repo/gomod/go.sum similarity index 100% rename from integration/testdata/fixtures/fs/gomod/go.sum rename to integration/testdata/fixtures/repo/gomod/go.sum diff --git a/integration/testdata/fixtures/fs/gomod/submod/go.mod b/integration/testdata/fixtures/repo/gomod/submod/go.mod similarity index 100% rename from integration/testdata/fixtures/fs/gomod/submod/go.mod rename to integration/testdata/fixtures/repo/gomod/submod/go.mod diff --git a/integration/testdata/fixtures/fs/gomod/submod/go.sum b/integration/testdata/fixtures/repo/gomod/submod/go.sum similarity index 85% rename from integration/testdata/fixtures/fs/gomod/submod/go.sum rename to integration/testdata/fixtures/repo/gomod/submod/go.sum index fc497bf927f2..38efa1d61ad4 100644 --- a/integration/testdata/fixtures/fs/gomod/submod/go.sum +++ b/integration/testdata/fixtures/repo/gomod/submod/go.sum @@ -1,4 +1,5 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -7,4 +8,4 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= \ No newline at end of file +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/integration/testdata/fixtures/fs/gomod/submod2/go.mod b/integration/testdata/fixtures/repo/gomod/submod2/go.mod similarity index 100% rename from integration/testdata/fixtures/fs/gomod/submod2/go.mod rename to integration/testdata/fixtures/repo/gomod/submod2/go.mod diff --git a/integration/testdata/fixtures/fs/gomod/submod2/go.sum b/integration/testdata/fixtures/repo/gomod/submod2/go.sum similarity index 100% rename from integration/testdata/fixtures/fs/gomod/submod2/go.sum rename to integration/testdata/fixtures/repo/gomod/submod2/go.sum diff --git a/integration/testdata/fixtures/fs/gradle/gradle.lockfile b/integration/testdata/fixtures/repo/gradle/gradle.lockfile similarity index 100% rename from integration/testdata/fixtures/fs/gradle/gradle.lockfile rename to integration/testdata/fixtures/repo/gradle/gradle.lockfile diff --git a/integration/testdata/fixtures/fs/helm/testchart.tar.gz b/integration/testdata/fixtures/repo/helm/testchart.tar.gz similarity index 100% rename from integration/testdata/fixtures/fs/helm/testchart.tar.gz rename to integration/testdata/fixtures/repo/helm/testchart.tar.gz diff --git a/integration/testdata/fixtures/fs/helm_badname/Chart.yaml b/integration/testdata/fixtures/repo/helm_badname/Chart.yaml similarity index 100% rename from integration/testdata/fixtures/fs/helm_badname/Chart.yaml rename to integration/testdata/fixtures/repo/helm_badname/Chart.yaml diff --git a/integration/testdata/fixtures/fs/helm_testchart/.helmignore b/integration/testdata/fixtures/repo/helm_testchart/.helmignore similarity index 100% rename from integration/testdata/fixtures/fs/helm_testchart/.helmignore rename to integration/testdata/fixtures/repo/helm_testchart/.helmignore diff --git a/integration/testdata/fixtures/fs/helm_testchart/Chart.yaml b/integration/testdata/fixtures/repo/helm_testchart/Chart.yaml similarity index 100% rename from integration/testdata/fixtures/fs/helm_testchart/Chart.yaml rename to integration/testdata/fixtures/repo/helm_testchart/Chart.yaml diff --git a/integration/testdata/fixtures/fs/helm_testchart/templates/NOTES.txt b/integration/testdata/fixtures/repo/helm_testchart/templates/NOTES.txt similarity index 100% rename from integration/testdata/fixtures/fs/helm_testchart/templates/NOTES.txt rename to integration/testdata/fixtures/repo/helm_testchart/templates/NOTES.txt diff --git a/integration/testdata/fixtures/fs/helm_testchart/templates/_helpers.tpl b/integration/testdata/fixtures/repo/helm_testchart/templates/_helpers.tpl similarity index 100% rename from integration/testdata/fixtures/fs/helm_testchart/templates/_helpers.tpl rename to integration/testdata/fixtures/repo/helm_testchart/templates/_helpers.tpl diff --git a/integration/testdata/fixtures/fs/helm_testchart/templates/deployment.yaml b/integration/testdata/fixtures/repo/helm_testchart/templates/deployment.yaml similarity index 100% rename from integration/testdata/fixtures/fs/helm_testchart/templates/deployment.yaml rename to integration/testdata/fixtures/repo/helm_testchart/templates/deployment.yaml diff --git a/integration/testdata/fixtures/fs/helm_testchart/templates/hpa.yaml b/integration/testdata/fixtures/repo/helm_testchart/templates/hpa.yaml similarity index 100% rename from integration/testdata/fixtures/fs/helm_testchart/templates/hpa.yaml rename to integration/testdata/fixtures/repo/helm_testchart/templates/hpa.yaml diff --git a/integration/testdata/fixtures/fs/helm_testchart/templates/ingress.yaml b/integration/testdata/fixtures/repo/helm_testchart/templates/ingress.yaml similarity index 100% rename from integration/testdata/fixtures/fs/helm_testchart/templates/ingress.yaml rename to integration/testdata/fixtures/repo/helm_testchart/templates/ingress.yaml diff --git a/integration/testdata/fixtures/fs/helm_testchart/templates/service.yaml b/integration/testdata/fixtures/repo/helm_testchart/templates/service.yaml similarity index 100% rename from integration/testdata/fixtures/fs/helm_testchart/templates/service.yaml rename to integration/testdata/fixtures/repo/helm_testchart/templates/service.yaml diff --git a/integration/testdata/fixtures/fs/helm_testchart/templates/serviceaccount.yaml b/integration/testdata/fixtures/repo/helm_testchart/templates/serviceaccount.yaml similarity index 100% rename from integration/testdata/fixtures/fs/helm_testchart/templates/serviceaccount.yaml rename to integration/testdata/fixtures/repo/helm_testchart/templates/serviceaccount.yaml diff --git a/integration/testdata/fixtures/fs/helm_testchart/templates/tests/test-connection.yaml b/integration/testdata/fixtures/repo/helm_testchart/templates/tests/test-connection.yaml similarity index 100% rename from integration/testdata/fixtures/fs/helm_testchart/templates/tests/test-connection.yaml rename to integration/testdata/fixtures/repo/helm_testchart/templates/tests/test-connection.yaml diff --git a/integration/testdata/fixtures/fs/helm_testchart/values.yaml b/integration/testdata/fixtures/repo/helm_testchart/values.yaml similarity index 100% rename from integration/testdata/fixtures/fs/helm_testchart/values.yaml rename to integration/testdata/fixtures/repo/helm_testchart/values.yaml diff --git a/integration/testdata/fixtures/fs/helm_values/values.yaml b/integration/testdata/fixtures/repo/helm_values/values.yaml similarity index 100% rename from integration/testdata/fixtures/fs/helm_values/values.yaml rename to integration/testdata/fixtures/repo/helm_values/values.yaml diff --git a/integration/testdata/fixtures/fs/mixlock/mix.lock b/integration/testdata/fixtures/repo/mixlock/mix.lock similarity index 100% rename from integration/testdata/fixtures/fs/mixlock/mix.lock rename to integration/testdata/fixtures/repo/mixlock/mix.lock diff --git a/integration/testdata/fixtures/fs/namespace-exception/Dockerfile b/integration/testdata/fixtures/repo/namespace-exception/Dockerfile similarity index 100% rename from integration/testdata/fixtures/fs/namespace-exception/Dockerfile rename to integration/testdata/fixtures/repo/namespace-exception/Dockerfile diff --git a/integration/testdata/fixtures/fs/namespace-exception/policy/exception.rego b/integration/testdata/fixtures/repo/namespace-exception/policy/exception.rego similarity index 100% rename from integration/testdata/fixtures/fs/namespace-exception/policy/exception.rego rename to integration/testdata/fixtures/repo/namespace-exception/policy/exception.rego diff --git a/integration/testdata/fixtures/fs/npm/node_modules/jquery/package.json b/integration/testdata/fixtures/repo/npm/node_modules/jquery/package.json similarity index 100% rename from integration/testdata/fixtures/fs/npm/node_modules/jquery/package.json rename to integration/testdata/fixtures/repo/npm/node_modules/jquery/package.json diff --git a/integration/testdata/fixtures/fs/npm/node_modules/promise/package.json b/integration/testdata/fixtures/repo/npm/node_modules/promise/package.json similarity index 100% rename from integration/testdata/fixtures/fs/npm/node_modules/promise/package.json rename to integration/testdata/fixtures/repo/npm/node_modules/promise/package.json diff --git a/integration/testdata/fixtures/fs/npm/node_modules/react-is/package.json b/integration/testdata/fixtures/repo/npm/node_modules/react-is/package.json similarity index 100% rename from integration/testdata/fixtures/fs/npm/node_modules/react-is/package.json rename to integration/testdata/fixtures/repo/npm/node_modules/react-is/package.json diff --git a/integration/testdata/fixtures/fs/npm/node_modules/react/package.json b/integration/testdata/fixtures/repo/npm/node_modules/react/package.json similarity index 100% rename from integration/testdata/fixtures/fs/npm/node_modules/react/package.json rename to integration/testdata/fixtures/repo/npm/node_modules/react/package.json diff --git a/integration/testdata/fixtures/fs/npm/node_modules/redux/package.json b/integration/testdata/fixtures/repo/npm/node_modules/redux/package.json similarity index 100% rename from integration/testdata/fixtures/fs/npm/node_modules/redux/package.json rename to integration/testdata/fixtures/repo/npm/node_modules/redux/package.json diff --git a/integration/testdata/fixtures/fs/npm/node_modules/z-lock/package.json b/integration/testdata/fixtures/repo/npm/node_modules/z-lock/package.json similarity index 100% rename from integration/testdata/fixtures/fs/npm/node_modules/z-lock/package.json rename to integration/testdata/fixtures/repo/npm/node_modules/z-lock/package.json diff --git a/integration/testdata/fixtures/fs/npm/package-lock.json b/integration/testdata/fixtures/repo/npm/package-lock.json similarity index 100% rename from integration/testdata/fixtures/fs/npm/package-lock.json rename to integration/testdata/fixtures/repo/npm/package-lock.json diff --git a/integration/testdata/fixtures/fs/nuget/packages.lock.json b/integration/testdata/fixtures/repo/nuget/packages.lock.json similarity index 100% rename from integration/testdata/fixtures/fs/nuget/packages.lock.json rename to integration/testdata/fixtures/repo/nuget/packages.lock.json diff --git a/integration/testdata/fixtures/fs/pip/requirements.txt b/integration/testdata/fixtures/repo/pip/requirements.txt similarity index 100% rename from integration/testdata/fixtures/fs/pip/requirements.txt rename to integration/testdata/fixtures/repo/pip/requirements.txt diff --git a/integration/testdata/fixtures/fs/pipenv/Pipfile.lock b/integration/testdata/fixtures/repo/pipenv/Pipfile.lock similarity index 100% rename from integration/testdata/fixtures/fs/pipenv/Pipfile.lock rename to integration/testdata/fixtures/repo/pipenv/Pipfile.lock diff --git a/integration/testdata/fixtures/fs/pnpm/pnpm-lock.yaml b/integration/testdata/fixtures/repo/pnpm/pnpm-lock.yaml similarity index 100% rename from integration/testdata/fixtures/fs/pnpm/pnpm-lock.yaml rename to integration/testdata/fixtures/repo/pnpm/pnpm-lock.yaml diff --git a/integration/testdata/fixtures/fs/poetry/poetry.lock b/integration/testdata/fixtures/repo/poetry/poetry.lock similarity index 100% rename from integration/testdata/fixtures/fs/poetry/poetry.lock rename to integration/testdata/fixtures/repo/poetry/poetry.lock diff --git a/integration/testdata/fixtures/fs/poetry/pyproject.toml b/integration/testdata/fixtures/repo/poetry/pyproject.toml similarity index 100% rename from integration/testdata/fixtures/fs/poetry/pyproject.toml rename to integration/testdata/fixtures/repo/poetry/pyproject.toml diff --git a/integration/testdata/fixtures/fs/pom/pom.xml b/integration/testdata/fixtures/repo/pom/pom.xml similarity index 100% rename from integration/testdata/fixtures/fs/pom/pom.xml rename to integration/testdata/fixtures/repo/pom/pom.xml diff --git a/integration/testdata/fixtures/fs/pubspec/pubspec.lock b/integration/testdata/fixtures/repo/pubspec/pubspec.lock similarity index 100% rename from integration/testdata/fixtures/fs/pubspec/pubspec.lock rename to integration/testdata/fixtures/repo/pubspec/pubspec.lock diff --git a/integration/testdata/fixtures/fs/rule-exception/Dockerfile b/integration/testdata/fixtures/repo/rule-exception/Dockerfile similarity index 100% rename from integration/testdata/fixtures/fs/rule-exception/Dockerfile rename to integration/testdata/fixtures/repo/rule-exception/Dockerfile diff --git a/integration/testdata/fixtures/fs/rule-exception/policy/exception.rego b/integration/testdata/fixtures/repo/rule-exception/policy/exception.rego similarity index 100% rename from integration/testdata/fixtures/fs/rule-exception/policy/exception.rego rename to integration/testdata/fixtures/repo/rule-exception/policy/exception.rego diff --git a/integration/testdata/fixtures/fs/secrets/deploy.sh b/integration/testdata/fixtures/repo/secrets/deploy.sh similarity index 100% rename from integration/testdata/fixtures/fs/secrets/deploy.sh rename to integration/testdata/fixtures/repo/secrets/deploy.sh diff --git a/integration/testdata/fixtures/fs/secrets/trivy-secret.yaml b/integration/testdata/fixtures/repo/secrets/trivy-secret.yaml similarity index 100% rename from integration/testdata/fixtures/fs/secrets/trivy-secret.yaml rename to integration/testdata/fixtures/repo/secrets/trivy-secret.yaml diff --git a/integration/testdata/fixtures/fs/yarn/package.json b/integration/testdata/fixtures/repo/yarn/package.json similarity index 100% rename from integration/testdata/fixtures/fs/yarn/package.json rename to integration/testdata/fixtures/repo/yarn/package.json diff --git a/integration/testdata/fixtures/fs/yarn/yarn.lock b/integration/testdata/fixtures/repo/yarn/yarn.lock similarity index 100% rename from integration/testdata/fixtures/fs/yarn/yarn.lock rename to integration/testdata/fixtures/repo/yarn/yarn.lock diff --git a/integration/testdata/gomod-skip.json.golden b/integration/testdata/gomod-skip.json.golden index 716e6381fa69..1dfd67938b7e 100644 --- a/integration/testdata/gomod-skip.json.golden +++ b/integration/testdata/gomod-skip.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/gomod", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/gomod", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/gomod.json.golden b/integration/testdata/gomod.json.golden index c7280a8de15c..30cee57c31ab 100644 --- a/integration/testdata/gomod.json.golden +++ b/integration/testdata/gomod.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/gomod", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/gomod", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/gradle.json.golden b/integration/testdata/gradle.json.golden index a8b5251c894c..a7cb4347977b 100644 --- a/integration/testdata/gradle.json.golden +++ b/integration/testdata/gradle.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/gradle", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/gradle", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/helm.json.golden b/integration/testdata/helm.json.golden index e613367ff782..3adc156ddad1 100644 --- a/integration/testdata/helm.json.golden +++ b/integration/testdata/helm.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/helm", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/helm", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/helm_badname.json.golden b/integration/testdata/helm_badname.json.golden index c485ec3af720..9ca547ffbbd4 100644 --- a/integration/testdata/helm_badname.json.golden +++ b/integration/testdata/helm_badname.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/helm_badname", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/helm_badname", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/helm_testchart.json.golden b/integration/testdata/helm_testchart.json.golden index 0314f93a748b..8f3c0ebdc678 100644 --- a/integration/testdata/helm_testchart.json.golden +++ b/integration/testdata/helm_testchart.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/helm_testchart", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/helm_testchart", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/helm_testchart.overridden.json.golden b/integration/testdata/helm_testchart.overridden.json.golden index fa6ad076116e..0d5e28dc638e 100644 --- a/integration/testdata/helm_testchart.overridden.json.golden +++ b/integration/testdata/helm_testchart.overridden.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/helm_testchart", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/helm_testchart", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/mix.lock.json.golden b/integration/testdata/mix.lock.json.golden index 10b08c5a90b3..bb558515422c 100644 --- a/integration/testdata/mix.lock.json.golden +++ b/integration/testdata/mix.lock.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/mixlock", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/mixlock", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/npm-with-dev.json.golden b/integration/testdata/npm-with-dev.json.golden index aa460f5ea53b..0b69c7067f27 100644 --- a/integration/testdata/npm-with-dev.json.golden +++ b/integration/testdata/npm-with-dev.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/npm", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/npm", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/npm.json.golden b/integration/testdata/npm.json.golden index 3a0e9583c373..3afbd63c5ceb 100644 --- a/integration/testdata/npm.json.golden +++ b/integration/testdata/npm.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/npm", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/npm", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/nuget.json.golden b/integration/testdata/nuget.json.golden index eab5daf99660..5a38c64b0a4b 100644 --- a/integration/testdata/nuget.json.golden +++ b/integration/testdata/nuget.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/nuget", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/nuget", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/pip.json.golden b/integration/testdata/pip.json.golden index 8d43fa84a6c6..01eaa3f295e1 100644 --- a/integration/testdata/pip.json.golden +++ b/integration/testdata/pip.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/pip", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/pip", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/pipenv.json.golden b/integration/testdata/pipenv.json.golden index d5d4205e6470..663a4f247444 100644 --- a/integration/testdata/pipenv.json.golden +++ b/integration/testdata/pipenv.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/pipenv", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/pipenv", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/pnpm.json.golden b/integration/testdata/pnpm.json.golden index aa1446284052..5f79165b34d0 100644 --- a/integration/testdata/pnpm.json.golden +++ b/integration/testdata/pnpm.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/pnpm", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/pnpm", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/poetry.json.golden b/integration/testdata/poetry.json.golden index 8572eded2e44..00a7c902e4a7 100644 --- a/integration/testdata/poetry.json.golden +++ b/integration/testdata/poetry.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/poetry", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/poetry", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/pom.json.golden b/integration/testdata/pom.json.golden index 1371f2a6d3af..731cb86bf028 100644 --- a/integration/testdata/pom.json.golden +++ b/integration/testdata/pom.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/pom", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/pom", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/pubspec.lock.json.golden b/integration/testdata/pubspec.lock.json.golden index 1180f08218c2..05ff31de633b 100644 --- a/integration/testdata/pubspec.lock.json.golden +++ b/integration/testdata/pubspec.lock.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/pubspec", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/pubspec", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/secrets.json.golden b/integration/testdata/secrets.json.golden index c982894967b8..10f7d03bcb2d 100644 --- a/integration/testdata/secrets.json.golden +++ b/integration/testdata/secrets.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/secrets", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/secrets", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/testdata/yarn.json.golden b/integration/testdata/yarn.json.golden index 821a6710c541..d24ef72905b1 100644 --- a/integration/testdata/yarn.json.golden +++ b/integration/testdata/yarn.json.golden @@ -1,7 +1,7 @@ { "SchemaVersion": 2, - "ArtifactName": "testdata/fixtures/fs/yarn", - "ArtifactType": "filesystem", + "ArtifactName": "testdata/fixtures/repo/yarn", + "ArtifactType": "repository", "Metadata": { "ImageConfig": { "architecture": "", diff --git a/integration/vm_test.go b/integration/vm_test.go index d17c0364f28d..fab87cc070a2 100644 --- a/integration/vm_test.go +++ b/integration/vm_test.go @@ -113,7 +113,7 @@ func TestVM(t *testing.T) { // Run "trivy vm" err = execute(osArgs) require.NoError(t, err) - compareReports(t, goldenFile, outputFile) + compareReports(t, goldenFile, outputFile, nil) }) } } diff --git a/mkdocs.yml b/mkdocs.yml index dbfff44ea83b..191578c2664d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -42,7 +42,7 @@ nav: - Container Image: docs/target/container_image.md - Filesystem: docs/target/filesystem.md - Rootfs: docs/target/rootfs.md - - Git Repository: docs/target/git-repository.md + - Code Repository: docs/target/repository.md - Virtual Machine Image: docs/target/vm.md - Kubernetes: docs/target/kubernetes.md - AWS: docs/target/aws.md diff --git a/pkg/commands/artifact/wire_gen.go b/pkg/commands/artifact/wire_gen.go index 280d7a411bd0..9f89dca066d8 100644 --- a/pkg/commands/artifact/wire_gen.go +++ b/pkg/commands/artifact/wire_gen.go @@ -13,7 +13,7 @@ import ( "github.com/aquasecurity/trivy/pkg/fanal/artifact" image2 "github.com/aquasecurity/trivy/pkg/fanal/artifact/image" local2 "github.com/aquasecurity/trivy/pkg/fanal/artifact/local" - "github.com/aquasecurity/trivy/pkg/fanal/artifact/remote" + "github.com/aquasecurity/trivy/pkg/fanal/artifact/repo" "github.com/aquasecurity/trivy/pkg/fanal/artifact/sbom" "github.com/aquasecurity/trivy/pkg/fanal/artifact/vm" "github.com/aquasecurity/trivy/pkg/fanal/cache" @@ -98,7 +98,7 @@ func initializeRepositoryScanner(ctx context.Context, url string, artifactCache config := db.Config{} client := vulnerability.NewClient(config) localScanner := local.NewScanner(applierApplier, ospkgScanner, langpkgScanner, client) - artifactArtifact, cleanup, err := remote.NewArtifact(url, artifactCache, artifactOption) + artifactArtifact, cleanup, err := repo.NewArtifact(url, artifactCache, artifactOption) if err != nil { return scanner.Scanner{}, nil, err } @@ -198,7 +198,7 @@ func initializeRemoteFilesystemScanner(ctx context.Context, path string, artifac func initializeRemoteRepositoryScanner(ctx context.Context, url string, artifactCache cache.ArtifactCache, remoteScanOptions client.ScannerOption, artifactOption artifact.Option) (scanner.Scanner, func(), error) { v := _wireValue clientScanner := client.NewScanner(remoteScanOptions, v...) - artifactArtifact, cleanup, err := remote.NewArtifact(url, artifactCache, artifactOption) + artifactArtifact, cleanup, err := repo.NewArtifact(url, artifactCache, artifactOption) if err != nil { return scanner.Scanner{}, nil, err } diff --git a/pkg/fanal/artifact/remote/git.go b/pkg/fanal/artifact/repo/git.go similarity index 64% rename from pkg/fanal/artifact/remote/git.go rename to pkg/fanal/artifact/repo/git.go index 34d5b1c439ce..de1a528f65dc 100644 --- a/pkg/fanal/artifact/remote/git.go +++ b/pkg/fanal/artifact/repo/git.go @@ -1,4 +1,4 @@ -package remote +package repo import ( "context" @@ -8,6 +8,7 @@ import ( "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/transport/http" + "github.com/hashicorp/go-multierror" "golang.org/x/xerrors" "github.com/aquasecurity/trivy/pkg/fanal/artifact" @@ -21,20 +22,94 @@ type Artifact struct { local artifact.Artifact } -func NewArtifact(rawurl string, c cache.ArtifactCache, artifactOpt artifact.Option) ( +func NewArtifact(target string, c cache.ArtifactCache, artifactOpt artifact.Option) ( artifact.Artifact, func(), error) { - cleanup := func() {} - u, err := newURL(rawurl) + var cleanup func() + var errs error + + // Try the local repository + art, err := tryLocalRepo(target, c, artifactOpt) + if err == nil { + return art, func() {}, nil + } + errs = multierror.Append(errs, err) + + // Try the remote git repository + art, cleanup, err = tryRemoteRepo(target, c, artifactOpt) + if err == nil { + return art, cleanup, nil + } + errs = multierror.Append(errs, err) + + // Return errors + return nil, cleanup, errs +} + +func (a Artifact) Inspect(ctx context.Context) (types.ArtifactReference, error) { + ref, err := a.local.Inspect(ctx) if err != nil { - return nil, cleanup, err + return types.ArtifactReference{}, xerrors.Errorf("remote repository error: %w", err) } - tmpDir, err := os.MkdirTemp("", "fanal-remote") + if a.url != "" { + ref.Name = a.url + } + ref.Type = types.ArtifactRepository + + return ref, nil +} + +func (Artifact) Clean(_ types.ArtifactReference) error { + return nil +} + +func tryLocalRepo(target string, c cache.ArtifactCache, artifactOpt artifact.Option) (artifact.Artifact, error) { + if _, err := os.Stat(target); err != nil { + return nil, xerrors.Errorf("no such path: %w", err) + } + + art, err := local.NewArtifact(target, c, artifactOpt) + if err != nil { + return nil, xerrors.Errorf("local repo artifact error: %w", err) + } + return Artifact{ + local: art, + }, nil +} + +func tryRemoteRepo(target string, c cache.ArtifactCache, artifactOpt artifact.Option) (artifact.Artifact, func(), error) { + cleanup := func() {} + u, err := newURL(target) if err != nil { return nil, cleanup, err } + tmpDir, err := cloneRepo(u, artifactOpt) + if err != nil { + return nil, cleanup, xerrors.Errorf("repository clone error: %w", err) + } + + cleanup = func() { _ = os.RemoveAll(tmpDir) } + + art, err := local.NewArtifact(tmpDir, c, artifactOpt) + if err != nil { + return nil, cleanup, xerrors.Errorf("fs artifact: %w", err) + } + + return Artifact{ + url: target, + local: art, + }, cleanup, nil + +} + +func cloneRepo(u *url.URL, artifactOpt artifact.Option) (string, error) { + tmpDir, err := os.MkdirTemp("", "trivy-remote-repo") + if err != nil { + return "", xerrors.Errorf("failed to create a temp dir: %w", err) + } + cloneOptions := git.CloneOptions{ URL: u.String(), Auth: gitAuth(), @@ -63,52 +138,24 @@ func NewArtifact(rawurl string, c cache.ArtifactCache, artifactOpt artifact.Opti r, err := git.PlainClone(tmpDir, false, &cloneOptions) if err != nil { - return nil, cleanup, xerrors.Errorf("git clone error: %w", err) + return "", xerrors.Errorf("git clone error: %w", err) } if artifactOpt.RepoCommit != "" { w, err := r.Worktree() if err != nil { - return nil, cleanup, xerrors.Errorf("git worktree error: %w", err) + return "", xerrors.Errorf("git worktree error: %w", err) } err = w.Checkout(&git.CheckoutOptions{ Hash: plumbing.NewHash(artifactOpt.RepoCommit), }) if err != nil { - return nil, cleanup, xerrors.Errorf("git checkout error: %w", err) + return "", xerrors.Errorf("git checkout error: %w", err) } } - cleanup = func() { - _ = os.RemoveAll(tmpDir) - } - - art, err := local.NewArtifact(tmpDir, c, artifactOpt) - if err != nil { - return nil, cleanup, xerrors.Errorf("fs artifact: %w", err) - } - - return Artifact{ - url: rawurl, - local: art, - }, cleanup, nil -} - -func (a Artifact) Inspect(ctx context.Context) (types.ArtifactReference, error) { - ref, err := a.local.Inspect(ctx) - if err != nil { - return types.ArtifactReference{}, xerrors.Errorf("remote repository error: %w", err) - } - - ref.Name = a.url - ref.Type = types.ArtifactRemoteRepository - - return ref, nil -} - -func (Artifact) Clean(_ types.ArtifactReference) error { - return nil + return tmpDir, nil } func newURL(rawurl string) (*url.URL, error) { @@ -128,7 +175,6 @@ func newURL(rawurl string) (*url.URL, error) { // Helper function to check for a GitHub/GitLab token from env vars in order to // make authenticated requests to access private repos func gitAuth() *http.BasicAuth { - var auth *http.BasicAuth // The username can be anything for HTTPS Git operations diff --git a/pkg/fanal/artifact/remote/git_test.go b/pkg/fanal/artifact/repo/git_test.go similarity index 88% rename from pkg/fanal/artifact/remote/git_test.go rename to pkg/fanal/artifact/repo/git_test.go index e87cc50faf1c..5103ba9f2730 100644 --- a/pkg/fanal/artifact/remote/git_test.go +++ b/pkg/fanal/artifact/repo/git_test.go @@ -1,6 +1,6 @@ //go:build unix -package remote +package repo import ( "context" @@ -39,7 +39,7 @@ func TestNewArtifact(t *testing.T) { defer ts.Close() type args struct { - rawurl string + target string c cache.ArtifactCache noProgress bool repoBranch string @@ -52,9 +52,18 @@ func TestNewArtifact(t *testing.T) { assertion assert.ErrorAssertionFunc }{ { - name: "happy path", + name: "remote repo", + args: args{ + target: ts.URL + "/test.git", + c: nil, + noProgress: false, + }, + assertion: assert.NoError, + }, + { + name: "local repo", args: args{ - rawurl: ts.URL + "/test.git", + target: "testdata", c: nil, noProgress: false, }, @@ -63,7 +72,7 @@ func TestNewArtifact(t *testing.T) { { name: "happy noProgress", args: args{ - rawurl: ts.URL + "/test.git", + target: ts.URL + "/test.git", c: nil, noProgress: true, }, @@ -72,7 +81,7 @@ func TestNewArtifact(t *testing.T) { { name: "branch", args: args{ - rawurl: ts.URL + "/test.git", + target: ts.URL + "/test.git", c: nil, repoBranch: "valid-branch", }, @@ -81,7 +90,7 @@ func TestNewArtifact(t *testing.T) { { name: "tag", args: args{ - rawurl: ts.URL + "/test.git", + target: ts.URL + "/test.git", c: nil, repoTag: "v1.0.0", }, @@ -90,7 +99,7 @@ func TestNewArtifact(t *testing.T) { { name: "commit", args: args{ - rawurl: ts.URL + "/test.git", + target: ts.URL + "/test.git", c: nil, repoCommit: "6ac152fe2b87cb5e243414df71790a32912e778d", }, @@ -99,7 +108,7 @@ func TestNewArtifact(t *testing.T) { { name: "sad path", args: args{ - rawurl: ts.URL + "/unknown.git", + target: ts.URL + "/unknown.git", c: nil, noProgress: false, }, @@ -110,7 +119,7 @@ func TestNewArtifact(t *testing.T) { { name: "invalid url", args: args{ - rawurl: "ht tp://foo.com", + target: "ht tp://foo.com", c: nil, noProgress: false, }, @@ -121,7 +130,7 @@ func TestNewArtifact(t *testing.T) { { name: "invalid branch", args: args{ - rawurl: ts.URL + "/test.git", + target: ts.URL + "/test.git", c: nil, repoBranch: "invalid-branch", }, @@ -132,7 +141,7 @@ func TestNewArtifact(t *testing.T) { { name: "invalid tag", args: args{ - rawurl: ts.URL + "/test.git", + target: ts.URL + "/test.git", c: nil, repoTag: "v1.0.9", }, @@ -143,7 +152,7 @@ func TestNewArtifact(t *testing.T) { { name: "invalid commit", args: args{ - rawurl: ts.URL + "/test.git", + target: ts.URL + "/test.git", c: nil, repoCommit: "6ac152fe2b87cb5e243414df71790a32912e778e", }, @@ -155,7 +164,7 @@ func TestNewArtifact(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - _, cleanup, err := NewArtifact(tt.args.rawurl, tt.args.c, artifact.Option{ + _, cleanup, err := NewArtifact(tt.args.target, tt.args.c, artifact.Option{ NoProgress: tt.args.noProgress, RepoBranch: tt.args.repoBranch, RepoTag: tt.args.repoTag, @@ -183,7 +192,7 @@ func TestArtifact_Inspect(t *testing.T) { rawurl: ts.URL + "/test.git", want: types.ArtifactReference{ Name: ts.URL + "/test.git", - Type: types.ArtifactRemoteRepository, + Type: types.ArtifactRepository, ID: "sha256:1fa928c33b16a335015ce96e1384127f8463c4f27ed0786806a6d4584b63d091", BlobIDs: []string{ "sha256:1fa928c33b16a335015ce96e1384127f8463c4f27ed0786806a6d4584b63d091", diff --git a/pkg/fanal/artifact/remote/testdata/test.git/HEAD b/pkg/fanal/artifact/repo/testdata/test.git/HEAD similarity index 100% rename from pkg/fanal/artifact/remote/testdata/test.git/HEAD rename to pkg/fanal/artifact/repo/testdata/test.git/HEAD diff --git a/pkg/fanal/artifact/remote/testdata/test.git/config b/pkg/fanal/artifact/repo/testdata/test.git/config similarity index 100% rename from pkg/fanal/artifact/remote/testdata/test.git/config rename to pkg/fanal/artifact/repo/testdata/test.git/config diff --git a/pkg/fanal/artifact/remote/testdata/test.git/objects/0d/8bf3f07c3970b3e38c2cfb1c619cb86fae76d2 b/pkg/fanal/artifact/repo/testdata/test.git/objects/0d/8bf3f07c3970b3e38c2cfb1c619cb86fae76d2 similarity index 100% rename from pkg/fanal/artifact/remote/testdata/test.git/objects/0d/8bf3f07c3970b3e38c2cfb1c619cb86fae76d2 rename to pkg/fanal/artifact/repo/testdata/test.git/objects/0d/8bf3f07c3970b3e38c2cfb1c619cb86fae76d2 diff --git a/pkg/fanal/artifact/remote/testdata/test.git/objects/1c/1d7deed649fbecd66fab423ccd9d001bf9ff91 b/pkg/fanal/artifact/repo/testdata/test.git/objects/1c/1d7deed649fbecd66fab423ccd9d001bf9ff91 similarity index 100% rename from pkg/fanal/artifact/remote/testdata/test.git/objects/1c/1d7deed649fbecd66fab423ccd9d001bf9ff91 rename to pkg/fanal/artifact/repo/testdata/test.git/objects/1c/1d7deed649fbecd66fab423ccd9d001bf9ff91 diff --git a/pkg/fanal/artifact/remote/testdata/test.git/objects/27/aaec53f92314d9438a53c703f169d2cbf5001a b/pkg/fanal/artifact/repo/testdata/test.git/objects/27/aaec53f92314d9438a53c703f169d2cbf5001a similarity index 100% rename from pkg/fanal/artifact/remote/testdata/test.git/objects/27/aaec53f92314d9438a53c703f169d2cbf5001a rename to pkg/fanal/artifact/repo/testdata/test.git/objects/27/aaec53f92314d9438a53c703f169d2cbf5001a diff --git a/pkg/fanal/artifact/remote/testdata/test.git/objects/5e/fb9bc29c482e023e40e0a2b3b7e49cec842034 b/pkg/fanal/artifact/repo/testdata/test.git/objects/5e/fb9bc29c482e023e40e0a2b3b7e49cec842034 similarity index 100% rename from pkg/fanal/artifact/remote/testdata/test.git/objects/5e/fb9bc29c482e023e40e0a2b3b7e49cec842034 rename to pkg/fanal/artifact/repo/testdata/test.git/objects/5e/fb9bc29c482e023e40e0a2b3b7e49cec842034 diff --git a/pkg/fanal/artifact/remote/testdata/test.git/objects/6a/c152fe2b87cb5e243414df71790a32912e778d b/pkg/fanal/artifact/repo/testdata/test.git/objects/6a/c152fe2b87cb5e243414df71790a32912e778d similarity index 100% rename from pkg/fanal/artifact/remote/testdata/test.git/objects/6a/c152fe2b87cb5e243414df71790a32912e778d rename to pkg/fanal/artifact/repo/testdata/test.git/objects/6a/c152fe2b87cb5e243414df71790a32912e778d diff --git a/pkg/fanal/artifact/remote/testdata/test.git/objects/c0/42cd14d2b999cade090785af47e9f8b8e342ff b/pkg/fanal/artifact/repo/testdata/test.git/objects/c0/42cd14d2b999cade090785af47e9f8b8e342ff similarity index 100% rename from pkg/fanal/artifact/remote/testdata/test.git/objects/c0/42cd14d2b999cade090785af47e9f8b8e342ff rename to pkg/fanal/artifact/repo/testdata/test.git/objects/c0/42cd14d2b999cade090785af47e9f8b8e342ff diff --git a/pkg/fanal/artifact/remote/testdata/test.git/objects/c9/06fc4a94762f8a2c77c718947143d16e4e9ec7 b/pkg/fanal/artifact/repo/testdata/test.git/objects/c9/06fc4a94762f8a2c77c718947143d16e4e9ec7 similarity index 100% rename from pkg/fanal/artifact/remote/testdata/test.git/objects/c9/06fc4a94762f8a2c77c718947143d16e4e9ec7 rename to pkg/fanal/artifact/repo/testdata/test.git/objects/c9/06fc4a94762f8a2c77c718947143d16e4e9ec7 diff --git a/pkg/fanal/artifact/remote/testdata/test.git/objects/d7/937c5f0ce7f2054e4e3be65ab3cd0f9462dc1b b/pkg/fanal/artifact/repo/testdata/test.git/objects/d7/937c5f0ce7f2054e4e3be65ab3cd0f9462dc1b similarity index 100% rename from pkg/fanal/artifact/remote/testdata/test.git/objects/d7/937c5f0ce7f2054e4e3be65ab3cd0f9462dc1b rename to pkg/fanal/artifact/repo/testdata/test.git/objects/d7/937c5f0ce7f2054e4e3be65ab3cd0f9462dc1b diff --git a/pkg/fanal/artifact/remote/testdata/test.git/objects/e2/4866d1d31ddffdb27fbcf583d5deb4386d5145 b/pkg/fanal/artifact/repo/testdata/test.git/objects/e2/4866d1d31ddffdb27fbcf583d5deb4386d5145 similarity index 100% rename from pkg/fanal/artifact/remote/testdata/test.git/objects/e2/4866d1d31ddffdb27fbcf583d5deb4386d5145 rename to pkg/fanal/artifact/repo/testdata/test.git/objects/e2/4866d1d31ddffdb27fbcf583d5deb4386d5145 diff --git a/pkg/fanal/artifact/remote/testdata/test.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 b/pkg/fanal/artifact/repo/testdata/test.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 similarity index 100% rename from pkg/fanal/artifact/remote/testdata/test.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 rename to pkg/fanal/artifact/repo/testdata/test.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/pkg/fanal/artifact/remote/testdata/test.git/objects/f4/836be6497e83e13dc0cfbce7e6b973b1ea511d b/pkg/fanal/artifact/repo/testdata/test.git/objects/f4/836be6497e83e13dc0cfbce7e6b973b1ea511d similarity index 100% rename from pkg/fanal/artifact/remote/testdata/test.git/objects/f4/836be6497e83e13dc0cfbce7e6b973b1ea511d rename to pkg/fanal/artifact/repo/testdata/test.git/objects/f4/836be6497e83e13dc0cfbce7e6b973b1ea511d diff --git a/pkg/fanal/artifact/remote/testdata/test.git/refs/heads/master b/pkg/fanal/artifact/repo/testdata/test.git/refs/heads/master similarity index 100% rename from pkg/fanal/artifact/remote/testdata/test.git/refs/heads/master rename to pkg/fanal/artifact/repo/testdata/test.git/refs/heads/master diff --git a/pkg/fanal/artifact/remote/testdata/test.git/refs/heads/valid-branch b/pkg/fanal/artifact/repo/testdata/test.git/refs/heads/valid-branch similarity index 100% rename from pkg/fanal/artifact/remote/testdata/test.git/refs/heads/valid-branch rename to pkg/fanal/artifact/repo/testdata/test.git/refs/heads/valid-branch diff --git a/pkg/fanal/artifact/remote/testdata/test.git/refs/tags/v1.0.0 b/pkg/fanal/artifact/repo/testdata/test.git/refs/tags/v1.0.0 similarity index 100% rename from pkg/fanal/artifact/remote/testdata/test.git/refs/tags/v1.0.0 rename to pkg/fanal/artifact/repo/testdata/test.git/refs/tags/v1.0.0 diff --git a/pkg/fanal/types/artifact.go b/pkg/fanal/types/artifact.go index f3487eee5316..57e94d93dd71 100644 --- a/pkg/fanal/types/artifact.go +++ b/pkg/fanal/types/artifact.go @@ -185,13 +185,13 @@ type File struct { type ArtifactType string const ( - ArtifactContainerImage ArtifactType = "container_image" - ArtifactFilesystem ArtifactType = "filesystem" - ArtifactRemoteRepository ArtifactType = "repository" - ArtifactCycloneDX ArtifactType = "cyclonedx" - ArtifactSPDX ArtifactType = "spdx" - ArtifactAWSAccount ArtifactType = "aws_account" - ArtifactVM ArtifactType = "vm" + ArtifactContainerImage ArtifactType = "container_image" + ArtifactFilesystem ArtifactType = "filesystem" + ArtifactRepository ArtifactType = "repository" + ArtifactCycloneDX ArtifactType = "cyclonedx" + ArtifactSPDX ArtifactType = "spdx" + ArtifactAWSAccount ArtifactType = "aws_account" + ArtifactVM ArtifactType = "vm" ) // ArtifactReference represents a reference of container image, local filesystem and repository diff --git a/pkg/sbom/cyclonedx/marshal.go b/pkg/sbom/cyclonedx/marshal.go index fc562f9d7d31..035263dc8122 100644 --- a/pkg/sbom/cyclonedx/marshal.go +++ b/pkg/sbom/cyclonedx/marshal.go @@ -237,7 +237,7 @@ func (e *Marshaler) rootComponent(r types.Report) (*core.Component, error) { case ftypes.ArtifactVM: root.Type = cdx.ComponentTypeContainer - case ftypes.ArtifactFilesystem, ftypes.ArtifactRemoteRepository: + case ftypes.ArtifactFilesystem, ftypes.ArtifactRepository: root.Type = cdx.ComponentTypeApplication } diff --git a/pkg/sbom/cyclonedx/marshal_test.go b/pkg/sbom/cyclonedx/marshal_test.go index 241d9c8f3193..a7074742a0e7 100644 --- a/pkg/sbom/cyclonedx/marshal_test.go +++ b/pkg/sbom/cyclonedx/marshal_test.go @@ -1427,7 +1427,7 @@ func TestMarshaler_Marshal(t *testing.T) { inputReport: types.Report{ SchemaVersion: report.SchemaVersion, ArtifactName: "test-aggregate", - ArtifactType: ftypes.ArtifactRemoteRepository, + ArtifactType: ftypes.ArtifactRepository, Results: types.Results{ { Target: "Node.js", diff --git a/pkg/sbom/spdx/marshal.go b/pkg/sbom/spdx/marshal.go index 2d089a7d52d7..266b02f7e3c0 100644 --- a/pkg/sbom/spdx/marshal.go +++ b/pkg/sbom/spdx/marshal.go @@ -497,7 +497,7 @@ func getPackageDownloadLocation(t ftypes.ArtifactType, artifactName string) stri location := noneField // this field is used for git/mercurial/subversion/bazaar: // https://spdx.github.io/spdx-spec/v2.2.2/package-information/#77-package-download-location-field - if t == ftypes.ArtifactRemoteRepository { + if t == ftypes.ArtifactRepository { // Trivy currently only supports git repositories. Format examples: // git+https://git.myproject.org/MyProject.git // git+http://git.myproject.org/MyProject diff --git a/pkg/sbom/spdx/marshal_test.go b/pkg/sbom/spdx/marshal_test.go index 55705d297429..b889d86f12a3 100644 --- a/pkg/sbom/spdx/marshal_test.go +++ b/pkg/sbom/spdx/marshal_test.go @@ -619,7 +619,7 @@ func TestMarshaler_Marshal(t *testing.T) { inputReport: types.Report{ SchemaVersion: report.SchemaVersion, ArtifactName: "http://test-aggregate", - ArtifactType: ftypes.ArtifactRemoteRepository, + ArtifactType: ftypes.ArtifactRepository, Results: types.Results{ { Target: "Node.js", diff --git a/pkg/scanner/scan.go b/pkg/scanner/scan.go index 1b679b4a25ec..931b5b0ea035 100644 --- a/pkg/scanner/scan.go +++ b/pkg/scanner/scan.go @@ -9,7 +9,7 @@ import ( "github.com/aquasecurity/trivy/pkg/fanal/artifact" aimage "github.com/aquasecurity/trivy/pkg/fanal/artifact/image" flocal "github.com/aquasecurity/trivy/pkg/fanal/artifact/local" - "github.com/aquasecurity/trivy/pkg/fanal/artifact/remote" + "github.com/aquasecurity/trivy/pkg/fanal/artifact/repo" "github.com/aquasecurity/trivy/pkg/fanal/artifact/sbom" "github.com/aquasecurity/trivy/pkg/fanal/artifact/vm" "github.com/aquasecurity/trivy/pkg/fanal/image" @@ -54,7 +54,7 @@ var StandaloneFilesystemSet = wire.NewSet( // StandaloneRepositorySet binds repository dependencies var StandaloneRepositorySet = wire.NewSet( - remote.NewArtifact, + repo.NewArtifact, StandaloneSuperSet, ) @@ -90,7 +90,7 @@ var RemoteFilesystemSet = wire.NewSet( // RemoteRepositorySet binds repository dependencies for client/server mode var RemoteRepositorySet = wire.NewSet( - remote.NewArtifact, + repo.NewArtifact, RemoteSuperSet, ) @@ -134,7 +134,10 @@ type Driver interface { // NewScanner is the factory method of Scanner func NewScanner(driver Driver, ar artifact.Artifact) Scanner { - return Scanner{driver: driver, artifact: ar} + return Scanner{ + driver: driver, + artifact: ar, + } } // ScanArtifact scans the artifacts and returns results