def test_safety(image): """ Runs safety check on a container with the capability to ignore safety issues that cannot be fixed, and only raise error if an issue is fixable. """ from dlc.safety_check import SafetyCheck safety_check = SafetyCheck() repo_name, image_tag = image.split("/")[-1].split(":") ignore_ids_list = _get_safety_ignore_list(image) sep = " -i " ignore_str = "" if not ignore_ids_list else f"{sep}{sep.join(ignore_ids_list)}" container_name = f"{repo_name}-{image_tag}-safety" docker_exec_cmd = f"docker exec -i {container_name}" test_file_path = os.path.join(CONTAINER_TESTS_PREFIX, "testSafety") # Add null entrypoint to ensure command exits immediately run( f"docker run -id " f"--name {container_name} " f"--mount type=bind,src=$(pwd)/container_tests,target=/test " f"--entrypoint='/bin/bash' " f"{image}", hide=True, ) try: run(f"{docker_exec_cmd} pip install safety yolk3k ", hide=True) json_str_safety_result = safety_check.run_safety_check_on_container( docker_exec_cmd) safety_result = json.loads(json_str_safety_result) for vulnerability in safety_result: package, affected_versions, curr_version, _, vulnerability_id = vulnerability[: 5] # Get the latest version of the package with vulnerability latest_version = _get_latest_package_version(package) # If the latest version of the package is also affected, ignore this vulnerability if Version(latest_version) in SpecifierSet(affected_versions): # Version(x) gives an object that can be easily compared with another version, or with a SpecifierSet. # Comparing two versions as a string has some edge cases which require us to write more code. # SpecifierSet(x) takes a version constraint, such as "<=4.5.6", ">1.2.3", or ">=1.2,<3.4.5", and # gives an object that can be easily compared against a Version object. # https://packaging.pypa.io/en/latest/specifiers/ ignore_str += f" -i {vulnerability_id}" assert (safety_check.run_safety_check_with_ignore_list( docker_exec_cmd, ignore_str) == 0), f"Safety test failed for {image}" finally: run(f"docker rm -f {container_name}", hide=True)
def run_safety_check_in_cb_context(self): """ Runs the safety check on the container in CodeBuild Context :return: string, A JSON formatted string containing vulnerabilities found in the container """ from dlc.safety_check import SafetyCheck return SafetyCheck().run_safety_check_on_container( self.docker_exec_cmd)