Skip to content

Commit eb60926

Browse files
author
Murat Kumykov
committed
SAP custom signature export/import
1 parent f52598c commit eb60926

File tree

3 files changed

+340
-0
lines changed

3 files changed

+340
-0
lines changed

blackduck/HubRestApi.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -803,6 +803,14 @@ def get_version_components(self, projectversion, limit=1000):
803803
response = requests.get(url, headers=headers, verify = not self.config['insecure'])
804804
jsondata = response.json()
805805
return jsondata
806+
807+
def update_project_settings(self, project, new_settings={}):
808+
url = project['_meta']['href']
809+
headers = self.get_headers()
810+
headers['Accept'] = 'application/vnd.blackducksoftware.project-detail-4+json'
811+
headers['Content-Type'] = 'application/vnd.blackducksoftware.project-detail-4+json'
812+
response = self.execute_put(url, new_settings, headers)
813+
return response
806814

807815
def update_project_version_settings(self, project_name, version_name, new_settings={}):
808816
# Apply any new settings to the given project version

examples/custom_signatures_export.py

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
#!/usr/local/bin/python2.7
2+
# encoding: utf-8
3+
'''
4+
examples.custom_signatures_export -- Exports project scan data for projects that have custom signatures enabled
5+
6+
examples.custom_signatures_export
7+
8+
Exports scans for all projects that have custom signature enabled
9+
All scans will be placed in the output directory.
10+
A metadata file will be written to specify project names and versions.
11+
Metadata will be used to identify projects that will require custom signature flag enabled
12+
13+
@author: kumykov
14+
15+
@copyright: 2020 Synopsys Inc. All rights reserved.
16+
17+
@license: Apache License 2.0
18+
19+
20+
@deffield updated: Updated
21+
'''
22+
23+
import sys
24+
import os
25+
26+
from argparse import ArgumentParser
27+
from argparse import RawDescriptionHelpFormatter
28+
from blackduck.HubRestApi import HubInstance
29+
import json
30+
31+
__all__ = []
32+
__version__ = 0.1
33+
__date__ = '2020-05-05'
34+
__updated__ = '2020-05-05'
35+
36+
DEBUG = 0
37+
TESTRUN = 0
38+
PROFILE = 0
39+
40+
class CLIError(Exception):
41+
'''Generic exception to raise and log different fatal errors.'''
42+
def __init__(self, msg):
43+
super(CLIError).__init__(type(self))
44+
self.msg = "E: %s" % msg
45+
def __str__(self):
46+
return self.msg
47+
def __unicode__(self):
48+
return self.msg
49+
50+
'''
51+
'''
52+
53+
def get_custom_signatures(hub):
54+
projects=hub.get_projects()
55+
custom_signatures=list()
56+
for project in projects['items']:
57+
if project["customSignatureEnabled"]:
58+
custom_signatures.append(project)
59+
return custom_signatures
60+
61+
def download_project_scans(project):
62+
pass
63+
64+
def main(argv=None): # IGNORE:C0111
65+
'''Command line options.'''
66+
67+
if argv is None:
68+
argv = sys.argv
69+
else:
70+
sys.argv.extend(argv)
71+
72+
program_name = os.path.basename(sys.argv[0])
73+
program_version = "v%s" % __version__
74+
program_build_date = str(__updated__)
75+
program_version_message = '%%(prog)s %s (%s)' % (program_version, program_build_date)
76+
program_shortdesc = __import__('__main__').__doc__.split("\n")[1]
77+
program_license = '''%s
78+
79+
Created by user_name on %s.
80+
Copyright 2020 organization_name. All rights reserved.
81+
82+
Licensed under the Apache License 2.0
83+
http://www.apache.org/licenses/LICENSE-2.0
84+
85+
Distributed on an "AS IS" basis without warranties
86+
or conditions of any kind, either express or implied.
87+
88+
USAGE
89+
''' % (program_shortdesc, str(__date__))
90+
91+
try:
92+
# Setup argument parser
93+
parser = ArgumentParser(description=program_license, formatter_class=RawDescriptionHelpFormatter)
94+
parser.add_argument(dest="output_path", help="path to folder to store exported data")
95+
96+
# Process arguments
97+
args = parser.parse_args()
98+
99+
output_path = args.output_path
100+
101+
## Do shit
102+
# print (output_path)
103+
# print (args)
104+
105+
workdir = os.path.abspath(output_path)
106+
107+
print(workdir)
108+
109+
hub=HubInstance()
110+
111+
projects = get_custom_signatures(hub)
112+
113+
metadata = {"magic": "CSMD001", "content": {}}
114+
metadata_path = os.path.join(workdir, "metadata.json")
115+
116+
for project in projects:
117+
project_name = project['name']
118+
versions = hub.get_project_versions(project)
119+
version_metadata = []
120+
metadata['content'][project_name] = version_metadata
121+
for version in versions['items']:
122+
version_name = version['versionName']
123+
version_metadata.append(version_name)
124+
codelocations = hub.get_version_codelocations(version)
125+
for codelocation in codelocations['items']:
126+
#print(json.dumps(codelocation,indent=2))
127+
scanurl=codelocation['_meta']['href'].replace('codelocations','scan/data') + ".bdio"
128+
print (scanurl)
129+
filename = scanurl.split('/')[6]
130+
if not os.path.exists(workdir):
131+
os.mkdir(workdir)
132+
pathname = os.path.join(workdir, filename)
133+
responce = hub.execute_get(scanurl, custom_headers=hub.get_headers())
134+
with open(pathname, "wb") as f:
135+
for data in responce.iter_content():
136+
f.write(data)
137+
print("File {} written".format(pathname))
138+
139+
# print(json.dumps(get_custom_signatures(hub),indent=2))
140+
141+
print("Writing metadata file")
142+
with open(metadata_path, 'w') as outfile:
143+
json.dump(metadata, outfile)
144+
print("Done.")
145+
146+
### handle keyboard interrupt ###
147+
return 0
148+
except Exception as e:
149+
if DEBUG or TESTRUN:
150+
raise(e)
151+
indent = len(program_name) * " "
152+
sys.stderr.write(program_name + ": " + repr(e) + "\n")
153+
sys.stderr.write(indent + " for help use --help")
154+
return 2
155+
156+
if __name__ == "__main__":
157+
if DEBUG:
158+
sys.argv.append("-h")
159+
sys.argv.append("-v")
160+
if TESTRUN:
161+
import doctest
162+
doctest.testmod()
163+
if PROFILE:
164+
import cProfile
165+
import pstats
166+
profile_filename = 'examples.custom_signatures_export_profile.txt'
167+
cProfile.run('main()', profile_filename)
168+
statsfile = open("profile_stats.txt", "wb")
169+
p = pstats.Stats(profile_filename, stream=statsfile)
170+
stats = p.strip_dirs().sort_stats('cumulative')
171+
stats.print_stats()
172+
statsfile.close()
173+
sys.exit(0)
174+
sys.exit(main())

