regscale-cli 6.16.0.0__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.
Potentially problematic release.
This version of regscale-cli might be problematic. Click here for more details.
- regscale/__init__.py +1 -0
- regscale/airflow/__init__.py +9 -0
- regscale/airflow/azure/__init__.py +9 -0
- regscale/airflow/azure/cli.py +89 -0
- regscale/airflow/azure/upload_dags.py +116 -0
- regscale/airflow/click_dags.py +127 -0
- regscale/airflow/click_mixins.py +82 -0
- regscale/airflow/config.py +25 -0
- regscale/airflow/factories/__init__.py +0 -0
- regscale/airflow/factories/connections.py +58 -0
- regscale/airflow/factories/workflows.py +78 -0
- regscale/airflow/hierarchy.py +88 -0
- regscale/airflow/operators/__init__.py +0 -0
- regscale/airflow/operators/click.py +36 -0
- regscale/airflow/sensors/__init__.py +0 -0
- regscale/airflow/sensors/sql.py +107 -0
- regscale/airflow/sessions/__init__.py +0 -0
- regscale/airflow/sessions/sql/__init__.py +3 -0
- regscale/airflow/sessions/sql/queries.py +64 -0
- regscale/airflow/sessions/sql/sql_server_queries.py +248 -0
- regscale/airflow/tasks/__init__.py +0 -0
- regscale/airflow/tasks/branches.py +22 -0
- regscale/airflow/tasks/cli.py +116 -0
- regscale/airflow/tasks/click.py +73 -0
- regscale/airflow/tasks/debugging.py +9 -0
- regscale/airflow/tasks/groups.py +116 -0
- regscale/airflow/tasks/init.py +60 -0
- regscale/airflow/tasks/states.py +47 -0
- regscale/airflow/tasks/workflows.py +36 -0
- regscale/ansible/__init__.py +9 -0
- regscale/core/__init__.py +0 -0
- regscale/core/app/__init__.py +3 -0
- regscale/core/app/api.py +571 -0
- regscale/core/app/application.py +665 -0
- regscale/core/app/internal/__init__.py +136 -0
- regscale/core/app/internal/admin_actions.py +230 -0
- regscale/core/app/internal/assessments_editor.py +873 -0
- regscale/core/app/internal/catalog.py +316 -0
- regscale/core/app/internal/comparison.py +459 -0
- regscale/core/app/internal/control_editor.py +571 -0
- regscale/core/app/internal/encrypt.py +79 -0
- regscale/core/app/internal/evidence.py +1240 -0
- regscale/core/app/internal/file_uploads.py +151 -0
- regscale/core/app/internal/healthcheck.py +66 -0
- regscale/core/app/internal/login.py +305 -0
- regscale/core/app/internal/migrations.py +240 -0
- regscale/core/app/internal/model_editor.py +1701 -0
- regscale/core/app/internal/poam_editor.py +632 -0
- regscale/core/app/internal/workflow.py +105 -0
- regscale/core/app/logz.py +74 -0
- regscale/core/app/utils/XMLIR.py +258 -0
- regscale/core/app/utils/__init__.py +0 -0
- regscale/core/app/utils/api_handler.py +358 -0
- regscale/core/app/utils/app_utils.py +1110 -0
- regscale/core/app/utils/catalog_utils/__init__.py +0 -0
- regscale/core/app/utils/catalog_utils/common.py +91 -0
- regscale/core/app/utils/catalog_utils/compare_catalog.py +193 -0
- regscale/core/app/utils/catalog_utils/diagnostic_catalog.py +97 -0
- regscale/core/app/utils/catalog_utils/download_catalog.py +103 -0
- regscale/core/app/utils/catalog_utils/update_catalog.py +718 -0
- regscale/core/app/utils/catalog_utils/update_catalog_v2.py +1378 -0
- regscale/core/app/utils/catalog_utils/update_catalog_v3.py +1272 -0
- regscale/core/app/utils/catalog_utils/update_plans.py +334 -0
- regscale/core/app/utils/file_utils.py +238 -0
- regscale/core/app/utils/parser_utils.py +81 -0
- regscale/core/app/utils/pickle_file_handler.py +57 -0
- regscale/core/app/utils/regscale_utils.py +319 -0
- regscale/core/app/utils/report_utils.py +119 -0
- regscale/core/app/utils/variables.py +226 -0
- regscale/core/decorators.py +31 -0
- regscale/core/lazy_group.py +65 -0
- regscale/core/login.py +63 -0
- regscale/core/server/__init__.py +0 -0
- regscale/core/server/flask_api.py +473 -0
- regscale/core/server/helpers.py +373 -0
- regscale/core/server/rest.py +64 -0
- regscale/core/server/static/css/bootstrap.css +6030 -0
- regscale/core/server/static/css/bootstrap.min.css +6 -0
- regscale/core/server/static/css/main.css +176 -0
- regscale/core/server/static/images/regscale-cli.svg +49 -0
- regscale/core/server/static/images/regscale.svg +38 -0
- regscale/core/server/templates/base.html +74 -0
- regscale/core/server/templates/index.html +43 -0
- regscale/core/server/templates/login.html +28 -0
- regscale/core/server/templates/make_base64.html +22 -0
- regscale/core/server/templates/upload_STIG.html +109 -0
- regscale/core/server/templates/upload_STIG_result.html +26 -0
- regscale/core/server/templates/upload_ssp.html +144 -0
- regscale/core/server/templates/upload_ssp_result.html +128 -0
- regscale/core/static/__init__.py +0 -0
- regscale/core/static/regex.py +14 -0
- regscale/core/utils/__init__.py +117 -0
- regscale/core/utils/click_utils.py +13 -0
- regscale/core/utils/date.py +238 -0
- regscale/core/utils/graphql.py +254 -0
- regscale/core/utils/urls.py +23 -0
- regscale/dev/__init__.py +6 -0
- regscale/dev/analysis.py +454 -0
- regscale/dev/cli.py +235 -0
- regscale/dev/code_gen.py +492 -0
- regscale/dev/dirs.py +69 -0
- regscale/dev/docs.py +384 -0
- regscale/dev/monitoring.py +26 -0
- regscale/dev/profiling.py +216 -0
- regscale/exceptions/__init__.py +4 -0
- regscale/exceptions/license_exception.py +7 -0
- regscale/exceptions/validation_exception.py +9 -0
- regscale/integrations/__init__.py +1 -0
- regscale/integrations/commercial/__init__.py +486 -0
- regscale/integrations/commercial/ad.py +433 -0
- regscale/integrations/commercial/amazon/__init__.py +0 -0
- regscale/integrations/commercial/amazon/common.py +106 -0
- regscale/integrations/commercial/aqua/__init__.py +0 -0
- regscale/integrations/commercial/aqua/aqua.py +91 -0
- regscale/integrations/commercial/aws/__init__.py +6 -0
- regscale/integrations/commercial/aws/cli.py +322 -0
- regscale/integrations/commercial/aws/inventory/__init__.py +110 -0
- regscale/integrations/commercial/aws/inventory/base.py +64 -0
- regscale/integrations/commercial/aws/inventory/resources/__init__.py +19 -0
- regscale/integrations/commercial/aws/inventory/resources/compute.py +234 -0
- regscale/integrations/commercial/aws/inventory/resources/containers.py +113 -0
- regscale/integrations/commercial/aws/inventory/resources/database.py +101 -0
- regscale/integrations/commercial/aws/inventory/resources/integration.py +237 -0
- regscale/integrations/commercial/aws/inventory/resources/networking.py +253 -0
- regscale/integrations/commercial/aws/inventory/resources/security.py +240 -0
- regscale/integrations/commercial/aws/inventory/resources/storage.py +91 -0
- regscale/integrations/commercial/aws/scanner.py +823 -0
- regscale/integrations/commercial/azure/__init__.py +0 -0
- regscale/integrations/commercial/azure/common.py +32 -0
- regscale/integrations/commercial/azure/intune.py +488 -0
- regscale/integrations/commercial/azure/scanner.py +49 -0
- regscale/integrations/commercial/burp.py +78 -0
- regscale/integrations/commercial/cpe.py +144 -0
- regscale/integrations/commercial/crowdstrike.py +1117 -0
- regscale/integrations/commercial/defender.py +1511 -0
- regscale/integrations/commercial/dependabot.py +210 -0
- regscale/integrations/commercial/durosuite/__init__.py +0 -0
- regscale/integrations/commercial/durosuite/api.py +1546 -0
- regscale/integrations/commercial/durosuite/process_devices.py +101 -0
- regscale/integrations/commercial/durosuite/scanner.py +637 -0
- regscale/integrations/commercial/durosuite/variables.py +21 -0
- regscale/integrations/commercial/ecr.py +90 -0
- regscale/integrations/commercial/gcp/__init__.py +237 -0
- regscale/integrations/commercial/gcp/auth.py +96 -0
- regscale/integrations/commercial/gcp/control_tests.py +238 -0
- regscale/integrations/commercial/gcp/variables.py +18 -0
- regscale/integrations/commercial/gitlab.py +332 -0
- regscale/integrations/commercial/grype.py +165 -0
- regscale/integrations/commercial/ibm.py +90 -0
- regscale/integrations/commercial/import_all/__init__.py +0 -0
- regscale/integrations/commercial/import_all/import_all_cmd.py +467 -0
- regscale/integrations/commercial/import_all/scan_file_fingerprints.json +27 -0
- regscale/integrations/commercial/jira.py +1046 -0
- regscale/integrations/commercial/mappings/__init__.py +0 -0
- regscale/integrations/commercial/mappings/csf_controls.json +713 -0
- regscale/integrations/commercial/mappings/nist_800_53_r5_controls.json +1516 -0
- regscale/integrations/commercial/nessus/__init__.py +0 -0
- regscale/integrations/commercial/nessus/nessus_utils.py +429 -0
- regscale/integrations/commercial/nessus/scanner.py +416 -0
- regscale/integrations/commercial/nexpose.py +90 -0
- regscale/integrations/commercial/okta.py +798 -0
- regscale/integrations/commercial/opentext/__init__.py +0 -0
- regscale/integrations/commercial/opentext/click.py +99 -0
- regscale/integrations/commercial/opentext/scanner.py +143 -0
- regscale/integrations/commercial/prisma.py +91 -0
- regscale/integrations/commercial/qualys.py +1462 -0
- regscale/integrations/commercial/salesforce.py +980 -0
- regscale/integrations/commercial/sap/__init__.py +0 -0
- regscale/integrations/commercial/sap/click.py +31 -0
- regscale/integrations/commercial/sap/sysdig/__init__.py +0 -0
- regscale/integrations/commercial/sap/sysdig/click.py +57 -0
- regscale/integrations/commercial/sap/sysdig/sysdig_scanner.py +190 -0
- regscale/integrations/commercial/sap/tenable/__init__.py +0 -0
- regscale/integrations/commercial/sap/tenable/click.py +49 -0
- regscale/integrations/commercial/sap/tenable/scanner.py +196 -0
- regscale/integrations/commercial/servicenow.py +1756 -0
- regscale/integrations/commercial/sicura/__init__.py +0 -0
- regscale/integrations/commercial/sicura/api.py +855 -0
- regscale/integrations/commercial/sicura/commands.py +73 -0
- regscale/integrations/commercial/sicura/scanner.py +481 -0
- regscale/integrations/commercial/sicura/variables.py +16 -0
- regscale/integrations/commercial/snyk.py +90 -0
- regscale/integrations/commercial/sonarcloud.py +260 -0
- regscale/integrations/commercial/sqlserver.py +369 -0
- regscale/integrations/commercial/stig_mapper_integration/__init__.py +0 -0
- regscale/integrations/commercial/stig_mapper_integration/click_commands.py +38 -0
- regscale/integrations/commercial/stig_mapper_integration/mapping_engine.py +353 -0
- regscale/integrations/commercial/stigv2/__init__.py +0 -0
- regscale/integrations/commercial/stigv2/ckl_parser.py +349 -0
- regscale/integrations/commercial/stigv2/click_commands.py +95 -0
- regscale/integrations/commercial/stigv2/stig_integration.py +202 -0
- regscale/integrations/commercial/synqly/__init__.py +0 -0
- regscale/integrations/commercial/synqly/assets.py +46 -0
- regscale/integrations/commercial/synqly/ticketing.py +132 -0
- regscale/integrations/commercial/synqly/vulnerabilities.py +223 -0
- regscale/integrations/commercial/synqly_jira.py +840 -0
- regscale/integrations/commercial/tenablev2/__init__.py +0 -0
- regscale/integrations/commercial/tenablev2/authenticate.py +31 -0
- regscale/integrations/commercial/tenablev2/click.py +1584 -0
- regscale/integrations/commercial/tenablev2/scanner.py +504 -0
- regscale/integrations/commercial/tenablev2/stig_parsers.py +140 -0
- regscale/integrations/commercial/tenablev2/utils.py +78 -0
- regscale/integrations/commercial/tenablev2/variables.py +17 -0
- regscale/integrations/commercial/trivy.py +162 -0
- regscale/integrations/commercial/veracode.py +96 -0
- regscale/integrations/commercial/wizv2/WizDataMixin.py +97 -0
- regscale/integrations/commercial/wizv2/__init__.py +0 -0
- regscale/integrations/commercial/wizv2/click.py +429 -0
- regscale/integrations/commercial/wizv2/constants.py +1001 -0
- regscale/integrations/commercial/wizv2/issue.py +361 -0
- regscale/integrations/commercial/wizv2/models.py +112 -0
- regscale/integrations/commercial/wizv2/parsers.py +339 -0
- regscale/integrations/commercial/wizv2/sbom.py +115 -0
- regscale/integrations/commercial/wizv2/scanner.py +416 -0
- regscale/integrations/commercial/wizv2/utils.py +796 -0
- regscale/integrations/commercial/wizv2/variables.py +39 -0
- regscale/integrations/commercial/wizv2/wiz_auth.py +159 -0
- regscale/integrations/commercial/xray.py +91 -0
- regscale/integrations/integration/__init__.py +2 -0
- regscale/integrations/integration/integration.py +26 -0
- regscale/integrations/integration/inventory.py +17 -0
- regscale/integrations/integration/issue.py +100 -0
- regscale/integrations/integration_override.py +149 -0
- regscale/integrations/public/__init__.py +103 -0
- regscale/integrations/public/cisa.py +641 -0
- regscale/integrations/public/criticality_updater.py +70 -0
- regscale/integrations/public/emass.py +411 -0
- regscale/integrations/public/emass_slcm_import.py +697 -0
- regscale/integrations/public/fedramp/__init__.py +0 -0
- regscale/integrations/public/fedramp/appendix_parser.py +548 -0
- regscale/integrations/public/fedramp/click.py +479 -0
- regscale/integrations/public/fedramp/components.py +714 -0
- regscale/integrations/public/fedramp/docx_parser.py +259 -0
- regscale/integrations/public/fedramp/fedramp_cis_crm.py +1124 -0
- regscale/integrations/public/fedramp/fedramp_common.py +3181 -0
- regscale/integrations/public/fedramp/fedramp_docx.py +388 -0
- regscale/integrations/public/fedramp/fedramp_five.py +2343 -0
- regscale/integrations/public/fedramp/fedramp_traversal.py +138 -0
- regscale/integrations/public/fedramp/import_fedramp_r4_ssp.py +279 -0
- regscale/integrations/public/fedramp/import_workbook.py +495 -0
- regscale/integrations/public/fedramp/inventory_items.py +244 -0
- regscale/integrations/public/fedramp/mappings/__init__.py +0 -0
- regscale/integrations/public/fedramp/mappings/fedramp_r4_parts.json +7388 -0
- regscale/integrations/public/fedramp/mappings/fedramp_r5_params.json +8636 -0
- regscale/integrations/public/fedramp/mappings/fedramp_r5_parts.json +9605 -0
- regscale/integrations/public/fedramp/mappings/system_roles.py +34 -0
- regscale/integrations/public/fedramp/mappings/user.py +175 -0
- regscale/integrations/public/fedramp/mappings/values.py +141 -0
- regscale/integrations/public/fedramp/markdown_parser.py +150 -0
- regscale/integrations/public/fedramp/metadata.py +689 -0
- regscale/integrations/public/fedramp/models/__init__.py +59 -0
- regscale/integrations/public/fedramp/models/leveraged_auth_new.py +168 -0
- regscale/integrations/public/fedramp/models/poam_importer.py +522 -0
- regscale/integrations/public/fedramp/parts_mapper.py +107 -0
- regscale/integrations/public/fedramp/poam/__init__.py +0 -0
- regscale/integrations/public/fedramp/poam/scanner.py +851 -0
- regscale/integrations/public/fedramp/properties.py +201 -0
- regscale/integrations/public/fedramp/reporting.py +84 -0
- regscale/integrations/public/fedramp/resources.py +496 -0
- regscale/integrations/public/fedramp/rosetta.py +110 -0
- regscale/integrations/public/fedramp/ssp_logger.py +87 -0
- regscale/integrations/public/fedramp/system_characteristics.py +922 -0
- regscale/integrations/public/fedramp/system_control_implementations.py +582 -0
- regscale/integrations/public/fedramp/system_implementation.py +190 -0
- regscale/integrations/public/fedramp/xml_utils.py +87 -0
- regscale/integrations/public/nist_catalog.py +275 -0
- regscale/integrations/public/oscal.py +1946 -0
- regscale/integrations/public/otx.py +169 -0
- regscale/integrations/scanner_integration.py +2692 -0
- regscale/integrations/variables.py +25 -0
- regscale/models/__init__.py +7 -0
- regscale/models/app_models/__init__.py +5 -0
- regscale/models/app_models/catalog_compare.py +213 -0
- regscale/models/app_models/click.py +252 -0
- regscale/models/app_models/datetime_encoder.py +21 -0
- regscale/models/app_models/import_validater.py +321 -0
- regscale/models/app_models/mapping.py +260 -0
- regscale/models/app_models/pipeline.py +37 -0
- regscale/models/click_models.py +413 -0
- regscale/models/config.py +154 -0
- regscale/models/email_style.css +67 -0
- regscale/models/hierarchy.py +8 -0
- regscale/models/inspect_models.py +79 -0
- regscale/models/integration_models/__init__.py +0 -0
- regscale/models/integration_models/amazon_models/__init__.py +0 -0
- regscale/models/integration_models/amazon_models/inspector.py +262 -0
- regscale/models/integration_models/amazon_models/inspector_scan.py +206 -0
- regscale/models/integration_models/aqua.py +247 -0
- regscale/models/integration_models/azure_alerts.py +255 -0
- regscale/models/integration_models/base64.py +23 -0
- regscale/models/integration_models/burp.py +433 -0
- regscale/models/integration_models/burp_models.py +128 -0
- regscale/models/integration_models/cisa_kev_data.json +19333 -0
- regscale/models/integration_models/defender_data.py +93 -0
- regscale/models/integration_models/defenderimport.py +143 -0
- regscale/models/integration_models/drf.py +443 -0
- regscale/models/integration_models/ecr_models/__init__.py +0 -0
- regscale/models/integration_models/ecr_models/data.py +69 -0
- regscale/models/integration_models/ecr_models/ecr.py +239 -0
- regscale/models/integration_models/flat_file_importer.py +1079 -0
- regscale/models/integration_models/grype_import.py +247 -0
- regscale/models/integration_models/ibm.py +126 -0
- regscale/models/integration_models/implementation_results.py +85 -0
- regscale/models/integration_models/nexpose.py +140 -0
- regscale/models/integration_models/prisma.py +202 -0
- regscale/models/integration_models/qualys.py +720 -0
- regscale/models/integration_models/qualys_scanner.py +160 -0
- regscale/models/integration_models/sbom/__init__.py +0 -0
- regscale/models/integration_models/sbom/cyclone_dx.py +139 -0
- regscale/models/integration_models/send_reminders.py +620 -0
- regscale/models/integration_models/snyk.py +155 -0
- regscale/models/integration_models/synqly_models/__init__.py +0 -0
- regscale/models/integration_models/synqly_models/capabilities.json +1 -0
- regscale/models/integration_models/synqly_models/connector_types.py +22 -0
- regscale/models/integration_models/synqly_models/connectors/__init__.py +7 -0
- regscale/models/integration_models/synqly_models/connectors/assets.py +97 -0
- regscale/models/integration_models/synqly_models/connectors/ticketing.py +583 -0
- regscale/models/integration_models/synqly_models/connectors/vulnerabilities.py +169 -0
- regscale/models/integration_models/synqly_models/ocsf_mapper.py +331 -0
- regscale/models/integration_models/synqly_models/param.py +72 -0
- regscale/models/integration_models/synqly_models/synqly_model.py +733 -0
- regscale/models/integration_models/synqly_models/tenants.py +39 -0
- regscale/models/integration_models/tenable_models/__init__.py +0 -0
- regscale/models/integration_models/tenable_models/integration.py +187 -0
- regscale/models/integration_models/tenable_models/models.py +513 -0
- regscale/models/integration_models/trivy_import.py +231 -0
- regscale/models/integration_models/veracode.py +217 -0
- regscale/models/integration_models/xray.py +135 -0
- regscale/models/locking.py +100 -0
- regscale/models/platform.py +110 -0
- regscale/models/regscale_models/__init__.py +67 -0
- regscale/models/regscale_models/assessment.py +570 -0
- regscale/models/regscale_models/assessment_plan.py +52 -0
- regscale/models/regscale_models/asset.py +567 -0
- regscale/models/regscale_models/asset_mapping.py +190 -0
- regscale/models/regscale_models/case.py +42 -0
- regscale/models/regscale_models/catalog.py +261 -0
- regscale/models/regscale_models/cci.py +46 -0
- regscale/models/regscale_models/change.py +167 -0
- regscale/models/regscale_models/checklist.py +372 -0
- regscale/models/regscale_models/comment.py +49 -0
- regscale/models/regscale_models/compliance_settings.py +112 -0
- regscale/models/regscale_models/component.py +412 -0
- regscale/models/regscale_models/component_mapping.py +65 -0
- regscale/models/regscale_models/control.py +38 -0
- regscale/models/regscale_models/control_implementation.py +1128 -0
- regscale/models/regscale_models/control_objective.py +261 -0
- regscale/models/regscale_models/control_parameter.py +100 -0
- regscale/models/regscale_models/control_test.py +34 -0
- regscale/models/regscale_models/control_test_plan.py +75 -0
- regscale/models/regscale_models/control_test_result.py +52 -0
- regscale/models/regscale_models/custom_field.py +245 -0
- regscale/models/regscale_models/data.py +109 -0
- regscale/models/regscale_models/data_center.py +40 -0
- regscale/models/regscale_models/deviation.py +203 -0
- regscale/models/regscale_models/email.py +97 -0
- regscale/models/regscale_models/evidence.py +47 -0
- regscale/models/regscale_models/evidence_mapping.py +40 -0
- regscale/models/regscale_models/facility.py +59 -0
- regscale/models/regscale_models/file.py +382 -0
- regscale/models/regscale_models/filetag.py +37 -0
- regscale/models/regscale_models/form_field_value.py +94 -0
- regscale/models/regscale_models/group.py +169 -0
- regscale/models/regscale_models/implementation_objective.py +335 -0
- regscale/models/regscale_models/implementation_option.py +275 -0
- regscale/models/regscale_models/implementation_role.py +33 -0
- regscale/models/regscale_models/incident.py +177 -0
- regscale/models/regscale_models/interconnection.py +43 -0
- regscale/models/regscale_models/issue.py +1176 -0
- regscale/models/regscale_models/leveraged_authorization.py +125 -0
- regscale/models/regscale_models/line_of_inquiry.py +52 -0
- regscale/models/regscale_models/link.py +205 -0
- regscale/models/regscale_models/meta_data.py +64 -0
- regscale/models/regscale_models/mixins/__init__.py +0 -0
- regscale/models/regscale_models/mixins/parent_cache.py +124 -0
- regscale/models/regscale_models/module.py +224 -0
- regscale/models/regscale_models/modules.py +191 -0
- regscale/models/regscale_models/objective.py +14 -0
- regscale/models/regscale_models/parameter.py +87 -0
- regscale/models/regscale_models/ports_protocol.py +81 -0
- regscale/models/regscale_models/privacy.py +89 -0
- regscale/models/regscale_models/profile.py +50 -0
- regscale/models/regscale_models/profile_link.py +68 -0
- regscale/models/regscale_models/profile_mapping.py +124 -0
- regscale/models/regscale_models/project.py +63 -0
- regscale/models/regscale_models/property.py +278 -0
- regscale/models/regscale_models/question.py +85 -0
- regscale/models/regscale_models/questionnaire.py +87 -0
- regscale/models/regscale_models/questionnaire_instance.py +177 -0
- regscale/models/regscale_models/rbac.py +132 -0
- regscale/models/regscale_models/reference.py +86 -0
- regscale/models/regscale_models/regscale_model.py +1643 -0
- regscale/models/regscale_models/requirement.py +29 -0
- regscale/models/regscale_models/risk.py +274 -0
- regscale/models/regscale_models/sbom.py +54 -0
- regscale/models/regscale_models/scan_history.py +436 -0
- regscale/models/regscale_models/search.py +53 -0
- regscale/models/regscale_models/security_control.py +132 -0
- regscale/models/regscale_models/security_plan.py +204 -0
- regscale/models/regscale_models/software_inventory.py +159 -0
- regscale/models/regscale_models/stake_holder.py +64 -0
- regscale/models/regscale_models/stig.py +647 -0
- regscale/models/regscale_models/supply_chain.py +152 -0
- regscale/models/regscale_models/system_role.py +188 -0
- regscale/models/regscale_models/system_role_external_assignment.py +40 -0
- regscale/models/regscale_models/tag.py +37 -0
- regscale/models/regscale_models/tag_mapping.py +19 -0
- regscale/models/regscale_models/task.py +133 -0
- regscale/models/regscale_models/threat.py +196 -0
- regscale/models/regscale_models/user.py +175 -0
- regscale/models/regscale_models/user_group.py +55 -0
- regscale/models/regscale_models/vulnerability.py +242 -0
- regscale/models/regscale_models/vulnerability_mapping.py +162 -0
- regscale/models/regscale_models/workflow.py +55 -0
- regscale/models/regscale_models/workflow_action.py +34 -0
- regscale/models/regscale_models/workflow_instance.py +269 -0
- regscale/models/regscale_models/workflow_instance_step.py +114 -0
- regscale/models/regscale_models/workflow_template.py +58 -0
- regscale/models/regscale_models/workflow_template_step.py +45 -0
- regscale/regscale.py +815 -0
- regscale/utils/__init__.py +7 -0
- regscale/utils/b64conversion.py +14 -0
- regscale/utils/click_utils.py +118 -0
- regscale/utils/decorators.py +48 -0
- regscale/utils/dict_utils.py +59 -0
- regscale/utils/files.py +79 -0
- regscale/utils/fxns.py +30 -0
- regscale/utils/graphql_client.py +113 -0
- regscale/utils/lists.py +16 -0
- regscale/utils/numbers.py +12 -0
- regscale/utils/shell.py +148 -0
- regscale/utils/string.py +121 -0
- regscale/utils/synqly_utils.py +165 -0
- regscale/utils/threading/__init__.py +8 -0
- regscale/utils/threading/threadhandler.py +131 -0
- regscale/utils/threading/threadsafe_counter.py +47 -0
- regscale/utils/threading/threadsafe_dict.py +242 -0
- regscale/utils/threading/threadsafe_list.py +83 -0
- regscale/utils/version.py +104 -0
- regscale/validation/__init__.py +0 -0
- regscale/validation/address.py +37 -0
- regscale/validation/record.py +48 -0
- regscale/visualization/__init__.py +5 -0
- regscale/visualization/click.py +34 -0
- regscale_cli-6.16.0.0.dist-info/LICENSE +21 -0
- regscale_cli-6.16.0.0.dist-info/METADATA +659 -0
- regscale_cli-6.16.0.0.dist-info/RECORD +481 -0
- regscale_cli-6.16.0.0.dist-info/WHEEL +5 -0
- regscale_cli-6.16.0.0.dist-info/entry_points.txt +6 -0
- regscale_cli-6.16.0.0.dist-info/top_level.txt +2 -0
- tests/fixtures/__init__.py +2 -0
- tests/fixtures/api.py +87 -0
- tests/fixtures/models.py +91 -0
- tests/fixtures/test_fixture.py +144 -0
- tests/mocks/__init__.py +0 -0
- tests/mocks/objects.py +3 -0
- tests/mocks/response.py +32 -0
- tests/mocks/xml.py +13 -0
- tests/regscale/__init__.py +0 -0
- tests/regscale/core/__init__.py +0 -0
- tests/regscale/core/test_api.py +232 -0
- tests/regscale/core/test_app.py +406 -0
- tests/regscale/core/test_login.py +37 -0
- tests/regscale/core/test_logz.py +66 -0
- tests/regscale/core/test_sbom_generator.py +87 -0
- tests/regscale/core/test_validation_utils.py +163 -0
- tests/regscale/core/test_version.py +78 -0
- tests/regscale/models/__init__.py +0 -0
- tests/regscale/models/test_asset.py +71 -0
- tests/regscale/models/test_config.py +26 -0
- tests/regscale/models/test_control_implementation.py +27 -0
- tests/regscale/models/test_import.py +97 -0
- tests/regscale/models/test_issue.py +36 -0
- tests/regscale/models/test_mapping.py +52 -0
- tests/regscale/models/test_platform.py +31 -0
- tests/regscale/models/test_regscale_model.py +346 -0
- tests/regscale/models/test_report.py +32 -0
- tests/regscale/models/test_tenable_integrations.py +118 -0
- tests/regscale/models/test_user_model.py +121 -0
- tests/regscale/test_about.py +19 -0
- tests/regscale/test_authorization.py +65 -0
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
from typing import Dict, Optional, Tuple, Union, List, Any
|
|
4
|
+
|
|
5
|
+
from regscale.integrations.commercial.cpe import extract_product_name_and_version
|
|
6
|
+
from regscale.integrations.commercial.wizv2.constants import CONTENT_TYPE
|
|
7
|
+
from regscale.integrations.commercial.wizv2.variables import WizVariables
|
|
8
|
+
from regscale.models import regscale_models
|
|
9
|
+
from regscale.utils import PaginatedGraphQLClient
|
|
10
|
+
|
|
11
|
+
logger = logging.getLogger("regscale")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def collect_components_to_create(data: List[Dict[str, Any]], components_to_create: List[str]) -> List[str]:
|
|
15
|
+
"""
|
|
16
|
+
Collect unique component titles to create from the data.
|
|
17
|
+
|
|
18
|
+
:param List[Dict[str, Any]] data: List of Wiz data.
|
|
19
|
+
:param List[str] components_to_create: List of component titles to create.
|
|
20
|
+
:return: List of unique component titles to create.
|
|
21
|
+
:rtype: List[str]
|
|
22
|
+
"""
|
|
23
|
+
for row in data:
|
|
24
|
+
component_title = row.get("type", "").title().replace("_", " ")
|
|
25
|
+
if component_title and component_title not in components_to_create:
|
|
26
|
+
components_to_create.append(component_title)
|
|
27
|
+
return list(set(components_to_create))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def handle_container_image_version(image_tags: list, name: str) -> str:
|
|
31
|
+
"""
|
|
32
|
+
Handle container image version
|
|
33
|
+
|
|
34
|
+
:param list image_tags: image tags for container image
|
|
35
|
+
:param str name: Name
|
|
36
|
+
:return: Container image version
|
|
37
|
+
:rtype: Optional[str]
|
|
38
|
+
"""
|
|
39
|
+
result = ""
|
|
40
|
+
|
|
41
|
+
# Check if `image_tags` has any items
|
|
42
|
+
if any(image_tags):
|
|
43
|
+
result = image_tags[0]
|
|
44
|
+
|
|
45
|
+
# If `image_tags` is empty, then check the next condition
|
|
46
|
+
elif name and len(name.split(":")) > 1:
|
|
47
|
+
result = name.split(":")[1]
|
|
48
|
+
|
|
49
|
+
# Return the final result
|
|
50
|
+
return result
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def handle_software_version(wiz_entity_properties: Dict, asset_category: str) -> Optional[str]:
|
|
54
|
+
"""
|
|
55
|
+
Handle software version
|
|
56
|
+
|
|
57
|
+
:param Dict wiz_entity_properties: Wiz entity properties
|
|
58
|
+
:param str asset_category: Asset category
|
|
59
|
+
:return: Software version
|
|
60
|
+
:rtype: Optional[str]
|
|
61
|
+
"""
|
|
62
|
+
return (
|
|
63
|
+
wiz_entity_properties.get("version")
|
|
64
|
+
if wiz_entity_properties.get("version") and asset_category == regscale_models.AssetCategory.Software
|
|
65
|
+
else None
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def get_software_name_from_cpe(wiz_entity_properties: Dict, name: str) -> Dict:
|
|
70
|
+
"""
|
|
71
|
+
Get software name from wiz CPE
|
|
72
|
+
:param Dict wiz_entity_properties: Wiz entity properties
|
|
73
|
+
:param str name: Name
|
|
74
|
+
:return: Software name
|
|
75
|
+
:rtype: Dict
|
|
76
|
+
"""
|
|
77
|
+
cpe_info_dict = {
|
|
78
|
+
"name": name,
|
|
79
|
+
"software_name": None,
|
|
80
|
+
"software_version": None,
|
|
81
|
+
"software_vendor": None,
|
|
82
|
+
}
|
|
83
|
+
if "cpe" in wiz_entity_properties.keys() and wiz_entity_properties.get("cpe"):
|
|
84
|
+
cpe_info_dict = extract_product_name_and_version(wiz_entity_properties.get("cpe", ""))
|
|
85
|
+
cpe_info_dict["name"] = name
|
|
86
|
+
return cpe_info_dict
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def get_latest_version(wiz_entity_properties: Dict) -> Optional[str]:
|
|
90
|
+
"""
|
|
91
|
+
Get the latest version from Wiz entity properties
|
|
92
|
+
:param Dict wiz_entity_properties: Wiz entity properties
|
|
93
|
+
:return: Latest version
|
|
94
|
+
:rtype: Optional[str]
|
|
95
|
+
"""
|
|
96
|
+
# Retrieve the latest version and current version
|
|
97
|
+
latest_version = wiz_entity_properties.get("latestVersion")
|
|
98
|
+
current_version = wiz_entity_properties.get("version")
|
|
99
|
+
|
|
100
|
+
# Return the latest version if it exists, otherwise return the current version
|
|
101
|
+
return latest_version if latest_version is not None else current_version
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def get_cloud_identifier(
|
|
105
|
+
wiz_entity_properties: Dict,
|
|
106
|
+
) -> Tuple[Optional[str], Optional[str]]:
|
|
107
|
+
"""
|
|
108
|
+
Get cloud identifier
|
|
109
|
+
:param Dict wiz_entity_properties: Wiz entity properties
|
|
110
|
+
:return: Cloud identifier
|
|
111
|
+
:rtype: Tuple[Optional[str], Optional[str]]
|
|
112
|
+
"""
|
|
113
|
+
# Define common keywords for each provider
|
|
114
|
+
aws_keywords = ["aws", "amazon", "ec2"]
|
|
115
|
+
azure_keywords = ["azure", "microsoft"]
|
|
116
|
+
google_keywords = ["google", "gcp", "google cloud"]
|
|
117
|
+
|
|
118
|
+
provider_unique_id = (
|
|
119
|
+
wiz_entity_properties.get("providerUniqueId").lower() if wiz_entity_properties.get("providerUniqueId") else ""
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
# Check for AWS identifiers
|
|
123
|
+
if any(keyword in provider_unique_id for keyword in aws_keywords):
|
|
124
|
+
return "aws", provider_unique_id
|
|
125
|
+
|
|
126
|
+
# Check for Azure identifiers
|
|
127
|
+
if any(keyword in provider_unique_id for keyword in azure_keywords):
|
|
128
|
+
return "azure", provider_unique_id
|
|
129
|
+
|
|
130
|
+
# Check for Google identifiers
|
|
131
|
+
if any(keyword in provider_unique_id for keyword in google_keywords):
|
|
132
|
+
return "google", provider_unique_id
|
|
133
|
+
|
|
134
|
+
# If none of the above, check if there is any providerUniqueId
|
|
135
|
+
if provider_unique_id:
|
|
136
|
+
return "other", provider_unique_id
|
|
137
|
+
|
|
138
|
+
# Return None if no identifier is found
|
|
139
|
+
return None, None
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def handle_provider(wiz_entity_properties: Dict) -> Dict:
|
|
143
|
+
"""
|
|
144
|
+
Handle provider
|
|
145
|
+
:param Dict wiz_entity_properties: Wiz entity properties
|
|
146
|
+
:return: Provider
|
|
147
|
+
:rtype: Dict
|
|
148
|
+
"""
|
|
149
|
+
provider, identifier = get_cloud_identifier(wiz_entity_properties)
|
|
150
|
+
return {
|
|
151
|
+
"awsIdentifier": identifier if provider == "aws" else None,
|
|
152
|
+
"azureIdentifier": identifier if provider == "azure" else None,
|
|
153
|
+
"googleIdentifier": identifier if provider == "google" else None,
|
|
154
|
+
"otherCloudIdentifier": identifier if provider == "other" else None,
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def parse_memory(memory_str: str) -> int:
|
|
159
|
+
"""
|
|
160
|
+
Parse memory string to integer (GiB to MiB conversion if needed)
|
|
161
|
+
|
|
162
|
+
:param str memory_str: Memory string (e.g., '2Gi', '512Mi', '1.5Gi')
|
|
163
|
+
:return: Memory in MiB
|
|
164
|
+
:rtype: int
|
|
165
|
+
"""
|
|
166
|
+
if not memory_str or memory_str == "0":
|
|
167
|
+
return 0
|
|
168
|
+
try:
|
|
169
|
+
value = float(memory_str[:-2])
|
|
170
|
+
return int(value * (1024 if memory_str.endswith("Gi") else 1))
|
|
171
|
+
except ValueError:
|
|
172
|
+
logger.warning("Failed to parse memory string: %s", memory_str)
|
|
173
|
+
return 0
|
|
174
|
+
|
|
175
|
+
|
|
176
|
+
def parse_cpu(cpu_str: Union[str, int]) -> int:
|
|
177
|
+
"""
|
|
178
|
+
Parse CPU string to integer
|
|
179
|
+
:param Union[str, int] cpu_str: CPU string
|
|
180
|
+
:return: CPU as integer
|
|
181
|
+
:rtype: int
|
|
182
|
+
"""
|
|
183
|
+
try:
|
|
184
|
+
return int(float(cpu_str))
|
|
185
|
+
except ValueError:
|
|
186
|
+
return 0
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def get_resources(wiz_entity_properties: Dict) -> Dict:
|
|
190
|
+
"""
|
|
191
|
+
Extract resources from Wiz entity properties
|
|
192
|
+
:param Dict wiz_entity_properties: Wiz entity properties
|
|
193
|
+
:return: Resources dictionary
|
|
194
|
+
:rtype: Dict
|
|
195
|
+
"""
|
|
196
|
+
if "resources" in wiz_entity_properties:
|
|
197
|
+
resources_str = wiz_entity_properties.get("resources", "{}")
|
|
198
|
+
try:
|
|
199
|
+
resources = json.loads(resources_str)
|
|
200
|
+
return resources.get("requests", {})
|
|
201
|
+
except json.JSONDecodeError:
|
|
202
|
+
pass
|
|
203
|
+
return {}
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
def pull_resource_info_from_props(wiz_entity_properties: Dict) -> Tuple[int, int]:
|
|
207
|
+
"""
|
|
208
|
+
Pull memory, cpu from properties
|
|
209
|
+
:param Dict wiz_entity_properties: Wiz entity properties
|
|
210
|
+
:return: Memory, CPU
|
|
211
|
+
:rtype: Tuple[int, int]
|
|
212
|
+
"""
|
|
213
|
+
resources = get_resources(wiz_entity_properties)
|
|
214
|
+
memory = parse_memory(resources.get("memory", ""))
|
|
215
|
+
cpu = parse_cpu(resources.get("cpu", 0))
|
|
216
|
+
cpu = parse_cpu(wiz_entity_properties.get("vCPUs", cpu))
|
|
217
|
+
return memory, cpu
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def get_disk_storage(wiz_entity_properties: Dict) -> int:
|
|
221
|
+
"""
|
|
222
|
+
Extract disk storage information.
|
|
223
|
+
:param Dict wiz_entity_properties: Wiz entity properties
|
|
224
|
+
:return: Disk storage
|
|
225
|
+
:rtype: int
|
|
226
|
+
"""
|
|
227
|
+
try:
|
|
228
|
+
return int(wiz_entity_properties.get("totalDisks", 0))
|
|
229
|
+
except ValueError:
|
|
230
|
+
return 0
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
def get_network_info(wiz_entity_properties: Dict) -> Dict:
|
|
234
|
+
"""
|
|
235
|
+
Extract network information.
|
|
236
|
+
:param Dict wiz_entity_properties: Wiz entity properties
|
|
237
|
+
:return: Network information
|
|
238
|
+
:rtype: Dict
|
|
239
|
+
"""
|
|
240
|
+
region = wiz_entity_properties.get("region")
|
|
241
|
+
ip4_address, ip6_address, dns, url = get_ip_address(wiz_entity_properties)
|
|
242
|
+
return {
|
|
243
|
+
"region": region,
|
|
244
|
+
"ip4_address": ip4_address,
|
|
245
|
+
"ip6_address": ip6_address,
|
|
246
|
+
"dns": dns,
|
|
247
|
+
"url": url,
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
def get_product_ids(wiz_entity_properties: Dict) -> Optional[str]:
|
|
252
|
+
"""
|
|
253
|
+
Get product IDs from Wiz entity properties
|
|
254
|
+
:param Dict wiz_entity_properties: Wiz entity properties
|
|
255
|
+
:return: Product IDs
|
|
256
|
+
:rtype: Optional[str]
|
|
257
|
+
"""
|
|
258
|
+
product_ids = wiz_entity_properties.get("_productIDs")
|
|
259
|
+
if product_ids and isinstance(product_ids, list):
|
|
260
|
+
return ", ".join(product_ids)
|
|
261
|
+
return product_ids
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
def get_ip_address_from_props(network_dict: Dict) -> Optional[str]:
|
|
265
|
+
"""
|
|
266
|
+
Get IP address from properties
|
|
267
|
+
:param Dict network_dict: Network dictionary
|
|
268
|
+
:return: IP address if it can be parsed from the network dictionary
|
|
269
|
+
:rtype: Optional[str]
|
|
270
|
+
"""
|
|
271
|
+
return network_dict.get("ip4_address") or network_dict.get("ip6_address")
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def fetch_wiz_data(
|
|
275
|
+
query: str,
|
|
276
|
+
variables: dict,
|
|
277
|
+
topic_key: str,
|
|
278
|
+
token: str,
|
|
279
|
+
api_endpoint_url: Optional[str] = None,
|
|
280
|
+
) -> List[Dict[str, Any]]:
|
|
281
|
+
"""
|
|
282
|
+
Sends a paginated GraphQL request to Wiz.
|
|
283
|
+
|
|
284
|
+
:param str query: The GraphQL query to send.
|
|
285
|
+
:param dict variables: The variables to use in the GraphQL request.
|
|
286
|
+
:param str topic_key: The topic key to use in the paginated request.
|
|
287
|
+
:param str token: The Wiz access token to use in the request.
|
|
288
|
+
:param Optional[str] api_endpoint_url: The API endpoint URL to use in the request.
|
|
289
|
+
:return: Response from the paginated GraphQL request.
|
|
290
|
+
:rtype: List[Dict[str, Any]]
|
|
291
|
+
"""
|
|
292
|
+
|
|
293
|
+
logger.debug("Sending a paginated request to Wiz API")
|
|
294
|
+
api_endpoint_url = WizVariables.wizUrl if api_endpoint_url is None else api_endpoint_url
|
|
295
|
+
|
|
296
|
+
logger.debug("Wiz QUERY: %s" % query)
|
|
297
|
+
client = PaginatedGraphQLClient(
|
|
298
|
+
endpoint=api_endpoint_url,
|
|
299
|
+
query=query,
|
|
300
|
+
headers={
|
|
301
|
+
"Content-Type": CONTENT_TYPE,
|
|
302
|
+
"Authorization": "Bearer " + token,
|
|
303
|
+
},
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
# Fetch all results using the client's pagination logic
|
|
307
|
+
logger.debug(f"{variables}, {topic_key}")
|
|
308
|
+
data = client.fetch_all(
|
|
309
|
+
variables=variables,
|
|
310
|
+
topic_key=topic_key,
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
return data
|
|
314
|
+
|
|
315
|
+
|
|
316
|
+
def get_ip_address(
|
|
317
|
+
wiz_entity_properties: Dict,
|
|
318
|
+
) -> Tuple[Union[str, None], Union[str, None], Union[str, None], Union[str, None]]:
|
|
319
|
+
"""
|
|
320
|
+
Get ip address from wiz entity properties
|
|
321
|
+
:param Dict wiz_entity_properties: Wiz entity properties
|
|
322
|
+
:return: IP4 address, IP6 address, DNS, URL
|
|
323
|
+
:rtype: Tuple[Union[str, None], Union[str, None], Union[str, None], Union[str, None]]
|
|
324
|
+
"""
|
|
325
|
+
ip4_address = None
|
|
326
|
+
ip6_address = None
|
|
327
|
+
dns = None
|
|
328
|
+
url = None
|
|
329
|
+
if "address" in wiz_entity_properties.keys():
|
|
330
|
+
if wiz_entity_properties.get("addressType") == "IPV4":
|
|
331
|
+
ip4_address = wiz_entity_properties.get("address")
|
|
332
|
+
elif wiz_entity_properties.get("addressType") == "IPV6":
|
|
333
|
+
ip6_address = wiz_entity_properties.get("address")
|
|
334
|
+
elif wiz_entity_properties.get("addressType") == "DNS":
|
|
335
|
+
dns = wiz_entity_properties.get("address")
|
|
336
|
+
elif wiz_entity_properties.get("addressType") == "URL":
|
|
337
|
+
url = wiz_entity_properties.get("address")
|
|
338
|
+
|
|
339
|
+
return ip4_address, ip6_address, dns, url
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
import sys
|
|
4
|
+
from typing import List, Dict, Optional
|
|
5
|
+
|
|
6
|
+
from regscale.core.app.utils.app_utils import error_and_exit
|
|
7
|
+
from regscale.integrations.commercial.wizv2.WizDataMixin import WizMixin
|
|
8
|
+
from regscale.models.regscale_models.sbom import Sbom
|
|
9
|
+
from regscale.integrations.commercial.wizv2.constants import SBOM_QUERY, SBOM_FILE_PATH
|
|
10
|
+
from regscale.utils import get_value
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class WizSbomIntegration(WizMixin):
|
|
16
|
+
"""
|
|
17
|
+
Integration class for handling SBOM data from Wiz.io
|
|
18
|
+
|
|
19
|
+
:param Optional[str] wiz_project_id: The Wiz project ID
|
|
20
|
+
:param int regscale_id: The RegScale ID
|
|
21
|
+
:param str regscale_module: The RegScale module
|
|
22
|
+
:param Optional[str] filter_by_override: The filterBy override
|
|
23
|
+
:param str client_id: The client ID
|
|
24
|
+
:param str client_secret: The client secret
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
wiz_project_id: Optional[str],
|
|
30
|
+
regscale_id: int,
|
|
31
|
+
regscale_module: str,
|
|
32
|
+
filter_by_override: Optional[str],
|
|
33
|
+
client_id: str,
|
|
34
|
+
client_secret: str,
|
|
35
|
+
):
|
|
36
|
+
super().__init__()
|
|
37
|
+
self.sbom_list: List[Sbom] = []
|
|
38
|
+
self.wiz_project_id = wiz_project_id or self.config.get("wizProjectId")
|
|
39
|
+
if not self.wiz_project_id:
|
|
40
|
+
error_and_exit("Wiz project ID not provided")
|
|
41
|
+
self.regscale_id = regscale_id
|
|
42
|
+
self.regscale_module = regscale_module
|
|
43
|
+
self.filter_by_override: Optional[str] = filter_by_override
|
|
44
|
+
self.client_id = client_id
|
|
45
|
+
self.client_secret = client_secret
|
|
46
|
+
self.filter_by = json.loads(filter_by_override) if filter_by_override else None
|
|
47
|
+
self.topic_key = "sbomArtifactsGroupedByName"
|
|
48
|
+
self.variables = {
|
|
49
|
+
"first": 200,
|
|
50
|
+
"filterBy": {"project": str(self.wiz_project_id)},
|
|
51
|
+
"orderBy": {"field": "NAME", "direction": "ASC"},
|
|
52
|
+
}
|
|
53
|
+
if self.filter_by:
|
|
54
|
+
logger.info(f"Using filterBy override: {self.filter_by}")
|
|
55
|
+
self.variables = {
|
|
56
|
+
"first": 200,
|
|
57
|
+
"filterBy": self.filter_by,
|
|
58
|
+
"orderBy": {"field": "NAME", "direction": "ASC"},
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
def run(self):
|
|
62
|
+
"""
|
|
63
|
+
Run the integration process
|
|
64
|
+
"""
|
|
65
|
+
self.fetch_sbom_data()
|
|
66
|
+
if not self.sbom_list:
|
|
67
|
+
logger.info("No SBOM data found")
|
|
68
|
+
sys.exit(0)
|
|
69
|
+
existing_sboms: List[Sbom] = Sbom.get_all_by_parent(
|
|
70
|
+
parent_id=self.regscale_id, parent_module=self.regscale_module
|
|
71
|
+
)
|
|
72
|
+
existing_sbom_names = [sbom.name for sbom in existing_sboms]
|
|
73
|
+
for sbom in self.sbom_list:
|
|
74
|
+
if sbom.name not in existing_sbom_names:
|
|
75
|
+
sbom.create()
|
|
76
|
+
logger.info(f"Successfully created SBOM {sbom.name}")
|
|
77
|
+
else:
|
|
78
|
+
logger.info(f"SBOM {sbom.name} already exists in RegScale")
|
|
79
|
+
|
|
80
|
+
def fetch_sbom_data(self):
|
|
81
|
+
"""
|
|
82
|
+
Fetch SBOM data from Wiz.io using the SBOM_QUERY
|
|
83
|
+
"""
|
|
84
|
+
logger.info("Fetching SBOM data from Wiz")
|
|
85
|
+
logger.info(f"Fetching SBOM data for project ID: {self.wiz_project_id}")
|
|
86
|
+
logger.info(f"Fetching SBOM data for topic_key: {self.topic_key}")
|
|
87
|
+
logger.info(f"Fetching SBOM data for variables: {self.variables}")
|
|
88
|
+
interval_hours = self.config.get("wizFullPullLimitHours", 8)
|
|
89
|
+
nodes = self.fetch_data_if_needed(
|
|
90
|
+
file_path=SBOM_FILE_PATH,
|
|
91
|
+
query=SBOM_QUERY,
|
|
92
|
+
topic_key=self.topic_key,
|
|
93
|
+
interval_hours=interval_hours,
|
|
94
|
+
variables=self.variables,
|
|
95
|
+
)
|
|
96
|
+
logger.info(f"Fetched {len(nodes)} SBOM data from Wiz")
|
|
97
|
+
self.map_sbom_data(nodes)
|
|
98
|
+
|
|
99
|
+
def map_sbom_data(self, nodes: List[Dict]):
|
|
100
|
+
"""
|
|
101
|
+
Map the fetched SBOM data to the Sbom model
|
|
102
|
+
:nodes List[Dict] sbom_data: List of SBOM data
|
|
103
|
+
"""
|
|
104
|
+
for data in nodes:
|
|
105
|
+
versions = [version_dict.get("version") for version_dict in get_value(data, "versions.nodes")]
|
|
106
|
+
sbom = Sbom(
|
|
107
|
+
name=data.get("name"),
|
|
108
|
+
sbomStandard=get_value(data, "type.codeLibraryLanguage") or data.get("name"),
|
|
109
|
+
standardVersion=",".join(versions) if versions else "",
|
|
110
|
+
tool=get_value(data, "type.group"),
|
|
111
|
+
parentId=self.regscale_id,
|
|
112
|
+
parentModule=self.regscale_module,
|
|
113
|
+
results=json.dumps(data),
|
|
114
|
+
)
|
|
115
|
+
self.sbom_list.append(sbom)
|