Skip to content

Commit a9a3828

Browse files
author
Glenn Snyder
committed
adding sample showing how to retreive multiple notification types and filter them in various ways
1 parent f91bb80 commit a9a3828

File tree

1 file changed

+117
-0
lines changed

1 file changed

+117
-0
lines changed

examples/get_notifications.py

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
#!/usr/bin/env python
2+
3+
'''
4+
Created on May 19, 2020
5+
6+
@author: gsnyder
7+
8+
Retrieve notifications (a variant/derivative of get_vulnerability_notifications.py)
9+
10+
Note: The user account you run this under will determine the scope (i.e. projects, versions) of
11+
the notifications that can be received.
12+
13+
'''
14+
15+
import argparse
16+
from datetime import datetime
17+
import json
18+
import logging
19+
import pytz
20+
import sys
21+
import timestring
22+
23+
from terminaltables import AsciiTable
24+
25+
from blackduck.HubRestApi import HubInstance, object_id
26+
27+
#
28+
# Example usage:
29+
# To get help,
30+
# python3 examples/get_notifications.py -h
31+
#
32+
# To get policy rule violation notifications system-wide, since the beginning of "time"
33+
# python3 examples/get_notifications.py > notifications.json
34+
#
35+
# To get policy rule notifications system-wide, since a given date/time,
36+
# python3 examples/get_notifications.py -n "May 17, 2020" > notifications.json
37+
#
38+
# To get policy rule violations and policy override notifications, since a given date/time,
39+
# python3 examples/get_notifications.py -n "May 17, 2020" -t RULE_VIOLATION POLICY_OVERRIDE > notifications.json
40+
41+
ALL_NOTIFICATION_TYPES = [
42+
'RULE_VIOLATION',
43+
'RULE_VIOLATION_CLEARED',
44+
'POLICY_OVERRIDE',
45+
'VULNERABILITY',
46+
'PROJECT_VERSION',
47+
'PROJECT'
48+
]
49+
50+
parser = argparse.ArgumentParser("Retreive vulnerability notifications")
51+
parser.add_argument("-p", "--project", help="If supplied, filter the notifications to this project")
52+
parser.add_argument("-v", "--version", help="If supplied, filter the notifications to this version (requires a project)")
53+
parser.add_argument("-n", "--newer_than",
54+
default=None,
55+
type=str,
56+
help="Set this option to see all vulnerability notifications published since the given date/time.")
57+
parser.add_argument("-d", "--save_dt",
58+
action='store_true',
59+
help="If set, the date/time will be saved to a file named '.last_run' in the current directory which can be used later with the -n option to see vulnerabilities published since the last run.")
60+
parser.add_argument("-l", "--limit", default=100000, help="To change the limit on the number of notifications to retrieve")
61+
parser.add_argument("-s", "--system", action='store_true', help="Pull notifications from the system as opposed to the user's account")
62+
parser.add_argument("-t", "--types", nargs='+', default=['RULE_VIOLATION'], help="A list of notification types you want to retrieve")
63+
args = parser.parse_args()
64+
65+
if args.newer_than:
66+
newer_than = timestring.Date(args.newer_than).date
67+
# adjust to UTC so the comparison is normalized
68+
newer_than = newer_than.astimezone(pytz.utc)
69+
else:
70+
newer_than = None
71+
72+
if args.save_dt:
73+
with open(".last_run", "w") as f:
74+
f.write(datetime.now().isoformat())
75+
76+
logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s', stream=sys.stderr, level=logging.DEBUG)
77+
logging.getLogger("requests").setLevel(logging.WARNING)
78+
logging.getLogger("urllib3").setLevel(logging.WARNING)
79+
80+
hub = HubInstance()
81+
current_user = hub.get_current_user()
82+
83+
if args.system:
84+
notifications_url = "{}/api/notifications".format(hub.get_urlbase())
85+
else:
86+
notifications_url = hub.get_link(current_user, "notifications")
87+
88+
notifications_url = "{}?limit={}".format(notifications_url, args.limit)
89+
90+
filtered_notifications = []
91+
92+
notifications = hub.execute_get(notifications_url).json().get('items', [])
93+
94+
logging.debug("Total of {} notifications retrieved".format(len(notifications)))
95+
filtered_notifications = list(filter(lambda n: n['type'] in args.types, notifications))
96+
logging.debug("After filtering for notification types ({}) we are left with {} notifications".format(
97+
args.types, len(filtered_notifications)))
98+
99+
if newer_than:
100+
logging.debug("Filtering {} notifications to only include those after {}".format(
101+
len(filtered_notifications), newer_than))
102+
filtered_notifications = list(
103+
filter(lambda n: timestring.Date(n['createdAt']) > newer_than, filtered_notifications))
104+
logging.debug("{} notifications after filtering for those after {}".format(
105+
len(filtered_notifications), newer_than))
106+
107+
if args.project:
108+
filtered_notifications = list(
109+
filter(lambda n: args.project in [apv['projectName'] for apv in n['content']['affectedProjectVersions']],
110+
filtered_notifications))
111+
if args.version:
112+
filtered_notifications = list(
113+
filter(lambda n: args.version in [apv['projectVersionName'] for apv in n['content']['affectedProjectVersions']],
114+
filtered_notifications))
115+
116+
print(json.dumps(filtered_notifications))
117+

0 commit comments

Comments
 (0)