examples/custom_signatures_import.py

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
#!/usr/local/bin/python2.7
2+
# encoding: utf-8
3+
'''
4+
examples.custom_signatures_import -- imports scan data for custom signatures
5+
6+
examples.custom_signatures_import
7+
8+
Used output of custom_signature_export
9+
It will create project structure according to the metadata.json file
10+
and enable custom signature flags for each project created
11+
12+
Then it will upload all scan files to Blackduck instnce.
13+
Once scan files are processed, custom signatures will be ready to use.
14+
15+
@author: kumykov
16+
17+
@copyright: 2020 Synopsys Inc. All rights reserved.
18+
19+
@license: Apache License 2.0
20+
21+
22+
@deffield updated: Updated
23+
'''
24+
25+
import sys
26+
import os
27+
28+
from argparse import ArgumentParser
29+
from argparse import RawDescriptionHelpFormatter
30+
from blackduck.HubRestApi import HubInstance
31+
import json
32+
33+
__all__ = []
34+
__version__ = 0.1
35+
__date__ = '2020-05-05'
36+
__updated__ = '2020-05-05'
37+
38+
DEBUG = 0
39+
TESTRUN = 0
40+
PROFILE = 0
41+
42+
class CLIError(Exception):
43+
'''Generic exception to raise and log different fatal errors.'''
44+
def __init__(self, msg):
45+
super(CLIError).__init__(type(self))
46+
self.msg = "E: %s" % msg
47+
def __str__(self):
48+
return self.msg
49+
def __unicode__(self):
50+
return self.msg
51+
52+
def read_metadata_file(metadata_path):
53+
with open(metadata_path) as json_file:
54+
data = json.load(json_file)
55+
if data['magic'] == "CSMD001":
56+
return data
57+
else:
58+
raise Exception ("Bad metadata.")
59+
60+
def create_projects(hub, metadata):
61+
for project_name in metadata['content']:
62+
for version_name in metadata['content'][project_name]:
63+
version = hub.get_or_create_project_version(project_name, version_name)
64+
project = hub.get_project_by_name(project_name)
65+
if not project['customSignatureEnabled']:
66+
print ("Enabling custom signature for {}".format(project['name']))
67+
project['customSignatureEnabled'] = True
68+
response = hub.update_project_settings(project, new_settings=project)
69+
print (response)
70+
else:
71+
print ("Custom signature for {} already enabled".format(project_name))
72+
73+
def upload_scan_data(hub, workdir):
74+
with (os.scandir(workdir)) as entries:
75+
for entry in entries:
76+
pathname = entry.path
77+
if pathname.endswith('.bdio'):
78+
print("Uploading {}".format(pathname), end = ". ")
79+
response = hub.upload_scan(pathname)
80+
print ("Response {}".format(response))
81+
82+
def main(argv=None): # IGNORE:C0111
83+
'''Command line options.'''
84+
85+
if argv is None:
86+
argv = sys.argv
87+
else:
88+
sys.argv.extend(argv)
89+
90+
program_name = os.path.basename(sys.argv[0])
91+
program_version = "v%s" % __version__
92+
program_build_date = str(__updated__)
93+
program_version_message = '%%(prog)s %s (%s)' % (program_version, program_build_date)
94+
program_shortdesc = __import__('__main__').__doc__.split("\n")[1]
95+
program_license = '''%s
96+
97+
Created by user_name on %s.
98+
Copyright 2020 organization_name. All rights reserved.
99+
100+
Licensed under the Apache License 2.0
101+
http://www.apache.org/licenses/LICENSE-2.0
102+
103+
Distributed on an "AS IS" basis without warranties
104+
or conditions of any kind, either express or implied.
105+
106+
USAGE
107+
''' % (program_shortdesc, str(__date__))
108+
109+
try:
110+
# Setup argument parser
111+
parser = ArgumentParser(description=program_license, formatter_class=RawDescriptionHelpFormatter)
112+
parser.add_argument(dest="input_path", help="path to folder to store exported data")
113+
114+
# Process arguments
115+
args = parser.parse_args()
116+
117+
input_path = args.input_path
118+
119+
workdir = os.path.abspath(input_path)
120+
metadata_path = os.path.join(workdir, "metadata.json")
121+
print("Reading metadata from {} ".format(metadata_path))
122+
metadata = read_metadata_file(metadata_path)
123+
124+
hub=HubInstance()
125+
126+
create_projects(hub, metadata)
127+
128+
upload_scan_data(hub, workdir)
129+
130+
131+
return 0
132+
except Exception as e:
133+
if DEBUG or TESTRUN:
134+
raise(e)
135+
indent = len(program_name) * " "
136+
sys.stderr.write(program_name + ": " + repr(e) + "\n")
137+
sys.stderr.write(indent + " for help use --help")
138+
return 2
139+
140+
if __name__ == "__main__":
141+
if DEBUG:
142+
sys.argv.append("-v")
143+
sys.argv.append("-h")
144+
if TESTRUN:
145+
import doctest
146+
doctest.testmod()
147+
if PROFILE:
148+
import cProfile
149+
import pstats
150+
profile_filename = 'examples.custom_signatures_import_profile.txt'
151+
cProfile.run('main()', profile_filename)
152+
statsfile = open("profile_stats.txt", "wb")
153+
p = pstats.Stats(profile_filename, stream=statsfile)
154+
stats = p.strip_dirs().sort_stats('cumulative')
155+
stats.print_stats()
156+
statsfile.close()
157+
sys.exit(0)
158+
sys.exit(main())

0 commit comments

Comments
 (0)