Skip to content

Commit

Permalink
feat: support for custom schemas
Browse files Browse the repository at this point in the history
Signed-off-by: nikpivkin <[email protected]>
  • Loading branch information
nikpivkin committed Aug 8, 2024
1 parent d661f91 commit 4860919
Show file tree
Hide file tree
Showing 35 changed files with 429 additions and 140 deletions.
111 changes: 77 additions & 34 deletions pkg/commands/artifact/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import (
"context"
"errors"
"fmt"
"io/fs"
"path/filepath"
"slices"
"strings"

"github.com/hashicorp/go-multierror"
"github.com/samber/lo"
Expand Down Expand Up @@ -501,43 +504,13 @@ func (r *runner) initScannerConfig(opts flag.Options) (ScannerConfig, types.Scan
log.WithPrefix(log.PrefixVulnerability).Info("Vulnerability scanning is enabled")
}

// ScannerOption is filled only when config scanning is enabled.
// Misconfig ScannerOption is filled only when config scanning is enabled.
var configScannerOptions misconf.ScannerOption
if opts.Scanners.Enabled(types.MisconfigScanner) || opts.ImageConfigScanners.Enabled(types.MisconfigScanner) {
logger := log.WithPrefix(log.PrefixMisconfiguration)
logger.Info("Misconfiguration scanning is enabled")

var downloadedPolicyPaths []string
var disableEmbedded bool

downloadedPolicyPaths, err := operation.InitBuiltinPolicies(context.Background(), opts.CacheDir, opts.Quiet, opts.SkipCheckUpdate, opts.MisconfOptions.ChecksBundleRepository, opts.RegistryOpts())
var err error
configScannerOptions, err = initMisconfScannerOption(opts)
if err != nil {
if !opts.SkipCheckUpdate {
logger.Error("Falling back to embedded checks", log.Err(err))
}
} else {
logger.Debug("Policies successfully loaded from disk")
disableEmbedded = true
}
configScannerOptions = misconf.ScannerOption{
Debug: opts.Debug,
Trace: opts.Trace,
Namespaces: append(opts.CheckNamespaces, rego.BuiltinNamespaces()...),
PolicyPaths: append(opts.CheckPaths, downloadedPolicyPaths...),
DataPaths: opts.DataPaths,
HelmValues: opts.HelmValues,
HelmValueFiles: opts.HelmValueFiles,
HelmFileValues: opts.HelmFileValues,
HelmStringValues: opts.HelmStringValues,
HelmAPIVersions: opts.HelmAPIVersions,
HelmKubeVersion: opts.HelmKubeVersion,
TerraformTFVars: opts.TerraformTFVars,
CloudFormationParamVars: opts.CloudFormationParamVars,
K8sVersion: opts.K8sVersion,
DisableEmbeddedPolicies: disableEmbedded,
DisableEmbeddedLibraries: disableEmbedded,
IncludeDeprecatedChecks: opts.IncludeDeprecatedChecks,
TfExcludeDownloaded: opts.TfExcludeDownloaded,
return ScannerConfig{}, types.ScanOptions{}, err
}
}

Expand Down Expand Up @@ -650,3 +623,73 @@ func (r *runner) scan(ctx context.Context, opts flag.Options, initializeScanner
}
return report, nil
}

