in internal/vulnerability/events_creator.go [223:356]
func (e EventsCreator) generateEvent(reportResult trivyTypes.Result, vul trivyTypes.DetectedVulnerability, instance ec2.Ec2Instance, seq time.Time) beat.Event {
timestamp := time.Now().UTC()
sequence := seq.Unix()
cloudSec, err := convertStructToMapStr(CloudSection{
Instance: Instance{
Id: instance.GetResourceId(),
Name: instance.GetResourceName(),
},
Service: Service{
// TODO: Support more services
Name: "AWS EC2",
},
Machine: Machine{
Type: string(instance.InstanceType),
Authentication: AuthInfo{
Key: instance.KeyName,
},
LaunchTime: instance.LaunchTime,
Image: instance.ImageId,
},
AvailabilityZone: getAvailabilityZone(instance),
Region: instance.Region,
Tags: instance.GetResourceTags(),
Security: Security{
SecurityGroups: instance.GetResourceSecurityGroups(),
},
})
// TODO: Should we fail the event if we can't enrich the cloud section?
if err != nil {
e.log.Errorf("failed to enrich cloud section: %v", err)
}
hostSec, err := convertStructToMapStr(HostSection{
Architecture: string(instance.Architecture),
Os: Os{
// TODO: Investigate how to get the full os name
// Property "Platform PlatformValues" shows
// the value Windows for Windows instances; otherwise blank
// this only gives us information if the platform is windows or not
// picked "PlatformDetails" as it gives us more information
Platform: instance.PlatformDetails,
},
Name: instance.GetResourceName(),
})
// TODO: Should we fail the event if we can't enrich the host section?
if err != nil {
e.log.Errorf("failed to enrich host section: %v", err)
}
networkSec, err := convertStructToMapStr(NetworkSection{
PrivateIp: instance.PrivateIpAddress,
PublicIp: instance.PublicIpAddress,
MacAddresses: instance.GetResourceMacAddresses(),
})
// TODO: Should we fail the event if we can't enrich the network section?
if err != nil {
e.log.Errorf("failed to enrich network section: %v", err)
}
event := beat.Event{
// TODO: Maybe configure or get from somewhere else?
Meta: mapstr.M{libevents.FieldMetaIndex: e.index},
Timestamp: timestamp,
Fields: mapstr.M{
// TODO: Replace sequence with more generic approach
"event": transformer.BuildECSEvent(sequence, timestamp, []string{vulEcsCategory}, transformer.EcsOutcomeSuccess),
// Deprecated replaced by cloud and host fields
"resource": Resource{
ID: instance.GetResourceId(),
Name: instance.GetResourceName(),
},
"package": Package{
Path: reportResult.Target,
Type: string(reportResult.Type),
Name: vul.PkgName,
Version: vul.InstalledVersion,
FixedVersion: vul.FixedVersion,
},
"vulnerability": Vulnerability{
// TODO: Replace sequence with more generic approach
// TODO: Do we need to add the ReportID duplication if we already have the sequence in event?
ReportId: sequence,
// Deprecated field Class renamed to Category
Class: reportResult.Class,
Category: reportResult.Class,
Cvss: getCVSS(vul),
DataSource: getDataSource(vul),
Scanner: Scanner{
// TODO: Populate with what?
Version: vulScannerVersion,
Vendor: vulScannerVendor,
},
Score: Score{
Base: e.getCVSSScore(vul),
Version: e.getCVSSVersion(vul),
},
Package: Package{ // kept for backward compatibility, new obj is under root
Name: vul.PkgName,
Version: vul.InstalledVersion,
FixedVersion: vul.FixedVersion,
},
Cwe: vul.CweIDs,
ID: vul.VulnerabilityID,
Title: vul.Title,
Enumeration: getIdentifierType(vul.VulnerabilityID),
Reference: getReference(vul),
Description: vul.Description,
Severity: vul.Severity,
Classification: vulScoreSystemClass,
PublishedDate: vul.PublishedDate,
},
// TODO: These sections might be overridden by the enricher of proccessor
"cloud": cloudSec,
"host": hostSec,
"network": networkSec,
},
}
err = e.cloudDataProvider.EnrichEvent(&event, fetching.ResourceMetadata{Region: instance.Region})
if err != nil {
e.log.Errorf("failed to enrich event with benchmark data provider: %v", err)
}
err = e.commonDataProvider.EnrichEvent(&event)
if err != nil {
e.log.Errorf("failed to enrich event with global data provider: %v", err)
}
return event
}