Batch QSS notifications after initial scan
This commit is contained in:
parent
c54a99b2c2
commit
eff1827d9d
3 changed files with 60 additions and 21 deletions
|
@ -9,6 +9,7 @@ from endpoints.notificationhelper import spawn_notification
|
|||
from data.database import ExternalNotificationEvent, IMAGE_NOT_SCANNED_ENGINE_VERSION, Image
|
||||
from data.model.tag import filter_tags_have_repository_event, get_tags_for_image
|
||||
from data.model.image import set_secscan_status, get_image_with_storage_and_parent_base
|
||||
from util.secscan import PRIORITY_LEVELS
|
||||
from util.secscan.api import (APIRequestFailure, AnalyzeLayerException, MissingParentLayerException,
|
||||
InvalidLayerException, AnalyzeLayerRetryException)
|
||||
from util.morecollections import AttrDict
|
||||
|
@ -150,30 +151,45 @@ class LayerAnalyzer(object):
|
|||
found_features = layer_data['Layer'].get('Features', [])
|
||||
for repository_id in repository_map:
|
||||
tags = repository_map[repository_id]
|
||||
vulnerabilities = dict()
|
||||
|
||||
# Collect all the vulnerabilities found for the layer under each repository and send
|
||||
# as a batch notification.
|
||||
for feature in found_features:
|
||||
if 'Vulnerabilities' not in feature:
|
||||
continue
|
||||
|
||||
for vulnerability in feature.get('Vulnerabilities', []):
|
||||
event_data = {
|
||||
'tags': [tag.name for tag in tags],
|
||||
'vulnerability': {
|
||||
'id': vulnerability['Name'],
|
||||
'description': vulnerability.get('Description', None),
|
||||
'link': vulnerability.get('Link', None),
|
||||
'has_fix': 'FixedBy' in vulnerability,
|
||||
vuln_data = {
|
||||
'id': vulnerability['Name'],
|
||||
'description': vulnerability.get('Description', None),
|
||||
'link': vulnerability.get('Link', None),
|
||||
'has_fix': 'FixedBy' in vulnerability,
|
||||
|
||||
# TODO: Change this key name if/when we change the event format.
|
||||
'priority': vulnerability.get('Severity', 'Unknown'),
|
||||
},
|
||||
# TODO: Change this key name if/when we change the event format.
|
||||
'priority': vulnerability.get('Severity', 'Unknown'),
|
||||
}
|
||||
|
||||
# TODO(jzelinskie): remove when more endpoints have been converted to using
|
||||
# interfaces
|
||||
repository = AttrDict({
|
||||
'namespace_name': tags[0].repository.namespace_user.username,
|
||||
'name': tags[0].repository.name,
|
||||
})
|
||||
vulnerabilities[vulnerability['Name']] = vuln_data
|
||||
|
||||
spawn_notification(repository, 'vulnerability_found', event_data)
|
||||
# TODO(jzelinskie): remove when more endpoints have been converted to using
|
||||
# interfaces
|
||||
repository = AttrDict({
|
||||
'namespace_name': tags[0].repository.namespace_user.username,
|
||||
'name': tags[0].repository.name,
|
||||
})
|
||||
|
||||
repo_vulnerabilities = list(vulnerabilities.values())
|
||||
if not repo_vulnerabilities:
|
||||
continue
|
||||
|
||||
priority_key = lambda v: PRIORITY_LEVELS.get(v['priority'], {}).get('index', 100)
|
||||
repo_vulnerabilities.sort(key=priority_key)
|
||||
|
||||
event_data = {
|
||||
'tags': [tag.name for tag in tags],
|
||||
'vulnerabilities': repo_vulnerabilities,
|
||||
'vulnerability': repo_vulnerabilities[0], # For back-compat with existing events.
|
||||
}
|
||||
|
||||
spawn_notification(repository, 'vulnerability_found', event_data)
|
||||
|
|
Reference in a new issue