func initMisconfScannerOption(opts flag.Options) (misconf.ScannerOption, error) {
logger := log.WithPrefix(log.PrefixMisconfiguration)
logger.Info("Misconfiguration scanning is enabled")

var downloadedPolicyPaths []string
var disableEmbedded bool

downloadedPolicyPaths, err := operation.InitBuiltinPolicies(context.Background(), opts.CacheDir, opts.Quiet, opts.SkipCheckUpdate, opts.MisconfOptions.ChecksBundleRepository, opts.RegistryOpts())
if err != nil {
if !opts.SkipCheckUpdate {
logger.Error("Falling back to embedded checks", log.Err(err))
}
} else {
logger.Debug("Policies successfully loaded from disk")
disableEmbedded = true
}

configSchemas, err := loadConfigSchemas(opts.ConfigFileSchemas)
if err != nil {
return misconf.ScannerOption{}, xerrors.Errorf("load schemas error: %w", err)
}

return misconf.ScannerOption{
Debug: opts.Debug,
Trace: opts.Trace,
Namespaces: append(opts.CheckNamespaces, rego.BuiltinNamespaces()...),
PolicyPaths: append(opts.CheckPaths, downloadedPolicyPaths...),
DataPaths: opts.DataPaths,
HelmValues: opts.HelmValues,
HelmValueFiles: opts.HelmValueFiles,
HelmFileValues: opts.HelmFileValues,
HelmStringValues: opts.HelmStringValues,
HelmAPIVersions: opts.HelmAPIVersions,
HelmKubeVersion: opts.HelmKubeVersion,
TerraformTFVars: opts.TerraformTFVars,
CloudFormationParamVars: opts.CloudFormationParamVars,
K8sVersion: opts.K8sVersion,
DisableEmbeddedPolicies: disableEmbedded,
DisableEmbeddedLibraries: disableEmbedded,
IncludeDeprecatedChecks: opts.IncludeDeprecatedChecks,
TfExcludeDownloaded: opts.TfExcludeDownloaded,
FilePatterns: opts.FilePatterns,
ConfigFileSchemas: configSchemas,
}, nil
}

func loadConfigSchemas(paths []string) ([]*misconf.ConfigFileSchema, error) {
var configSchemas []*misconf.ConfigFileSchema
for _, path := range paths {
filepath.WalkDir(path, func(path string, info fs.DirEntry, err error) error {

Check failure on line 676 in pkg/commands/artifact/run.go

View workflow job for this annotation

GitHub Actions / Test (ubuntu-latest)

G104: Errors unhandled. (gosec)
if err != nil {
return err
}
if info.IsDir() || !strings.HasSuffix(info.Name(), ".json") {
return nil
}

schema, err := misconf.NewConfigFileSchema(path)
if err != nil {
return xerrors.Errorf("load config file schema: %w", err)
}

configSchemas = append(configSchemas, schema)
return nil
})
}

return configSchemas, nil
}
4 changes: 2 additions & 2 deletions pkg/fanal/analyzer/config/azurearm/azurearm.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer/config"
"github.com/aquasecurity/trivy/pkg/misconf"
"github.com/aquasecurity/trivy/pkg/iac/detection"
)

