github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/pkg/scanners/yaml/scanner.go (about) 1 package yaml 2 3 import ( 4 "context" 5 "io" 6 "io/fs" 7 "sync" 8 9 "github.com/khulnasoft-lab/defsec/pkg/types" 10 11 "github.com/khulnasoft-lab/defsec/pkg/framework" 12 13 "github.com/khulnasoft-lab/defsec/pkg/debug" 14 15 "github.com/khulnasoft-lab/defsec/pkg/scanners/options" 16 17 "github.com/khulnasoft-lab/defsec/pkg/rego" 18 "github.com/khulnasoft-lab/defsec/pkg/scan" 19 "github.com/khulnasoft-lab/defsec/pkg/scanners/yaml/parser" 20 ) 21 22 var _ options.ConfigurableScanner = (*Scanner)(nil) 23 24 type Scanner struct { 25 options []options.ScannerOption 26 debug debug.Logger 27 policyDirs []string 28 policyReaders []io.Reader 29 parser *parser.Parser 30 regoScanner *rego.Scanner 31 skipRequired bool 32 sync.Mutex 33 frameworks []framework.Framework 34 spec string 35 loadEmbeddedLibraries bool 36 loadEmbeddedPolicies bool 37 } 38 39 func (s *Scanner) SetRegoOnly(bool) {} 40 41 func (s *Scanner) SetFrameworks(frameworks []framework.Framework) { 42 s.frameworks = frameworks 43 } 44 45 func (s *Scanner) SetSpec(spec string) { 46 s.spec = spec 47 } 48 49 func (s *Scanner) SetUseEmbeddedPolicies(b bool) { 50 s.loadEmbeddedPolicies = b 51 } 52 53 func (s *Scanner) SetUseEmbeddedLibraries(b bool) { 54 s.loadEmbeddedLibraries = b 55 } 56 57 func (s *Scanner) Name() string { 58 return "YAML" 59 } 60 61 func (s *Scanner) SetPolicyReaders(readers []io.Reader) { 62 s.policyReaders = readers 63 } 64 65 func (s *Scanner) SetSkipRequiredCheck(skip bool) { 66 s.skipRequired = skip 67 } 68 69 func (s *Scanner) SetDebugWriter(writer io.Writer) { 70 s.debug = debug.New(writer, "yaml", "scanner") 71 } 72 73 func (s *Scanner) SetTraceWriter(_ io.Writer) {} 74 func (s *Scanner) SetPerResultTracingEnabled(_ bool) {} 75 76 func (s *Scanner) SetPolicyDirs(dirs ...string) { 77 s.policyDirs = dirs 78 } 79 80 func (s *Scanner) SetDataDirs(_ ...string) {} 81 func (s *Scanner) SetPolicyNamespaces(_ ...string) {} 82 83 func (s *Scanner) SetPolicyFilesystem(_ fs.FS) { 84 // handled by rego when option is passed on 85 } 86 func (s *Scanner) SetDataFilesystem(_ fs.FS) { 87 // handled by rego when option is passed on 88 } 89 func (s *Scanner) SetRegoErrorLimit(_ int) {} 90 91 func NewScanner(opts ...options.ScannerOption) *Scanner { 92 s := &Scanner{ 93 options: opts, 94 } 95 for _, opt := range opts { 96 opt(s) 97 } 98 s.parser = parser.New(options.ParserWithSkipRequiredCheck(s.skipRequired)) 99 return s 100 } 101 102 func (s *Scanner) ScanFS(ctx context.Context, fs fs.FS, path string) (scan.Results, error) { 103 104 fileset, err := s.parser.ParseFS(ctx, fs, path) 105 if err != nil { 106 return nil, err 107 } 108 109 if len(fileset) == 0 { 110 return nil, nil 111 } 112 113 var inputs []rego.Input 114 for path, files := range fileset { 115 for _, file := range files { 116 inputs = append(inputs, rego.Input{ 117 Path: path, 118 Contents: file, 119 FS: fs, 120 }) 121 } 122 } 123 124 results, err := s.scanRego(ctx, fs, inputs...) 125 if err != nil { 126 return nil, err 127 } 128 return results, nil 129 } 130 131 func (s *Scanner) ScanFile(ctx context.Context, fs fs.FS, path string) (scan.Results, error) { 132 parsed, err := s.parser.ParseFile(ctx, fs, path) 133 if err != nil { 134 return nil, err 135 } 136 s.debug.Log("Scanning %s...", path) 137 return s.scanRego(ctx, fs, rego.Input{ 138 Path: path, 139 Contents: parsed, 140 }) 141 } 142 143 func (s *Scanner) initRegoScanner(srcFS fs.FS) (*rego.Scanner, error) { 144 s.Lock() 145 defer s.Unlock() 146 if s.regoScanner != nil { 147 return s.regoScanner, nil 148 } 149 regoScanner := rego.NewScanner(types.SourceYAML, s.options...) 150 regoScanner.SetParentDebugLogger(s.debug) 151 if err := regoScanner.LoadPolicies(s.loadEmbeddedLibraries, s.loadEmbeddedPolicies, srcFS, s.policyDirs, s.policyReaders); err != nil { 152 return nil, err 153 } 154 s.regoScanner = regoScanner 155 return regoScanner, nil 156 } 157 158 func (s *Scanner) scanRego(ctx context.Context, srcFS fs.FS, inputs ...rego.Input) (scan.Results, error) { 159 regoScanner, err := s.initRegoScanner(srcFS) 160 if err != nil { 161 return nil, err 162 } 163 results, err := regoScanner.ScanInput(ctx, inputs...) 164 if err != nil { 165 return nil, err 166 } 167 results.SetSourceAndFilesystem("", srcFS, false) 168 return results, nil 169 }