Files
trivy/pkg/rpc/convert.go
2023-11-02 01:46:32 +00:00

934 lines
30 KiB
Go

package rpc
import (
"time"
"github.com/samber/lo"
"google.golang.org/protobuf/types/known/structpb"
"google.golang.org/protobuf/types/known/timestamppb"
dbTypes "github.com/aquasecurity/trivy-db/pkg/types"
"github.com/aquasecurity/trivy/pkg/digest"
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
"github.com/aquasecurity/trivy/pkg/log"
"github.com/aquasecurity/trivy/pkg/types"
"github.com/aquasecurity/trivy/rpc/cache"
"github.com/aquasecurity/trivy/rpc/common"
"github.com/aquasecurity/trivy/rpc/scanner"
)
var LicenseCategoryMap = map[common.LicenseCategory_Enum]ftypes.LicenseCategory{
common.LicenseCategory_UNSPECIFIED: "",
common.LicenseCategory_FORBIDDEN: ftypes.CategoryForbidden,
common.LicenseCategory_RESTRICTED: ftypes.CategoryRestricted,
common.LicenseCategory_RECIPROCAL: ftypes.CategoryReciprocal,
common.LicenseCategory_NOTICE: ftypes.CategoryNotice,
common.LicenseCategory_PERMISSIVE: ftypes.CategoryPermissive,
common.LicenseCategory_UNENCUMBERED: ftypes.CategoryUnencumbered,
common.LicenseCategory_UNKNOWN: ftypes.CategoryUnknown,
}
var LicenseTypeMap = map[common.LicenseType_Enum]ftypes.LicenseType{
common.LicenseType_UNSPECIFIED: "",
common.LicenseType_DPKG: ftypes.LicenseTypeDpkg,
common.LicenseType_HEADER: ftypes.LicenseTypeHeader,
common.LicenseType_LICENSE_FILE: ftypes.LicenseTypeFile,
}
// ByValueOr returns the key from the map of the first matched value,
// or default key if the value is not present.
func ByValueOr[K, V comparable](m map[K]V, val V, d K) K {
for k, v := range m {
if v == val {
return k
}
}
return d
}
// ConvertToRPCPkgs returns the list of RPC package objects
func ConvertToRPCPkgs(pkgs []ftypes.Package) []*common.Package {
var rpcPkgs []*common.Package
for _, pkg := range pkgs {
rpcPkgs = append(rpcPkgs, &common.Package{
Id: pkg.ID,
Name: pkg.Name,
Version: pkg.Version,
Release: pkg.Release,
Epoch: int32(pkg.Epoch),
Arch: pkg.Arch,
Dev: pkg.Dev,
SrcName: pkg.SrcName,
SrcVersion: pkg.SrcVersion,
SrcRelease: pkg.SrcRelease,
SrcEpoch: int32(pkg.SrcEpoch),
Licenses: pkg.Licenses,
Layer: ConvertToRPCLayer(pkg.Layer),
FilePath: pkg.FilePath,
DependsOn: pkg.DependsOn,
Digest: pkg.Digest.String(),
Indirect: pkg.Indirect,
})
}
return rpcPkgs
}
func ConvertToRPCCustomResources(resources []ftypes.CustomResource) []*common.CustomResource {
var rpcResources []*common.CustomResource
for _, r := range resources {
data, err := structpb.NewValue(r.Data)
if err != nil {
log.Logger.Warn(err)
}
rpcResources = append(rpcResources, &common.CustomResource{
Type: r.Type,
FilePath: r.FilePath,
Layer: &common.Layer{
Digest: r.Layer.Digest,
DiffId: r.Layer.DiffID,
},
Data: data,
})
}
return rpcResources
}
func ConvertToRPCCode(code ftypes.Code) *common.Code {
var rpcLines []*common.Line
for _, line := range code.Lines {
rpcLines = append(rpcLines, &common.Line{
Number: int32(line.Number),
Content: line.Content,
IsCause: line.IsCause,
Annotation: line.Annotation,
Truncated: line.Truncated,
Highlighted: line.Highlighted,
FirstCause: line.FirstCause,
LastCause: line.LastCause,
})
}
return &common.Code{
Lines: rpcLines,
}
}
func ConvertToRPCSecrets(secrets []ftypes.Secret) []*common.Secret {
var rpcSecrets []*common.Secret
for _, s := range secrets {
rpcSecrets = append(rpcSecrets, &common.Secret{
Filepath: s.FilePath,
Findings: ConvertToRPCSecretFindings(s.Findings),
})
}
return rpcSecrets
}
func ConvertToRPCSecretFindings(findings []ftypes.SecretFinding) []*common.SecretFinding {
var rpcFindings []*common.SecretFinding
for _, f := range findings {
rpcFindings = append(rpcFindings, &common.SecretFinding{
RuleId: f.RuleID,
Category: string(f.Category),
Severity: f.Severity,
Title: f.Title,
EndLine: int32(f.EndLine),
StartLine: int32(f.StartLine),
Code: ConvertToRPCCode(f.Code),
Match: f.Match,
Layer: ConvertToRPCLayer(f.Layer),
})
}
return rpcFindings
}
func ConvertToRPCLicenseFiles(licenses []ftypes.LicenseFile) []*common.LicenseFile {
var rpcLicenses []*common.LicenseFile
for _, lic := range licenses {
rpcLicenses = append(rpcLicenses, &common.LicenseFile{
LicenseType: ConvertToRPCLicenseType(lic.Type),
FilePath: lic.FilePath,
PkgName: lic.PkgName,
Fingings: ConvertToRPCLicenseFindings(lic.Findings),
Layer: ConvertToRPCLayer(lic.Layer),
})
}
return rpcLicenses
}
func ConvertToRPCLicenseFindings(findings ftypes.LicenseFindings) []*common.LicenseFinding {
var rpcFindings []*common.LicenseFinding
for _, f := range findings {
rpcFindings = append(rpcFindings, &common.LicenseFinding{
Category: ConvertToRPCLicenseCategory(f.Category),
Name: f.Name,
Confidence: float32(f.Confidence),
Link: f.Link,
})
}
return rpcFindings
}
// ConvertFromRPCPkgs returns list of Fanal package objects
func ConvertFromRPCPkgs(rpcPkgs []*common.Package) []ftypes.Package {
var pkgs []ftypes.Package
for _, pkg := range rpcPkgs {
pkgs = append(pkgs, ftypes.Package{
ID: pkg.Id,
Name: pkg.Name,
Version: pkg.Version,
Release: pkg.Release,
Epoch: int(pkg.Epoch),
Arch: pkg.Arch,
Dev: pkg.Dev,
SrcName: pkg.SrcName,
SrcVersion: pkg.SrcVersion,
SrcRelease: pkg.SrcRelease,
SrcEpoch: int(pkg.SrcEpoch),
Licenses: pkg.Licenses,
Layer: ConvertFromRPCLayer(pkg.Layer),
FilePath: pkg.FilePath,
DependsOn: pkg.DependsOn,
Digest: digest.Digest(pkg.Digest),
Indirect: pkg.Indirect,
})
}
return pkgs
}
// ConvertToRPCVulns returns common.Vulnerability
func ConvertToRPCVulns(vulns []types.DetectedVulnerability) []*common.Vulnerability {
var rpcVulns []*common.Vulnerability
for _, vuln := range vulns {
severity, err := dbTypes.NewSeverity(vuln.Severity)
if err != nil {
log.Logger.Warn(err)
}
cvssMap := make(map[string]*common.CVSS) // This is needed because protobuf generates a map[string]*CVSS type
for vendor, vendorSeverity := range vuln.CVSS {
cvssMap[string(vendor)] = &common.CVSS{
V2Vector: vendorSeverity.V2Vector,
V3Vector: vendorSeverity.V3Vector,
V2Score: vendorSeverity.V2Score,
V3Score: vendorSeverity.V3Score,
}
}
vensorSeverityMap := make(map[string]common.Severity)
for vendor, vendorSeverity := range vuln.VendorSeverity {
vensorSeverityMap[string(vendor)] = common.Severity(vendorSeverity)
}
var lastModifiedDate, publishedDate *timestamppb.Timestamp
if vuln.LastModifiedDate != nil {
lastModifiedDate = timestamppb.New(*vuln.LastModifiedDate) // nolint: errcheck
}
if vuln.PublishedDate != nil {
publishedDate = timestamppb.New(*vuln.PublishedDate) // nolint: errcheck
}
var customAdvisoryData, customVulnData *structpb.Value
if vuln.Custom != nil {
customAdvisoryData, _ = structpb.NewValue(vuln.Custom) // nolint: errcheck
}
if vuln.Vulnerability.Custom != nil {
customVulnData, _ = structpb.NewValue(vuln.Vulnerability.Custom) // nolint: errcheck
}
rpcVulns = append(rpcVulns, &common.Vulnerability{
VulnerabilityId: vuln.VulnerabilityID,
VendorIds: vuln.VendorIDs,
PkgId: vuln.PkgID,
PkgName: vuln.PkgName,
PkgPath: vuln.PkgPath,
InstalledVersion: vuln.InstalledVersion,
FixedVersion: vuln.FixedVersion,
Status: int32(vuln.Status),
Title: vuln.Title,
Description: vuln.Description,
Severity: common.Severity(severity),
VendorSeverity: vensorSeverityMap,
References: vuln.References,
Layer: ConvertToRPCLayer(vuln.Layer),
Cvss: cvssMap,
SeveritySource: string(vuln.SeveritySource),
CweIds: vuln.CweIDs,
PrimaryUrl: vuln.PrimaryURL,
LastModifiedDate: lastModifiedDate,
PublishedDate: publishedDate,
CustomAdvisoryData: customAdvisoryData,
CustomVulnData: customVulnData,
DataSource: ConvertToRPCDataSource(vuln.DataSource),
})
}
return rpcVulns
}
// ConvertToRPCMisconfs returns common.DetectedMisconfigurations
func ConvertToRPCMisconfs(misconfs []types.DetectedMisconfiguration) []*common.DetectedMisconfiguration {
var rpcMisconfs []*common.DetectedMisconfiguration
for _, m := range misconfs {
severity, err := dbTypes.NewSeverity(m.Severity)
if err != nil {
log.Logger.Warn(err)
}
rpcMisconfs = append(rpcMisconfs, &common.DetectedMisconfiguration{
Type: m.Type,
Id: m.ID,
AvdId: m.AVDID,
Title: m.Title,
Description: m.Description,
Message: m.Message,
Namespace: m.Namespace,
Query: m.Query,
Resolution: m.Resolution,
Severity: common.Severity(severity),
PrimaryUrl: m.PrimaryURL,
References: m.References,
Status: string(m.Status),
Layer: ConvertToRPCLayer(m.Layer),
CauseMetadata: ConvertToRPCCauseMetadata(m.CauseMetadata),
})
}
return rpcMisconfs
}
// ConvertToRPCLayer returns common.Layer
func ConvertToRPCLayer(layer ftypes.Layer) *common.Layer {
return &common.Layer{
Digest: layer.Digest,
DiffId: layer.DiffID,
CreatedBy: layer.CreatedBy,
}
}
func ConvertToRPCPolicyMetadata(policy ftypes.PolicyMetadata) *common.PolicyMetadata {
return &common.PolicyMetadata{
Id: policy.ID,
AdvId: policy.AVDID,
Type: policy.Type,
Title: policy.Title,
Description: policy.Description,
Severity: policy.Severity,
RecommendedActions: policy.RecommendedActions,
References: policy.References,
}
}
func ConvertToRPCCauseMetadata(cause ftypes.CauseMetadata) *common.CauseMetadata {
return &common.CauseMetadata{
Resource: cause.Resource,
Provider: cause.Provider,
Service: cause.Service,
StartLine: int32(cause.StartLine),
EndLine: int32(cause.EndLine),
Code: ConvertToRPCCode(cause.Code),
}
}
// ConvertToRPCDataSource returns common.DataSource
func ConvertToRPCDataSource(ds *dbTypes.DataSource) *common.DataSource {
if ds == nil {
return nil
}
return &common.DataSource{
Id: string(ds.ID),
Name: ds.Name,
Url: ds.URL,
}
}
// ConvertFromRPCResults converts scanner.Result to types.Result
func ConvertFromRPCResults(rpcResults []*scanner.Result) []types.Result {
var results []types.Result
for _, result := range rpcResults {
results = append(results, types.Result{
Target: result.Target,
Vulnerabilities: ConvertFromRPCVulns(result.Vulnerabilities),
Misconfigurations: ConvertFromRPCMisconfs(result.Misconfigurations),
Class: types.ResultClass(result.Class),
Type: ftypes.TargetType(result.Type),
Packages: ConvertFromRPCPkgs(result.Packages),
CustomResources: ConvertFromRPCCustomResources(result.CustomResources),
Secrets: ConvertFromRPCSecretFindings(result.Secrets),
Licenses: ConvertFromRPCDetectedLicenses(result.Licenses),
})
}
return results
}
func ConvertFromRPCDetectedLicenses(rpcLicenses []*common.DetectedLicense) []types.DetectedLicense {
var licenses []types.DetectedLicense
for _, l := range rpcLicenses {
severity := dbTypes.Severity(l.Severity)
licenses = append(licenses, types.DetectedLicense{
Severity: severity.String(),
Category: ConvertFromRPCLicenseCategory(l.Category),
PkgName: l.PkgName,
FilePath: l.FilePath,
Name: l.Name,
Confidence: float64(l.Confidence),
Link: l.Link,
})
}
return licenses
}
func ConvertFromRPCLicenseCategory(rpcCategory common.LicenseCategory_Enum) ftypes.LicenseCategory {
return lo.ValueOr(LicenseCategoryMap, rpcCategory, "")
}
func ConvertFromRPCLicenseType(rpcLicenseType common.LicenseType_Enum) ftypes.LicenseType {
return lo.ValueOr(LicenseTypeMap, rpcLicenseType, "")
}
// ConvertFromRPCCustomResources converts array of cache.CustomResource to fanal.CustomResource
func ConvertFromRPCCustomResources(rpcCustomResources []*common.CustomResource) []ftypes.CustomResource {
var resources []ftypes.CustomResource
for _, res := range rpcCustomResources {
resources = append(resources, ftypes.CustomResource{
Type: res.Type,
FilePath: res.FilePath,
Layer: ftypes.Layer{
Digest: res.Layer.Digest,
DiffID: res.Layer.DiffId,
},
Data: res.Data,
})
}
return resources
}
func ConvertFromRPCCode(rpcCode *common.Code) ftypes.Code {
var lines []ftypes.Line
for _, line := range rpcCode.Lines {
lines = append(lines, ftypes.Line{
Number: int(line.Number),
Content: line.Content,
IsCause: line.IsCause,
Annotation: line.Annotation,
Truncated: line.Truncated,
Highlighted: line.Highlighted,
FirstCause: line.FirstCause,
LastCause: line.LastCause,
})
}
return ftypes.Code{
Lines: lines,
}
}
func ConvertFromRPCSecretFindings(rpcFindings []*common.SecretFinding) []ftypes.SecretFinding {
var findings []ftypes.SecretFinding
for _, finding := range rpcFindings {
findings = append(findings, ftypes.SecretFinding{
RuleID: finding.RuleId,
Category: ftypes.SecretRuleCategory(finding.Category),
Severity: finding.Severity,
Title: finding.Title,
StartLine: int(finding.StartLine),
EndLine: int(finding.EndLine),
Code: ConvertFromRPCCode(finding.Code),
Match: finding.Match,
Layer: ftypes.Layer{
Digest: finding.Layer.Digest,
DiffID: finding.Layer.DiffId,
CreatedBy: finding.Layer.CreatedBy,
},
})
}
return findings
}
func ConvertFromRPCSecrets(recSecrets []*common.Secret) []ftypes.Secret {
var secrets []ftypes.Secret
for _, secret := range recSecrets {
secrets = append(secrets, ftypes.Secret{
FilePath: secret.Filepath,
Findings: ConvertFromRPCSecretFindings(secret.Findings),
})
}
return secrets
}
func ConvertFromRPCLicenseFiles(rpcLicenses []*common.LicenseFile) []ftypes.LicenseFile {
var licenses []ftypes.LicenseFile
for _, lic := range rpcLicenses {
licenses = append(licenses, ftypes.LicenseFile{
Type: ConvertFromRPCLicenseType(lic.LicenseType),
FilePath: lic.FilePath,
PkgName: lic.PkgName,
Findings: ConvertFromRPCLicenseFindings(lic.Fingings),
Layer: ConvertFromRPCLayer(lic.Layer),
})
}
return licenses
}
func ConvertFromRPCLicenseFindings(rpcFindings []*common.LicenseFinding) ftypes.LicenseFindings {
var findings ftypes.LicenseFindings
for _, finding := range rpcFindings {
findings = append(findings, ftypes.LicenseFinding{
Category: ConvertFromRPCLicenseCategory(finding.Category),
Name: finding.Name,
Confidence: float64(finding.Confidence),
Link: finding.Link,
})
}
return findings
}
// ConvertFromRPCVulns converts []*common.Vulnerability to []types.DetectedVulnerability
func ConvertFromRPCVulns(rpcVulns []*common.Vulnerability) []types.DetectedVulnerability {
var vulns []types.DetectedVulnerability
for _, vuln := range rpcVulns {
severity := dbTypes.Severity(vuln.Severity)
cvssMap := make(dbTypes.VendorCVSS) // This is needed because protobuf generates a map[string]*CVSS type
for vendor, vendorSeverity := range vuln.Cvss {
cvssMap[dbTypes.SourceID(vendor)] = dbTypes.CVSS{
V2Vector: vendorSeverity.V2Vector,
V3Vector: vendorSeverity.V3Vector,
V2Score: vendorSeverity.V2Score,
V3Score: vendorSeverity.V3Score,
}
}
vensorSeverityMap := make(dbTypes.VendorSeverity)
for vendor, vendorSeverity := range vuln.VendorSeverity {
vensorSeverityMap[dbTypes.SourceID(vendor)] = dbTypes.Severity(vendorSeverity)
}
var lastModifiedDate, publishedDate *time.Time
if vuln.LastModifiedDate != nil {
lastModifiedDate = lo.ToPtr(vuln.LastModifiedDate.AsTime())
}
if vuln.PublishedDate != nil {
publishedDate = lo.ToPtr(vuln.PublishedDate.AsTime())
}
vulns = append(vulns, types.DetectedVulnerability{
VulnerabilityID: vuln.VulnerabilityId,
VendorIDs: vuln.VendorIds,
PkgID: vuln.PkgId,
PkgName: vuln.PkgName,
PkgPath: vuln.PkgPath,
InstalledVersion: vuln.InstalledVersion,
FixedVersion: vuln.FixedVersion,
Status: dbTypes.Status(vuln.Status),
Vulnerability: dbTypes.Vulnerability{
Title: vuln.Title,
Description: vuln.Description,
Severity: severity.String(),
CVSS: cvssMap,
References: vuln.References,
CweIDs: vuln.CweIds,
LastModifiedDate: lastModifiedDate,
PublishedDate: publishedDate,
Custom: vuln.CustomVulnData.AsInterface(),
VendorSeverity: vensorSeverityMap,
},
Layer: ConvertFromRPCLayer(vuln.Layer),
SeveritySource: dbTypes.SourceID(vuln.SeveritySource),
PrimaryURL: vuln.PrimaryUrl,
Custom: vuln.CustomAdvisoryData.AsInterface(),
DataSource: ConvertFromRPCDataSource(vuln.DataSource),
})
}
return vulns
}
// ConvertFromRPCMisconfs converts []*common.DetectedMisconfigurations to []types.DetectedMisconfiguration
func ConvertFromRPCMisconfs(rpcMisconfs []*common.DetectedMisconfiguration) []types.DetectedMisconfiguration {
var misconfs []types.DetectedMisconfiguration
for _, rpcMisconf := range rpcMisconfs {
misconfs = append(misconfs, types.DetectedMisconfiguration{
Type: rpcMisconf.Type,
ID: rpcMisconf.Id,
AVDID: rpcMisconf.AvdId,
Title: rpcMisconf.Title,
Description: rpcMisconf.Description,
Message: rpcMisconf.Message,
Namespace: rpcMisconf.Namespace,
Query: rpcMisconf.Query,
Resolution: rpcMisconf.Resolution,
Severity: rpcMisconf.Severity.String(),
PrimaryURL: rpcMisconf.PrimaryUrl,
References: rpcMisconf.References,
Status: types.MisconfStatus(rpcMisconf.Status),
Layer: ConvertFromRPCLayer(rpcMisconf.Layer),
CauseMetadata: ConvertFromRPCCauseMetadata(rpcMisconf.CauseMetadata),
})
}
return misconfs
}
// ConvertFromRPCLayer converts *common.Layer to fanal.Layer
func ConvertFromRPCLayer(rpcLayer *common.Layer) ftypes.Layer {
if rpcLayer == nil {
return ftypes.Layer{}
}
return ftypes.Layer{
Digest: rpcLayer.Digest,
DiffID: rpcLayer.DiffId,
CreatedBy: rpcLayer.CreatedBy,
}
}
func ConvertFromRPCPolicyMetadata(rpcPolicy *common.PolicyMetadata) ftypes.PolicyMetadata {
if rpcPolicy == nil {
return ftypes.PolicyMetadata{}
}
return ftypes.PolicyMetadata{
ID: rpcPolicy.Id,
AVDID: rpcPolicy.AdvId,
Type: rpcPolicy.Type,
Title: rpcPolicy.Title,
Description: rpcPolicy.Description,
Severity: rpcPolicy.Severity,
RecommendedActions: rpcPolicy.RecommendedActions,
References: rpcPolicy.References,
}
}
func ConvertFromRPCCauseMetadata(rpcCause *common.CauseMetadata) ftypes.CauseMetadata {
if rpcCause == nil {
return ftypes.CauseMetadata{}
}
return ftypes.CauseMetadata{
Resource: rpcCause.Resource,
Provider: rpcCause.Provider,
Service: rpcCause.Service,
StartLine: int(rpcCause.StartLine),
EndLine: int(rpcCause.EndLine),
Code: ConvertFromRPCCode(rpcCause.Code),
}
}
// ConvertFromRPCOS converts common.OS to fanal.OS
func ConvertFromRPCOS(rpcOS *common.OS) ftypes.OS {
if rpcOS == nil {
return ftypes.OS{}
}
return ftypes.OS{
Family: ftypes.OSType(rpcOS.Family),
Name: rpcOS.Name,
Eosl: rpcOS.Eosl,
Extended: rpcOS.Extended,
}
}
// ConvertFromRPCRepository converts common.Repository to fanal.Repository
func ConvertFromRPCRepository(rpcRepo *common.Repository) *ftypes.Repository {
if rpcRepo == nil {
return nil
}
return &ftypes.Repository{
Family: ftypes.OSType(rpcRepo.Family),
Release: rpcRepo.Release,
}
}
// ConvertFromRPCDataSource converts *common.DataSource to *dbTypes.DataSource
func ConvertFromRPCDataSource(ds *common.DataSource) *dbTypes.DataSource {
if ds == nil {
return nil
}
return &dbTypes.DataSource{
ID: dbTypes.SourceID(ds.Id),
Name: ds.Name,
URL: ds.Url,
}
}
// ConvertFromRPCPackageInfos converts common.PackageInfo to fanal.PackageInfo
func ConvertFromRPCPackageInfos(rpcPkgInfos []*common.PackageInfo) []ftypes.PackageInfo {
var pkgInfos []ftypes.PackageInfo
for _, rpcPkgInfo := range rpcPkgInfos {
pkgInfos = append(pkgInfos, ftypes.PackageInfo{
FilePath: rpcPkgInfo.FilePath,
Packages: ConvertFromRPCPkgs(rpcPkgInfo.Packages),
})
}
return pkgInfos
}
// ConvertFromRPCApplications converts common.Application to fanal.Application
func ConvertFromRPCApplications(rpcApps []*common.Application) []ftypes.Application {
var apps []ftypes.Application
for _, rpcApp := range rpcApps {
apps = append(apps, ftypes.Application{
Type: ftypes.LangType(rpcApp.Type),
FilePath: rpcApp.FilePath,
Libraries: ConvertFromRPCPkgs(rpcApp.Libraries),
})
}
return apps
}
// ConvertFromRPCMisconfigurations converts common.Misconfiguration to fanal.Misconfiguration
func ConvertFromRPCMisconfigurations(rpcMisconfs []*common.Misconfiguration) []ftypes.Misconfiguration {
var misconfs []ftypes.Misconfiguration
for _, rpcMisconf := range rpcMisconfs {
misconfs = append(misconfs, ftypes.Misconfiguration{
FileType: ftypes.ConfigType(rpcMisconf.FileType),
FilePath: rpcMisconf.FilePath,
Successes: ConvertFromRPCMisconfResults(rpcMisconf.Successes),
Warnings: ConvertFromRPCMisconfResults(rpcMisconf.Warnings),
Failures: ConvertFromRPCMisconfResults(rpcMisconf.Failures),
Exceptions: ConvertFromRPCMisconfResults(rpcMisconf.Exceptions),
Layer: ftypes.Layer{},
})
}
return misconfs
}
// ConvertFromRPCMisconfResults converts common.MisconfResult to fanal.MisconfResult
func ConvertFromRPCMisconfResults(rpcResults []*common.MisconfResult) []ftypes.MisconfResult {
var results []ftypes.MisconfResult
for _, r := range rpcResults {
results = append(results, ftypes.MisconfResult{
Namespace: r.Namespace,
Message: r.Message,
PolicyMetadata: ConvertFromRPCPolicyMetadata(r.PolicyMetadata),
CauseMetadata: ConvertFromRPCCauseMetadata(r.CauseMetadata),
})
}
return results
}
// ConvertFromRPCPutArtifactRequest converts cache.PutArtifactRequest to fanal.PutArtifactRequest
func ConvertFromRPCPutArtifactRequest(req *cache.PutArtifactRequest) ftypes.ArtifactInfo {
return ftypes.ArtifactInfo{
SchemaVersion: int(req.ArtifactInfo.SchemaVersion),
Architecture: req.ArtifactInfo.Architecture,
Created: req.ArtifactInfo.Created.AsTime(),
DockerVersion: req.ArtifactInfo.DockerVersion,
OS: req.ArtifactInfo.Os,
HistoryPackages: ConvertFromRPCPkgs(req.ArtifactInfo.HistoryPackages),
}
}
// ConvertFromRPCPutBlobRequest returns ftypes.BlobInfo
func ConvertFromRPCPutBlobRequest(req *cache.PutBlobRequest) ftypes.BlobInfo {
return ftypes.BlobInfo{
SchemaVersion: int(req.BlobInfo.SchemaVersion),
Digest: req.BlobInfo.Digest,
DiffID: req.BlobInfo.DiffId,
OS: ConvertFromRPCOS(req.BlobInfo.Os),
Repository: ConvertFromRPCRepository(req.BlobInfo.Repository),
PackageInfos: ConvertFromRPCPackageInfos(req.BlobInfo.PackageInfos),
Applications: ConvertFromRPCApplications(req.BlobInfo.Applications),
Misconfigurations: ConvertFromRPCMisconfigurations(req.BlobInfo.Misconfigurations),
OpaqueDirs: req.BlobInfo.OpaqueDirs,
WhiteoutFiles: req.BlobInfo.WhiteoutFiles,
CustomResources: ConvertFromRPCCustomResources(req.BlobInfo.CustomResources),
Secrets: ConvertFromRPCSecrets(req.BlobInfo.Secrets),
Licenses: ConvertFromRPCLicenseFiles(req.BlobInfo.Licenses),
}
}
// ConvertToRPCOS returns common.OS
func ConvertToRPCOS(fos ftypes.OS) *common.OS {
return &common.OS{
Family: string(fos.Family),
Name: fos.Name,
Eosl: fos.Eosl,
Extended: fos.Extended,
}
}
// ConvertToRPCRepository returns common.Repository
func ConvertToRPCRepository(repo *ftypes.Repository) *common.Repository {
if repo == nil {
return nil
}
return &common.Repository{
Family: string(repo.Family),
Release: repo.Release,
}
}
// ConvertToRPCArtifactInfo returns PutArtifactRequest
func ConvertToRPCArtifactInfo(imageID string, imageInfo ftypes.ArtifactInfo) *cache.PutArtifactRequest {
t := timestamppb.New(imageInfo.Created)
if err := t.CheckValid(); err != nil {
log.Logger.Warnf("invalid timestamp: %s", err)
}
return &cache.PutArtifactRequest{
ArtifactId: imageID,
ArtifactInfo: &cache.ArtifactInfo{
SchemaVersion: int32(imageInfo.SchemaVersion),
Architecture: imageInfo.Architecture,
Created: t,
DockerVersion: imageInfo.DockerVersion,
Os: imageInfo.OS,
HistoryPackages: ConvertToRPCPkgs(imageInfo.HistoryPackages),
},
}
}
// ConvertToRPCPutBlobRequest returns PutBlobRequest
func ConvertToRPCPutBlobRequest(diffID string, blobInfo ftypes.BlobInfo) *cache.PutBlobRequest {
var packageInfos []*common.PackageInfo
for _, pkgInfo := range blobInfo.PackageInfos {
packageInfos = append(packageInfos, &common.PackageInfo{
FilePath: pkgInfo.FilePath,
Packages: ConvertToRPCPkgs(pkgInfo.Packages),
})
}
var applications []*common.Application
for _, app := range blobInfo.Applications {
applications = append(applications, &common.Application{
Type: string(app.Type),
FilePath: app.FilePath,
Libraries: ConvertToRPCPkgs(app.Libraries),
})
}
var misconfigurations []*common.Misconfiguration
for _, m := range blobInfo.Misconfigurations {
misconfigurations = append(misconfigurations, &common.Misconfiguration{
FileType: string(m.FileType),
FilePath: m.FilePath,
Successes: ConvertToMisconfResults(m.Successes),
Warnings: ConvertToMisconfResults(m.Warnings),
Failures: ConvertToMisconfResults(m.Failures),
Exceptions: ConvertToMisconfResults(m.Exceptions),
})
}
var customResources []*common.CustomResource
for _, res := range blobInfo.CustomResources {
data, err := structpb.NewValue(res.Data)
if err != nil {
} else {
customResources = append(customResources, &common.CustomResource{
Type: res.Type,
FilePath: res.FilePath,
Layer: &common.Layer{
Digest: res.Layer.Digest,
DiffId: res.Layer.DiffID,
},
Data: data,
})
}
}
return &cache.PutBlobRequest{
DiffId: diffID,
BlobInfo: &cache.BlobInfo{
SchemaVersion: ftypes.BlobJSONSchemaVersion,
Digest: blobInfo.Digest,
DiffId: blobInfo.DiffID,
Os: ConvertToRPCOS(blobInfo.OS),
Repository: ConvertToRPCRepository(blobInfo.Repository),
PackageInfos: packageInfos,
Applications: applications,
Misconfigurations: misconfigurations,
OpaqueDirs: blobInfo.OpaqueDirs,
WhiteoutFiles: blobInfo.WhiteoutFiles,
CustomResources: customResources,
Secrets: ConvertToRPCSecrets(blobInfo.Secrets),
Licenses: ConvertToRPCLicenseFiles(blobInfo.Licenses),
},
}
}
// ConvertToMisconfResults returns common.MisconfResult
func ConvertToMisconfResults(results []ftypes.MisconfResult) []*common.MisconfResult {
var rpcResults []*common.MisconfResult
for _, r := range results {
rpcResults = append(rpcResults, &common.MisconfResult{
Namespace: r.Namespace,
Message: r.Message,
PolicyMetadata: ConvertToRPCPolicyMetadata(r.PolicyMetadata),
CauseMetadata: ConvertToRPCCauseMetadata(r.CauseMetadata),
})
}
return rpcResults
}
// ConvertToMissingBlobsRequest returns MissingBlobsRequest object
func ConvertToMissingBlobsRequest(imageID string, layerIDs []string) *cache.MissingBlobsRequest {
return &cache.MissingBlobsRequest{
ArtifactId: imageID,
BlobIds: layerIDs,
}
}
// ConvertToRPCScanResponse converts types.Result to ScanResponse
func ConvertToRPCScanResponse(results types.Results, fos ftypes.OS) *scanner.ScanResponse {
var rpcResults []*scanner.Result
for _, result := range results {
rpcResults = append(rpcResults, &scanner.Result{
Target: result.Target,
Class: string(result.Class),
Type: string(result.Type),
Vulnerabilities: ConvertToRPCVulns(result.Vulnerabilities),
Misconfigurations: ConvertToRPCMisconfs(result.Misconfigurations),
Packages: ConvertToRPCPkgs(result.Packages),
CustomResources: ConvertToRPCCustomResources(result.CustomResources),
Secrets: ConvertToRPCSecretFindings(result.Secrets),
Licenses: ConvertToRPCLicenses(result.Licenses),
})
}
return &scanner.ScanResponse{
Os: ConvertToRPCOS(fos),
Results: rpcResults,
}
}
func ConvertToRPCLicenses(licenses []types.DetectedLicense) []*common.DetectedLicense {
var rpcLicenses []*common.DetectedLicense
for _, l := range licenses {
severity, err := dbTypes.NewSeverity(l.Severity)
if err != nil {
log.Logger.Warn(err)
}
rpcLicenses = append(rpcLicenses, &common.DetectedLicense{
Severity: common.Severity(severity),
Category: ConvertToRPCLicenseCategory(l.Category),
PkgName: l.PkgName,
FilePath: l.FilePath,
Name: l.Name,
Confidence: float32(l.Confidence),
Link: l.Link,
})
}
return rpcLicenses
}
func ConvertToRPCLicenseCategory(category ftypes.LicenseCategory) common.LicenseCategory_Enum {
return ByValueOr(LicenseCategoryMap, category, common.LicenseCategory_UNSPECIFIED)
}
func ConvertToRPCLicenseType(ty ftypes.LicenseType) common.LicenseType_Enum {
return ByValueOr(LicenseTypeMap, ty, common.LicenseType_UNSPECIFIED)
}
func ConvertToDeleteBlobsRequest(blobIDs []string) *cache.DeleteBlobsRequest {
return &cache.DeleteBlobsRequest{BlobIds: blobIDs}
}
func ConvertFromDeleteBlobsRequest(deleteBlobsRequest *cache.DeleteBlobsRequest) []string {
if deleteBlobsRequest == nil {
return []string{}
}
return deleteBlobsRequest.GetBlobIds()
}