Files
aquasecurity-trivy/pkg/flag/vulnerability_flags.go

121 lines
3.6 KiB
Go

package flag
import (
"github.com/samber/lo"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/vex"
xstrings "github.com/aquasecurity/trivy/pkg/x/strings"
)
var (
IgnoreUnfixedFlag = Flag[bool]{
Name: "ignore-unfixed",
ConfigName: "vulnerability.ignore-unfixed",
Usage: "display only fixed vulnerabilities",
}
IgnoreStatusFlag = Flag[[]string]{
Name: "ignore-status",
ConfigName: "vulnerability.ignore-status",
Values: dbTypes.Statuses,
Usage: "comma-separated list of vulnerability status to ignore",
TelemetrySafe: true,
}
VEXFlag = Flag[[]string]{
Name: "vex",
ConfigName: "vulnerability.vex",
Usage: `[EXPERIMENTAL] VEX sources ("repo", "oci" or file path)`,
}
SkipVEXRepoUpdateFlag = Flag[bool]{
Name: "skip-vex-repo-update",
ConfigName: "vulnerability.skip-vex-repo-update",
Usage: `[EXPERIMENTAL] Skip VEX Repository update`,
}
VulnSeveritySourceFlag = Flag[[]string]{
Name: "vuln-severity-source",
ConfigName: "vulnerability.severity-source",
Default: []string{
"auto",
},
Values: append(xstrings.ToStringSlice(vulnerability.AllSourceIDs), "auto"),
Usage: "order of data sources for selecting vulnerability severity level",
TelemetrySafe: true,
}
)
type VulnerabilityFlagGroup struct {
IgnoreUnfixed *Flag[bool]
IgnoreStatus *Flag[[]string]
VEX *Flag[[]string]
SkipVEXRepoUpdate *Flag[bool]
VulnSeveritySource *Flag[[]string]
}
type VulnerabilityOptions struct {
IgnoreStatuses []dbTypes.Status
VEXSources []vex.Source
SkipVEXRepoUpdate bool
VulnSeveritySources []dbTypes.SourceID
}
func NewVulnerabilityFlagGroup() *VulnerabilityFlagGroup {
return &VulnerabilityFlagGroup{
IgnoreUnfixed: IgnoreUnfixedFlag.Clone(),
IgnoreStatus: IgnoreStatusFlag.Clone(),
VEX: VEXFlag.Clone(),
SkipVEXRepoUpdate: SkipVEXRepoUpdateFlag.Clone(),
VulnSeveritySource: VulnSeveritySourceFlag.Clone(),
}
}
func (f *VulnerabilityFlagGroup) Name() string {
return "Vulnerability"
}
func (f *VulnerabilityFlagGroup) Flags() []Flagger {
return []Flagger{
f.IgnoreUnfixed,
f.IgnoreStatus,
f.VEX,
f.SkipVEXRepoUpdate,
f.VulnSeveritySource,
}
}
func (f *VulnerabilityFlagGroup) ToOptions(opts *Options) error {
// Just convert string to dbTypes.Status as the validated values are passed here.
ignoreStatuses := lo.Map(f.IgnoreStatus.Value(), func(s string, _ int) dbTypes.Status {
return dbTypes.NewStatus(s)
})
ignoreUnfixed := f.IgnoreUnfixed.Value()
switch {
case ignoreUnfixed && len(ignoreStatuses) > 0:
log.Warn("'--ignore-unfixed' is ignored because '--ignore-status' is specified")
case ignoreUnfixed:
// '--ignore-unfixed' is a shorthand of '--ignore-status'.
ignoreStatuses = lo.FilterMap(dbTypes.Statuses, func(s string, _ int) (dbTypes.Status, bool) {
fixed := dbTypes.StatusFixed
if s == fixed.String() {
return 0, false
}
return dbTypes.NewStatus(s), true
})
case len(ignoreStatuses) == 0:
ignoreStatuses = nil
}
log.Debug("Ignore statuses", log.Any("statuses", ignoreStatuses))
opts.VulnerabilityOptions = VulnerabilityOptions{
IgnoreStatuses: ignoreStatuses,
VEXSources: lo.Map(f.VEX.Value(), func(s string, _ int) vex.Source {
return vex.NewSource(s)
}),
SkipVEXRepoUpdate: f.SkipVEXRepoUpdate.Value(),
VulnSeveritySources: xstrings.ToTSlice[dbTypes.SourceID](f.VulnSeveritySource.Value()),
}
return nil
}