const (
Expand All @@ -25,7 +25,7 @@ type azureARMConfigAnalyzer struct {
}

func newAzureARMConfigAnalyzer(opts analyzer.AnalyzerOptions) (analyzer.PostAnalyzer, error) {
a, err := config.NewAnalyzer(analyzerType, version, misconf.NewAzureARMScanner, opts)
a, err := config.NewAnalyzer(analyzerType, version, detection.FileTypeAzureARM, opts)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/fanal/analyzer/config/cloudformation/cloudformation.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package cloudformation
import (
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer/config"
"github.com/aquasecurity/trivy/pkg/misconf"
"github.com/aquasecurity/trivy/pkg/iac/detection"
)

const (
Expand All @@ -22,7 +22,7 @@ type cloudFormationConfigAnalyzer struct {
}

func newCloudFormationConfigAnalyzer(opts analyzer.AnalyzerOptions) (analyzer.PostAnalyzer, error) {
a, err := config.NewAnalyzer(analyzerType, version, misconf.NewCloudFormationScanner, opts)
a, err := config.NewAnalyzer(analyzerType, version, detection.FileTypeCloudFormation, opts)
if err != nil {
return nil, err
}
Expand Down
7 changes: 3 additions & 4 deletions pkg/fanal/analyzer/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"k8s.io/utils/strings/slices"

"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/iac/detection"
"github.com/aquasecurity/trivy/pkg/misconf"
)

Expand All @@ -26,10 +27,8 @@ type Analyzer struct {
scanner *misconf.Scanner
}

type NewScanner func([]string, misconf.ScannerOption) (*misconf.Scanner, error)

func NewAnalyzer(t analyzer.Type, version int, newScanner NewScanner, opts analyzer.AnalyzerOptions) (*Analyzer, error) {
s, err := newScanner(opts.FilePatterns, opts.MisconfScannerOption)
func NewAnalyzer(t analyzer.Type, version int, fileType detection.FileType, opts analyzer.AnalyzerOptions) (*Analyzer, error) {
s, err := misconf.NewScanner(fileType, opts.MisconfScannerOption)
if err != nil {
return nil, xerrors.Errorf("%s scanner init error: %w", t, err)
}
Expand Down
17 changes: 9 additions & 8 deletions pkg/fanal/analyzer/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@ import (
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer/config"
"github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/iac/detection"
"github.com/aquasecurity/trivy/pkg/misconf"
)

func TestAnalyzer_PostAnalyze(t *testing.T) {
type fields struct {
typ analyzer.Type
newScanner config.NewScanner
opts analyzer.AnalyzerOptions
typ analyzer.Type
fileType detection.FileType
opts analyzer.AnalyzerOptions
}
tests := []struct {
name string
Expand All @@ -31,8 +32,8 @@ func TestAnalyzer_PostAnalyze(t *testing.T) {
{
name: "dockerfile",
fields: fields{
typ: analyzer.TypeDockerfile,
newScanner: misconf.NewDockerfileScanner,
typ: analyzer.TypeDockerfile,
fileType: detection.FileTypeDockerfile,
opts: analyzer.AnalyzerOptions{
MisconfScannerOption: misconf.ScannerOption{
Namespaces: []string{"user"},
Expand Down Expand Up @@ -74,8 +75,8 @@ func TestAnalyzer_PostAnalyze(t *testing.T) {
{
name: "non-existent dir",
fields: fields{
typ: analyzer.TypeDockerfile,
newScanner: misconf.NewDockerfileScanner,
typ: analyzer.TypeDockerfile,
fileType: detection.FileTypeDockerfile,
opts: analyzer.AnalyzerOptions{
MisconfScannerOption: misconf.ScannerOption{
Namespaces: []string{"user"},
Expand All @@ -90,7 +91,7 @@ func TestAnalyzer_PostAnalyze(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a, err := config.NewAnalyzer(tt.fields.typ, 0, tt.fields.newScanner, tt.fields.opts)
a, err := config.NewAnalyzer(tt.fields.typ, 0, tt.fields.fileType, tt.fields.opts)
require.NoError(t, err)

got, err := a.PostAnalyze(context.Background(), analyzer.PostAnalysisInput{
Expand Down
4 changes: 2 additions & 2 deletions pkg/fanal/analyzer/config/dockerfile/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer/config"
"github.com/aquasecurity/trivy/pkg/misconf"
"github.com/aquasecurity/trivy/pkg/iac/detection"
)

const (
Expand All @@ -28,7 +28,7 @@ type dockerConfigAnalyzer struct {
}

func newDockerfileConfigAnalyzer(opts analyzer.AnalyzerOptions) (analyzer.PostAnalyzer, error) {
a, err := config.NewAnalyzer(analyzerType, version, misconf.NewDockerfileScanner, opts)
a, err := config.NewAnalyzer(analyzerType, version, detection.FileTypeDockerfile, opts)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/fanal/analyzer/config/helm/helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (

"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer/config"
"github.com/aquasecurity/trivy/pkg/misconf"
"github.com/aquasecurity/trivy/pkg/iac/detection"
)

const (
Expand All @@ -29,7 +29,7 @@ type helmConfigAnalyzer struct {
}

func newHelmConfigAnalyzer(opts analyzer.AnalyzerOptions) (analyzer.PostAnalyzer, error) {
a, err := config.NewAnalyzer(analyzerType, version, misconf.NewHelmScanner, opts)
a, err := config.NewAnalyzer(analyzerType, version, detection.FileTypeHelm, opts)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/fanal/analyzer/config/json/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer/config"
"github.com/aquasecurity/trivy/pkg/misconf"
"github.com/aquasecurity/trivy/pkg/iac/detection"
)

const (
Expand All @@ -24,7 +24,7 @@ type jsonConfigAnalyzer struct {
}

func newJSONConfigAnalyzer(opts analyzer.AnalyzerOptions) (analyzer.PostAnalyzer, error) {
a, err := config.NewAnalyzer(analyzerType, version, misconf.NewJSONScanner, opts)
a, err := config.NewAnalyzer(analyzerType, version, detection.FileTypeJSON, opts)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/fanal/analyzer/config/k8s/k8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package k8s
import (
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer/config"
"github.com/aquasecurity/trivy/pkg/misconf"
"github.com/aquasecurity/trivy/pkg/iac/detection"
)

const (
Expand All @@ -22,7 +22,7 @@ type kubernetesConfigAnalyzer struct {
}

func newKubernetesConfigAnalyzer(opts analyzer.AnalyzerOptions) (analyzer.PostAnalyzer, error) {
a, err := config.NewAnalyzer(analyzerType, version, misconf.NewKubernetesScanner, opts)
a, err := config.NewAnalyzer(analyzerType, version, detection.FileTypeKubernetes, opts)
if err != nil {
return nil, err
}
Expand Down
3 changes: 1 addition & 2 deletions pkg/fanal/analyzer/config/terraform/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer/config"
"github.com/aquasecurity/trivy/pkg/iac/detection"
"github.com/aquasecurity/trivy/pkg/misconf"
)

const (
Expand All @@ -25,7 +24,7 @@ type terraformConfigAnalyzer struct {
}

func newTerraformConfigAnalyzer(opts analyzer.AnalyzerOptions) (analyzer.PostAnalyzer, error) {
a, err := config.NewAnalyzer(analyzerType, version, misconf.NewTerraformScanner, opts)
a, err := config.NewAnalyzer(analyzerType, version, detection.FileTypeTerraform, opts)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/fanal/analyzer/config/terraformplan/json/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer/config"
"github.com/aquasecurity/trivy/pkg/misconf"
"github.com/aquasecurity/trivy/pkg/iac/detection"
)

const (
Expand All @@ -31,7 +31,7 @@ type terraformPlanConfigAnalyzer struct {
}

func newTerraformPlanJSONConfigAnalyzer(opts analyzer.AnalyzerOptions) (analyzer.PostAnalyzer, error) {
a, err := config.NewAnalyzer(analyzerType, version, misconf.NewTerraformPlanJSONScanner, opts)
a, err := config.NewAnalyzer(analyzerType, version, detection.FileTypeTerraformPlanJSON, opts)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/fanal/analyzer/config/terraformplan/snapshot/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer/config"
"github.com/aquasecurity/trivy/pkg/misconf"
"github.com/aquasecurity/trivy/pkg/iac/detection"
)

const (
Expand All @@ -25,7 +25,7 @@ type terraformPlanConfigAnalyzer struct {
}

func newTerraformPlanSnapshotConfigAnalyzer(opts analyzer.AnalyzerOptions) (analyzer.PostAnalyzer, error) {
a, err := config.NewAnalyzer(analyzerType, version, misconf.NewTerraformPlanSnapshotScanner, opts)
a, err := config.NewAnalyzer(analyzerType, version, detection.FileTypeTerraformPlanSnapshot, opts)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/fanal/analyzer/config/yaml/yaml.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer/config"
"github.com/aquasecurity/trivy/pkg/misconf"
"github.com/aquasecurity/trivy/pkg/iac/detection"
)

const (
Expand All @@ -24,7 +24,7 @@ type yamlConfigAnalyzer struct {
}

func newYAMLConfigAnalyzer(opts analyzer.AnalyzerOptions) (analyzer.PostAnalyzer, error) {
a, err := config.NewAnalyzer(analyzerType, version, misconf.NewYAMLScanner, opts)
a, err := config.NewAnalyzer(analyzerType, version, detection.FileTypeYAML, opts)
if err != nil {
return nil, err
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/fanal/analyzer/imgconf/dockerfile/dockerfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/fanal/image"
"github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/iac/detection"
"github.com/aquasecurity/trivy/pkg/mapfs"
"github.com/aquasecurity/trivy/pkg/misconf"
)
Expand All @@ -26,7 +27,7 @@ type historyAnalyzer struct {
}

func newHistoryAnalyzer(opts analyzer.ConfigAnalyzerOptions) (analyzer.ConfigAnalyzer, error) {
s, err := misconf.NewDockerfileScanner(opts.FilePatterns, opts.MisconfScannerOption)
s, err := misconf.NewScanner(detection.FileTypeDockerfile, opts.MisconfScannerOption)
if err != nil {
return nil, xerrors.Errorf("misconfiguration scanner error: %w", err)
}
Expand Down
Loading

0 comments on commit 4860919

Please sign in to comment.