|
| 1 | +import argparse |
| 2 | +from blackduck import Client |
| 3 | +from pprint import pprint |
| 4 | +import logging |
| 5 | +import sys |
| 6 | +import json |
| 7 | + |
| 8 | +logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s', stream=sys.stderr, level=logging.DEBUG) |
| 9 | +logging.getLogger("requests").setLevel(logging.INFO) |
| 10 | +logging.getLogger("urllib3").setLevel(logging.INFO) |
| 11 | +logging.getLogger("blackduck").setLevel(logging.INFO) |
| 12 | + |
| 13 | +def find_project_by_name(project_name): |
| 14 | + params = { |
| 15 | + 'q': [f"name:{project_name}"] |
| 16 | + } |
| 17 | + projects = [p for p in bd.get_resource('projects', params=params) if p['name'] == project_name] |
| 18 | + if len(projects) == 1: |
| 19 | + return projects[0] |
| 20 | + else: |
| 21 | + return None |
| 22 | + |
| 23 | +def find_project_version_by_name(project, version_name): |
| 24 | + params = { |
| 25 | + 'q': [f"versionName:{version_name}"] |
| 26 | + } |
| 27 | + versions = [v for v in bd.get_resource('versions', project, params=params) if v['versionName'] == version_name] |
| 28 | + if len(versions) == 1: |
| 29 | + return versions[0] |
| 30 | + else: |
| 31 | + return None |
| 32 | + |
| 33 | +def parse_command_args(): |
| 34 | + |
| 35 | + parser = argparse.ArgumentParser("product-from-bom.py") |
| 36 | + parser.add_argument("-u", "--base-url", required=True, help="Hub server URL e.g. https://your.blackduck.url") |
| 37 | + parser.add_argument("-t", "--token-file", required=True, help="File containing access token") |
| 38 | + parser.add_argument("-pn", "--project-name", required=True, help="Project Name") |
| 39 | + parser.add_argument("-vn", "--version-name", required=True, help="Version Name") |
| 40 | + parser.add_argument("-nv", "--no-verify", action='store_false', help="Disable TLS certificate verification") |
| 41 | + parser.add_argument("--reset", action='store_true') |
| 42 | + return parser.parse_args() |
| 43 | + |
| 44 | +def set_custom_field(field, url, value): |
| 45 | + payload = {"fields": [{"customField": field['_meta']['href'],"values": value}]} |
| 46 | + headers = {"Accept": "application/vnd.blackducksoftware.bill-of-materials-6+json", |
| 47 | + "Content-Type": "application/vnd.blackducksoftware.bill-of-materials-6+json"} |
| 48 | + response = bd.session.put(url, data=json.dumps(payload), headers=headers) |
| 49 | + print(response) |
| 50 | + |
| 51 | +def process_project_version(args): |
| 52 | + project = find_project_by_name(args.project_name) |
| 53 | + version = find_project_version_by_name(project, args.version_name) |
| 54 | + |
| 55 | + components = bd.get_resource('components',version) |
| 56 | + for component in components: |
| 57 | + print (component['componentName'], component['componentVersionName']) |
| 58 | + custom_fields = bd.get_resource('custom-fields',component, items=False) |
| 59 | + custom_fields_url = custom_fields['_meta']['href'] |
| 60 | + c = [x for x in custom_fields['items'] if x['label'] == 'BadCrypto'][0] |
| 61 | + resources = bd.list_resources(component) |
| 62 | + if 'crypto-algorithms' in resources.keys(): |
| 63 | + crypto_algorithms = bd.get_resource('crypto-algorithms', component) |
| 64 | + for crypto in crypto_algorithms: |
| 65 | + if crypto['knownWeaknesses']: |
| 66 | + pprint('Has Weakness') |
| 67 | + value = ['true'] |
| 68 | + if args.reset: |
| 69 | + value = [] |
| 70 | + set_custom_field(c, custom_fields_url, value=value) |
| 71 | + break |
| 72 | + |
| 73 | +def main(): |
| 74 | + args = parse_command_args() |
| 75 | + with open(args.token_file, 'r') as tf: |
| 76 | + access_token = tf.readline().strip() |
| 77 | + global bd |
| 78 | + bd = Client(base_url=args.base_url, token=access_token, verify=args.no_verify, timeout=60.0, retries=4) |
| 79 | + |
| 80 | + process_project_version(args) |
| 81 | + |
| 82 | +if __name__ == "__main__": |
| 83 | + sys.exit(main()) |
| 84 | + |
0 commit comments