-
Notifications
You must be signed in to change notification settings - Fork 0
/
sbom_script.py
89 lines (64 loc) · 2.63 KB
/
sbom_script.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/usr/bin/python3
import requests
import json
import subprocess
snyk_sbom_api = "https://api.snyk.io/rest/orgs/"
version = '2023-09-20'
snyk_params = {'version':{version}, 'format':'cyclonedx1.4+json'}
config_file = 'sbom_poc_config.json'
def get_config():
try:
with open(config_file) as config:
config = json.load(config)
except:
exit(f"Unable to open config file {config_file}. Quitting")
return config
def get_all_projects_in_org(org_id, snyk_header):
#Retrieve all projects in a Snyk Organization
projects = []
url = f'{snyk_sbom_api}{org_id}/projects?version={version}&limit=100'
# pagination
while True:
response = requests.request(
'GET',
url,
headers=snyk_header
)
response_json = json.loads(response.content)
if 'data' in response_json:
projects = projects + response_json['data']
if 'next' not in response_json['links'] or response_json['links']['next'] == '':
break
url = f"{snyk_sbom_api}/{response_json['links']['next']}"
return projects
def mergeSBOMs(sbom_file_names):
# Merge sboms here with cyclonedx
command = ['cyclonedx', 'merge']
command += ['--input-files'] + sbom_file_names
command += ['--output-file', 'org_sbom.json', '--output-format', 'json']
subprocess.run(command)
def main():
sbom_file_names= []
final_proj_list = []
config = get_config()
snyk_header = {
'Authorization':'token ' + config['snyk_api_token'],
'Content-Type': 'application/json'
}
all_proj_list = get_all_projects_in_org(config['org_id'], snyk_header)
for project in all_proj_list:
if project['attributes']['type'] not in ['sast', 'cloudformationconfig', 'helmconfig', 'k8sconfig', 'terraformconfig']:
final_proj_list.append([project['id'], project['attributes']['name']])
for project_id in final_proj_list:
result = requests.get(snyk_sbom_api + config['org_id'] + '/projects/' + project_id[0] + '/sbom', params=snyk_params, headers=snyk_header)
if result.status_code != 200:
print(f"Failed to generate SBOM for {project_id} because {result.status_code}")
else:
out_file_name = f"sbom_{project_id[1].split('/')[-1]}.json"
sbom_file_names.append(out_file_name)
results = json.dumps(result.json(), indent=4)
with open(out_file_name,'w') as outfile:
outfile.write(results)
mergeSBOMs(sbom_file_names)
if __name__ == "__main__":
main()