diff options
author | Mark Benvenuto <mark.benvenuto@mongodb.com> | 2020-10-15 23:37:24 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-10-16 04:01:54 +0000 |
commit | 070b70d8ef2d77d967fc5ae8afd984f1bd46adc7 (patch) | |
tree | 2852cfb7c0d4f49a24df4e1b829e2b25da12d737 | |
parent | b69f93de867415ea1e700fbea462399ed63b309b (diff) | |
download | mongo-070b70d8ef2d77d967fc5ae8afd984f1bd46adc7.tar.gz |
SERVER-51036 Write new and missing component checks for Black Duck Scanner
-rw-r--r-- | buildscripts/blackduck_hub.py | 231 | ||||
-rw-r--r-- | etc/evergreen.yml | 5 | ||||
-rw-r--r-- | etc/third_party_components.yml | 61 |
3 files changed, 260 insertions, 37 deletions
diff --git a/buildscripts/blackduck_hub.py b/buildscripts/blackduck_hub.py index 92a35127176..124a2c92eb2 100644 --- a/buildscripts/blackduck_hub.py +++ b/buildscripts/blackduck_hub.py @@ -11,7 +11,6 @@ import os import subprocess import sys import tempfile -import textwrap import time import warnings @@ -53,6 +52,9 @@ BLACKDUCK_WIKI_PAGE = "https://wiki.corp.mongodb.com/display/KERNEL/Black+Duck" # Black Duck failed report prefix BLACKDUCK_FAILED_PREFIX = "A Black Duck scan was run and failed" +# Black Duck default teaam +BLACKDUCK_DEFAULT_TEAM = "Service Development Platform" + ############################################################################ # Globals @@ -74,6 +76,11 @@ LOCAL_REPORTS_DIR = "bd_reports" ############################################################################ +THIRD_PARTY_DIRECTORIES = [ + 'src/third_party/wiredtiger/test/3rdparty', + 'src/third_party', +] + THIRD_PARTY_COMPONENTS_FILE = "etc/third_party_components.yml" ############################################################################ @@ -450,9 +457,6 @@ class Component: # Blackduck's newerReleases is based on "releasedOn" date. This means that if a upstream component releases a beta or rc, # it counts as newer but we do not consider those newer for our purposes # Missing newerReleases means we do not have to upgrade - # TODO - remove skip of FireFox since it has soooo many versions - #if newer_releases > 0 and name not in ("Mozilla Firefox", "Boost C++ Libraries - boost"): - if newer_releases > 0: limit = newer_releases + 1 versions_url = component["component"] + f"/versions?sort=releasedon%20desc&limit={limit}" @@ -773,6 +777,7 @@ class ThirdPartyComponent: self.team_owner = team_owner # optional fields + self.is_test_only = False self.vulnerability_suppression = None self.upgrade_suppression = None @@ -784,6 +789,20 @@ def _get_field(name, ymap, field: str): return ymap[field] +def _get_supression_field(ymap, field: str): + if field not in ymap: + return None + + value = ymap[field].lower() + + if not "todo" in value: + raise ValueError( + "Invalid suppression, a suppression must include the word 'TODO' so that the TODO scanner finds resolved tickets." + ) + + return value + + def _read_third_party_components(): with open(THIRD_PARTY_COMPONENTS_FILE) as rfh: yaml_file = yaml.load(rfh.read()) @@ -797,14 +816,102 @@ def _read_third_party_components(): _get_field(comp, cmap, 'local_directory_path'), _get_field(comp, cmap, 'team_owner')) - tp.vulnerability_suppression = cmap.get("vulnerability_suppression", None) - tp.upgrade_suppression = cmap.get("upgrade_suppression", None) + tp.is_test_only = cmap.get("is_test_only", False) + tp.vulnerability_suppression = _get_supression_field(cmap, "vulnerability_suppression") + tp.upgrade_suppression = _get_supression_field(cmap, "upgrade_suppression") third_party.append(tp) return third_party +def _generate_report_missing_blackduck_component(mgr: ReportManager, mcomp: ThirdPartyComponent): + mgr.write_report( + mcomp.name, "missing_blackduck_component", "fail", f"""{BLACKDUCK_FAILED_PREFIX} + +The {mcomp.name} library was found in {THIRD_PARTY_COMPONENTS_FILE} but not detected by Black Duck. + +This is caused by one of two issues: +1. The {THIRD_PARTY_COMPONENTS_FILE} file is out of date and the entry needs to be removed for "{mcomp.name}". +or +2. A entry to the component needs to be manually added to Black Duck. + +Next Steps: + +Build Baron: +A BF ticket should be generated and assigned to "{BLACKDUCK_DEFAULT_TEAM}" with +this text. + +Developer: +To address this build failure, the next steps are as follows: +1. Verify that the component is correct in {THIRD_PARTY_COMPONENTS_FILE}. + +2. If the component is incorrect, add a comment to the component in Black Duck and mark it as "Ignored". +or +2. If the component is correct, add the correct information to {THIRD_PARTY_COMPONENTS_FILE}. + +If the "{BLACKDUCK_DEFAULT_TEAM}" cannot do this work for any reason, the BF should be assigned to +the component owner team "{mcomp.team_owner}". + +For more information, see {BLACKDUCK_WIKI_PAGE}. +""") + + +def _generate_report_blackduck_missing_directory(mgr: ReportManager, directory: str): + mgr.write_report( + directory, "missing_directory", "fail", f"""{BLACKDUCK_FAILED_PREFIX} + +The directory "{directory}" was found in a known MongoDB third_party directory but is not known to +Black Duck or {THIRD_PARTY_COMPONENTS_FILE}. This directory likely needs to be added to Black Duck +manually. + +Next Steps: + +Build Baron: +A BF ticket should be generated and assigned to "{BLACKDUCK_DEFAULT_TEAM}" with +this text. + +Developer: +To address this build failure, the next steps are as follows: +1. Verify that the component is correct. +2. Add the component manually to the Black Duck project at + {BLACKDUCK_PROJECT_URL}. +3. Once the component has been accepted by Black Duck, add the correct information to + {THIRD_PARTY_COMPONENTS_FILE}. + +For more information, see {BLACKDUCK_WIKI_PAGE}. +""") + + +def _generate_report_missing_yaml_component(mgr: ReportManager, comp: Component): + mgr.write_report( + comp.name, "missing_yaml_component", "fail", f"""{BLACKDUCK_FAILED_PREFIX} + +The {comp.name} library with version "{comp.version}" was detected by Black Duck but not found in +{THIRD_PARTY_COMPONENTS_FILE}. + +This is caused by one of two issues: +1. Black Duck has made an error and the software is not being vendored by MongoDB. +2. Black Duck is correct and {THIRD_PARTY_COMPONENTS_FILE} must be updated. + +Next Steps: + +Build Baron: +A BF ticket should be generated and assigned to "{BLACKDUCK_DEFAULT_TEAM}" with +this text. + +Developer: +To address this build failure, the next steps are as follows: +1. Verify that the component is correct at {BLACKDUCK_PROJECT_URL}. + +2. If the component is incorrect, add a comment to the component and mark it as "Ignored". +or +3. If the component is correct, add the correct information to {THIRD_PARTY_COMPONENTS_FILE}. + +For more information, see {BLACKDUCK_WIKI_PAGE}. +""") + + def _generate_report_upgrade(mgr: ReportManager, comp: Component, mcomp: ThirdPartyComponent, fail: bool): if not fail: @@ -821,9 +928,12 @@ branch. Next Steps: -Build Baron: A BF ticket should be generated and assigned to "Service Development Platform" with this text. +Build Baron: +A BF ticket should be generated and assigned to "{BLACKDUCK_DEFAULT_TEAM}" with +this text. -Developer: To address this build failure, the next steps are as follows: +Developer: +To address this build failure, the next steps are as follows: 1. File a SERVER ticket to update the software if one already does not exist. 2. Add a “upgrade_supression” to {THIRD_PARTY_COMPONENTS_FILE} with the SERVER ticket to acknowledge this report. Note that you do not need to immediately update the library, just file a ticket. @@ -831,7 +941,10 @@ Developer: To address this build failure, the next steps are as follows: If you believe the library is already up-to-date but Black Duck has the wrong version, please update version information for this component at {BLACKDUCK_PROJECT_URL}. -For more information, {BLACKDUCK_WIKI_PAGE}. +If the "{BLACKDUCK_DEFAULT_TEAM}" cannot do this work for any reason, the BF should be assigned to +the component owner team "{mcomp.team_owner}". + +For more information, see {BLACKDUCK_WIKI_PAGE}. """) mgr.add_report_metric(comp.name, str(comp.version)) @@ -855,9 +968,12 @@ CRITICAL vulnerabilities on the master branch. Next Steps: -Build Baron: A BF ticket should be generated and assigned to "Service Development Platform" with this text. +Build Baron: +A BF ticket should be generated and assigned to "{BLACKDUCK_DEFAULT_TEAM}" with +this text. -Developer: To address this build failure, the next steps are as follows: +Developer: +To address this build failure, the next steps are as follows: 1. File a SERVER ticket to update the software if one already does not exist. Note that you do not need to immediately update the library, just file a ticket. 2. Add a “vulnerability_supression” to {THIRD_PARTY_COMPONENTS_FILE} with the SERVER ticket to @@ -866,10 +982,23 @@ Developer: To address this build failure, the next steps are as follows: If you believe the library is already up-to-date but Black Duck has the wrong version, please update version information for this component at {BLACKDUCK_PROJECT_URL}. - For more information, {BLACKDUCK_WIKI_PAGE}. +If the "{BLACKDUCK_DEFAULT_TEAM}" cannot do this work for any reason, the BF should be assigned to +the component owner team "{mcomp.team_owner}". + +For more information, see {BLACKDUCK_WIKI_PAGE}. """) +def _get_third_party_directories(): + third_party = [] + for tp in THIRD_PARTY_DIRECTORIES: + for entry in os.scandir(tp): + if entry.name not in ["scripts"] and entry.is_dir(): + third_party.append(entry.path) + + return sorted(third_party) + + class Analyzer: """ Analyze the MongoDB source code for software maintence issues. @@ -887,16 +1016,59 @@ class Analyzer: def _do_reports(self): for comp in self.black_duck_components: - # 1. Validate there are no security issues - self._verify_vulnerability_status(comp) + # 1. Validate if this is in the YAML file + if self._verify_yaml_contains_component(comp): + + # 2. Validate there are no security issues + self._verify_vulnerability_status(comp) + + # 3. Check for upgrade issues + self._verify_upgrade_status(comp) + + # 4. Validate that each third_party directory is in the YAML file + self._verify_directories_in_yaml() + + # 5. Verify the YAML file has all the entries in Black Duck + self._verify_components_in_yaml() + + def _verify_yaml_contains_component(self, comp: Component): + # It should be rare that Black Duck detects something that is not in the YAML file + # As a result, we do not generate a "pass" report for simply be consistent between Black Duck and the yaml file + if comp.name not in [c.name for c in self.third_party_components]: + _generate_report_missing_yaml_component(self.mgr, comp) + return False + + return True - # 2. Check for upgrade issues - self._verify_upgrade_status(comp) + def _verify_directories_in_yaml(self): + + comp_dirs = [c.local_path for c in self.third_party_components] + for cdir in self.third_party_directories: + # Ignore WiredTiger since it is not a third-party library but made by MongoDB, Inc. + if cdir in ["src/third_party/wiredtiger"]: + continue + + if cdir not in comp_dirs: + _generate_report_blackduck_missing_directory(self.mgr, cdir) + + def _verify_components_in_yaml(self): + + comp_names = [c.name for c in self.black_duck_components] + for mcomp in self.third_party_components: + # These components are known to be missing from Black Duck + # Aladdin MD5 is a pair of C files for MD5 computation + # timelib is simply missing + # Unicode is not code + if mcomp.name in ["Aladdin MD5", "timelib", "unicode"]: + continue + + if mcomp.name not in comp_names: + _generate_report_missing_blackduck_component(self.mgr, mcomp) def _verify_upgrade_status(self, comp: Component): mcomp = self._get_mongo_component(comp) - if comp.newest_release and not mcomp.upgrade_suppression: + if comp.newest_release and not mcomp.upgrade_suppression and not mcomp.is_test_only: _generate_report_upgrade(self.mgr, comp, mcomp, True) else: _generate_report_upgrade(self.mgr, comp, mcomp, False) @@ -904,7 +1076,9 @@ class Analyzer: def _verify_vulnerability_status(self, comp: Component): mcomp = self._get_mongo_component(comp) - if comp.security_risk in ["HIGH", "CRITICAL"] and not mcomp.vulnerability_suppression: + if comp.security_risk in [ + "HIGH", "CRITICAL" + ] and not mcomp.vulnerability_suppression and not mcomp.is_test_only: _generate_report_vulnerability(self.mgr, comp, mcomp, True) else: _generate_report_vulnerability(self.mgr, comp, mcomp, False) @@ -922,6 +1096,10 @@ class Analyzer: def run(self, logger: ReportLogger, report_file: Optional[str]): """Run analysis of Black Duck scan and local files.""" + self.third_party_directories = _get_third_party_directories() + + LOGGER.info("Found the following third party directories: %s", self.third_party_directories) + self.third_party_components = _read_third_party_components() self.black_duck_components = _query_blackduck() @@ -933,6 +1111,23 @@ class Analyzer: comp for comp in self.black_duck_components if not comp.name == "MongoDB" ] + # Remove duplicate Black Duck components. We only care about the component with highest version number + # Black Duck can detect different versions of the same component for instance if an upgrade of a component happens + bd_names = {comp.name for comp in self.black_duck_components} + if len(bd_names) != len(self.black_duck_components): + LOGGER.warning("Found duplicate Black Duck components") + bd_unique = {} + for comp in self.black_duck_components: + if comp.name in bd_unique: + LOGGER.warning("Found duplicate Black Duck component: %s", comp.name) + first = bd_unique[comp.name] + if comp.version > first.version: + bd_unique[comp.name] = comp + else: + bd_unique[comp.name] = comp + + self.black_duck_components = list(bd_unique.values()) + self.mgr = ReportManager(logger) self._do_reports() diff --git a/etc/evergreen.yml b/etc/evergreen.yml index e30472fc016..cfa393955b7 100644 --- a/etc/evergreen.yml +++ b/etc/evergreen.yml @@ -7493,6 +7493,7 @@ tasks: - func: "run idl tests" - name: blackduck_scanner + patchable: false commands: - func: "do non-compile setup" - command: shell.exec @@ -7522,7 +7523,9 @@ tasks: # activate the virtualenv if it has been set up ${activate_virtualenv} - python buildscripts/blackduck_hub.py -v scan + if [ "${is_patch}" = "false" ]; then + python buildscripts/blackduck_hub.py -v scan_and_report --build_logger=mci.buildlogger --build_logger_task_id=${task_id} --report_file=report.json + fi - name: tla_plus commands: diff --git a/etc/third_party_components.yml b/etc/third_party_components.yml index 9852aaae9df..78d93af68b0 100644 --- a/etc/third_party_components.yml +++ b/etc/third_party_components.yml @@ -3,25 +3,36 @@ # This file is consumed by buildscripts/blackduck_hub.py # Sample +# Note: the word TO_DO is supposed to be spelled as "TODO". It is spelled awkwardly in the example +# to avoid the TODO scanner from filing an issue on the sample code. +# # component_name: Sample Example Compnent # homepage_url: https://www.example.com # local_directory_path: src/third_party/example # open_hub_url: https://www.openhub.net/p/example # release_monitoring_id: 1234 -# upgrade_suppression: SERVER-12345 -# vulnerability_suppression: SERVER-12345 +# is_test_only: false +# upgrade_suppression: TO_DO SERVER-12345 +# vulnerability_suppression: TO_DO SERVER-12345 # team_owner: example + # Description # component_name - string - required - Name of component in Black Duck Hub # homepage_url - URL - required - website where to find third party component # open_hub_url - URL - required - Black Duck Open Hub URL where to find third party component # not always available, see https://www.openhub.net +# if not available, use text "N/A" # release_monitoring_id - integer - required - id of Fedora's Anitya project for monitoring releases # not always available, see https://release-monitoring.org/ +# if not available, use integer "-1" # local_directory_path - path - required - relative path to directory containing code -# upgrade_suppression - string - optional - SERVER- ticket in JIRA, if present upgrade issues are ignored -# vulnerability_suppression - string - optional - SERVER- ticket in JIRA, if present vulnerability issues are ignored +# is_test_only - bool - optional - false by default, true if the component is only part of test code and not shipped to users +# test only components are not checked for upgrade or vulnerability issues +# upgrade_suppression - string - optional - SERVER- or TW- ticket in JIRA, if present upgrade issues are ignored +# Must be prefixed with TODO +# vulnerability_suppression - string - optional - SERVER- or WT- ticket in JIRA, if present vulnerability issues are ignored +# Must be prefixed with TODO # team_owner - string - required - server team that is responsible for maintaining library # TODO - can we query JIRA to see if the tickets are closed, check DAG code @@ -34,6 +45,7 @@ components: release_monitoring_id: 115295 local_directory_path: src/third_party/abseil-cpp-master team_owner: "Service Architecture" + upgrade_suppression: TODO SERVER-51476 # Note: abseil exists in Black Duck, but not OpenHub Aladdin MD5: @@ -50,15 +62,16 @@ components: release_monitoring_id: 117 local_directory_path: src/third_party/asio-master team_owner: "Service Architecture" - upgrade_suppression: SERVER-44078 + upgrade_suppression: TODO SERVER-44078 benchmark: homepage_url: https://github.com/google/benchmark open_hub_url: https://www.openhub.net/p/benchmark release_monitoring_id: 18299 local_directory_path: src/third_party/benchmark + is_test_only: true team_owner: "Service Architecture" - upgrade_suppression: SERVER-49200 + upgrade_suppression: TODO SERVER-49200 "Boost C++ Libraries - boost": homepage_url: https://www.boost.org/ @@ -66,13 +79,14 @@ components: release_monitoring_id: 6845 local_directory_path: src/third_party/boost-1.70.0 team_owner: "Service Architecture" - upgrade_suppression: SERVER-44079 + upgrade_suppression: TODO SERVER-44079 concurrencytest: homepage_url: https://github.com/cgoldberg/concurrencytest open_hub_url: https://www.openhub.net/p/concurrencytest release_monitoring_id: -1 local_directory_path: src/third_party/wiredtiger/test/3rdparty/concurrencytest-0.1.2 + is_test_only: true team_owner: "Wiredtiger" "dcleblanc/SafeInt": @@ -81,13 +95,14 @@ components: release_monitoring_id: -1 local_directory_path: src/third_party/SafeInt team_owner: "Service Architecture" - upgrade_suppression: SERVER-49213 + upgrade_suppression: TODO SERVER-49213 discover-python: homepage_url: https://pypi.org/project/discover/ open_hub_url: N/A release_monitoring_id: -1 local_directory_path: src/third_party/wiredtiger/test/3rdparty/discover-0.4.0 + is_test_only: true team_owner: "Wiredtiger" fmt: @@ -96,7 +111,7 @@ components: release_monitoring_id: 11526 local_directory_path: src/third_party/fmt team_owner: "Security" - upgrade_suppression: SERVER-45445 + upgrade_suppression: TODO SERVER-45445 google/s2geometry: homepage_url: https://github.com/google/s2geometry @@ -112,7 +127,7 @@ components: release_monitoring_id: 4844 local_directory_path: src/third_party/snappy-1.1.7 team_owner: "Execution" - upgrade_suppression: SERVER-47281 + upgrade_suppression: TODO SERVER-47281 # TODO - bad version data gperftools: @@ -129,8 +144,8 @@ components: release_monitoring_id: 16134 local_directory_path: src/third_party/icu4c-57.1 team_owner: "Query" - vulnerability_suppression: SERVER-49211 - upgrade_suppression: SERVER-49211 + vulnerability_suppression: TODO SERVER-49211 + upgrade_suppression: TODO SERVER-49211 "Intel Decimal Floating-Point Math Library": homepage_url: https://software.intel.com/content/www/us/en/develop/articles/intel-decimal-floating-point-math-library.html @@ -145,6 +160,7 @@ components: open_hub_url: https://www.openhub.net/p/json-schema-test-suite release_monitoring_id: -1 local_directory_path: src/third_party/JSON-Schema-Test-Suite + is_test_only: true team_owner: "Query" libmongocrypt: @@ -161,6 +177,7 @@ components: release_monitoring_id: 5691 local_directory_path: [src/mongo/shell/linenoise.h, src/mongo/shell/linenoise.cpp] team_owner: "Server Tools and Methodology" + upgrade_suppression: TODO SERVER-514767 LibTomCrypt: homepage_url: https://www.libtom.net/ @@ -183,8 +200,8 @@ components: release_monitoring_id: 16838 local_directory_path: src/third_party/mozjs-60 team_owner: "Query" - vulnerability_suppression: SERVER-42427 - upgrade_suppression: SERVER-42427 + vulnerability_suppression: TODO SERVER-42427 + upgrade_suppression: TODO SERVER-42427 "mpark-variant-devel": homepage_url: https://github.com/mpark/variant @@ -198,6 +215,7 @@ components: open_hub_url: N/A release_monitoring_id: -1 local_directory_path: src/third_party/mock_ocsp_responder + is_test_only: true team_owner: "Security" # Note: ocspbuilder exists in Black Duck, but not OpenHub @@ -206,6 +224,7 @@ components: open_hub_url: N/A release_monitoring_id: -1 local_directory_path: src/third_party/mock_ocsp_responder + is_test_only: true team_owner: "Security" # Note: ocspresponder exists in Black Duck, but not OpenHub @@ -215,13 +234,14 @@ components: release_monitoring_id: 2610 local_directory_path: src/third_party/pcre-8.42 team_owner: "Query" - upgrade_suppression: SERVER-47278 + upgrade_suppression: TODO SERVER-47278 python-testscenarios: homepage_url: https://launchpad.net/testscenarios open_hub_url: https://www.openhub.net/p/testscenarios release_monitoring_id: 13220 local_directory_path: src/third_party/wiredtiger/test/3rdparty/testscenarios-0.4 + is_test_only: true team_owner: "Wiredtiger" python3-extras: @@ -229,6 +249,7 @@ components: open_hub_url: N/A release_monitoring_id: 13192 local_directory_path: src/third_party/wiredtiger/test/3rdparty/extras-0.0.3 + is_test_only: true team_owner: "Wiredtiger" "SCons - a Software Construction tool": @@ -237,7 +258,7 @@ components: release_monitoring_id: 4770 local_directory_path: src/third_party/scons-3.1.2 team_owner: "Service Development Platform" - upgrade_suppression: SERVER-49324 + upgrade_suppression: TODO SERVER-49324 smhasher: homepage_url: https://github.com/aappleby/smhasher @@ -252,12 +273,14 @@ components: release_monitoring_id: 7853 local_directory_path: src/third_party/libstemmer_c team_owner: "Query" + upgrade_suppression: TODO SERVER-51478 subunit: homepage_url: https://launchpad.net/subunit open_hub_url: N/A release_monitoring_id: 85461 local_directory_path: src/third_party/wiredtiger/test/3rdparty/python-subunit-0.0.16 + is_test_only: true team_owner: "Wiredtiger" timelib: @@ -281,12 +304,14 @@ components: release_monitoring_id: 13639 local_directory_path: src/third_party/valgrind-3.14.0 team_owner: "Decision Automation Group" + upgrade_suppression: TODO SERVER-51479 testtools: homepage_url: https://launchpad.net/testtools open_hub_url: https://www.openhub.net/p/python-testtools release_monitoring_id: 4047 local_directory_path: src/third_party/wiredtiger/test/3rdparty/testtools-0.9.34 + is_test_only: true team_owner: "Wiredtiger" yaml-cpp: @@ -295,7 +320,7 @@ components: release_monitoring_id: 5284 local_directory_path: src/third_party/yaml-cpp-0.6.2 team_owner: "Security" - upgrade_suppression: SERVER-48258 + upgrade_suppression: TODO SERVER-48258 yhirose/cpp-peglib: homepage_url: https://github.com/yhirose/cpp-peglib @@ -318,4 +343,4 @@ components: release_monitoring_id: 12083 local_directory_path: src/third_party/zstandard-1.4.4 team_owner: "Execution" - upgrade_suppression: SERVER-49230 + upgrade_suppression: TODO SERVER-49230 |