Skip to content

Commit

Permalink
feat: add config command (#1876)
Browse files Browse the repository at this point in the history
Signed-off-by: Keith Zantow <kzantow@gmail.com>
  • Loading branch information
kzantow committed May 23, 2024
1 parent 2b1ca9b commit d4b6cd6
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 26 deletions.
1 change: 1 addition & 0 deletions cmd/grype/cli/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ func create(id clio.Identification) (clio.Application, *cobra.Command) {
commands.Completion(app),
commands.Explain(app),
clio.VersionCommand(id, syftVersion, dbVersion),
clio.ConfigCommand(app, nil),
)

return app, rootCmd
Expand Down
20 changes: 20 additions & 0 deletions cmd/grype/cli/options/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ type Database struct {
UpdateDownloadTimeout time.Duration `yaml:"update-download-timeout" json:"update-download-timeout" mapstructure:"update-download-timeout"`
}

var _ interface {
clio.FieldDescriber
} = (*Database)(nil)

const (
defaultMaxDBAge time.Duration = time.Hour * 24 * 5
defaultUpdateAvailableTimeout = time.Second * 30
Expand Down Expand Up @@ -54,3 +58,19 @@ func (cfg Database) ToCuratorConfig() db.Config {
UpdateTimeout: cfg.UpdateDownloadTimeout,
}
}

func (cfg *Database) DescribeFields(descriptions clio.FieldDescriptionSet) {
descriptions.Add(&cfg.Dir, `location to write the vulnerability database cache`)
descriptions.Add(&cfg.UpdateURL, `URL of the vulnerability database`)
descriptions.Add(&cfg.CACert, `certificate to trust download the database and listing file`)
descriptions.Add(&cfg.AutoUpdate, `check for database updates on execution`)
descriptions.Add(&cfg.ValidateAge, `ensure db build is no older than the max-allowed-built-age`)
descriptions.Add(&cfg.ValidateByHashOnStart, `validate the database matches the known hash each execution`)
descriptions.Add(&cfg.MaxAllowedBuiltAge, `Max allowed age for vulnerability database,
age being the time since it was built
Default max age is 120h (or five days)`)
descriptions.Add(&cfg.UpdateAvailableTimeout, `Timeout for downloading GRYPE_DB_UPDATE_URL to see if the database needs to be downloaded
This file is ~156KiB as of 2024-04-17 so the download should be quick; adjust as needed`)
descriptions.Add(&cfg.UpdateDownloadTimeout, `Timeout for downloading actual vulnerability DB
The DB is ~156MB as of 2024-04-17 so slower connections may exceed the default timeout; adjust as needed`)
}
11 changes: 11 additions & 0 deletions cmd/grype/cli/options/datasources.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package options

import (
"github.com/anchore/clio"
"github.com/anchore/grype/grype/matcher/java"
)

Expand All @@ -13,6 +14,10 @@ type externalSources struct {
Maven maven `yaml:"maven" json:"maven" mapstructure:"maven"`
}

var _ interface {
clio.FieldDescriber
} = (*externalSources)(nil)

type maven struct {
SearchUpstreamBySha1 bool `yaml:"search-upstream" json:"searchUpstreamBySha1" mapstructure:"search-maven-upstream"`
BaseURL string `yaml:"base-url" json:"baseUrl" mapstructure:"base-url"`
Expand All @@ -38,3 +43,9 @@ func (cfg externalSources) ToJavaMatcherConfig() java.ExternalSearchConfig {
MavenBaseURL: cfg.Maven.BaseURL,
}
}

func (cfg *externalSources) DescribeFields(descriptions clio.FieldDescriptionSet) {
descriptions.Add(&cfg.Enable, `enable Grype searching network source for additional information`)
descriptions.Add(&cfg.Maven.SearchUpstreamBySha1, `search for Maven artifacts by SHA1`)
descriptions.Add(&cfg.Maven.BaseURL, `base URL of the Maven repository to search`)
}
38 changes: 38 additions & 0 deletions cmd/grype/cli/options/grype.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ type Grype struct {
var _ interface {
clio.FlagAdder
clio.PostLoader
clio.FieldDescriber
} = (*Grype)(nil)

func DefaultGrype(id clio.Identification) *Grype {
Expand Down Expand Up @@ -147,6 +148,43 @@ func (o *Grype) PostLoad() error {
return nil
}

func (o *Grype) DescribeFields(descriptions clio.FieldDescriptionSet) {
descriptions.Add(&o.CheckForAppUpdate, `enable/disable checking for application updates on startup`)
descriptions.Add(&o.DefaultImagePullSource, `allows users to specify which image source should be used to generate the sbom
valid values are: registry, docker, podman`)
descriptions.Add(&o.Name, `same as --name; set the name of the target being analyzed`)
descriptions.Add(&o.Exclusions, `a list of globs to exclude from scanning, for example:
- '/etc/**'
- './out/**/*.json'
same as --exclude`)
descriptions.Add(&o.File, `if using template output, you must provide a path to a Go template file
see https://github.com/anchore/grype#using-templates for more information on template output
the default path to the template file is the current working directory
output-template-file: .grype/html.tmpl
write output report to a file (default is to write to stdout)`)
descriptions.Add(&o.Outputs, `the output format of the vulnerability report (options: table, template, json, cyclonedx)
when using template as the output type, you must also provide a value for 'output-template-file'`)
descriptions.Add(&o.FailOn, `upon scanning, if a severity is found at or above the given severity then the return code will be 1
default is unset which will skip this validation (options: negligible, low, medium, high, critical)`)
descriptions.Add(&o.Ignore, `A list of vulnerability ignore rules, one or more property may be specified and all matching vulnerabilities will be ignored.
This is the full set of supported rule fields:
- vulnerability: CVE-2008-4318
fix-state: unknown
package:
name: libcurl
version: 1.5.1
type: npm
location: "/usr/local/lib/node_modules/**"
VEX fields apply when Grype reads vex data:
- vex-status: not_affected
vex-justification: vulnerable_code_not_present
`)
descriptions.Add(&o.VexAdd, `VEX statuses to consider as ignored rules`)
descriptions.Add(&o.MatchUpstreamKernelHeaders, `match kernel-header packages with upstream kernel as kernel vulnerabilities`)
}

func (o Grype) FailOnSeverity() *vulnerability.Severity {
severity := vulnerability.ParseSeverity(o.FailOn)
return &severity
Expand Down
20 changes: 20 additions & 0 deletions cmd/grype/cli/options/match.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package options

import "github.com/anchore/clio"

// matchConfig contains all matching-related configuration options available to the user via the application config.
type matchConfig struct {
Java matcherConfig `yaml:"java" json:"java" mapstructure:"java"` // settings for the java matcher
Expand All @@ -12,6 +14,10 @@ type matchConfig struct {
Stock matcherConfig `yaml:"stock" json:"stock" mapstructure:"stock"` // settings for the default/stock matcher
}

var _ interface {
clio.FieldDescriber
} = (*matchConfig)(nil)

type matcherConfig struct {
UseCPEs bool `yaml:"using-cpes" json:"using-cpes" mapstructure:"using-cpes"` // if CPEs should be used during matching
}
Expand Down Expand Up @@ -46,3 +52,17 @@ func defaultMatchConfig() matchConfig {
Stock: useCpe,
}
}

func (cfg *matchConfig) DescribeFields(descriptions clio.FieldDescriptionSet) {
usingCpeDescription := `use CPE matching to find vulnerabilities`
descriptions.Add(&cfg.Java.UseCPEs, usingCpeDescription)
descriptions.Add(&cfg.Dotnet.UseCPEs, usingCpeDescription)
descriptions.Add(&cfg.Golang.UseCPEs, usingCpeDescription)
descriptions.Add(&cfg.Golang.AlwaysUseCPEForStdlib, usingCpeDescription+" for the Go standard library")
descriptions.Add(&cfg.Golang.AllowMainModulePseudoVersionComparison, `allow comparison between main module pseudo-versions (e.g. v0.0.0-20240413-2b432cf643...)`)
descriptions.Add(&cfg.Javascript.UseCPEs, usingCpeDescription)
descriptions.Add(&cfg.Python.UseCPEs, usingCpeDescription)
descriptions.Add(&cfg.Ruby.UseCPEs, usingCpeDescription)
descriptions.Add(&cfg.Rust.UseCPEs, usingCpeDescription)
descriptions.Add(&cfg.Stock.UseCPEs, usingCpeDescription)
}
19 changes: 18 additions & 1 deletion cmd/grype/cli/options/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,10 @@ type registry struct {
CACert string `yaml:"ca-cert" json:"ca-cert" mapstructure:"ca-cert"`
}

var _ clio.PostLoader = (*registry)(nil)
var _ interface {
clio.PostLoader
clio.FieldDescriber
} = (*registry)(nil)

func (cfg *registry) PostLoad() error {
// there may be additional credentials provided by env var that should be appended to the set of credentials
Expand Down Expand Up @@ -53,6 +56,20 @@ func (cfg *registry) PostLoad() error {
return nil
}

func (cfg *registry) DescribeFields(descriptions clio.FieldDescriptionSet) {
descriptions.Add(&cfg.InsecureSkipTLSVerify, "skip TLS verification when communicating with the registry")
descriptions.Add(&cfg.InsecureUseHTTP, "use http instead of https when connecting to the registry")
descriptions.Add(&cfg.CACert, "filepath to a CA certificate (or directory containing *.crt, *.cert, *.pem) used to generate the client certificate")
descriptions.Add(&cfg.Auth, `Authentication credentials for specific registries. Each entry describes authentication for a specific authority:
- authority: the registry authority URL the URL to the registry (e.g. "docker.io", "localhost:5000", etc.) (env: SYFT_REGISTRY_AUTH_AUTHORITY)
username: a username if using basic credentials (env: SYFT_REGISTRY_AUTH_USERNAME)
password: a corresponding password (env: SYFT_REGISTRY_AUTH_PASSWORD)
token: a token if using token-based authentication, mutually exclusive with username/password (env: SYFT_REGISTRY_AUTH_TOKEN)
tls-cert: filepath to the client certificate used for TLS authentication to the registry (env: SYFT_REGISTRY_AUTH_TLS_CERT)
tls-key: filepath to the client key used for TLS authentication to the registry (env: SYFT_REGISTRY_AUTH_TLS_KEY)
`)
}

func hasNonEmptyCredentials(username, password, token, tlsCert, tlsKey string) bool {
hasUserPass := username != "" && password != ""
hasToken := token != ""
Expand Down
13 changes: 12 additions & 1 deletion cmd/grype/cli/options/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ type search struct {
IncludeIndexedArchives bool `yaml:"indexed-archives" json:"indexed-archives" mapstructure:"indexed-archives"`
}

var _ clio.PostLoader = (*search)(nil)
var _ interface {
clio.PostLoader
clio.FieldDescriber
} = (*search)(nil)

func defaultSearch(scope source.Scope) search {
c := cataloging.DefaultArchiveSearchConfig()
Expand All @@ -33,6 +36,14 @@ func (cfg *search) PostLoad() error {
return nil
}

func (cfg *search) DescribeFields(descriptions clio.FieldDescriptionSet) {
descriptions.Add(&cfg.IncludeUnindexedArchives, `search within archives that do contain a file index to search against (zip)
note: for now this only applies to the java package cataloger`)
descriptions.Add(&cfg.IncludeIndexedArchives, `search within archives that do not contain a file index to search against (tar, tar.gz, tar.bz2, etc)
note: enabling this may result in a performance impact since all discovered compressed tars will be decompressed
note: for now this only applies to the java package cataloger`)
}

func (cfg search) GetScope() source.Scope {
return source.ParseScope(cfg.Scope)
}
14 changes: 7 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ require (
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
github.com/adrg/xdg v0.4.0
github.com/anchore/bubbly v0.0.0-20231115134915-def0aba654a9
github.com/anchore/clio v0.0.0-20240209204744-cb94e40a4f65
github.com/anchore/clio v0.0.0-20240522144804-d81e109008aa
github.com/anchore/go-logger v0.0.0-20230725134548-c21dafa1ec5a
github.com/anchore/go-testutils v0.0.0-20200925183923-d5f45b0d3c04
github.com/anchore/go-version v1.2.2-0.20210903204242-51efa5b487c4
Expand Down Expand Up @@ -79,7 +79,7 @@ require (
github.com/Microsoft/hcsshim v0.11.4 // indirect
github.com/ProtonMail/go-crypto v1.0.0 // indirect
github.com/acobaugh/osrelease v0.1.0 // indirect
github.com/anchore/fangs v0.0.0-20231201140849-5075d28d6d8b // indirect
github.com/anchore/fangs v0.0.0-20240508143433-f016b099950f // indirect
github.com/anchore/go-macholibre v0.0.0-20220308212642-53e6d0aaf6fb // indirect
github.com/anchore/go-struct-converter v0.0.0-20221118182256-c68fdcfa2092 // indirect
github.com/andybalholm/brotli v1.0.4 // indirect
Expand Down Expand Up @@ -118,7 +118,7 @@ require (
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect
github.com/felixge/fgprof v0.9.3 // indirect
github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/github/go-spdx/v2 v2.2.0 // indirect
github.com/gkampitakis/ciinfo v0.3.0 // indirect
github.com/gkampitakis/go-diff v1.3.2 // indirect
Expand Down Expand Up @@ -200,17 +200,17 @@ require (
github.com/rivo/uniseg v0.4.7 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
github.com/saferwall/pe v1.5.2 // indirect
github.com/sagikazarmark/locafero v0.3.0 // indirect
github.com/sagikazarmark/locafero v0.4.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/saintfish/chardet v0.0.0-20230101081208-5e3ef4b5456d // indirect
github.com/sassoftware/go-rpmutils v0.4.0 // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/skeema/knownhosts v1.2.2 // indirect
github.com/sourcegraph/conc v0.3.0 // indirect
github.com/spdx/tools-golang v0.5.4 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/cast v1.6.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.17.0 // indirect
github.com/spf13/viper v1.18.2 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
github.com/sylabs/sif/v2 v2.11.5 // indirect
github.com/sylabs/squashfs v0.6.1 // indirect
Expand Down Expand Up @@ -247,7 +247,7 @@ require (
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.19.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/api v0.152.0 // indirect
google.golang.org/api v0.153.0 // indirect
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect
Expand Down

0 comments on commit d4b6cd6

Please sign in to comment.