Update MozDef event structure
This changes the MozDef event structure from a single json blob describing all changes and issues observed in a given account to multiple events, one for each "item" found by a "watcher", if that item has "issues". This allows for more granular searches in MozDef of the data. This also disabled alerting via email so all alerting now happens exclusively through MozDef
This commit is contained in:
Родитель
430e321b77
Коммит
163a2b4f75
|
@ -30,6 +30,20 @@ import jinja2
|
|||
import os.path
|
||||
from moz_security_monkey.common.utils.utils import publish_to_mozdef
|
||||
|
||||
|
||||
def get_summary(
|
||||
has_issues, has_new_issue, has_unjustified_issue, account,
|
||||
watcher_str):
|
||||
if has_new_issue:
|
||||
return "NEW ISSUE - [{}] Changes in {}".format(account, watcher_str)
|
||||
elif has_issues and has_unjustified_issue:
|
||||
return "[{}] Changes w/existing issues in {}".format(account, watcher_str)
|
||||
elif has_issues and not has_unjustified_issue:
|
||||
return "[{}] Changes w/justified issues in {}".format(account, watcher_str)
|
||||
else:
|
||||
return "[{}] Changes in {}".format(account, watcher_str)
|
||||
|
||||
|
||||
class Alerter(security_monkey.alerter.Alerter):
|
||||
|
||||
def report(self):
|
||||
|
@ -66,174 +80,67 @@ class Alerter(security_monkey.alerter.Alerter):
|
|||
if app.config.get('SQS_QUEUE_ARN'):
|
||||
# Intentionally leaving out new_item.get_pdiff_html() as we
|
||||
# don't need it
|
||||
watchers = [
|
||||
{'created_items': [
|
||||
{'account': new_item.account,
|
||||
'region': new_item.region,
|
||||
'name': new_item.name,
|
||||
'issues': {
|
||||
'new': [
|
||||
{'score': issue.score,
|
||||
'issue': issue.issue,
|
||||
'notes': issue.notes,
|
||||
'justification': {
|
||||
'justified': issue.justified,
|
||||
'user_name': (issue.user.name
|
||||
if issue.user is not None
|
||||
else None),
|
||||
'user_email': (issue.user.email
|
||||
if issue.user is not None
|
||||
else None),
|
||||
'date': issue.justified_date,
|
||||
'justification': issue.justification}}
|
||||
for issue in new_item.confirmed_new_issues],
|
||||
'fixed': [
|
||||
{'score': issue.score,
|
||||
'issue': issue.issue,
|
||||
'notes': issue.notes,
|
||||
'justification': {
|
||||
'justified': issue.justified,
|
||||
'user_name': (issue.user.name
|
||||
if issue.user is not None
|
||||
else None),
|
||||
'user_email': (issue.user.email
|
||||
if issue.user is not None
|
||||
else None),
|
||||
'date': issue.justified_date,
|
||||
'justification': issue.justification}}
|
||||
for issue in new_item.confirmed_fixed_issues],
|
||||
'existing': [
|
||||
{'score': issue.score,
|
||||
'issue': issue.issue,
|
||||
'notes': issue.notes,
|
||||
'justification': {
|
||||
'justified': issue.justified,
|
||||
'user_name': (issue.user.name
|
||||
if issue.user is not None
|
||||
else None),
|
||||
'user_email': (issue.user.email
|
||||
if issue.user is not None
|
||||
else None),
|
||||
'date': issue.justified_date,
|
||||
'justification': issue.justification}}
|
||||
for issue in new_item.confirmed_existing_issues]
|
||||
}
|
||||
}
|
||||
for new_item in (watcher.created_items if
|
||||
watcher.created() else [])],
|
||||
'changed_items': [
|
||||
{'account': new_item.account,
|
||||
'region': new_item.region,
|
||||
'name': new_item.name,
|
||||
'issues': {
|
||||
'new': [
|
||||
{'score': issue.score,
|
||||
'issue': issue.issue,
|
||||
'notes': issue.notes,
|
||||
'justification': {
|
||||
'justified': issue.justified,
|
||||
'user_name': (issue.user.name
|
||||
if issue.user is not None
|
||||
else None),
|
||||
'user_email': (issue.user.email
|
||||
if issue.user is not None
|
||||
else None),
|
||||
'date': issue.justified_date,
|
||||
'justification': issue.justification}}
|
||||
for issue in new_item.confirmed_new_issues],
|
||||
'fixed': [
|
||||
{'score': issue.score,
|
||||
'issue': issue.issue,
|
||||
'notes': issue.notes,
|
||||
'justification': {
|
||||
'justified': issue.justified,
|
||||
'user_name': (issue.user.name
|
||||
if issue.user is not None
|
||||
else None),
|
||||
'user_email': (issue.user.email
|
||||
if issue.user is not None
|
||||
else None),
|
||||
'date': issue.justified_date,
|
||||
'justification': issue.justification}}
|
||||
for issue in new_item.confirmed_fixed_issues],
|
||||
'existing': [
|
||||
{'score': issue.score,
|
||||
'issue': issue.issue,
|
||||
'notes': issue.notes,
|
||||
'justification': {
|
||||
'justified': issue.justified,
|
||||
'user_name': (issue.user.name
|
||||
if issue.user is not None
|
||||
else None),
|
||||
'user_email': (issue.user.email
|
||||
if issue.user is not None
|
||||
else None),
|
||||
'date': issue.justified_date,
|
||||
'justification': issue.justification}}
|
||||
for issue in new_item.confirmed_existing_issues]
|
||||
}
|
||||
}
|
||||
for new_item in (watcher.changed_items if
|
||||
watcher.changed() else [])],
|
||||
|
||||
'deleted_items': [
|
||||
{'account': new_item.account,
|
||||
'region': new_item.region,
|
||||
'name': new_item.name,
|
||||
'issues': {
|
||||
'new': [
|
||||
{'score': issue.score,
|
||||
'issue': issue.issue,
|
||||
'notes': issue.notes,
|
||||
'justification': {
|
||||
'justified': issue.justified,
|
||||
'user_name': (issue.user.name
|
||||
if issue.user is not None
|
||||
else None),
|
||||
'user_email': (issue.user.email
|
||||
if issue.user is not None
|
||||
else None),
|
||||
'date': issue.justified_date,
|
||||
'justification': issue.justification}}
|
||||
for issue in new_item.confirmed_new_issues],
|
||||
'fixed': [
|
||||
{'score': issue.score,
|
||||
'issue': issue.issue,
|
||||
'notes': issue.notes,
|
||||
'justification': {
|
||||
'justified': issue.justified,
|
||||
'user_name': (issue.user.name
|
||||
if issue.user is not None
|
||||
else None),
|
||||
'user_email': (issue.user.email
|
||||
if issue.user is not None
|
||||
else None),
|
||||
'date': issue.justified_date,
|
||||
'justification': issue.justification}}
|
||||
for issue in new_item.confirmed_fixed_issues],
|
||||
'existing': [
|
||||
{'score': issue.score,
|
||||
'issue': issue.issue,
|
||||
'notes': issue.notes,
|
||||
'justification': {
|
||||
'justified': issue.justified,
|
||||
'user_name': (issue.user.name
|
||||
if issue.user is not None
|
||||
else None),
|
||||
'user_email': (issue.user.email
|
||||
if issue.user is not None
|
||||
else None),
|
||||
'date': issue.justified_date,
|
||||
'justification': issue.justification}}
|
||||
for issue in new_item.confirmed_existing_issues]
|
||||
}
|
||||
}
|
||||
for new_item in (watcher.deleted_items if
|
||||
watcher.deleted() else [])]
|
||||
}
|
||||
for watcher in
|
||||
changed_watchers]
|
||||
publish_to_mozdef(summary=subject,
|
||||
details={'subject': subject,
|
||||
'watchers': watchers})
|
||||
return send_email(subject=subject, recipients=self.emails, html=body)
|
||||
for watcher in changed_watchers:
|
||||
for action in ["created", "changed", "deleted"]:
|
||||
for new_item in (
|
||||
getattr(watcher, action + "_items")
|
||||
if getattr(watcher, action)() else
|
||||
[]):
|
||||
issues = []
|
||||
for issue_type in ["new", "fixed", "existing"]:
|
||||
for issue_obj in getattr(
|
||||
new_item, "confirmed_" +
|
||||
issue_type + "_issues"):
|
||||
issue = {
|
||||
'type': issue_type,
|
||||
'score': issue_obj.score,
|
||||
'issue': issue_obj.issue,
|
||||
'notes': issue_obj.notes}
|
||||
if issue_obj.justified:
|
||||
issue['justification'] = {
|
||||
'user_name': (
|
||||
issue_obj.user.name
|
||||
if issue_obj.user is not None
|
||||
else None),
|
||||
'user_email': (
|
||||
issue_obj.user.email
|
||||
if issue_obj.user is not None
|
||||
else None),
|
||||
'date': issue_obj.justified_date,
|
||||
'justification': issue_obj.justification
|
||||
}
|
||||
issues.append(issue)
|
||||
(has_issues,
|
||||
has_new_issue,
|
||||
has_unjustified_issue) = watcher.issues_found()
|
||||
details = {'account_name': new_item.account,
|
||||
'region': new_item.region,
|
||||
'name': new_item.name,
|
||||
'action': action,
|
||||
'watcher': watcher.index,
|
||||
'has_issues': has_issues,
|
||||
'has_new_issue': has_new_issue,
|
||||
'has_unjustified_issue': has_unjustified_issue}
|
||||
summary = get_summary(
|
||||
has_issues,
|
||||
has_new_issue,
|
||||
has_unjustified_issue,
|
||||
self.account,
|
||||
watcher.index
|
||||
)
|
||||
if len(issues) > 0:
|
||||
details['issues'] = {}
|
||||
i = 0
|
||||
for issue in issues:
|
||||
i += 1
|
||||
details['issues'][i] = issue
|
||||
# If there are no issues with an item,
|
||||
# don't publish to mozdef
|
||||
# This behaviour deviates from the default
|
||||
# security monkey which emails items that have
|
||||
# no issues
|
||||
publish_to_mozdef(summary=summary,
|
||||
details=details)
|
||||
return True
|
||||
# return send_email(subject=subject, recipients=self.emails, html=body)
|
||||
|
|
Загрузка…
Ссылка в новой задаче