/
analyzer.go
99 lines (87 loc) · 2.45 KB
/
analyzer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package analyzer
import (
"context"
"io/fs"
"sync"
"github.com/aquasecurity/fanal/analyzer"
_ "github.com/aquasecurity/fanal/analyzer/all"
"github.com/aquasecurity/fanal/artifact"
_ "github.com/aquasecurity/fanal/hook/all"
"github.com/aquasecurity/fanal/types"
dio "github.com/aquasecurity/go-dep-parser/pkg/io"
api "github.com/chaitin/libveinmind/go"
"github.com/chaitin/veinmind-tools/veinmind-asset/model"
"golang.org/x/sync/semaphore"
)
func ScanImage(image api.Image, parallel int64) (model.ScanImageResult, error) {
ctx := context.Background()
limit := semaphore.NewWeighted(parallel)
// TODO 扫描配置开放
var artifactOpt artifact.Option
var analysisOpt analyzer.AnalysisOptions
ag := analyzer.NewAnalyzerGroup(artifactOpt.AnalyzerGroup, artifactOpt.DisabledAnalyzers)
var wg sync.WaitGroup
res := new(analyzer.AnalysisResult)
image.Walk("/", func(path string, info fs.FileInfo, err error) error {
open := func() (dio.ReadSeekCloserAt, error) {
file, err := image.Open(path)
if err != nil {
return nil, err
}
return file, nil
}
ag.AnalyzeFile(ctx, &wg, limit, res, "", path, info, open, nil, analysisOpt)
return nil
})
wg.Wait()
res.Sort()
blobInfo := types.BlobInfo{
SchemaVersion: types.BlobJSONSchemaVersion,
Digest: "",
OS: res.OS,
Repository: res.Repository,
PackageInfos: res.PackageInfos,
Applications: res.Applications,
SystemFiles: res.SystemInstalledFiles,
OpaqueDirs: []string{},
WhiteoutFiles: []string{},
CustomResources: res.CustomResources,
// For Red Hat
BuildInfo: res.BuildInfo,
}
//result = append(result, blobInfo)
//artifactDetail := applier.ApplyLayers(result)
return parseResults(image, blobInfo)
}
func parseResults(image api.Image, res types.BlobInfo) (model.ScanImageResult, error) {
name, err := image.Repos()
id := image.ID()
if err != nil {
return model.ScanImageResult{}, err
}
if len(name) == 0 {
name = append(name, id)
}
os := types.OS{}
// os判空,否则可能会导致空指针
if res.OS != nil {
os = *res.OS
}
// format results
scanRes := model.ScanImageResult{
ImageName: name[0],
ImageID: id,
ImageOSInfo: os,
PackageTotal: len(res.PackageInfos),
PackageInfos: res.PackageInfos,
ApplicationTotal: func() int {
var a int
for _, lib := range res.Applications {
a += len(lib.Libraries)
}
return a
}(),
Applications: res.Applications,
}
return scanRes, nil
}