Skip to content

Commit 9369c89

Browse files
authored
Merge branch 'master' into custom_signatures
2 parents 0e32426 + 91b45b6 commit 9369c89

8 files changed

+234
-9
lines changed

blackduck/HubRestApi.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,11 +1275,17 @@ def remove_version_as_component(self, main_project_release, sub_project_release)
12751275

12761276
def upload_scan(self, filename):
12771277
url = self.get_apibase() + "/scan/data/?mode=replace"
1278-
files = {'file':open(filename,'rb')}
12791278
headers = self.get_headers()
1280-
headers['Content-Type'] = 'application/vnd.blackducksoftware.bdio+zip'
1281-
with open(filename,"rb") as f:
1282-
response = requests.post(url, headers=headers, data=f, verify=False)
1279+
if filename.endswith('.json') or filename.endswith('.jsonld'):
1280+
headers['Content-Type'] = 'application/ld+json'
1281+
with open(filename,"r") as f:
1282+
response = requests.post(url, headers=headers, data=f, verify=False)
1283+
elif filename.endswith('.bdio'):
1284+
headers['Content-Type'] = 'application/vnd.blackducksoftware.bdio+zip'
1285+
with open(filename,"rb") as f:
1286+
response = requests.post(url, headers=headers, data=f, verify=False)
1287+
else:
1288+
raise Exception("Unkown file type")
12831289
return response
12841290

12851291
def download_project_scans(self, project_name,version_name, output_folder=None):
@@ -1676,4 +1682,9 @@ def execute_post(self, url, data, custom_headers={}):
16761682
response = requests.post(url, headers=headers, data=json_data, verify = not self.config['insecure'])
16771683
return response
16781684

1679-
1685+
def get_matched_components(self, version_obj, limit=9999):
1686+
url = "{}/matched-files".format(version_obj['_meta']['href'])
1687+
param_string = self._get_parameter_string({'limit': limit})
1688+
url = "{}{}".format(url, param_string)
1689+
response = self.execute_get(url)
1690+
return response.json()

blackduck/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
VERSION = (0, 0, 45)
1+
VERSION = (0, 0, 46)
22

33
__version__ = '.'.join(map(str, VERSION))

examples/custom_signatures_export.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/local/bin/python2.7
1+
#!/usr/local/bin/python3
22
# encoding: utf-8
33
'''
44
examples.custom_signatures_export -- Exports project scan data for projects that have custom signatures enabled

examples/custom_signatures_import.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/local/bin/python2.7
1+
#!/usr/local/bin/python3
22
# encoding: utf-8
33
'''
44
examples.custom_signatures_import -- imports scan data for custom signatures

examples/generate_confidence_score.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/usr/bin/env python
2+
3+
import argparse
4+
import json
5+
import logging
6+
import sys
7+
8+
from blackduck.HubRestApi import HubInstance
9+
10+
parser = argparse.ArgumentParser("Generate Confidence Score Report")
11+
parser.add_argument("project_name")
12+
parser.add_argument("version")
13+
14+
args = parser.parse_args()
15+
16+
17+
hub = HubInstance()
18+
19+
project = hub.get_project_by_name(args.project_name)
20+
version = hub.get_version_by_name(project, args.version)
21+
22+
result = hub.get_matched_components(version)
23+
print(json.dumps(result))
24+
25+
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#!/usr/bin/env python
2+
3+
import argparse
4+
import json
5+
import csv
6+
import logging
7+
import sys
8+
9+
from blackduck.HubRestApi import HubInstance
10+
11+
12+
parser = argparse.ArgumentParser("Retreive BOM component license information for the given project and version")
13+
parser.add_argument("project_name")
14+
parser.add_argument("version")
15+
16+
args = parser.parse_args()
17+
18+
19+
hub = HubInstance()
20+
21+
project = hub.get_project_by_name(args.project_name)
22+
version = hub.get_version_by_name(project, args.version)
23+
24+
bom_components = hub.get_version_components(version)
25+
26+
all_origins = dict()
27+
28+
logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s', stream=sys.stderr, level=logging.DEBUG)
29+
logging.getLogger("requests").setLevel(logging.WARNING)
30+
logging.getLogger("urllib3").setLevel(logging.WARNING)
31+
32+
all_origin_info = {}
33+
components_info = [["Component Name", "Component Version" ,"Homepage", "Approval Status", "Component ID", "Component Version ID", "License"]]
34+
35+
for bom_component in bom_components['items']:
36+
component_url = bom_component['component']
37+
response = hub.execute_get(component_url)
38+
39+
# Component details include the home page url and additional home pages
40+
logging.debug("Retrieving component home page info for {}:{}".format(
41+
bom_component.get("componentName"), bom_component.get("componentVersionName")))
42+
component_details = None
43+
if response.status_code == 200:
44+
component_details = response.json()
45+
46+
for origin in bom_component.get('origins', []):
47+
logging.debug("Retrieving origin details for origin {}".format(origin['name']))
48+
origin_url = hub.get_link(origin, 'origin')
49+
response = hub.execute_get(origin_url)
50+
origin_details = None
51+
if response.status_code == 200:
52+
origin_details = response.json()
53+
54+
all_origin_info.update({
55+
"{}:{}".format(bom_component['componentName'], bom_component['componentVersionName']): {
56+
"component_details": component_details,
57+
"component_home_page": component_details.get("url"),
58+
"additional_home_pages": component_details.get("additionalHomepages"),
59+
"origin_details": origin_details,
60+
}
61+
})
62+
#component_info = [bom_component['componentName'], bom_component['componentVersionName'], component_details.get("url"), component_details['approvalStatus'], bom_component['component'], bom_component['componentVersion'], origin_details['license']['licenseDisplay']]
63+
component_info = [bom_component.get("componentName"), bom_component.get("componentVersionName"), component_details.get("url"), bom_component.get("approvalStatus"), bom_component.get("component"), bom_component.get("componentVersion"), origin_details.get('license').get("licenseDisplay")]
64+
components_info.append(component_info)
65+
66+
mycsv = csv.writer(open(r'Report.csv', 'w'), lineterminator='\n')
67+
for row in components_info:
68+
if any(row):
69+
mycsv.writerow(row)
70+
print("Report.csv is successfully generated")
71+
#print(json.dumps(all_origin_info))
72+

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+

examples/get_project_versions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def write_to_csv_file(filename, version_list):
6666
if args.phase:
6767
new_list = list()
6868
for version in sorted_version_list:
69-
if sorted_version_list['phase'] == phase_map[args.phase]:
69+
if version['phase'] == phase_map[args.phase]:
7070
new_list.append(version)
7171
sorted_version_list = new_list
7272
if args.limit:

0 commit comments

Comments
 (0)