regscale-cli 6.21.2.0__py3-none-any.whl → 6.28.2.1__py3-none-any.whl
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.
- regscale/_version.py +1 -1
- regscale/airflow/hierarchy.py +2 -2
- regscale/core/app/api.py +5 -2
- regscale/core/app/application.py +36 -6
- regscale/core/app/internal/control_editor.py +73 -21
- regscale/core/app/internal/evidence.py +727 -204
- regscale/core/app/internal/login.py +4 -2
- regscale/core/app/internal/model_editor.py +219 -64
- regscale/core/app/utils/app_utils.py +86 -12
- regscale/core/app/utils/catalog_utils/common.py +1 -1
- regscale/core/login.py +21 -4
- regscale/core/utils/async_graphql_client.py +363 -0
- regscale/core/utils/date.py +77 -1
- regscale/dev/cli.py +26 -0
- regscale/dev/code_gen.py +109 -24
- regscale/dev/version.py +72 -0
- regscale/integrations/commercial/__init__.py +30 -2
- regscale/integrations/commercial/aws/audit_manager_compliance.py +3908 -0
- regscale/integrations/commercial/aws/cli.py +3107 -54
- regscale/integrations/commercial/aws/cloudtrail_control_mappings.py +333 -0
- regscale/integrations/commercial/aws/cloudtrail_evidence.py +501 -0
- regscale/integrations/commercial/aws/cloudwatch_control_mappings.py +357 -0
- regscale/integrations/commercial/aws/cloudwatch_evidence.py +490 -0
- regscale/integrations/commercial/{amazon → aws}/common.py +71 -19
- regscale/integrations/commercial/aws/config_compliance.py +914 -0
- regscale/integrations/commercial/aws/conformance_pack_mappings.py +198 -0
- regscale/integrations/commercial/aws/control_compliance_analyzer.py +439 -0
- regscale/integrations/commercial/aws/evidence_generator.py +283 -0
- regscale/integrations/commercial/aws/guardduty_control_mappings.py +340 -0
- regscale/integrations/commercial/aws/guardduty_evidence.py +1053 -0
- regscale/integrations/commercial/aws/iam_control_mappings.py +368 -0
- regscale/integrations/commercial/aws/iam_evidence.py +574 -0
- regscale/integrations/commercial/aws/inventory/__init__.py +338 -22
- regscale/integrations/commercial/aws/inventory/base.py +107 -5
- regscale/integrations/commercial/aws/inventory/resources/analytics.py +390 -0
- regscale/integrations/commercial/aws/inventory/resources/applications.py +234 -0
- regscale/integrations/commercial/aws/inventory/resources/audit_manager.py +513 -0
- regscale/integrations/commercial/aws/inventory/resources/cloudtrail.py +315 -0
- regscale/integrations/commercial/aws/inventory/resources/cloudtrail_logs_metadata.py +476 -0
- regscale/integrations/commercial/aws/inventory/resources/cloudwatch.py +191 -0
- regscale/integrations/commercial/aws/inventory/resources/compute.py +328 -9
- regscale/integrations/commercial/aws/inventory/resources/config.py +464 -0
- regscale/integrations/commercial/aws/inventory/resources/containers.py +74 -9
- regscale/integrations/commercial/aws/inventory/resources/database.py +481 -31
- regscale/integrations/commercial/aws/inventory/resources/developer_tools.py +253 -0
- regscale/integrations/commercial/aws/inventory/resources/guardduty.py +286 -0
- regscale/integrations/commercial/aws/inventory/resources/iam.py +470 -0
- regscale/integrations/commercial/aws/inventory/resources/inspector.py +476 -0
- regscale/integrations/commercial/aws/inventory/resources/integration.py +175 -61
- regscale/integrations/commercial/aws/inventory/resources/kms.py +447 -0
- regscale/integrations/commercial/aws/inventory/resources/machine_learning.py +358 -0
- regscale/integrations/commercial/aws/inventory/resources/networking.py +390 -67
- regscale/integrations/commercial/aws/inventory/resources/s3.py +394 -0
- regscale/integrations/commercial/aws/inventory/resources/security.py +268 -72
- regscale/integrations/commercial/aws/inventory/resources/securityhub.py +473 -0
- regscale/integrations/commercial/aws/inventory/resources/storage.py +288 -29
- regscale/integrations/commercial/aws/inventory/resources/systems_manager.py +657 -0
- regscale/integrations/commercial/aws/inventory/resources/vpc.py +655 -0
- regscale/integrations/commercial/aws/kms_control_mappings.py +288 -0
- regscale/integrations/commercial/aws/kms_evidence.py +879 -0
- regscale/integrations/commercial/aws/ocsf/__init__.py +7 -0
- regscale/integrations/commercial/aws/ocsf/constants.py +115 -0
- regscale/integrations/commercial/aws/ocsf/mapper.py +435 -0
- regscale/integrations/commercial/aws/org_control_mappings.py +286 -0
- regscale/integrations/commercial/aws/org_evidence.py +666 -0
- regscale/integrations/commercial/aws/s3_control_mappings.py +356 -0
- regscale/integrations/commercial/aws/s3_evidence.py +632 -0
- regscale/integrations/commercial/aws/scanner.py +1072 -205
- regscale/integrations/commercial/aws/security_hub.py +319 -0
- regscale/integrations/commercial/aws/session_manager.py +282 -0
- regscale/integrations/commercial/aws/ssm_control_mappings.py +291 -0
- regscale/integrations/commercial/aws/ssm_evidence.py +492 -0
- regscale/integrations/commercial/jira.py +489 -153
- regscale/integrations/commercial/microsoft_defender/defender.py +326 -5
- regscale/integrations/commercial/microsoft_defender/defender_api.py +348 -14
- regscale/integrations/commercial/microsoft_defender/defender_constants.py +157 -0
- regscale/integrations/commercial/qualys/__init__.py +167 -68
- regscale/integrations/commercial/qualys/scanner.py +305 -39
- regscale/integrations/commercial/sarif/sairf_importer.py +432 -0
- regscale/integrations/commercial/sarif/sarif_converter.py +67 -0
- regscale/integrations/commercial/sicura/api.py +79 -42
- regscale/integrations/commercial/sicura/commands.py +8 -2
- regscale/integrations/commercial/sicura/scanner.py +83 -44
- regscale/integrations/commercial/stigv2/ckl_parser.py +5 -5
- regscale/integrations/commercial/synqly/assets.py +133 -16
- regscale/integrations/commercial/synqly/edr.py +2 -8
- regscale/integrations/commercial/synqly/query_builder.py +536 -0
- regscale/integrations/commercial/synqly/ticketing.py +27 -0
- regscale/integrations/commercial/synqly/vulnerabilities.py +165 -28
- regscale/integrations/commercial/tenablev2/cis_parsers.py +453 -0
- regscale/integrations/commercial/tenablev2/cis_scanner.py +447 -0
- regscale/integrations/commercial/tenablev2/commands.py +146 -5
- regscale/integrations/commercial/tenablev2/scanner.py +1 -3
- regscale/integrations/commercial/tenablev2/stig_parsers.py +113 -57
- regscale/integrations/commercial/wizv2/WizDataMixin.py +1 -1
- regscale/integrations/commercial/wizv2/click.py +191 -76
- regscale/integrations/commercial/wizv2/compliance/__init__.py +15 -0
- regscale/integrations/commercial/wizv2/{policy_compliance_helpers.py → compliance/helpers.py} +78 -60
- regscale/integrations/commercial/wizv2/compliance_report.py +1592 -0
- regscale/integrations/commercial/wizv2/core/__init__.py +133 -0
- regscale/integrations/commercial/wizv2/{async_client.py → core/client.py} +7 -3
- regscale/integrations/commercial/wizv2/{constants.py → core/constants.py} +92 -89
- regscale/integrations/commercial/wizv2/core/file_operations.py +237 -0
- regscale/integrations/commercial/wizv2/fetchers/__init__.py +11 -0
- regscale/integrations/commercial/wizv2/{data_fetcher.py → fetchers/policy_assessment.py} +66 -9
- regscale/integrations/commercial/wizv2/file_cleanup.py +104 -0
- regscale/integrations/commercial/wizv2/issue.py +776 -28
- regscale/integrations/commercial/wizv2/models/__init__.py +0 -0
- regscale/integrations/commercial/wizv2/parsers/__init__.py +34 -0
- regscale/integrations/commercial/wizv2/{parsers.py → parsers/main.py} +1 -1
- regscale/integrations/commercial/wizv2/processors/__init__.py +11 -0
- regscale/integrations/commercial/wizv2/{finding_processor.py → processors/finding.py} +1 -1
- regscale/integrations/commercial/wizv2/reports.py +243 -0
- regscale/integrations/commercial/wizv2/sbom.py +1 -1
- regscale/integrations/commercial/wizv2/scanner.py +1031 -441
- regscale/integrations/commercial/wizv2/utils/__init__.py +48 -0
- regscale/integrations/commercial/wizv2/{utils.py → utils/main.py} +116 -61
- regscale/integrations/commercial/wizv2/variables.py +89 -3
- regscale/integrations/compliance_integration.py +1036 -151
- regscale/integrations/control_matcher.py +432 -0
- regscale/integrations/due_date_handler.py +333 -0
- regscale/integrations/milestone_manager.py +291 -0
- regscale/integrations/public/__init__.py +14 -0
- regscale/integrations/public/cci_importer.py +834 -0
- regscale/integrations/public/csam/__init__.py +0 -0
- regscale/integrations/public/csam/csam.py +938 -0
- regscale/integrations/public/csam/csam_agency_defined.py +179 -0
- regscale/integrations/public/csam/csam_common.py +154 -0
- regscale/integrations/public/csam/csam_controls.py +432 -0
- regscale/integrations/public/csam/csam_poam.py +124 -0
- regscale/integrations/public/fedramp/click.py +77 -6
- regscale/integrations/public/fedramp/docx_parser.py +10 -1
- regscale/integrations/public/fedramp/fedramp_cis_crm.py +675 -289
- regscale/integrations/public/fedramp/fedramp_five.py +1 -1
- regscale/integrations/public/fedramp/poam/scanner.py +75 -7
- regscale/integrations/public/fedramp/poam_export_v5.py +888 -0
- regscale/integrations/scanner_integration.py +1961 -430
- regscale/models/integration_models/CCI_List.xml +1 -0
- regscale/models/integration_models/aqua.py +2 -2
- regscale/models/integration_models/cisa_kev_data.json +805 -11
- regscale/models/integration_models/flat_file_importer/__init__.py +5 -8
- regscale/models/integration_models/nexpose.py +36 -10
- regscale/models/integration_models/qualys.py +3 -4
- regscale/models/integration_models/synqly_models/capabilities.json +1 -1
- regscale/models/integration_models/synqly_models/connectors/vulnerabilities.py +87 -18
- regscale/models/integration_models/synqly_models/filter_parser.py +332 -0
- regscale/models/integration_models/synqly_models/ocsf_mapper.py +124 -25
- regscale/models/integration_models/synqly_models/synqly_model.py +89 -16
- regscale/models/locking.py +12 -8
- regscale/models/platform.py +4 -2
- regscale/models/regscale_models/__init__.py +7 -0
- regscale/models/regscale_models/assessment.py +2 -1
- regscale/models/regscale_models/catalog.py +1 -1
- regscale/models/regscale_models/compliance_settings.py +251 -1
- regscale/models/regscale_models/component.py +1 -0
- regscale/models/regscale_models/control_implementation.py +236 -41
- regscale/models/regscale_models/control_objective.py +74 -5
- regscale/models/regscale_models/file.py +2 -0
- regscale/models/regscale_models/form_field_value.py +5 -3
- regscale/models/regscale_models/inheritance.py +44 -0
- regscale/models/regscale_models/issue.py +301 -102
- regscale/models/regscale_models/milestone.py +33 -14
- regscale/models/regscale_models/organization.py +3 -0
- regscale/models/regscale_models/regscale_model.py +310 -73
- regscale/models/regscale_models/security_plan.py +4 -2
- regscale/models/regscale_models/vulnerability.py +3 -3
- regscale/regscale.py +25 -4
- regscale/templates/__init__.py +0 -0
- regscale/utils/threading/threadhandler.py +20 -15
- regscale/validation/record.py +23 -1
- {regscale_cli-6.21.2.0.dist-info → regscale_cli-6.28.2.1.dist-info}/METADATA +17 -33
- {regscale_cli-6.21.2.0.dist-info → regscale_cli-6.28.2.1.dist-info}/RECORD +310 -111
- tests/core/__init__.py +0 -0
- tests/core/utils/__init__.py +0 -0
- tests/core/utils/test_async_graphql_client.py +472 -0
- tests/fixtures/test_fixture.py +13 -8
- tests/regscale/core/test_login.py +171 -4
- tests/regscale/integrations/commercial/__init__.py +0 -0
- tests/regscale/integrations/commercial/aws/__init__.py +0 -0
- tests/regscale/integrations/commercial/aws/test_audit_manager_compliance.py +1304 -0
- tests/regscale/integrations/commercial/aws/test_audit_manager_evidence_aggregation.py +341 -0
- tests/regscale/integrations/commercial/aws/test_aws_analytics_collector.py +260 -0
- tests/regscale/integrations/commercial/aws/test_aws_applications_collector.py +242 -0
- tests/regscale/integrations/commercial/aws/test_aws_audit_manager_collector.py +1155 -0
- tests/regscale/integrations/commercial/aws/test_aws_cloudtrail_collector.py +534 -0
- tests/regscale/integrations/commercial/aws/test_aws_config_collector.py +400 -0
- tests/regscale/integrations/commercial/aws/test_aws_developer_tools_collector.py +203 -0
- tests/regscale/integrations/commercial/aws/test_aws_guardduty_collector.py +315 -0
- tests/regscale/integrations/commercial/aws/test_aws_iam_collector.py +458 -0
- tests/regscale/integrations/commercial/aws/test_aws_inspector_collector.py +353 -0
- tests/regscale/integrations/commercial/aws/test_aws_inventory_integration.py +530 -0
- tests/regscale/integrations/commercial/aws/test_aws_kms_collector.py +919 -0
- tests/regscale/integrations/commercial/aws/test_aws_machine_learning_collector.py +237 -0
- tests/regscale/integrations/commercial/aws/test_aws_s3_collector.py +722 -0
- tests/regscale/integrations/commercial/aws/test_aws_scanner_integration.py +722 -0
- tests/regscale/integrations/commercial/aws/test_aws_securityhub_collector.py +792 -0
- tests/regscale/integrations/commercial/aws/test_aws_systems_manager_collector.py +918 -0
- tests/regscale/integrations/commercial/aws/test_aws_vpc_collector.py +996 -0
- tests/regscale/integrations/commercial/aws/test_cli_evidence.py +431 -0
- tests/regscale/integrations/commercial/aws/test_cloudtrail_control_mappings.py +452 -0
- tests/regscale/integrations/commercial/aws/test_cloudtrail_evidence.py +788 -0
- tests/regscale/integrations/commercial/aws/test_config_compliance.py +298 -0
- tests/regscale/integrations/commercial/aws/test_conformance_pack_mappings.py +200 -0
- tests/regscale/integrations/commercial/aws/test_control_compliance_analyzer.py +375 -0
- tests/regscale/integrations/commercial/aws/test_datetime_parsing.py +223 -0
- tests/regscale/integrations/commercial/aws/test_evidence_generator.py +386 -0
- tests/regscale/integrations/commercial/aws/test_guardduty_control_mappings.py +564 -0
- tests/regscale/integrations/commercial/aws/test_guardduty_evidence.py +1041 -0
- tests/regscale/integrations/commercial/aws/test_iam_control_mappings.py +718 -0
- tests/regscale/integrations/commercial/aws/test_iam_evidence.py +1375 -0
- tests/regscale/integrations/commercial/aws/test_kms_control_mappings.py +656 -0
- tests/regscale/integrations/commercial/aws/test_kms_evidence.py +1163 -0
- tests/regscale/integrations/commercial/aws/test_ocsf_mapper.py +370 -0
- tests/regscale/integrations/commercial/aws/test_org_control_mappings.py +546 -0
- tests/regscale/integrations/commercial/aws/test_org_evidence.py +1240 -0
- tests/regscale/integrations/commercial/aws/test_s3_control_mappings.py +672 -0
- tests/regscale/integrations/commercial/aws/test_s3_evidence.py +987 -0
- tests/regscale/integrations/commercial/aws/test_scanner_evidence.py +373 -0
- tests/regscale/integrations/commercial/aws/test_security_hub_config_filtering.py +539 -0
- tests/regscale/integrations/commercial/aws/test_session_manager.py +516 -0
- tests/regscale/integrations/commercial/aws/test_ssm_control_mappings.py +588 -0
- tests/regscale/integrations/commercial/aws/test_ssm_evidence.py +735 -0
- tests/regscale/integrations/commercial/conftest.py +28 -0
- tests/regscale/integrations/commercial/microsoft_defender/__init__.py +1 -0
- tests/regscale/integrations/commercial/microsoft_defender/test_defender.py +1517 -0
- tests/regscale/integrations/commercial/microsoft_defender/test_defender_api.py +1748 -0
- tests/regscale/integrations/commercial/microsoft_defender/test_defender_constants.py +327 -0
- tests/regscale/integrations/commercial/microsoft_defender/test_defender_scanner.py +487 -0
- tests/regscale/integrations/commercial/test_aws.py +3742 -0
- tests/regscale/integrations/commercial/test_burp.py +48 -0
- tests/regscale/integrations/commercial/test_crowdstrike.py +49 -0
- tests/regscale/integrations/commercial/test_dependabot.py +341 -0
- tests/regscale/integrations/commercial/test_gcp.py +1543 -0
- tests/regscale/integrations/commercial/test_gitlab.py +549 -0
- tests/regscale/integrations/commercial/test_ip_mac_address_length.py +84 -0
- tests/regscale/integrations/commercial/test_jira.py +2204 -0
- tests/regscale/integrations/commercial/test_npm_audit.py +42 -0
- tests/regscale/integrations/commercial/test_okta.py +1228 -0
- tests/regscale/integrations/commercial/test_sarif_converter.py +251 -0
- tests/regscale/integrations/commercial/test_sicura.py +349 -0
- tests/regscale/integrations/commercial/test_snow.py +423 -0
- tests/regscale/integrations/commercial/test_sonarcloud.py +394 -0
- tests/regscale/integrations/commercial/test_sqlserver.py +186 -0
- tests/regscale/integrations/commercial/test_stig.py +33 -0
- tests/regscale/integrations/commercial/test_stig_mapper.py +153 -0
- tests/regscale/integrations/commercial/test_stigv2.py +406 -0
- tests/regscale/integrations/commercial/test_wiz.py +1365 -0
- tests/regscale/integrations/commercial/test_wiz_inventory.py +256 -0
- tests/regscale/integrations/commercial/wizv2/__init__.py +339 -0
- tests/regscale/integrations/commercial/wizv2/compliance/__init__.py +1 -0
- tests/regscale/integrations/commercial/wizv2/compliance/test_helpers.py +903 -0
- tests/regscale/integrations/commercial/wizv2/core/__init__.py +1 -0
- tests/regscale/integrations/commercial/wizv2/core/test_auth.py +701 -0
- tests/regscale/integrations/commercial/wizv2/core/test_client.py +1037 -0
- tests/regscale/integrations/commercial/wizv2/core/test_file_operations.py +989 -0
- tests/regscale/integrations/commercial/wizv2/fetchers/__init__.py +1 -0
- tests/regscale/integrations/commercial/wizv2/fetchers/test_policy_assessment.py +805 -0
- tests/regscale/integrations/commercial/wizv2/parsers/__init__.py +1 -0
- tests/regscale/integrations/commercial/wizv2/parsers/test_main.py +1153 -0
- tests/regscale/integrations/commercial/wizv2/processors/__init__.py +1 -0
- tests/regscale/integrations/commercial/wizv2/processors/test_finding.py +671 -0
- tests/regscale/integrations/commercial/wizv2/test_WizDataMixin.py +537 -0
- tests/regscale/integrations/commercial/wizv2/test_click_comprehensive.py +851 -0
- tests/regscale/integrations/commercial/wizv2/test_compliance_report_comprehensive.py +910 -0
- tests/regscale/integrations/commercial/wizv2/test_compliance_report_normalization.py +138 -0
- tests/regscale/integrations/commercial/wizv2/test_file_cleanup.py +283 -0
- tests/regscale/integrations/commercial/wizv2/test_file_operations.py +260 -0
- tests/regscale/integrations/commercial/wizv2/test_issue.py +343 -0
- tests/regscale/integrations/commercial/wizv2/test_issue_comprehensive.py +1203 -0
- tests/regscale/integrations/commercial/wizv2/test_reports.py +497 -0
- tests/regscale/integrations/commercial/wizv2/test_sbom.py +643 -0
- tests/regscale/integrations/commercial/wizv2/test_scanner_comprehensive.py +805 -0
- tests/regscale/integrations/commercial/wizv2/test_wiz_click_client_id.py +165 -0
- tests/regscale/integrations/commercial/wizv2/test_wiz_compliance_report.py +1394 -0
- tests/regscale/integrations/commercial/wizv2/test_wiz_compliance_unit.py +341 -0
- tests/regscale/integrations/commercial/wizv2/test_wiz_control_normalization.py +138 -0
- tests/regscale/integrations/commercial/wizv2/test_wiz_findings_comprehensive.py +364 -0
- tests/regscale/integrations/commercial/wizv2/test_wiz_inventory_comprehensive.py +644 -0
- tests/regscale/integrations/commercial/wizv2/test_wiz_status_mapping.py +149 -0
- tests/regscale/integrations/commercial/wizv2/test_wizv2.py +1218 -0
- tests/regscale/integrations/commercial/wizv2/test_wizv2_utils.py +519 -0
- tests/regscale/integrations/commercial/wizv2/utils/__init__.py +1 -0
- tests/regscale/integrations/commercial/wizv2/utils/test_main.py +1523 -0
- tests/regscale/integrations/public/__init__.py +0 -0
- tests/regscale/integrations/public/fedramp/__init__.py +1 -0
- tests/regscale/integrations/public/fedramp/test_gen_asset_list.py +150 -0
- tests/regscale/integrations/public/fedramp/test_poam_export_v5.py +1293 -0
- tests/regscale/integrations/public/test_alienvault.py +220 -0
- tests/regscale/integrations/public/test_cci.py +1053 -0
- tests/regscale/integrations/public/test_cisa.py +1021 -0
- tests/regscale/integrations/public/test_emass.py +518 -0
- tests/regscale/integrations/public/test_fedramp.py +1152 -0
- tests/regscale/integrations/public/test_fedramp_cis_crm.py +3661 -0
- tests/regscale/integrations/public/test_file_uploads.py +506 -0
- tests/regscale/integrations/public/test_oscal.py +453 -0
- tests/regscale/integrations/test_compliance_status_mapping.py +406 -0
- tests/regscale/integrations/test_control_matcher.py +1421 -0
- tests/regscale/integrations/test_control_matching.py +155 -0
- tests/regscale/integrations/test_milestone_manager.py +408 -0
- tests/regscale/models/test_control_implementation.py +118 -3
- tests/regscale/models/test_form_field_value_integration.py +304 -0
- tests/regscale/models/test_issue.py +378 -1
- tests/regscale/models/test_module_integration.py +582 -0
- tests/regscale/models/test_tenable_integrations.py +811 -105
- regscale/integrations/commercial/wizv2/policy_compliance.py +0 -3057
- regscale/integrations/public/fedramp/mappings/fedramp_r4_parts.json +0 -7388
- regscale/integrations/public/fedramp/mappings/fedramp_r5_parts.json +0 -9605
- regscale/integrations/public/fedramp/parts_mapper.py +0 -107
- /regscale/integrations/commercial/{amazon → sarif}/__init__.py +0 -0
- /regscale/integrations/commercial/wizv2/{wiz_auth.py → core/auth.py} +0 -0
- {regscale_cli-6.21.2.0.dist-info → regscale_cli-6.28.2.1.dist-info}/LICENSE +0 -0
- {regscale_cli-6.21.2.0.dist-info → regscale_cli-6.28.2.1.dist-info}/WHEEL +0 -0
- {regscale_cli-6.21.2.0.dist-info → regscale_cli-6.28.2.1.dist-info}/entry_points.txt +0 -0
- {regscale_cli-6.21.2.0.dist-info → regscale_cli-6.28.2.1.dist-info}/top_level.txt +0 -0
|
@@ -8,8 +8,8 @@ import os
|
|
|
8
8
|
from datetime import datetime
|
|
9
9
|
from typing import Dict, List, Optional, Any, Callable
|
|
10
10
|
|
|
11
|
-
from regscale.integrations.commercial.wizv2.
|
|
12
|
-
from regscale.integrations.commercial.wizv2.constants import WizVulnerabilityType, WIZ_POLICY_QUERY
|
|
11
|
+
from regscale.integrations.commercial.wizv2.core.client import run_async_queries
|
|
12
|
+
from regscale.integrations.commercial.wizv2.core.constants import WizVulnerabilityType, WIZ_POLICY_QUERY
|
|
13
13
|
|
|
14
14
|
logger = logging.getLogger("regscale")
|
|
15
15
|
|
|
@@ -127,14 +127,10 @@ class WizApiClient:
|
|
|
127
127
|
"Content-Type": "application/json",
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
def fetch_policy_assessments_async(
|
|
131
|
-
self, wiz_project_id: str, progress_callback: Optional[Callable] = None
|
|
132
|
-
) -> List[Dict[str, Any]]:
|
|
130
|
+
def fetch_policy_assessments_async(self) -> List[Dict[str, Any]]:
|
|
133
131
|
"""
|
|
134
132
|
Fetch policy assessments using async client.
|
|
135
133
|
|
|
136
|
-
:param wiz_project_id: Wiz project ID
|
|
137
|
-
:param progress_callback: Optional progress callback
|
|
138
134
|
:return: List of policy assessment nodes
|
|
139
135
|
"""
|
|
140
136
|
try:
|
|
@@ -204,7 +200,7 @@ class WizApiClient:
|
|
|
204
200
|
logger.debug(f"Filter variant {filter_variant} failed: {e}")
|
|
205
201
|
continue
|
|
206
202
|
|
|
207
|
-
raise
|
|
203
|
+
raise RuntimeError(f"All filter variants failed. Last error: {last_error}")
|
|
208
204
|
|
|
209
205
|
def _create_requests_session(self):
|
|
210
206
|
"""
|
|
@@ -333,6 +329,9 @@ class PolicyAssessmentFetcher:
|
|
|
333
329
|
logger.debug("Async client failed, falling back to requests")
|
|
334
330
|
nodes = self._fetch_with_requests()
|
|
335
331
|
|
|
332
|
+
# Clean data (trim whitespace from externalId values)
|
|
333
|
+
nodes = self._clean_node_data(nodes)
|
|
334
|
+
|
|
336
335
|
# Filter to framework
|
|
337
336
|
filtered_nodes = self._filter_nodes_to_framework(nodes)
|
|
338
337
|
|
|
@@ -347,7 +346,7 @@ class PolicyAssessmentFetcher:
|
|
|
347
346
|
|
|
348
347
|
:return: List of policy assessment nodes
|
|
349
348
|
"""
|
|
350
|
-
return self.api_client.fetch_policy_assessments_async(
|
|
349
|
+
return self.api_client.fetch_policy_assessments_async()
|
|
351
350
|
|
|
352
351
|
def _fetch_with_requests(self) -> List[Dict[str, Any]]:
|
|
353
352
|
"""
|
|
@@ -399,3 +398,61 @@ class PolicyAssessmentFetcher:
|
|
|
399
398
|
filtered_nodes.append(node)
|
|
400
399
|
|
|
401
400
|
return filtered_nodes
|
|
401
|
+
|
|
402
|
+
def _clean_node_data(self, nodes: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
|
|
403
|
+
"""
|
|
404
|
+
Clean node data by trimming whitespace from externalId values.
|
|
405
|
+
|
|
406
|
+
This fixes issues where Wiz API returns control IDs with trailing/leading
|
|
407
|
+
whitespace (e.g., "AC-14 " instead of "AC-14") which prevents proper matching
|
|
408
|
+
with RegScale control implementations.
|
|
409
|
+
|
|
410
|
+
:param nodes: Raw assessment nodes from Wiz API
|
|
411
|
+
:return: Cleaned nodes with trimmed externalId values
|
|
412
|
+
"""
|
|
413
|
+
cleaned_nodes = []
|
|
414
|
+
|
|
415
|
+
for node in nodes:
|
|
416
|
+
try:
|
|
417
|
+
cleaned_node = self._clean_single_node(node)
|
|
418
|
+
cleaned_nodes.append(cleaned_node)
|
|
419
|
+
except Exception:
|
|
420
|
+
# On error, include the original node unchanged (defensive)
|
|
421
|
+
cleaned_nodes.append(node)
|
|
422
|
+
|
|
423
|
+
return cleaned_nodes
|
|
424
|
+
|
|
425
|
+
def _clean_single_node(self, node: Dict[str, Any]) -> Dict[str, Any]:
|
|
426
|
+
"""Clean a single node's data."""
|
|
427
|
+
# Deep copy the node to avoid modifying the original
|
|
428
|
+
cleaned_node = dict(node)
|
|
429
|
+
|
|
430
|
+
policy = cleaned_node.get("policy")
|
|
431
|
+
if self._should_clean_policy(policy):
|
|
432
|
+
cleaned_node["policy"] = self._clean_policy_subcategories(policy)
|
|
433
|
+
|
|
434
|
+
return cleaned_node
|
|
435
|
+
|
|
436
|
+
def _should_clean_policy(self, policy: Dict[str, Any]) -> bool:
|
|
437
|
+
"""Check if policy should be cleaned."""
|
|
438
|
+
return policy and "securitySubCategories" in policy
|
|
439
|
+
|
|
440
|
+
def _clean_policy_subcategories(self, policy: Dict[str, Any]) -> Dict[str, Any]:
|
|
441
|
+
"""Clean security subcategories in policy."""
|
|
442
|
+
subcategories = policy["securitySubCategories"]
|
|
443
|
+
cleaned_subcategories = [self._clean_subcategory(subcat) for subcat in subcategories]
|
|
444
|
+
|
|
445
|
+
cleaned_policy = dict(policy)
|
|
446
|
+
cleaned_policy["securitySubCategories"] = cleaned_subcategories
|
|
447
|
+
return cleaned_policy
|
|
448
|
+
|
|
449
|
+
def _clean_subcategory(self, subcat: Dict[str, Any]) -> Dict[str, Any]:
|
|
450
|
+
"""Clean a single subcategory's externalId."""
|
|
451
|
+
cleaned_subcat = dict(subcat)
|
|
452
|
+
|
|
453
|
+
if "externalId" in cleaned_subcat:
|
|
454
|
+
original_id = cleaned_subcat["externalId"]
|
|
455
|
+
cleaned_id = original_id.strip() if isinstance(original_id, str) else original_id
|
|
456
|
+
cleaned_subcat["externalId"] = cleaned_id
|
|
457
|
+
|
|
458
|
+
return cleaned_subcat
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""File cleanup utilities for Wiz integrations."""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
from typing import List, Tuple
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger("regscale")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class ReportFileCleanup:
|
|
13
|
+
"""Utility class for cleaning up old report files."""
|
|
14
|
+
|
|
15
|
+
@staticmethod
|
|
16
|
+
def cleanup_old_files(directory: str, file_prefix: str, extensions: List[str] = None, keep_count: int = 5) -> None:
|
|
17
|
+
"""
|
|
18
|
+
Keep the most recent files matching the pattern, delete older ones.
|
|
19
|
+
|
|
20
|
+
:param str directory: Directory containing files to clean
|
|
21
|
+
:param str file_prefix: File name prefix to match (e.g., 'compliance_report_')
|
|
22
|
+
:param List[str] extensions: List of extensions to clean (e.g., ['.csv', '.json']), defaults to None
|
|
23
|
+
:param int keep_count: Number of most recent files per extension to keep, defaults to 5
|
|
24
|
+
:return: None
|
|
25
|
+
:rtype: None
|
|
26
|
+
"""
|
|
27
|
+
if extensions is None:
|
|
28
|
+
extensions = [".csv", ".json", ".jsonl"]
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
if not os.path.exists(directory):
|
|
32
|
+
return
|
|
33
|
+
|
|
34
|
+
matching_entries = ReportFileCleanup._find_matching_files(directory, file_prefix, extensions)
|
|
35
|
+
files_by_extension = ReportFileCleanup._group_files_by_extension(matching_entries)
|
|
36
|
+
files_deleted = ReportFileCleanup._cleanup_files_by_extension(files_by_extension, keep_count)
|
|
37
|
+
|
|
38
|
+
if files_deleted > 0:
|
|
39
|
+
logger.info(f"Cleaned up {files_deleted} old report files from {directory}")
|
|
40
|
+
|
|
41
|
+
except Exception as e:
|
|
42
|
+
logger.warning(f"Error during file cleanup in {directory}: {e}")
|
|
43
|
+
|
|
44
|
+
@staticmethod
|
|
45
|
+
def _find_matching_files(directory: str, file_prefix: str, extensions: List[str]) -> List[Tuple[str, str, str]]:
|
|
46
|
+
"""
|
|
47
|
+
Find all files matching the prefix and extensions.
|
|
48
|
+
|
|
49
|
+
:param str directory: Directory to search for files
|
|
50
|
+
:param str file_prefix: File name prefix to match
|
|
51
|
+
:param List[str] extensions: List of file extensions to match
|
|
52
|
+
:return: List of tuples containing (filename, file_path, extension)
|
|
53
|
+
:rtype: List[Tuple[str, str, str]]
|
|
54
|
+
"""
|
|
55
|
+
entries = []
|
|
56
|
+
for filename in os.listdir(directory):
|
|
57
|
+
if filename.startswith(file_prefix):
|
|
58
|
+
for ext in extensions:
|
|
59
|
+
if filename.endswith(ext):
|
|
60
|
+
file_path = os.path.join(directory, filename)
|
|
61
|
+
entries.append((filename, file_path, ext))
|
|
62
|
+
break
|
|
63
|
+
return entries
|
|
64
|
+
|
|
65
|
+
@staticmethod
|
|
66
|
+
def _group_files_by_extension(entries: List[Tuple[str, str, str]]) -> dict:
|
|
67
|
+
"""
|
|
68
|
+
Group files by their extensions.
|
|
69
|
+
|
|
70
|
+
:param List[Tuple[str, str, str]] entries: List of file entries (filename, file_path, extension)
|
|
71
|
+
:return: Dictionary mapping extensions to lists of (filename, file_path) tuples
|
|
72
|
+
:rtype: dict
|
|
73
|
+
"""
|
|
74
|
+
by_extension = {}
|
|
75
|
+
for filename, file_path, ext in entries:
|
|
76
|
+
if ext not in by_extension:
|
|
77
|
+
by_extension[ext] = []
|
|
78
|
+
by_extension[ext].append((filename, file_path))
|
|
79
|
+
return by_extension
|
|
80
|
+
|
|
81
|
+
@staticmethod
|
|
82
|
+
def _cleanup_files_by_extension(files_by_extension: dict, keep_count: int) -> int:
|
|
83
|
+
"""
|
|
84
|
+
Clean up files for each extension, keeping the most recent ones.
|
|
85
|
+
|
|
86
|
+
:param dict files_by_extension: Dictionary mapping extensions to lists of (filename, file_path) tuples
|
|
87
|
+
:param int keep_count: Number of most recent files to keep for each extension
|
|
88
|
+
:return: Total number of files deleted
|
|
89
|
+
:rtype: int
|
|
90
|
+
"""
|
|
91
|
+
files_deleted = 0
|
|
92
|
+
|
|
93
|
+
for ext, files in files_by_extension.items():
|
|
94
|
+
files.sort(key=lambda x: os.path.getmtime(x[1]), reverse=True)
|
|
95
|
+
|
|
96
|
+
for filename, file_path in files[keep_count:]:
|
|
97
|
+
try:
|
|
98
|
+
os.remove(file_path)
|
|
99
|
+
files_deleted += 1
|
|
100
|
+
logger.debug(f"Deleted old report file: {filename}")
|
|
101
|
+
except Exception as e:
|
|
102
|
+
logger.warning(f"Failed to delete file {filename}: {e}")
|
|
103
|
+
|
|
104
|
+
return files_deleted
|