mirror of
https://github.com/aquasecurity/trivy.git
synced 2025-12-05 20:40:16 -08:00
feat(java): use trivy-java-db to get GAV (#3484)
Co-authored-by: knqyf263 <knqyf263@gmail.com>
This commit is contained in:
@@ -5,6 +5,8 @@ Trivy can be used in air-gapped environments. Note that an allowlist is [here][a
|
||||
## Air-Gapped Environment for vulnerabilities
|
||||
|
||||
### Download the vulnerability database
|
||||
At first, you need to download the vulnerability database for use in air-gapped environments.
|
||||
|
||||
=== "Trivy"
|
||||
|
||||
```
|
||||
@@ -15,7 +17,6 @@ Trivy can be used in air-gapped environments. Note that an allowlist is [here][a
|
||||
```
|
||||
|
||||
=== "oras >= v0.13.0"
|
||||
At first, you need to download the vulnerability database for use in air-gapped environments.
|
||||
Please follow [oras installation instruction][oras].
|
||||
|
||||
Download `db.tar.gz`:
|
||||
@@ -25,7 +26,6 @@ Trivy can be used in air-gapped environments. Note that an allowlist is [here][a
|
||||
```
|
||||
|
||||
=== "oras < v0.13.0"
|
||||
At first, you need to download the vulnerability database for use in air-gapped environments.
|
||||
Please follow [oras installation instruction][oras].
|
||||
|
||||
Download `db.tar.gz`:
|
||||
@@ -34,41 +34,95 @@ Trivy can be used in air-gapped environments. Note that an allowlist is [here][a
|
||||
$ oras pull -a ghcr.io/aquasecurity/trivy-db:2
|
||||
```
|
||||
|
||||
### Transfer the DB file into the air-gapped environment
|
||||
### Download the Java index database[^1]
|
||||
Java users also need to download the Java index database for use in air-gapped environments.
|
||||
|
||||
!!! note
|
||||
You container image may contain JAR files even though you don't use Java directly.
|
||||
In that case, you also need to download the Java index database.
|
||||
|
||||
=== "Trivy"
|
||||
|
||||
```
|
||||
TRIVY_TEMP_DIR=$(mktemp -d)
|
||||
trivy --cache-dir $TRIVY_TEMP_DIR image --download-java-db-only
|
||||
tar -cf ./javadb.tar.gz -C $TRIVY_TEMP_DIR/java-db metadata.json trivy-java.db
|
||||
rm -rf $TRIVY_TEMP_DIR
|
||||
```
|
||||
=== "oras >= v0.13.0"
|
||||
Please follow [oras installation instruction][oras].
|
||||
|
||||
Download `db.tar.gz`:
|
||||
|
||||
```
|
||||
$ oras pull ghcr.io/aquasecurity/trivy-java-db:1
|
||||
```
|
||||
|
||||
=== "oras < v0.13.0"
|
||||
Please follow [oras installation instruction][oras].
|
||||
|
||||
Download `db.tar.gz`:
|
||||
|
||||
```
|
||||
$ oras pull -a ghcr.io/aquasecurity/trivy-java-db:1
|
||||
```
|
||||
|
||||
|
||||
### Transfer the DB files into the air-gapped environment
|
||||
The way of transfer depends on the environment.
|
||||
|
||||
```
|
||||
$ rsync -av -e ssh /path/to/db.tar.gz [user]@[host]:dst
|
||||
```
|
||||
=== "Vulnerability db"
|
||||
```
|
||||
$ rsync -av -e ssh /path/to/db.tar.gz [user]@[host]:dst
|
||||
```
|
||||
|
||||
### Put the DB file in Trivy's cache directory
|
||||
You have to know where to put the DB file. The following command shows the default cache directory.
|
||||
=== "Java index db[^1]"
|
||||
```
|
||||
$ rsync -av -e ssh /path/to/javadb.tar.gz [user]@[host]:dst
|
||||
```
|
||||
|
||||
### Put the DB files in Trivy's cache directory
|
||||
You have to know where to put the DB files. The following command shows the default cache directory.
|
||||
|
||||
```
|
||||
$ ssh user@host
|
||||
$ trivy -h | grep cache
|
||||
--cache-dir value cache directory (default: "/home/myuser/.cache/trivy") [$TRIVY_CACHE_DIR]
|
||||
```
|
||||
=== "Vulnerability db"
|
||||
Put the DB file in the cache directory + `/db`.
|
||||
|
||||
```
|
||||
$ mkdir -p /home/myuser/.cache/trivy/db
|
||||
$ cd /home/myuser/.cache/trivy/db
|
||||
$ tar xvf /path/to/db.tar.gz -C /home/myuser/.cache/trivy/db
|
||||
x trivy.db
|
||||
x metadata.json
|
||||
$ rm /path/to/db.tar.gz
|
||||
```
|
||||
|
||||
Put the DB file in the cache directory + `/db`.
|
||||
=== "Java index db[^1]"
|
||||
Put the DB file in the cache directory + `/java-db`.
|
||||
|
||||
```
|
||||
$ mkdir -p /home/myuser/.cache/trivy/java-db
|
||||
$ cd /home/myuser/.cache/trivy/java-db
|
||||
$ tar xvf /path/to/javadb.tar.gz -C /home/myuser/.cache/trivy/java-db
|
||||
x trivy-java.db
|
||||
x metadata.json
|
||||
$ rm /path/to/javadb.tar.gz
|
||||
```
|
||||
|
||||
|
||||
|
||||
In an air-gapped environment it is your responsibility to update the Trivy databases on a regular basis, so that the scanner can detect recently-identified vulnerabilities.
|
||||
|
||||
### Run Trivy with the specific flags.
|
||||
In an air-gapped environment, you have to specify `--skip-db-update` and `--skip-java-db-update`[^1] so that Trivy doesn't attempt to download the latest database files.
|
||||
In addition, if you want to scan `pom.xml` dependencies, you need to specify `--offline-scan` since Trivy tries to issue API requests for scanning Java applications by default.
|
||||
|
||||
```
|
||||
$ mkdir -p /home/myuser/.cache/trivy/db
|
||||
$ cd /home/myuser/.cache/trivy/db
|
||||
$ tar xvf /path/to/db.tar.gz -C /home/myuser/.cache/trivy/db
|
||||
x trivy.db
|
||||
x metadata.json
|
||||
$ rm /path/to/db.tar.gz
|
||||
```
|
||||
|
||||
In an air-gapped environment it is your responsibility to update the Trivy database on a regular basis, so that the scanner can detect recently-identified vulnerabilities.
|
||||
|
||||
### Run Trivy with `--skip-update` and `--offline-scan` option
|
||||
In an air-gapped environment, specify `--skip-update` so that Trivy doesn't attempt to download the latest database file.
|
||||
In addition, if you want to scan Java dependencies such as JAR and pom.xml, you need to specify `--offline-scan` since Trivy tries to issue API requests for scanning Java applications by default.
|
||||
|
||||
```
|
||||
$ trivy image --skip-update --offline-scan alpine:3.12
|
||||
$ trivy image --skip-update --skip-java-db-update --offline-scan alpine:3.12
|
||||
```
|
||||
|
||||
## Air-Gapped Environment for misconfigurations
|
||||
@@ -84,3 +138,5 @@ $ trivy conf --skip-policy-update /path/to/conf
|
||||
|
||||
[allowlist]: ../references/troubleshooting.md
|
||||
[oras]: https://oras.land/cli/
|
||||
|
||||
[^1]: This is only required to scan `jar` files. More information about `Java index db` [here](../vulnerability/languages/java.md)
|
||||
@@ -36,9 +36,11 @@ Cache Flags
|
||||
DB Flags
|
||||
--db-repository string OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db")
|
||||
--download-db-only download/update vulnerability database but don't run a scan
|
||||
--download-java-db-only download/update java indexes database but don't run a scan
|
||||
--no-progress suppress progress bar
|
||||
--reset remove all caches and database
|
||||
--skip-db-update skip updating vulnerability database
|
||||
--skip-java-db-update skip updating java indexes database
|
||||
|
||||
Vulnerability Flags
|
||||
--ignore-unfixed display only fixed vulnerabilities
|
||||
|
||||
@@ -44,9 +44,11 @@ Cache Flags
|
||||
DB Flags
|
||||
--db-repository string OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db")
|
||||
--download-db-only download/update vulnerability database but don't run a scan
|
||||
--download-java-db-only download/update java indexes database but don't run a scan
|
||||
--no-progress suppress progress bar
|
||||
--reset remove all caches and database
|
||||
--skip-db-update skip updating vulnerability database
|
||||
--skip-java-db-update skip updating java indexes database
|
||||
|
||||
Vulnerability Flags
|
||||
--ignore-unfixed display only fixed vulnerabilities
|
||||
|
||||
@@ -58,9 +58,11 @@ Cache Flags
|
||||
DB Flags
|
||||
--db-repository string OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db")
|
||||
--download-db-only download/update vulnerability database but don't run a scan
|
||||
--download-java-db-only download/update java indexes database but don't run a scan
|
||||
--no-progress suppress progress bar
|
||||
--reset remove all caches and database
|
||||
--skip-db-update skip updating vulnerability database
|
||||
--skip-java-db-update skip updating java indexes database
|
||||
|
||||
Image Flags
|
||||
--input string input file path instead of image name
|
||||
|
||||
@@ -41,9 +41,11 @@ Cache Flags
|
||||
DB Flags
|
||||
--db-repository string OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db")
|
||||
--download-db-only download/update vulnerability database but don't run a scan
|
||||
--download-java-db-only download/update java indexes database but don't run a scan
|
||||
--no-progress suppress progress bar
|
||||
--reset remove all caches and database
|
||||
--skip-db-update skip updating vulnerability database
|
||||
--skip-java-db-update skip updating java indexes database
|
||||
|
||||
Vulnerability Flags
|
||||
--ignore-unfixed display only fixed vulnerabilities
|
||||
|
||||
@@ -47,9 +47,11 @@ Cache Flags
|
||||
DB Flags
|
||||
--db-repository string OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db")
|
||||
--download-db-only download/update vulnerability database but don't run a scan
|
||||
--download-java-db-only download/update java indexes database but don't run a scan
|
||||
--no-progress suppress progress bar
|
||||
--reset remove all caches and database
|
||||
--skip-db-update skip updating vulnerability database
|
||||
--skip-java-db-update skip updating java indexes database
|
||||
|
||||
Vulnerability Flags
|
||||
--ignore-unfixed display only fixed vulnerabilities
|
||||
|
||||
@@ -44,9 +44,11 @@ Cache Flags
|
||||
DB Flags
|
||||
--db-repository string OCI repository to retrieve trivy-db from (default "ghcr.io/aquasecurity/trivy-db")
|
||||
--download-db-only download/update vulnerability database but don't run a scan
|
||||
--download-java-db-only download/update java indexes database but don't run a scan
|
||||
--no-progress suppress progress bar
|
||||
--reset remove all caches and database
|
||||
--skip-db-update skip updating vulnerability database
|
||||
--skip-java-db-update skip updating java indexes database
|
||||
|
||||
Vulnerability Flags
|
||||
--ignore-unfixed display only fixed vulnerabilities
|
||||
|
||||
@@ -39,49 +39,23 @@ https://developer.github.com/v3/#rate-limiting
|
||||
$ GITHUB_TOKEN=XXXXXXXXXX trivy alpine:3.10
|
||||
```
|
||||
|
||||
### Maven rate limiting / inconsistent jar vulnerability reporting
|
||||
### Unable to open JAR files
|
||||
|
||||
!!! error
|
||||
``` bash
|
||||
$ trivy image ...
|
||||
...
|
||||
status 403 Forbidden from http://search.maven.org/solrsearch/select
|
||||
failed to analyze file: failed to analyze usr/lib/jvm/java-1.8-openjdk/lib/tools.jar: unable to open usr/lib/jvm/java-1.8-openjdk/lib/tools.jar: failed to open: unable to read the file: stream error: stream ID 9; PROTOCOL_ERROR; received from peer
|
||||
```
|
||||
|
||||
Trivy calls Maven API for better detection of JAR files, but many requests may exceed rate limiting.
|
||||
This can easily happen if you are running more than one instance of Trivy which is concurrently scanning multiple images.
|
||||
Once this starts happening Trivy's vulnerability reporting on jar files may become inconsistent.
|
||||
There are two options to resolve this issue:
|
||||
Currently, we're investigating this issue. As a temporary mitigation, you may be able to avoid this issue by downloading the Java DB in advance.
|
||||
|
||||
The first is to enable offline scanning using the `--offline-scan` option to stop Trivy from making API requests.
|
||||
This option affects only vulnerability scanning. The vulnerability database and builtin policies are downloaded as usual.
|
||||
If you want to skip them as well, you can try `--skip-update` and `--skip-policy-update`.
|
||||
**Note that a number of vulnerabilities might be fewer than without the `--offline-scan` option.**
|
||||
|
||||
The second, more scalable, option is to place Trivy behind a rate-limiting forward-proxy to the Maven Central API.
|
||||
One way to achieve this is to use nginx. You can use the following nginx config to enable both rate-limiting and caching (the caching greatly reduces the number of calls to the Maven Central API, especially if you are scanning a lot of similar images):
|
||||
|
||||
```nginx
|
||||
limit_req_zone global zone=maven:1m rate=10r/s;
|
||||
proxy_cache_path /tmp/cache keys_zone=mavencache:10m;
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
proxy_cache mavencache;
|
||||
|
||||
location / {
|
||||
limit_req zone=maven burst=1000;
|
||||
proxy_cache_valid any 1h;
|
||||
proxy_pass https://search.maven.org:443;
|
||||
}
|
||||
}
|
||||
```shell
|
||||
$ trivy image --download-java-db-only
|
||||
2023-02-01T16:57:04.322+0900 INFO Downloading the Java DB...
|
||||
$ trivy image [YOUR_JAVA_IMAGE]
|
||||
```
|
||||
|
||||
This config file will allow a maximum of 10 requests per second to the Maven API, this number was determined experimentally so you might want to use something else if it doesn't fit your needs.
|
||||
|
||||
Once nginx is up and running, you need to tell all your Trivy deployments to proxy their Maven API calls through nginx. You can do this by setting the `MAVEN_CENTRAL_URL` environment variable. For example, if your nginx proxy is running at `127.0.0.1`, you can set `MAVEN_CENTRAL_URL=http://127.0.0.1/solrsearch/select`.
|
||||
|
||||
|
||||
### Running in parallel takes same time as series run
|
||||
When running trivy on multiple images simultaneously, it will take same time as running trivy in series.
|
||||
This is because of a limitation of boltdb.
|
||||
|
||||
32
go.mod
32
go.mod
@@ -9,7 +9,7 @@ require (
|
||||
github.com/alicebob/miniredis/v2 v2.23.0
|
||||
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986
|
||||
github.com/aquasecurity/defsec v0.82.9
|
||||
github.com/aquasecurity/go-dep-parser v0.0.0-20230123091557-6a4a819ab8da
|
||||
github.com/aquasecurity/go-dep-parser v0.0.0-20230130190635-5e31092b0621
|
||||
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce
|
||||
github.com/aquasecurity/go-npm-version v0.0.0-20201110091526-0b796d180798
|
||||
github.com/aquasecurity/go-pep440-version v0.0.0-20210121094942-22b2f8951d46
|
||||
@@ -20,6 +20,7 @@ require (
|
||||
github.com/aquasecurity/testdocker v0.0.0-20230111101738-e741bda259da
|
||||
github.com/aquasecurity/tml v0.6.1
|
||||
github.com/aquasecurity/trivy-db v0.0.0-20230116084806-4bcdf1c414d0
|
||||
github.com/aquasecurity/trivy-java-db v0.0.0-20230130194604-b1b12e703cf9
|
||||
github.com/aquasecurity/trivy-kubernetes v0.3.1-0.20230124152305-a266786d8ded
|
||||
github.com/aws/aws-sdk-go v1.44.171
|
||||
github.com/aws/aws-sdk-go-v2 v1.17.3
|
||||
@@ -78,13 +79,19 @@ require (
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2
|
||||
google.golang.org/protobuf v1.28.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/utils v0.0.0-20221107191617-1a15be271d1d
|
||||
k8s.io/utils v0.0.0-20230115233650-391b47cb4029
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/dustin/go-humanize v1.0.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.16 // indirect
|
||||
github.com/moby/patternmatcher v0.5.0 // indirect
|
||||
github.com/moby/sys/sequential v0.5.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
gorm.io/driver/sqlite v1.4.4 // indirect
|
||||
gorm.io/gorm v1.24.3 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -237,7 +244,6 @@ require (
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/hashicorp/go-retryablehttp v0.7.2 // indirect
|
||||
github.com/hashicorp/go-safetemp v1.0.0 // indirect
|
||||
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
||||
github.com/hashicorp/go-version v1.6.0 // indirect
|
||||
@@ -369,16 +375,16 @@ require (
|
||||
k8s.io/klog/v2 v2.80.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
|
||||
k8s.io/kubectl v0.26.1 // indirect
|
||||
lukechampine.com/uint128 v1.1.1 // indirect
|
||||
modernc.org/cc/v3 v3.36.0 // indirect
|
||||
modernc.org/ccgo/v3 v3.16.6 // indirect
|
||||
modernc.org/libc v1.16.7 // indirect
|
||||
modernc.org/mathutil v1.4.1 // indirect
|
||||
modernc.org/memory v1.1.1 // indirect
|
||||
modernc.org/opt v0.1.1 // indirect
|
||||
modernc.org/sqlite v1.17.3 // indirect
|
||||
modernc.org/strutil v1.1.1 // indirect
|
||||
modernc.org/token v1.0.0 // indirect
|
||||
lukechampine.com/uint128 v1.2.0 // indirect
|
||||
modernc.org/cc/v3 v3.40.0 // indirect
|
||||
modernc.org/ccgo/v3 v3.16.13 // indirect
|
||||
modernc.org/libc v1.22.2 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.4.0 // indirect
|
||||
modernc.org/opt v0.1.3 // indirect
|
||||
modernc.org/sqlite v1.20.3 // indirect
|
||||
modernc.org/strutil v1.1.3 // indirect
|
||||
modernc.org/token v1.0.1 // indirect
|
||||
oras.land/oras-go v1.2.0 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
|
||||
sigs.k8s.io/kustomize/api v0.12.1 // indirect
|
||||
|
||||
86
go.sum
86
go.sum
@@ -195,8 +195,8 @@ github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986 h1:2a30
|
||||
github.com/aquasecurity/bolt-fixtures v0.0.0-20200903104109-d34e7f983986/go.mod h1:NT+jyeCzXk6vXR5MTkdn4z64TgGfE5HMLC8qfj5unl8=
|
||||
github.com/aquasecurity/defsec v0.82.9 h1:bThdD+Mr/6ZYPDTX0f24GY9wF4hoVJ5KF/L0WnhjEwQ=
|
||||
github.com/aquasecurity/defsec v0.82.9/go.mod h1:f/acz2sBQzfTcnaPxSjVnkRhCQ9hUbC6qwQCaHQwrFc=
|
||||
github.com/aquasecurity/go-dep-parser v0.0.0-20230123091557-6a4a819ab8da h1:dQ9R41jz6tAZCw6NNJQCkdNYfEzRUxK1ZmuChldWcbc=
|
||||
github.com/aquasecurity/go-dep-parser v0.0.0-20230123091557-6a4a819ab8da/go.mod h1:Cj+0xDZFgXGQin2fo40aH2a9srUKMOCFPw50NHsfVEk=
|
||||
github.com/aquasecurity/go-dep-parser v0.0.0-20230130190635-5e31092b0621 h1:y8e5XlnOJd2kdKOB2TDNM+84yHkkkIjVCxHhePxXy+4=
|
||||
github.com/aquasecurity/go-dep-parser v0.0.0-20230130190635-5e31092b0621/go.mod h1:E5p/rvZrFOz2Py3WtBopQjC1d7AqU54D2FqjjEFHEkk=
|
||||
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce h1:QgBRgJvtEOBtUXilDb1MLi1p1MWoyFDXAu5DEUl5nwM=
|
||||
github.com/aquasecurity/go-gem-version v0.0.0-20201115065557-8eed6fe000ce/go.mod h1:HXgVzOPvXhVGLJs4ZKO817idqr/xhwsTcj17CLYY74s=
|
||||
github.com/aquasecurity/go-mock-aws v0.0.0-20220726154943-99847deb62b0 h1:tihCUjLWkF0b1SAjAKcFltUs3SpsqGrLtI+Frye0D10=
|
||||
@@ -219,6 +219,8 @@ github.com/aquasecurity/tml v0.6.1 h1:y2ZlGSfrhnn7t4ZJ/0rotuH+v5Jgv6BDDO5jB6A9gw
|
||||
github.com/aquasecurity/tml v0.6.1/go.mod h1:OnYMWY5lvI9ejU7yH9LCberWaaTBW7hBFsITiIMY2yY=
|
||||
github.com/aquasecurity/trivy-db v0.0.0-20230116084806-4bcdf1c414d0 h1:FI5qaSoJEH47SZVvRVtTPvOmlECG2IRN92deZ/oXHis=
|
||||
github.com/aquasecurity/trivy-db v0.0.0-20230116084806-4bcdf1c414d0/go.mod h1:l3BWhRS80Mkeb++dgXij/6BmZIxLb9IpZCSAZHeI6Zk=
|
||||
github.com/aquasecurity/trivy-java-db v0.0.0-20230130194604-b1b12e703cf9 h1:EPtmaA/5AtzgCR4m5ZP9htTExn0daxoeA92azpUxp2Y=
|
||||
github.com/aquasecurity/trivy-java-db v0.0.0-20230130194604-b1b12e703cf9/go.mod h1:eAl4owZFb6vRIWYTpDNhDJy72uYaHQhLBXqa44zL/PY=
|
||||
github.com/aquasecurity/trivy-kubernetes v0.3.1-0.20230124152305-a266786d8ded h1:TCHqh3C/9I03lHTznKq5NysotxDJ8kk1cKLRR91/CHk=
|
||||
github.com/aquasecurity/trivy-kubernetes v0.3.1-0.20230124152305-a266786d8ded/go.mod h1:8LEgLAWLU8TR8tVkQ6R9x+zoXl8HZdpR0frvNUvgiZI=
|
||||
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
|
||||
@@ -904,6 +906,7 @@ github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLe
|
||||
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
|
||||
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
|
||||
@@ -965,8 +968,6 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||
github.com/hashicorp/go-getter v1.6.2 h1:7jX7xcB+uVCliddZgeKyNxv0xoT7qL5KDtH7rU4IqIk=
|
||||
github.com/hashicorp/go-getter v1.6.2/go.mod h1:IZCrswsZPeWv9IkVnLElzRU/gz/QPi6pZHn4tv6vbwA=
|
||||
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
||||
github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
|
||||
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
|
||||
@@ -974,7 +975,6 @@ github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHh
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0=
|
||||
github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
|
||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
|
||||
github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo=
|
||||
github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
|
||||
@@ -1022,6 +1022,11 @@ github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6t
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
|
||||
@@ -1177,8 +1182,9 @@ github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vq
|
||||
github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
||||
github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.12 h1:TJ1bhYJPV44phC+IMu1u2K/i5RriLTPe+yc68XDJ1Z0=
|
||||
github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
|
||||
@@ -1921,7 +1927,6 @@ golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -2034,7 +2039,6 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc
|
||||
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
|
||||
golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU=
|
||||
golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201124115921-2c860bdd6e78/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
@@ -2306,6 +2310,11 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C
|
||||
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/sqlite v1.4.4 h1:gIufGoR0dQzjkyqDyYSCvsYR6fba1Gw5YKDqKeChxFc=
|
||||
gorm.io/driver/sqlite v1.4.4/go.mod h1:0Aq3iPO+v9ZKbcdiz8gLWRw5VOPcBOPUQJFLq5e2ecI=
|
||||
gorm.io/gorm v1.24.0/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
gorm.io/gorm v1.24.3 h1:WL2ifUmzR/SLp85CSURAfybcHnGZ+yLSGSxgYXlFBHg=
|
||||
gorm.io/gorm v1.24.3/go.mod h1:DVrVomtaYTbqs7gB/x2uVvqnXzv0nqjB396B8cG4dBA=
|
||||
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||
gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk=
|
||||
@@ -2370,43 +2379,32 @@ k8s.io/kubectl v0.26.1 h1:K8A0Jjlwg8GqrxOXxAbjY5xtmXYeYjLU96cHp2WMQ7s=
|
||||
k8s.io/kubectl v0.26.1/go.mod h1:miYFVzldVbdIiXMrHZYmL/EDWwJKM+F0sSsdxsATFPo=
|
||||
k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk=
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
|
||||
k8s.io/utils v0.0.0-20221107191617-1a15be271d1d h1:0Smp/HP1OH4Rvhe+4B8nWGERtlqAGSftbSbbmm45oFs=
|
||||
k8s.io/utils v0.0.0-20221107191617-1a15be271d1d/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU=
|
||||
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
modernc.org/cc/v3 v3.36.0 h1:0kmRkTmqNidmu3c7BNDSdVHCxXCkWLmWmCIVX4LUboo=
|
||||
modernc.org/cc/v3 v3.36.0/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=
|
||||
modernc.org/ccgo/v3 v3.0.0-20220428102840-41399a37e894/go.mod h1:eI31LL8EwEBKPpNpA4bU1/i+sKOwOrQy8D87zWUcRZc=
|
||||
modernc.org/ccgo/v3 v3.0.0-20220430103911-bc99d88307be/go.mod h1:bwdAnOoaIt8Ax9YdWGjxWsdkPcZyRPHqrOvJxaKAKGw=
|
||||
modernc.org/ccgo/v3 v3.16.4/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ=
|
||||
modernc.org/ccgo/v3 v3.16.6 h1:3l18poV+iUemQ98O3X5OMr97LOqlzis+ytivU4NqGhA=
|
||||
modernc.org/ccgo/v3 v3.16.6/go.mod h1:tGtX0gE9Jn7hdZFeU88slbTh1UtCYKusWOoCJuvkWsQ=
|
||||
k8s.io/utils v0.0.0-20230115233650-391b47cb4029 h1:L8zDtT4jrxj+TaQYD0k8KNlr556WaVQylDXswKmX+dE=
|
||||
k8s.io/utils v0.0.0-20230115233650-391b47cb4029/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
|
||||
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw=
|
||||
modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
|
||||
modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw=
|
||||
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
|
||||
modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk=
|
||||
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
||||
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
|
||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
||||
modernc.org/libc v0.0.0-20220428101251-2d5f3daf273b/go.mod h1:p7Mg4+koNjc8jkqwcoFBJx7tXkpj00G77X7A72jXPXA=
|
||||
modernc.org/libc v1.16.0/go.mod h1:N4LD6DBE9cf+Dzf9buBlzVJndKr/iJHG97vGLHYnb5A=
|
||||
modernc.org/libc v1.16.1/go.mod h1:JjJE0eu4yeK7tab2n4S1w8tlWd9MxXLRzheaRnAKymU=
|
||||
modernc.org/libc v1.16.7 h1:qzQtHhsZNpVPpeCu+aMIQldXeV1P0vRhSqCL0nOIJOA=
|
||||
modernc.org/libc v1.16.7/go.mod h1:hYIV5VZczAmGZAnG15Vdngn5HSF5cSkbvfz2B7GRuVU=
|
||||
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8=
|
||||
modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.1.1 h1:bDOL0DIDLQv7bWhP3gMvIrnoFw+Eo6F7a2QK9HPDiFU=
|
||||
modernc.org/memory v1.1.1/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=
|
||||
modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
|
||||
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sqlite v1.17.3 h1:iE+coC5g17LtByDYDWKpR6m2Z9022YrSh3bumwOnIrI=
|
||||
modernc.org/sqlite v1.17.3/go.mod h1:10hPVYar9C0kfXuTWGz8s0XtB8uAGymUy51ZzStYe3k=
|
||||
modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs=
|
||||
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
|
||||
modernc.org/tcl v1.13.1 h1:npxzTwFTZYM8ghWicVIX1cRWzj7Nd8i6AqqX2p+IYao=
|
||||
modernc.org/tcl v1.13.1/go.mod h1:XOLfOwzhkljL4itZkK6T72ckMgvj0BDsnKNdZVUOecw=
|
||||
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
|
||||
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/z v1.5.1 h1:RTNHdsrOpeoSeOF4FbzTo8gBYByaJ5xT7NgZ9ZqRiJM=
|
||||
modernc.org/z v1.5.1/go.mod h1:eWFB510QWW5Th9YGZT81s+LwvaAs3Q2yr4sP0rmLkv8=
|
||||
modernc.org/libc v1.22.2 h1:4U7v51GyhlWqQmwCHj28Rdq2Yzwk55ovjFrdPjs8Hb0=
|
||||
modernc.org/libc v1.22.2/go.mod h1:uvQavJ1pZ0hIoC/jfqNoMLURIMhKzINIWypNM17puug=
|
||||
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
||||
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.4.0 h1:crykUfNSnMAXaOJnnxcSzbUGMqkLWjklJKkBK2nwZwk=
|
||||
modernc.org/memory v1.4.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sqlite v1.20.3 h1:SqGJMMxjj1PHusLxdYxeQSodg7Jxn9WWkaAQjKrntZs=
|
||||
modernc.org/sqlite v1.20.3/go.mod h1:zKcGyrICaxNTMEHSr1HQ2GUraP0j+845GYw37+EyT6A=
|
||||
modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
|
||||
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
|
||||
modernc.org/tcl v1.15.0 h1:oY+JeD11qVVSgVvodMJsu7Edf8tr5E/7tuhF5cNYz34=
|
||||
modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg=
|
||||
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/z v1.7.0 h1:xkDw/KepgEjeizO2sNco+hqYkU12taxQFqPEmgm1GWE=
|
||||
oras.land/oras-go v1.1.1 h1:gI00ftziRivKXaw1BdMeEoIA4uBgga33iVlOsEwefFs=
|
||||
oras.land/oras-go v1.1.1/go.mod h1:n2TE1ummt9MUyprGhT+Q7kGZUF4kVUpYysPFxeV2IpQ=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
|
||||
@@ -1069,9 +1069,10 @@ func showVersion(cacheDir, outputFormat, version string, outputWriter io.Writer)
|
||||
}
|
||||
|
||||
func validateArgs(cmd *cobra.Command, args []string) error {
|
||||
// '--clear-cache', '--download-db-only', '--reset' and '--generate-default-config' don't conduct the subsequent scanning
|
||||
// '--clear-cache', '--download-db-only', '--download-java-db-only', '--reset' and '--generate-default-config' don't conduct the subsequent scanning
|
||||
if viper.GetBool(flag.ClearCacheFlag.ConfigName) || viper.GetBool(flag.DownloadDBOnlyFlag.ConfigName) ||
|
||||
viper.GetBool(flag.ResetFlag.ConfigName) || viper.GetBool(flag.GenerateDefaultConfigFlag.ConfigName) {
|
||||
viper.GetBool(flag.ResetFlag.ConfigName) || viper.GetBool(flag.GenerateDefaultConfigFlag.ConfigName) ||
|
||||
viper.GetBool(flag.DownloadJavaDBOnlyFlag.ConfigName) {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"os"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
@@ -20,6 +21,7 @@ import (
|
||||
"github.com/aquasecurity/trivy/pkg/fanal/artifact"
|
||||
"github.com/aquasecurity/trivy/pkg/fanal/cache"
|
||||
"github.com/aquasecurity/trivy/pkg/flag"
|
||||
"github.com/aquasecurity/trivy/pkg/javadb"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
"github.com/aquasecurity/trivy/pkg/module"
|
||||
pkgReport "github.com/aquasecurity/trivy/pkg/report"
|
||||
@@ -302,9 +304,18 @@ func (r *runner) initDB(opts flag.Options) error {
|
||||
if opts.ServerAddr != "" || !opts.Scanners.Enabled(types.VulnerabilityScanner) {
|
||||
return nil
|
||||
}
|
||||
noProgress := opts.Quiet || opts.NoProgress
|
||||
|
||||
// Java DB
|
||||
javadb.Init(opts.CacheDir, opts.SkipJavaDBUpdate, noProgress, opts.Insecure)
|
||||
if opts.DownloadJavaDBOnly {
|
||||
if err := javadb.Update(); err != nil {
|
||||
return xerrors.Errorf("Java DB error: %w", err)
|
||||
}
|
||||
return SkipScan
|
||||
}
|
||||
|
||||
// download the database file
|
||||
noProgress := opts.Quiet || opts.NoProgress
|
||||
if err := operation.DownloadDB(opts.AppVersion, opts.CacheDir, opts.DBRepository, noProgress, opts.Insecure, opts.SkipDBUpdate); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -390,7 +390,7 @@ func (ag AnalyzerGroup) AnalyzeFile(ctx context.Context, wg *sync.WaitGroup, lim
|
||||
Content: rc,
|
||||
Options: opts,
|
||||
})
|
||||
if err != nil && !xerrors.Is(err, aos.AnalyzeOSError) {
|
||||
if err != nil && !errors.Is(err, aos.AnalyzeOSError) {
|
||||
log.Logger.Debugf("Analysis error: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -5,14 +5,16 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/aquasecurity/trivy/pkg/fanal/types"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/aquasecurity/go-dep-parser/pkg/java/jar"
|
||||
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
|
||||
"github.com/aquasecurity/trivy/pkg/fanal/analyzer/language"
|
||||
"github.com/aquasecurity/trivy/pkg/fanal/types"
|
||||
"github.com/aquasecurity/trivy/pkg/javadb"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -21,13 +23,41 @@ func init() {
|
||||
|
||||
const version = 1
|
||||
|
||||
var requiredExtensions = []string{".jar", ".war", ".ear", ".par"}
|
||||
var requiredExtensions = []string{
|
||||
".jar",
|
||||
".war",
|
||||
".ear",
|
||||
".par",
|
||||
}
|
||||
|
||||
// javaLibraryAnalyzer analyzes jar/war/ear/par files
|
||||
type javaLibraryAnalyzer struct{}
|
||||
type javaLibraryAnalyzer struct {
|
||||
once sync.Once
|
||||
client *javadb.DB
|
||||
}
|
||||
|
||||
func (a javaLibraryAnalyzer) Analyze(_ context.Context, input analyzer.AnalysisInput) (*analyzer.AnalysisResult, error) {
|
||||
p := jar.NewParser(jar.WithSize(input.Info.Size()), jar.WithFilePath(input.FilePath), jar.WithOffline(input.Options.Offline))
|
||||
func (a *javaLibraryAnalyzer) Analyze(_ context.Context, input analyzer.AnalysisInput) (*analyzer.AnalysisResult, error) {
|
||||
// TODO: think about the sonatype API and "--offline"
|
||||
var err error
|
||||
a.once.Do(func() {
|
||||
log.Logger.Info("JAR files found")
|
||||
a.client, err = javadb.NewClient()
|
||||
if err != nil {
|
||||
log.Logger.Errorf("Unable to initialize the Java DB: %s", err)
|
||||
return
|
||||
}
|
||||
log.Logger.Info("Analyzing JAR files takes a while...")
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Skip analyzing JAR files as the nil client means the Java DB was not downloaded successfully.
|
||||
if a.client == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
p := jar.NewParser(a.client, jar.WithSize(input.Info.Size()), jar.WithFilePath(input.FilePath))
|
||||
libs, deps, err := p.Parse(input.Content)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("jar/war/ear/par parse error: %w", err)
|
||||
@@ -36,7 +66,7 @@ func (a javaLibraryAnalyzer) Analyze(_ context.Context, input analyzer.AnalysisI
|
||||
return language.ToAnalysisResult(types.Jar, input.FilePath, input.FilePath, libs, deps), nil
|
||||
}
|
||||
|
||||
func (a javaLibraryAnalyzer) Required(filePath string, _ os.FileInfo) bool {
|
||||
func (a *javaLibraryAnalyzer) Required(filePath string, _ os.FileInfo) bool {
|
||||
ext := filepath.Ext(filePath)
|
||||
for _, required := range requiredExtensions {
|
||||
if strings.EqualFold(ext, required) {
|
||||
@@ -46,10 +76,10 @@ func (a javaLibraryAnalyzer) Required(filePath string, _ os.FileInfo) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (a javaLibraryAnalyzer) Type() analyzer.Type {
|
||||
func (a *javaLibraryAnalyzer) Type() analyzer.Type {
|
||||
return analyzer.TypeJar
|
||||
}
|
||||
|
||||
func (a javaLibraryAnalyzer) Version() int {
|
||||
func (a *javaLibraryAnalyzer) Version() int {
|
||||
return version
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package jar
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/aquasecurity/trivy/pkg/javadb"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
@@ -92,6 +93,25 @@ func Test_javaLibraryAnalyzer_Analyze(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "happy path (package found in trivy-java-db by sha1)",
|
||||
inputFile: "testdata/test.jar",
|
||||
want: &analyzer.AnalysisResult{
|
||||
Applications: []types.Application{
|
||||
{
|
||||
Type: types.Jar,
|
||||
FilePath: "testdata/test.jar",
|
||||
Libraries: []types.Package{
|
||||
{
|
||||
Name: "org.apache.tomcat.embed:tomcat-embed-websocket",
|
||||
FilePath: "testdata/test.jar",
|
||||
Version: "9.0.65",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "sad path",
|
||||
inputFile: "testdata/test.txt",
|
||||
@@ -107,6 +127,9 @@ func Test_javaLibraryAnalyzer_Analyze(t *testing.T) {
|
||||
stat, err := f.Stat()
|
||||
require.NoError(t, err)
|
||||
|
||||
// init java-trivy-db with skip update
|
||||
javadb.Init("testdata/testdb", true, false, false)
|
||||
|
||||
a := javaLibraryAnalyzer{}
|
||||
ctx := context.Background()
|
||||
got, err := a.Analyze(ctx, analyzer.AnalysisInput{
|
||||
|
||||
BIN
pkg/fanal/analyzer/language/java/jar/testdata/test.jar
vendored
Normal file
BIN
pkg/fanal/analyzer/language/java/jar/testdata/test.jar
vendored
Normal file
Binary file not shown.
1
pkg/fanal/analyzer/language/java/jar/testdata/testdb/java-db/metadata.json
vendored
Normal file
1
pkg/fanal/analyzer/language/java/jar/testdata/testdb/java-db/metadata.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"Version":1,"NextUpdate":"0001-01-01T00:00:00Z","UpdatedAt":"0001-01-01T00:00:00Z","DownloadedAt":"0001-01-01T00:00:00Z"}
|
||||
BIN
pkg/fanal/analyzer/language/java/jar/testdata/testdb/java-db/trivy-java.db
vendored
Normal file
BIN
pkg/fanal/analyzer/language/java/jar/testdata/testdb/java-db/trivy-java.db
vendored
Normal file
Binary file not shown.
@@ -33,6 +33,18 @@ var (
|
||||
},
|
||||
},
|
||||
}
|
||||
DownloadJavaDBOnlyFlag = Flag{
|
||||
Name: "download-java-db-only",
|
||||
ConfigName: "db.download-java-only",
|
||||
Value: false,
|
||||
Usage: "download/update Java index database but don't run a scan",
|
||||
}
|
||||
SkipJavaDBUpdateFlag = Flag{
|
||||
Name: "skip-java-db-update",
|
||||
ConfigName: "db.java-skip-update",
|
||||
Value: false,
|
||||
Usage: "skip updating Java index database",
|
||||
}
|
||||
NoProgressFlag = Flag{
|
||||
Name: "no-progress",
|
||||
ConfigName: "db.no-progress",
|
||||
@@ -56,32 +68,38 @@ var (
|
||||
|
||||
// DBFlagGroup composes common printer flag structs used for commands requiring DB logic.
|
||||
type DBFlagGroup struct {
|
||||
Reset *Flag
|
||||
DownloadDBOnly *Flag
|
||||
SkipDBUpdate *Flag
|
||||
NoProgress *Flag
|
||||
DBRepository *Flag
|
||||
Light *Flag // deprecated
|
||||
Reset *Flag
|
||||
DownloadDBOnly *Flag
|
||||
SkipDBUpdate *Flag
|
||||
DownloadJavaDBOnly *Flag
|
||||
SkipJavaDBUpdate *Flag
|
||||
NoProgress *Flag
|
||||
DBRepository *Flag
|
||||
Light *Flag // deprecated
|
||||
}
|
||||
|
||||
type DBOptions struct {
|
||||
Reset bool
|
||||
DownloadDBOnly bool
|
||||
SkipDBUpdate bool
|
||||
NoProgress bool
|
||||
DBRepository string
|
||||
Light bool // deprecated
|
||||
Reset bool
|
||||
DownloadDBOnly bool
|
||||
SkipDBUpdate bool
|
||||
DownloadJavaDBOnly bool
|
||||
SkipJavaDBUpdate bool
|
||||
NoProgress bool
|
||||
DBRepository string
|
||||
Light bool // deprecated
|
||||
}
|
||||
|
||||
// NewDBFlagGroup returns a default DBFlagGroup
|
||||
func NewDBFlagGroup() *DBFlagGroup {
|
||||
return &DBFlagGroup{
|
||||
Reset: &ResetFlag,
|
||||
DownloadDBOnly: &DownloadDBOnlyFlag,
|
||||
SkipDBUpdate: &SkipDBUpdateFlag,
|
||||
Light: &LightFlag,
|
||||
NoProgress: &NoProgressFlag,
|
||||
DBRepository: &DBRepositoryFlag,
|
||||
Reset: &ResetFlag,
|
||||
DownloadDBOnly: &DownloadDBOnlyFlag,
|
||||
SkipDBUpdate: &SkipDBUpdateFlag,
|
||||
DownloadJavaDBOnly: &DownloadJavaDBOnlyFlag,
|
||||
SkipJavaDBUpdate: &SkipJavaDBUpdateFlag,
|
||||
Light: &LightFlag,
|
||||
NoProgress: &NoProgressFlag,
|
||||
DBRepository: &DBRepositoryFlag,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,6 +112,8 @@ func (f *DBFlagGroup) Flags() []*Flag {
|
||||
f.Reset,
|
||||
f.DownloadDBOnly,
|
||||
f.SkipDBUpdate,
|
||||
f.DownloadJavaDBOnly,
|
||||
f.SkipJavaDBUpdate,
|
||||
f.NoProgress,
|
||||
f.DBRepository,
|
||||
f.Light,
|
||||
@@ -102,22 +122,29 @@ func (f *DBFlagGroup) Flags() []*Flag {
|
||||
|
||||
func (f *DBFlagGroup) ToOptions() (DBOptions, error) {
|
||||
skipDBUpdate := getBool(f.SkipDBUpdate)
|
||||
skipJavaDBUpdate := getBool(f.SkipJavaDBUpdate)
|
||||
downloadDBOnly := getBool(f.DownloadDBOnly)
|
||||
downloadJavaDBOnly := getBool(f.DownloadJavaDBOnly)
|
||||
light := getBool(f.Light)
|
||||
|
||||
if downloadDBOnly && skipDBUpdate {
|
||||
return DBOptions{}, xerrors.New("--skip-db-update and --download-db-only options can not be specified both")
|
||||
}
|
||||
if downloadJavaDBOnly && skipJavaDBUpdate {
|
||||
return DBOptions{}, xerrors.New("--skip-java-db-update and --download-java-db-only options can not be specified both")
|
||||
}
|
||||
if light {
|
||||
log.Logger.Warn("'--light' option is deprecated and will be removed. See also: https://github.com/aquasecurity/trivy/discussions/1649")
|
||||
}
|
||||
|
||||
return DBOptions{
|
||||
Reset: getBool(f.Reset),
|
||||
DownloadDBOnly: downloadDBOnly,
|
||||
SkipDBUpdate: skipDBUpdate,
|
||||
Light: light,
|
||||
NoProgress: getBool(f.NoProgress),
|
||||
DBRepository: getString(f.DBRepository),
|
||||
Reset: getBool(f.Reset),
|
||||
DownloadDBOnly: downloadDBOnly,
|
||||
SkipDBUpdate: skipDBUpdate,
|
||||
DownloadJavaDBOnly: downloadJavaDBOnly,
|
||||
SkipJavaDBUpdate: skipJavaDBUpdate,
|
||||
Light: light,
|
||||
NoProgress: getBool(f.NoProgress),
|
||||
DBRepository: getString(f.DBRepository),
|
||||
}, nil
|
||||
}
|
||||
|
||||
167
pkg/javadb/client.go
Normal file
167
pkg/javadb/client.go
Normal file
@@ -0,0 +1,167 @@
|
||||
package javadb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"github.com/aquasecurity/go-dep-parser/pkg/java/jar"
|
||||
"github.com/aquasecurity/trivy-java-db/pkg/db"
|
||||
"github.com/aquasecurity/trivy-java-db/pkg/metadata"
|
||||
"github.com/aquasecurity/trivy-java-db/pkg/types"
|
||||
"github.com/aquasecurity/trivy/pkg/log"
|
||||
"github.com/aquasecurity/trivy/pkg/oci"
|
||||
)
|
||||
|
||||
const (
|
||||
version = 1
|
||||
defaultJavaDBRepository = "ghcr.io/aquasecurity/trivy-java-db"
|
||||
mediaType = "application/vnd.aquasec.trivy.javadb.layer.v1.tar+gzip"
|
||||
)
|
||||
|
||||
var updater *Updater
|
||||
|
||||
type Updater struct {
|
||||
repo string
|
||||
dbDir string
|
||||
skip bool
|
||||
quiet bool
|
||||
insecure bool
|
||||
}
|
||||
|
||||
func (u *Updater) Update() error {
|
||||
dbDir := u.dbDir
|
||||
metac := metadata.New(dbDir)
|
||||
|
||||
meta, err := metac.Get()
|
||||
if err != nil {
|
||||
if !errors.Is(err, os.ErrNotExist) {
|
||||
return xerrors.Errorf("Java DB metadata error: %w", err)
|
||||
} else if u.skip {
|
||||
log.Logger.Error("The first run cannot skip downloading java DB")
|
||||
return xerrors.New("--skip-java-update cannot be specified on the first run")
|
||||
}
|
||||
}
|
||||
|
||||
if (meta.Version != version || meta.NextUpdate.Before(time.Now().UTC())) && !u.skip {
|
||||
// Download DB
|
||||
log.Logger.Info("Downloading the Java DB...")
|
||||
|
||||
var a *oci.Artifact
|
||||
if a, err = oci.NewArtifact(u.repo, mediaType, u.quiet, u.insecure); err != nil {
|
||||
return xerrors.Errorf("oci error: %w", err)
|
||||
}
|
||||
if err = a.Download(context.Background(), dbDir); err != nil {
|
||||
return xerrors.Errorf("DB download error: %w", err)
|
||||
}
|
||||
|
||||
// Parse the newly downloaded metadata.json
|
||||
meta, err = metac.Get()
|
||||
if err != nil {
|
||||
return xerrors.Errorf("Java DB metadata error: %w", err)
|
||||
}
|
||||
|
||||
// Update DownloadedAt
|
||||
meta.DownloadedAt = time.Now().UTC()
|
||||
if err = metac.Update(meta); err != nil {
|
||||
return xerrors.Errorf("Java DB metadata update error: %w", err)
|
||||
}
|
||||
log.Logger.Info("The Java DB is cached for 3 days. If you want to update the database more frequently, " +
|
||||
"the '--reset' flag clears the DB cache.")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func Init(cacheDir string, skip, quiet, insecure bool) {
|
||||
updater = &Updater{
|
||||
repo: fmt.Sprintf("%s:%d", defaultJavaDBRepository, version), // TODO: make it configurable
|
||||
dbDir: filepath.Join(cacheDir, "java-db"),
|
||||
skip: skip,
|
||||
quiet: quiet,
|
||||
insecure: insecure,
|
||||
}
|
||||
}
|
||||
|
||||
func Update() error {
|
||||
if updater == nil {
|
||||
return xerrors.New("not initialized")
|
||||
}
|
||||
if err := updater.Update(); err != nil {
|
||||
return xerrors.Errorf("Java DB update error: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type DB struct {
|
||||
driver db.DB
|
||||
}
|
||||
|
||||
func NewClient() (*DB, error) {
|
||||
if err := Update(); err != nil {
|
||||
return nil, xerrors.Errorf("Java DB update failed: %s", err)
|
||||
}
|
||||
|
||||
dbc, err := db.New(updater.dbDir)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("Java DB open error: %w", err)
|
||||
}
|
||||
|
||||
return &DB{driver: dbc}, nil
|
||||
}
|
||||
|
||||
func (d *DB) Exists(groupID, artifactID string) (bool, error) {
|
||||
index, err := d.driver.SelectIndexByArtifactIDAndGroupID(groupID, artifactID)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return index.ArtifactID != "", nil
|
||||
}
|
||||
|
||||
func (d *DB) SearchBySHA1(sha1 string) (jar.Properties, error) {
|
||||
index, err := d.driver.SelectIndexBySha1(sha1)
|
||||
if err != nil {
|
||||
return jar.Properties{}, xerrors.Errorf("select error: %w", err)
|
||||
} else if index.ArtifactID == "" {
|
||||
return jar.Properties{}, xerrors.Errorf("digest %s: %w", sha1, jar.ArtifactNotFoundErr)
|
||||
}
|
||||
return jar.Properties{
|
||||
GroupID: index.GroupID,
|
||||
ArtifactID: index.ArtifactID,
|
||||
Version: index.Version,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (d *DB) SearchByArtifactID(artifactID string) (string, error) {
|
||||
indexes, err := d.driver.SelectIndexesByArtifactIDAndFileType(artifactID, types.JarType)
|
||||
if err != nil {
|
||||
return "", xerrors.Errorf("select error: %w", err)
|
||||
} else if len(indexes) == 0 {
|
||||
return "", xerrors.Errorf("artifactID %s: %w", artifactID, jar.ArtifactNotFoundErr)
|
||||
}
|
||||
|
||||
// Some artifacts might have the same artifactId.
|
||||
// e.g. "javax.servlet:jstl" and "jstl:jstl"
|
||||
groupIDs := map[string]int{}
|
||||
for _, index := range indexes {
|
||||
if i, ok := groupIDs[index.GroupID]; ok {
|
||||
groupIDs[index.GroupID] = i + 1
|
||||
continue
|
||||
}
|
||||
groupIDs[index.GroupID] = 1
|
||||
}
|
||||
maxCount := 0
|
||||
var groupID string
|
||||
for k, v := range groupIDs {
|
||||
if v > maxCount {
|
||||
groupID = k
|
||||
}
|
||||
}
|
||||
|
||||
return groupID, nil
|
||||
}
|
||||
Reference in New Issue
Block a user