|
| 1 | +#!/usr/bin/env python |
| 2 | + |
| 3 | +''' |
| 4 | +Created on Sep 2, 2020 |
| 5 | +
|
| 6 | +@author: gsnyder |
| 7 | +
|
| 8 | +Parse the Synopsys Detect log to get the status.json file emitted and use status.json to monitor |
| 9 | +the scans (codelocations) and wait for the scan processing to complete |
| 10 | +''' |
| 11 | + |
| 12 | +import argparse |
| 13 | +import arrow |
| 14 | +import json |
| 15 | +import logging |
| 16 | +import re |
| 17 | +import sys |
| 18 | +import time |
| 19 | +from tzlocal import get_localzone # pip install tzlocal |
| 20 | + |
| 21 | +from blackduck.HubRestApi import HubInstance, object_id |
| 22 | + |
| 23 | +# Ensure your PYTHONPATH includes the folder where this class is defined |
| 24 | +from wait_for_scan_results import ScanMonitor |
| 25 | + |
| 26 | + |
| 27 | +parser = argparse.ArgumentParser("Parse the Synopsys Detect log, load status.json, and wait for all scan processing to complete") |
| 28 | +parser.add_argument("-d", "--detect_log", help="By default, this script will read the detect log from stdin, but you can alternatively supply a detect log filename") |
| 29 | +# parser.add_argument('-m', '--max_checks', type=int, default=10, help="Set the maximum number of checks before quitting") |
| 30 | +# parser.add_argument('-t', '--time_between_checks', type=int, default=5, help="Set the number of seconds to wait in-between checks") |
| 31 | +# parser.add_argument('-s', '--snippet_scan', action='store_true', help="Select this option if you want to wait for a snippet scan to complete along with it's corresponding component scan.") |
| 32 | +args = parser.parse_args() |
| 33 | + |
| 34 | +logging.basicConfig(format='%(asctime)s:%(levelname)s:%(message)s', stream=sys.stderr, level=logging.DEBUG) |
| 35 | +logging.getLogger("requests").setLevel(logging.WARNING) |
| 36 | +logging.getLogger("urllib3").setLevel(logging.WARNING) |
| 37 | + |
| 38 | +if args.detect_log: |
| 39 | + detect_log = open(args.detect_log, 'r') |
| 40 | +else: |
| 41 | + detect_log = sys.stdin |
| 42 | + |
| 43 | +snippet_scan = False |
| 44 | +status_file_path = None |
| 45 | +start_time = None |
| 46 | + |
| 47 | +for line in detect_log.readlines(): |
| 48 | + if not start_time: |
| 49 | + start_time_re = re.search("(.*) INFO .*", line) |
| 50 | + if start_time_re: |
| 51 | + start_time = arrow.get(start_time_re[1], tzinfo=get_localzone()) |
| 52 | + logging.debug(f"Found detect start time {start_time}") |
| 53 | + |
| 54 | + cleanup_prop = re.search(".*detect.cleanup = (true|false).*", line) |
| 55 | + if cleanup_prop: |
| 56 | + if cleanup_prop[1] == 'true': |
| 57 | + logging.error("You must use --detect.cleanup=false to preserve the status.json file, exiting") |
| 58 | + sys.exit(1) |
| 59 | + |
| 60 | + snippet_matching_re = re.search(".*detect.blackduck.signature.scanner.snippet.matching = (.*)", line) |
| 61 | + if snippet_matching_re: |
| 62 | + if 'SNIPPET' in snippet_matching_re[1]: |
| 63 | + snippet_scan = True |
| 64 | + logging.debug("Found snippet scanning option") |
| 65 | + |
| 66 | + status_file_re = re.search(".*Creating status file: (.*)", line) |
| 67 | + if status_file_re: |
| 68 | + status_file_path = status_file_re[1] |
| 69 | + logging.debug(f"Found status.json path {status_file_path}") |
| 70 | + |
| 71 | +assert start_time, "Hmm, not sure how that happened but we need a start time" |
| 72 | + |
| 73 | +logging.debug(f"detect start time: {start_time}") |
| 74 | +logging.debug(f"snippet_scan: {snippet_scan}") |
| 75 | +logging.debug(f"status.json path: {status_file_path}") |
| 76 | + |
| 77 | +hub = HubInstance() |
| 78 | + |
| 79 | +with open(status_file_path, 'r') as status_file: |
| 80 | + status_info = json.load(status_file) |
| 81 | + |
| 82 | + # Monitoring status serially cause it's simpler (i.e. than spawning multiple threads and waiting for them) |
| 83 | + for code_location in status_info['codeLocations']: |
| 84 | + logging.debug(f"Waiting for scan to finish at scan/code location {code_location['codeLocationName']}") |
| 85 | + scan_monitor = ScanMonitor( |
| 86 | + hub, |
| 87 | + start_time=start_time, |
| 88 | + scan_location_name=code_location['codeLocationName'], |
| 89 | + snippet_scan=snippet_scan) |
| 90 | + scan_monitor.wait_for_scan_completion() |
| 91 | + |
| 92 | + |
0 commit comments