cycode 2.3.1.dev2__tar.gz → 2.3.2.dev1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/PKG-INFO +1 -1
- cycode-2.3.2.dev1/cycode/__init__.py +1 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/scan/code_scanner.py +68 -60
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/scan/pre_commit/pre_commit_command.py +2 -2
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/scan/repository/repository_command.py +1 -2
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/consts.py +4 -0
- cycode-2.3.2.dev1/cycode/cli/utils/scan_batch.py +138 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/pyproject.toml +1 -1
- cycode-2.3.1.dev2/cycode/__init__.py +0 -1
- cycode-2.3.1.dev2/cycode/cli/utils/scan_batch.py +0 -75
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/LICENCE +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/README.md +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/ai_remediation/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/ai_remediation/ai_remediation_command.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/auth/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/auth/auth_command.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/auth/auth_manager.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/auth_common.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/configure/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/configure/configure_command.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/ignore/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/ignore/ignore_command.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/main_cli.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/report/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/report/report_command.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/report/sbom/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/report/sbom/common.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/report/sbom/path/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/report/sbom/path/path_command.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/report/sbom/repository_url/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/report/sbom/repository_url/repository_url_command.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/report/sbom/sbom_command.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/report/sbom/sbom_report_file.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/scan/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/scan/commit_history/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/scan/commit_history/commit_history_command.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/scan/path/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/scan/path/path_command.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/scan/pre_commit/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/scan/pre_receive/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/scan/pre_receive/pre_receive_command.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/scan/repository/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/scan/scan_ci/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/scan/scan_ci/ci_integrations.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/scan/scan_ci/scan_ci_command.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/scan/scan_command.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/status/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/status/status_command.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/version/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/version/version_checker.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/version/version_command.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/config.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/config.yaml +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/exceptions/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/exceptions/common.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/exceptions/custom_exceptions.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/exceptions/handle_ai_remediation_errors.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/exceptions/handle_report_sbom_errors.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/exceptions/handle_scan_errors.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/excluder.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/iac/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/iac/tf_content_generator.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/models/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/models/in_memory_zip.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/path_documents.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/repository_documents.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/sca/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/sca/base_restore_dependencies.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/sca/go/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/sca/go/restore_go_dependencies.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/sca/maven/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/sca/maven/restore_gradle_dependencies.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/sca/maven/restore_maven_dependencies.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/sca/npm/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/sca/npm/restore_npm_dependencies.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/sca/nuget/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/sca/nuget/restore_nuget_dependencies.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/sca/ruby/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/sca/ruby/restore_ruby_dependencies.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/sca/sbt/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/sca/sbt/restore_sbt_dependencies.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/sca/sca_code_scanner.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/walk_ignore.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/zip_documents.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/main.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/models.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/printers/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/printers/console_printer.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/printers/json_printer.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/printers/printer_base.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/printers/tables/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/printers/tables/sca_table_printer.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/printers/tables/table.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/printers/tables/table_models.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/printers/tables/table_printer.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/printers/tables/table_printer_base.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/printers/text_printer.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/sentry.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/user_settings/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/user_settings/base_file_manager.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/user_settings/config_file_manager.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/user_settings/configuration_manager.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/user_settings/credentials_manager.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/user_settings/jwt_creator.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/utils/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/utils/enum_utils.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/utils/get_api_client.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/utils/git_proxy.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/utils/ignore_utils.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/utils/jwt_utils.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/utils/path_utils.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/utils/progress_bar.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/utils/scan_utils.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/utils/shell_executor.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/utils/string_utils.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/utils/task_timer.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/utils/yaml_utils.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cyclient/__init__.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cyclient/auth_client.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cyclient/client_creator.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cyclient/config.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cyclient/config.yaml +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cyclient/config_dev.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cyclient/cycode_client.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cyclient/cycode_client_base.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cyclient/cycode_dev_based_client.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cyclient/cycode_token_based_client.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cyclient/headers.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cyclient/models.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cyclient/report_client.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cyclient/scan_client.py +0 -0
- {cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cyclient/scan_config_base.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '2.3.2.dev1' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
|
|
@@ -45,7 +45,7 @@ start_scan_time = time.time()
|
|
|
45
45
|
|
|
46
46
|
def scan_sca_pre_commit(context: click.Context) -> None:
|
|
47
47
|
scan_type = context.obj['scan_type']
|
|
48
|
-
scan_parameters =
|
|
48
|
+
scan_parameters = get_scan_parameters(context)
|
|
49
49
|
git_head_documents, pre_committed_documents = get_pre_commit_modified_documents(
|
|
50
50
|
context.obj['progress_bar'], ScanProgressBarSection.PREPARE_LOCAL_FILES
|
|
51
51
|
)
|
|
@@ -80,14 +80,13 @@ def scan_sca_commit_range(context: click.Context, path: str, commit_range: str)
|
|
|
80
80
|
|
|
81
81
|
|
|
82
82
|
def scan_disk_files(context: click.Context, paths: Tuple[str]) -> None:
|
|
83
|
-
scan_parameters = get_scan_parameters(context, paths)
|
|
84
83
|
scan_type = context.obj['scan_type']
|
|
85
84
|
progress_bar = context.obj['progress_bar']
|
|
86
85
|
|
|
87
86
|
try:
|
|
88
87
|
documents = get_relevant_documents(progress_bar, ScanProgressBarSection.PREPARE_LOCAL_FILES, scan_type, paths)
|
|
89
88
|
perform_pre_scan_documents_actions(context, scan_type, documents)
|
|
90
|
-
scan_documents(context, documents,
|
|
89
|
+
scan_documents(context, documents, get_scan_parameters(context, paths))
|
|
91
90
|
except Exception as e:
|
|
92
91
|
handle_scan_exception(context, e)
|
|
93
92
|
|
|
@@ -151,14 +150,12 @@ def _enrich_scan_result_with_data_from_detection_rules(
|
|
|
151
150
|
|
|
152
151
|
def _get_scan_documents_thread_func(
|
|
153
152
|
context: click.Context, is_git_diff: bool, is_commit_range: bool, scan_parameters: dict
|
|
154
|
-
) ->
|
|
153
|
+
) -> Callable[[List[Document]], Tuple[str, CliError, LocalScanResult]]:
|
|
155
154
|
cycode_client = context.obj['client']
|
|
156
155
|
scan_type = context.obj['scan_type']
|
|
157
156
|
severity_threshold = context.obj['severity_threshold']
|
|
158
157
|
sync_option = context.obj['sync']
|
|
159
158
|
command_scan_type = context.info_name
|
|
160
|
-
aggregation_id = str(_generate_unique_id())
|
|
161
|
-
scan_parameters['aggregation_id'] = aggregation_id
|
|
162
159
|
|
|
163
160
|
def _scan_batch_thread_func(batch: List[Document]) -> Tuple[str, CliError, LocalScanResult]:
|
|
164
161
|
local_scan_result = error = error_message = None
|
|
@@ -171,7 +168,7 @@ def _get_scan_documents_thread_func(
|
|
|
171
168
|
should_use_sync_flow = _should_use_sync_flow(command_scan_type, scan_type, sync_option, scan_parameters)
|
|
172
169
|
|
|
173
170
|
try:
|
|
174
|
-
logger.debug('Preparing local files, %s', {'
|
|
171
|
+
logger.debug('Preparing local files, %s', {'batch_files_count': len(batch)})
|
|
175
172
|
zipped_documents = zip_documents(scan_type, batch)
|
|
176
173
|
zip_file_size = zipped_documents.size
|
|
177
174
|
scan_result = perform_scan(
|
|
@@ -227,7 +224,7 @@ def _get_scan_documents_thread_func(
|
|
|
227
224
|
|
|
228
225
|
return scan_id, error, local_scan_result
|
|
229
226
|
|
|
230
|
-
return _scan_batch_thread_func
|
|
227
|
+
return _scan_batch_thread_func
|
|
231
228
|
|
|
232
229
|
|
|
233
230
|
def scan_commit_range(
|
|
@@ -287,20 +284,19 @@ def scan_commit_range(
|
|
|
287
284
|
logger.debug('List of commit ids to scan, %s', {'commit_ids': commit_ids_to_scan})
|
|
288
285
|
logger.debug('Starting to scan commit range (it may take a few minutes)')
|
|
289
286
|
|
|
290
|
-
scan_documents(
|
|
287
|
+
scan_documents(
|
|
288
|
+
context, documents_to_scan, get_scan_parameters(context, (path,)), is_git_diff=True, is_commit_range=True
|
|
289
|
+
)
|
|
291
290
|
return None
|
|
292
291
|
|
|
293
292
|
|
|
294
293
|
def scan_documents(
|
|
295
294
|
context: click.Context,
|
|
296
295
|
documents_to_scan: List[Document],
|
|
296
|
+
scan_parameters: dict,
|
|
297
297
|
is_git_diff: bool = False,
|
|
298
298
|
is_commit_range: bool = False,
|
|
299
|
-
scan_parameters: Optional[dict] = None,
|
|
300
299
|
) -> None:
|
|
301
|
-
if not scan_parameters:
|
|
302
|
-
scan_parameters = get_default_scan_parameters(context)
|
|
303
|
-
|
|
304
300
|
scan_type = context.obj['scan_type']
|
|
305
301
|
progress_bar = context.obj['progress_bar']
|
|
306
302
|
|
|
@@ -315,19 +311,15 @@ def scan_documents(
|
|
|
315
311
|
)
|
|
316
312
|
return
|
|
317
313
|
|
|
318
|
-
scan_batch_thread_func
|
|
319
|
-
context, is_git_diff, is_commit_range, scan_parameters
|
|
320
|
-
)
|
|
314
|
+
scan_batch_thread_func = _get_scan_documents_thread_func(context, is_git_diff, is_commit_range, scan_parameters)
|
|
321
315
|
errors, local_scan_results = run_parallel_batched_scan(
|
|
322
316
|
scan_batch_thread_func, scan_type, documents_to_scan, progress_bar=progress_bar
|
|
323
317
|
)
|
|
324
318
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
)
|
|
330
|
-
set_aggregation_report_url(context, aggregation_report_url)
|
|
319
|
+
aggregation_report_url = _try_get_aggregation_report_url_if_needed(
|
|
320
|
+
scan_parameters, context.obj['client'], scan_type
|
|
321
|
+
)
|
|
322
|
+
_set_aggregation_report_url(context, aggregation_report_url)
|
|
331
323
|
|
|
332
324
|
progress_bar.set_section_length(ScanProgressBarSection.GENERATE_REPORT, 1)
|
|
333
325
|
progress_bar.update(ScanProgressBarSection.GENERATE_REPORT)
|
|
@@ -337,25 +329,6 @@ def scan_documents(
|
|
|
337
329
|
print_results(context, local_scan_results, errors)
|
|
338
330
|
|
|
339
331
|
|
|
340
|
-
def set_aggregation_report_url(context: click.Context, aggregation_report_url: Optional[str] = None) -> None:
|
|
341
|
-
context.obj['aggregation_report_url'] = aggregation_report_url
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
def _try_get_aggregation_report_url_if_needed(
|
|
345
|
-
scan_parameters: dict, cycode_client: 'ScanClient', scan_type: str
|
|
346
|
-
) -> Optional[str]:
|
|
347
|
-
aggregation_id = scan_parameters.get('aggregation_id')
|
|
348
|
-
if not scan_parameters.get('report'):
|
|
349
|
-
return None
|
|
350
|
-
if aggregation_id is None:
|
|
351
|
-
return None
|
|
352
|
-
try:
|
|
353
|
-
report_url_response = cycode_client.get_scan_aggregation_report_url(aggregation_id, scan_type)
|
|
354
|
-
return report_url_response.report_url
|
|
355
|
-
except Exception as e:
|
|
356
|
-
logger.debug('Failed to get aggregation report url: %s', str(e))
|
|
357
|
-
|
|
358
|
-
|
|
359
332
|
def scan_commit_range_documents(
|
|
360
333
|
context: click.Context,
|
|
361
334
|
from_documents_to_scan: List[Document],
|
|
@@ -380,7 +353,7 @@ def scan_commit_range_documents(
|
|
|
380
353
|
try:
|
|
381
354
|
progress_bar.set_section_length(ScanProgressBarSection.SCAN, 1)
|
|
382
355
|
|
|
383
|
-
scan_result = init_default_scan_result(
|
|
356
|
+
scan_result = init_default_scan_result(scan_id)
|
|
384
357
|
if should_scan_documents(from_documents_to_scan, to_documents_to_scan):
|
|
385
358
|
logger.debug('Preparing from-commit zip')
|
|
386
359
|
from_commit_zipped_documents = zip_documents(scan_type, from_documents_to_scan)
|
|
@@ -518,7 +491,7 @@ def perform_scan_async(
|
|
|
518
491
|
cycode_client,
|
|
519
492
|
scan_async_result.scan_id,
|
|
520
493
|
scan_type,
|
|
521
|
-
scan_parameters
|
|
494
|
+
scan_parameters,
|
|
522
495
|
)
|
|
523
496
|
|
|
524
497
|
|
|
@@ -553,16 +526,14 @@ def perform_commit_range_scan_async(
|
|
|
553
526
|
logger.debug(
|
|
554
527
|
'Async commit range scan request has been triggered successfully, %s', {'scan_id': scan_async_result.scan_id}
|
|
555
528
|
)
|
|
556
|
-
return poll_scan_results(
|
|
557
|
-
cycode_client, scan_async_result.scan_id, scan_type, scan_parameters.get('report'), timeout
|
|
558
|
-
)
|
|
529
|
+
return poll_scan_results(cycode_client, scan_async_result.scan_id, scan_type, scan_parameters, timeout)
|
|
559
530
|
|
|
560
531
|
|
|
561
532
|
def poll_scan_results(
|
|
562
533
|
cycode_client: 'ScanClient',
|
|
563
534
|
scan_id: str,
|
|
564
535
|
scan_type: str,
|
|
565
|
-
|
|
536
|
+
scan_parameters: dict,
|
|
566
537
|
polling_timeout: Optional[int] = None,
|
|
567
538
|
) -> ZippedFileScanResult:
|
|
568
539
|
if polling_timeout is None:
|
|
@@ -579,7 +550,7 @@ def poll_scan_results(
|
|
|
579
550
|
print_debug_scan_details(scan_details)
|
|
580
551
|
|
|
581
552
|
if scan_details.scan_status == consts.SCAN_STATUS_COMPLETED:
|
|
582
|
-
return _get_scan_result(cycode_client, scan_type, scan_id, scan_details,
|
|
553
|
+
return _get_scan_result(cycode_client, scan_type, scan_id, scan_details, scan_parameters)
|
|
583
554
|
|
|
584
555
|
if scan_details.scan_status == consts.SCAN_STATUS_ERROR:
|
|
585
556
|
raise custom_exceptions.ScanAsyncError(
|
|
@@ -671,18 +642,19 @@ def parse_pre_receive_input() -> str:
|
|
|
671
642
|
return pre_receive_input.splitlines()[0]
|
|
672
643
|
|
|
673
644
|
|
|
674
|
-
def
|
|
645
|
+
def _get_default_scan_parameters(context: click.Context) -> dict:
|
|
675
646
|
return {
|
|
676
647
|
'monitor': context.obj.get('monitor'),
|
|
677
648
|
'report': context.obj.get('report'),
|
|
678
649
|
'package_vulnerabilities': context.obj.get('package-vulnerabilities'),
|
|
679
650
|
'license_compliance': context.obj.get('license-compliance'),
|
|
680
651
|
'command_type': context.info_name,
|
|
652
|
+
'aggregation_id': str(_generate_unique_id()),
|
|
681
653
|
}
|
|
682
654
|
|
|
683
655
|
|
|
684
|
-
def get_scan_parameters(context: click.Context, paths: Tuple[str]) -> dict:
|
|
685
|
-
scan_parameters =
|
|
656
|
+
def get_scan_parameters(context: click.Context, paths: Optional[Tuple[str]] = None) -> dict:
|
|
657
|
+
scan_parameters = _get_default_scan_parameters(context)
|
|
686
658
|
|
|
687
659
|
if not paths:
|
|
688
660
|
return scan_parameters
|
|
@@ -890,10 +862,10 @@ def _get_scan_result(
|
|
|
890
862
|
scan_type: str,
|
|
891
863
|
scan_id: str,
|
|
892
864
|
scan_details: 'ScanDetailsResponse',
|
|
893
|
-
|
|
865
|
+
scan_parameters: dict,
|
|
894
866
|
) -> ZippedFileScanResult:
|
|
895
867
|
if not scan_details.detections_count:
|
|
896
|
-
return init_default_scan_result(
|
|
868
|
+
return init_default_scan_result(scan_id)
|
|
897
869
|
|
|
898
870
|
scan_raw_detections = cycode_client.get_scan_raw_detections(scan_type, scan_id)
|
|
899
871
|
|
|
@@ -901,25 +873,40 @@ def _get_scan_result(
|
|
|
901
873
|
did_detect=True,
|
|
902
874
|
detections_per_file=_map_detections_per_file_and_commit_id(scan_type, scan_raw_detections),
|
|
903
875
|
scan_id=scan_id,
|
|
904
|
-
report_url=
|
|
876
|
+
report_url=_try_get_any_report_url_if_needed(cycode_client, scan_id, scan_type, scan_parameters),
|
|
905
877
|
)
|
|
906
878
|
|
|
907
879
|
|
|
908
|
-
def init_default_scan_result(
|
|
909
|
-
cycode_client: 'ScanClient', scan_id: str, scan_type: str, should_get_report: bool = False
|
|
910
|
-
) -> ZippedFileScanResult:
|
|
880
|
+
def init_default_scan_result(scan_id: str) -> ZippedFileScanResult:
|
|
911
881
|
return ZippedFileScanResult(
|
|
912
882
|
did_detect=False,
|
|
913
883
|
detections_per_file=[],
|
|
914
884
|
scan_id=scan_id,
|
|
915
|
-
report_url=_try_get_report_url_if_needed(cycode_client, should_get_report, scan_id, scan_type),
|
|
916
885
|
)
|
|
917
886
|
|
|
918
887
|
|
|
888
|
+
def _try_get_any_report_url_if_needed(
|
|
889
|
+
cycode_client: 'ScanClient',
|
|
890
|
+
scan_id: str,
|
|
891
|
+
scan_type: str,
|
|
892
|
+
scan_parameters: dict,
|
|
893
|
+
) -> Optional[str]:
|
|
894
|
+
"""Tries to get aggregation report URL if needed, otherwise tries to get report URL."""
|
|
895
|
+
aggregation_report_url = None
|
|
896
|
+
if scan_parameters:
|
|
897
|
+
_try_get_report_url_if_needed(cycode_client, scan_id, scan_type, scan_parameters)
|
|
898
|
+
aggregation_report_url = _try_get_aggregation_report_url_if_needed(scan_parameters, cycode_client, scan_type)
|
|
899
|
+
|
|
900
|
+
if aggregation_report_url:
|
|
901
|
+
return aggregation_report_url
|
|
902
|
+
|
|
903
|
+
return _try_get_report_url_if_needed(cycode_client, scan_id, scan_type, scan_parameters)
|
|
904
|
+
|
|
905
|
+
|
|
919
906
|
def _try_get_report_url_if_needed(
|
|
920
|
-
cycode_client: 'ScanClient',
|
|
907
|
+
cycode_client: 'ScanClient', scan_id: str, scan_type: str, scan_parameters: dict
|
|
921
908
|
) -> Optional[str]:
|
|
922
|
-
if not
|
|
909
|
+
if not scan_parameters.get('report', False):
|
|
923
910
|
return None
|
|
924
911
|
|
|
925
912
|
try:
|
|
@@ -929,6 +916,27 @@ def _try_get_report_url_if_needed(
|
|
|
929
916
|
logger.debug('Failed to get report URL', exc_info=e)
|
|
930
917
|
|
|
931
918
|
|
|
919
|
+
def _set_aggregation_report_url(context: click.Context, aggregation_report_url: Optional[str] = None) -> None:
|
|
920
|
+
context.obj['aggregation_report_url'] = aggregation_report_url
|
|
921
|
+
|
|
922
|
+
|
|
923
|
+
def _try_get_aggregation_report_url_if_needed(
|
|
924
|
+
scan_parameters: dict, cycode_client: 'ScanClient', scan_type: str
|
|
925
|
+
) -> Optional[str]:
|
|
926
|
+
if not scan_parameters.get('report', False):
|
|
927
|
+
return None
|
|
928
|
+
|
|
929
|
+
aggregation_id = scan_parameters.get('aggregation_id')
|
|
930
|
+
if aggregation_id is None:
|
|
931
|
+
return None
|
|
932
|
+
|
|
933
|
+
try:
|
|
934
|
+
report_url_response = cycode_client.get_scan_aggregation_report_url(aggregation_id, scan_type)
|
|
935
|
+
return report_url_response.report_url
|
|
936
|
+
except Exception as e:
|
|
937
|
+
logger.debug('Failed to get aggregation report url: %s', str(e))
|
|
938
|
+
|
|
939
|
+
|
|
932
940
|
def _map_detections_per_file_and_commit_id(scan_type: str, raw_detections: List[dict]) -> List[DetectionsPerFile]:
|
|
933
941
|
"""Converts list of detections (async flow) to list of DetectionsPerFile objects (sync flow).
|
|
934
942
|
|
{cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/scan/pre_commit/pre_commit_command.py
RENAMED
|
@@ -4,7 +4,7 @@ from typing import List
|
|
|
4
4
|
import click
|
|
5
5
|
|
|
6
6
|
from cycode.cli import consts
|
|
7
|
-
from cycode.cli.commands.scan.code_scanner import scan_documents, scan_sca_pre_commit
|
|
7
|
+
from cycode.cli.commands.scan.code_scanner import get_scan_parameters, scan_documents, scan_sca_pre_commit
|
|
8
8
|
from cycode.cli.files_collector.excluder import exclude_irrelevant_documents_to_scan
|
|
9
9
|
from cycode.cli.files_collector.repository_documents import (
|
|
10
10
|
get_diff_file_content,
|
|
@@ -44,4 +44,4 @@ def pre_commit_command(context: click.Context, ignored_args: List[str]) -> None:
|
|
|
44
44
|
documents_to_scan.append(Document(get_path_by_os(get_diff_file_path(file)), get_diff_file_content(file)))
|
|
45
45
|
|
|
46
46
|
documents_to_scan = exclude_irrelevant_documents_to_scan(scan_type, documents_to_scan)
|
|
47
|
-
scan_documents(context, documents_to_scan, is_git_diff=True)
|
|
47
|
+
scan_documents(context, documents_to_scan, get_scan_parameters(context), is_git_diff=True)
|
{cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/scan/repository/repository_command.py
RENAMED
|
@@ -63,7 +63,6 @@ def repository_command(context: click.Context, path: str, branch: str) -> None:
|
|
|
63
63
|
perform_pre_scan_documents_actions(context, scan_type, documents_to_scan)
|
|
64
64
|
|
|
65
65
|
logger.debug('Found all relevant files for scanning %s', {'path': path, 'branch': branch})
|
|
66
|
-
|
|
67
|
-
scan_documents(context, documents_to_scan, scan_parameters=scan_parameters)
|
|
66
|
+
scan_documents(context, documents_to_scan, get_scan_parameters(context, (path,)))
|
|
68
67
|
except Exception as e:
|
|
69
68
|
handle_scan_exception(context, e)
|
|
@@ -145,7 +145,11 @@ ZIP_MAX_SIZE_LIMIT_IN_BYTES = {
|
|
|
145
145
|
# scan in batches
|
|
146
146
|
DEFAULT_SCAN_BATCH_MAX_SIZE_IN_BYTES = 9 * 1024 * 1024
|
|
147
147
|
SCAN_BATCH_MAX_SIZE_IN_BYTES = {SAST_SCAN_TYPE: 50 * 1024 * 1024}
|
|
148
|
+
SCAN_BATCH_MAX_SIZE_IN_BYTES_ENV_VAR_NAME = 'SCAN_BATCH_MAX_SIZE_IN_BYTES'
|
|
149
|
+
|
|
148
150
|
DEFAULT_SCAN_BATCH_MAX_FILES_COUNT = 1000
|
|
151
|
+
SCAN_BATCH_MAX_FILES_COUNT_ENV_VAR_NAME = 'SCAN_BATCH_MAX_FILES_COUNT'
|
|
152
|
+
|
|
149
153
|
# if we increase this values, the server doesn't allow connecting (ConnectionError)
|
|
150
154
|
SCAN_BATCH_MAX_PARALLEL_SCANS = 5
|
|
151
155
|
SCAN_BATCH_SCANS_PER_CPU = 1
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from multiprocessing.pool import ThreadPool
|
|
3
|
+
from typing import TYPE_CHECKING, Callable, Dict, List, Tuple
|
|
4
|
+
|
|
5
|
+
from cycode.cli import consts
|
|
6
|
+
from cycode.cli.models import Document
|
|
7
|
+
from cycode.cli.utils.progress_bar import ScanProgressBarSection
|
|
8
|
+
from cycode.cyclient import logger
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
from cycode.cli.models import CliError, LocalScanResult
|
|
12
|
+
from cycode.cli.utils.progress_bar import BaseProgressBar
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _get_max_batch_size(scan_type: str) -> int:
|
|
16
|
+
logger.debug(
|
|
17
|
+
'You can customize the batch size by setting the environment variable "%s"',
|
|
18
|
+
consts.SCAN_BATCH_MAX_SIZE_IN_BYTES_ENV_VAR_NAME,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
custom_size = os.environ.get(consts.SCAN_BATCH_MAX_SIZE_IN_BYTES_ENV_VAR_NAME)
|
|
22
|
+
if custom_size:
|
|
23
|
+
logger.debug('Custom batch size is set, %s', {'custom_size': custom_size})
|
|
24
|
+
return int(custom_size)
|
|
25
|
+
|
|
26
|
+
return consts.SCAN_BATCH_MAX_SIZE_IN_BYTES.get(scan_type, consts.DEFAULT_SCAN_BATCH_MAX_SIZE_IN_BYTES)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _get_max_batch_files_count(_: str) -> int:
|
|
30
|
+
logger.debug(
|
|
31
|
+
'You can customize the batch files count by setting the environment variable "%s"',
|
|
32
|
+
consts.SCAN_BATCH_MAX_FILES_COUNT_ENV_VAR_NAME,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
custom_files_count = os.environ.get(consts.SCAN_BATCH_MAX_FILES_COUNT_ENV_VAR_NAME)
|
|
36
|
+
if custom_files_count:
|
|
37
|
+
logger.debug('Custom batch files count is set, %s', {'custom_files_count': custom_files_count})
|
|
38
|
+
return int(custom_files_count)
|
|
39
|
+
|
|
40
|
+
return consts.DEFAULT_SCAN_BATCH_MAX_FILES_COUNT
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def split_documents_into_batches(
|
|
44
|
+
scan_type: str,
|
|
45
|
+
documents: List[Document],
|
|
46
|
+
) -> List[List[Document]]:
|
|
47
|
+
max_size = _get_max_batch_size(scan_type)
|
|
48
|
+
max_files_count = _get_max_batch_files_count(scan_type)
|
|
49
|
+
|
|
50
|
+
logger.debug(
|
|
51
|
+
'Splitting documents into batches, %s',
|
|
52
|
+
{'document_count': len(documents), 'max_batch_size': max_size, 'max_files_count': max_files_count},
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
batches = []
|
|
56
|
+
|
|
57
|
+
current_size = 0
|
|
58
|
+
current_batch = []
|
|
59
|
+
for document in documents:
|
|
60
|
+
document_size = len(document.content.encode('UTF-8'))
|
|
61
|
+
|
|
62
|
+
exceeds_max_size = current_size + document_size > max_size
|
|
63
|
+
if exceeds_max_size:
|
|
64
|
+
logger.debug(
|
|
65
|
+
'Going to create new batch because current batch size exceeds the limit, %s',
|
|
66
|
+
{
|
|
67
|
+
'batch_index': len(batches),
|
|
68
|
+
'current_batch_size': current_size + document_size,
|
|
69
|
+
'max_batch_size': max_size,
|
|
70
|
+
},
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
exceeds_max_files_count = len(current_batch) >= max_files_count
|
|
74
|
+
if exceeds_max_files_count:
|
|
75
|
+
logger.debug(
|
|
76
|
+
'Going to create new batch because current batch files count exceeds the limit, %s',
|
|
77
|
+
{
|
|
78
|
+
'batch_index': len(batches),
|
|
79
|
+
'current_batch_files_count': len(current_batch),
|
|
80
|
+
'max_batch_files_count': max_files_count,
|
|
81
|
+
},
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
if exceeds_max_size or exceeds_max_files_count:
|
|
85
|
+
batches.append(current_batch)
|
|
86
|
+
|
|
87
|
+
current_batch = [document]
|
|
88
|
+
current_size = document_size
|
|
89
|
+
else:
|
|
90
|
+
current_batch.append(document)
|
|
91
|
+
current_size += document_size
|
|
92
|
+
|
|
93
|
+
if current_batch:
|
|
94
|
+
batches.append(current_batch)
|
|
95
|
+
|
|
96
|
+
logger.debug('Documents were split into batches %s', {'batches_count': len(batches)})
|
|
97
|
+
|
|
98
|
+
return batches
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def _get_threads_count() -> int:
|
|
102
|
+
cpu_count = os.cpu_count() or 1
|
|
103
|
+
return min(cpu_count * consts.SCAN_BATCH_SCANS_PER_CPU, consts.SCAN_BATCH_MAX_PARALLEL_SCANS)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def run_parallel_batched_scan(
|
|
107
|
+
scan_function: Callable[[List[Document]], Tuple[str, 'CliError', 'LocalScanResult']],
|
|
108
|
+
scan_type: str,
|
|
109
|
+
documents: List[Document],
|
|
110
|
+
progress_bar: 'BaseProgressBar',
|
|
111
|
+
) -> Tuple[Dict[str, 'CliError'], List['LocalScanResult']]:
|
|
112
|
+
# batching is disabled for SCA; requested by Mor
|
|
113
|
+
batches = [documents] if scan_type == consts.SCA_SCAN_TYPE else split_documents_into_batches(scan_type, documents)
|
|
114
|
+
|
|
115
|
+
progress_bar.set_section_length(ScanProgressBarSection.SCAN, len(batches)) # * 3
|
|
116
|
+
# TODO(MarshalX): we should multiply the count of batches in SCAN section because each batch has 3 steps:
|
|
117
|
+
# 1. scan creation
|
|
118
|
+
# 2. scan completion
|
|
119
|
+
# 3. detection creation
|
|
120
|
+
# it's not possible yet because not all scan types moved to polling mechanism
|
|
121
|
+
# the progress bar could be significant improved (be more dynamic) in the future
|
|
122
|
+
|
|
123
|
+
threads_count = _get_threads_count()
|
|
124
|
+
local_scan_results: List['LocalScanResult'] = []
|
|
125
|
+
cli_errors: Dict[str, 'CliError'] = {}
|
|
126
|
+
|
|
127
|
+
logger.debug('Running parallel batched scan, %s', {'threads_count': threads_count, 'batches_count': len(batches)})
|
|
128
|
+
|
|
129
|
+
with ThreadPool(processes=threads_count) as pool:
|
|
130
|
+
for scan_id, err, result in pool.imap(scan_function, batches):
|
|
131
|
+
if result:
|
|
132
|
+
local_scan_results.append(result)
|
|
133
|
+
if err:
|
|
134
|
+
cli_errors[scan_id] = err
|
|
135
|
+
|
|
136
|
+
progress_bar.update(ScanProgressBarSection.SCAN)
|
|
137
|
+
|
|
138
|
+
return cli_errors, local_scan_results
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "cycode"
|
|
3
|
-
version = "2.3.
|
|
3
|
+
version = "2.3.2.dev1" # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
|
|
4
4
|
description = "Boost security in your dev lifecycle via SAST, SCA, Secrets & IaC scanning."
|
|
5
5
|
keywords=["secret-scan", "cycode", "devops", "token", "secret", "security", "cycode", "code"]
|
|
6
6
|
authors = ["Cycode <support@cycode.com>"]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '2.3.1.dev2' # DON'T TOUCH. Placeholder. Will be filled automatically on poetry build from Git Tag
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from multiprocessing.pool import ThreadPool
|
|
3
|
-
from typing import TYPE_CHECKING, Callable, Dict, List, Tuple
|
|
4
|
-
|
|
5
|
-
from cycode.cli import consts
|
|
6
|
-
from cycode.cli.models import Document
|
|
7
|
-
from cycode.cli.utils.progress_bar import ScanProgressBarSection
|
|
8
|
-
|
|
9
|
-
if TYPE_CHECKING:
|
|
10
|
-
from cycode.cli.models import CliError, LocalScanResult
|
|
11
|
-
from cycode.cli.utils.progress_bar import BaseProgressBar
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def split_documents_into_batches(
|
|
15
|
-
documents: List[Document],
|
|
16
|
-
max_size: int = consts.DEFAULT_SCAN_BATCH_MAX_SIZE_IN_BYTES,
|
|
17
|
-
max_files_count: int = consts.DEFAULT_SCAN_BATCH_MAX_FILES_COUNT,
|
|
18
|
-
) -> List[List[Document]]:
|
|
19
|
-
batches = []
|
|
20
|
-
|
|
21
|
-
current_size = 0
|
|
22
|
-
current_batch = []
|
|
23
|
-
for document in documents:
|
|
24
|
-
document_size = len(document.content.encode('UTF-8'))
|
|
25
|
-
|
|
26
|
-
if (current_size + document_size > max_size) or (len(current_batch) >= max_files_count):
|
|
27
|
-
batches.append(current_batch)
|
|
28
|
-
|
|
29
|
-
current_batch = [document]
|
|
30
|
-
current_size = document_size
|
|
31
|
-
else:
|
|
32
|
-
current_batch.append(document)
|
|
33
|
-
current_size += document_size
|
|
34
|
-
|
|
35
|
-
if current_batch:
|
|
36
|
-
batches.append(current_batch)
|
|
37
|
-
|
|
38
|
-
return batches
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
def _get_threads_count() -> int:
|
|
42
|
-
cpu_count = os.cpu_count() or 1
|
|
43
|
-
return min(cpu_count * consts.SCAN_BATCH_SCANS_PER_CPU, consts.SCAN_BATCH_MAX_PARALLEL_SCANS)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def run_parallel_batched_scan(
|
|
47
|
-
scan_function: Callable[[List[Document]], Tuple[str, 'CliError', 'LocalScanResult']],
|
|
48
|
-
scan_type: str,
|
|
49
|
-
documents: List[Document],
|
|
50
|
-
progress_bar: 'BaseProgressBar',
|
|
51
|
-
) -> Tuple[Dict[str, 'CliError'], List['LocalScanResult']]:
|
|
52
|
-
max_size = consts.SCAN_BATCH_MAX_SIZE_IN_BYTES.get(scan_type, consts.DEFAULT_SCAN_BATCH_MAX_SIZE_IN_BYTES)
|
|
53
|
-
|
|
54
|
-
batches = [documents] if scan_type == consts.SCA_SCAN_TYPE else split_documents_into_batches(documents, max_size)
|
|
55
|
-
|
|
56
|
-
progress_bar.set_section_length(ScanProgressBarSection.SCAN, len(batches)) # * 3
|
|
57
|
-
# TODO(MarshalX): we should multiply the count of batches in SCAN section because each batch has 3 steps:
|
|
58
|
-
# 1. scan creation
|
|
59
|
-
# 2. scan completion
|
|
60
|
-
# 3. detection creation
|
|
61
|
-
# it's not possible yet because not all scan types moved to polling mechanism
|
|
62
|
-
# the progress bar could be significant improved (be more dynamic) in the future
|
|
63
|
-
|
|
64
|
-
local_scan_results: List['LocalScanResult'] = []
|
|
65
|
-
cli_errors: Dict[str, 'CliError'] = {}
|
|
66
|
-
with ThreadPool(processes=_get_threads_count()) as pool:
|
|
67
|
-
for scan_id, err, result in pool.imap(scan_function, batches):
|
|
68
|
-
if result:
|
|
69
|
-
local_scan_results.append(result)
|
|
70
|
-
if err:
|
|
71
|
-
cli_errors[scan_id] = err
|
|
72
|
-
|
|
73
|
-
progress_bar.update(ScanProgressBarSection.SCAN)
|
|
74
|
-
|
|
75
|
-
return cli_errors, local_scan_results
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/ai_remediation/ai_remediation_command.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/report/sbom/path/path_command.py
RENAMED
|
File without changes
|
{cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/report/sbom/repository_url/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/commands/scan/pre_receive/pre_receive_command.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/exceptions/handle_ai_remediation_errors.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/iac/tf_content_generator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/sca/base_restore_dependencies.py
RENAMED
|
File without changes
|
|
File without changes
|
{cycode-2.3.1.dev2 → cycode-2.3.2.dev1}/cycode/cli/files_collector/sca/go/restore_go_dependencies.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|