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,78 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tenable V2 Utils
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import datetime
|
|
6
|
+
from typing import List
|
|
7
|
+
|
|
8
|
+
from dateutil.relativedelta import relativedelta
|
|
9
|
+
|
|
10
|
+
from regscale.core.app.application import Application
|
|
11
|
+
from regscale.core.app.utils.app_utils import get_current_datetime
|
|
12
|
+
from regscale.core.utils.date import date_str, datetime_obj
|
|
13
|
+
from regscale.models import ScanHistory, regscale_models
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_last_pull_epoch(regscale_ssp_id: int) -> int:
|
|
17
|
+
"""
|
|
18
|
+
Gather last pull epoch from RegScale Security Plan
|
|
19
|
+
|
|
20
|
+
:param int regscale_ssp_id: RegScale System Security Plan ID
|
|
21
|
+
:return: Last pull epoch
|
|
22
|
+
:rtype: int
|
|
23
|
+
"""
|
|
24
|
+
two_months_ago = datetime.datetime.now() - relativedelta(months=2)
|
|
25
|
+
two_weeks_ago = datetime.datetime.now() - relativedelta(weeks=2)
|
|
26
|
+
last_pull = round(two_weeks_ago.timestamp()) # default the last pull date to two weeks
|
|
27
|
+
|
|
28
|
+
# Limit the query with a filter_date to avoid taxing the database in the case of a large number of scans
|
|
29
|
+
filter_date = date_str(two_months_ago)
|
|
30
|
+
|
|
31
|
+
if res := ScanHistory.get_by_parent_recursive(
|
|
32
|
+
parent_id=regscale_ssp_id, parent_module="securityplans", filter_date=filter_date
|
|
33
|
+
):
|
|
34
|
+
# Sort by ScanDate desc
|
|
35
|
+
res = sorted(res, key=lambda x: (datetime_obj(x.scanDate) or get_current_datetime()), reverse=True)
|
|
36
|
+
# Convert to timestamp
|
|
37
|
+
last_pull = round(datetime_obj(res[0].scanDate).timestamp()) if res else 0
|
|
38
|
+
|
|
39
|
+
return last_pull
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def get_filtered_severities() -> List[regscale_models.IssueSeverity]:
|
|
43
|
+
"""
|
|
44
|
+
Return a list of severities that we want from Tenable
|
|
45
|
+
|
|
46
|
+
:return: A list of severities
|
|
47
|
+
:rtype: List[regscale_models.IssueSeverity]
|
|
48
|
+
"""
|
|
49
|
+
app = Application()
|
|
50
|
+
severity_filter = app.config.get("tenableMinimumSeverityFilter", "low").lower()
|
|
51
|
+
severity_map = {
|
|
52
|
+
"info": [
|
|
53
|
+
regscale_models.IssueSeverity.NotAssigned,
|
|
54
|
+
regscale_models.IssueSeverity.Low,
|
|
55
|
+
regscale_models.IssueSeverity.Moderate,
|
|
56
|
+
regscale_models.IssueSeverity.High,
|
|
57
|
+
regscale_models.IssueSeverity.Critical,
|
|
58
|
+
],
|
|
59
|
+
"low": [
|
|
60
|
+
regscale_models.IssueSeverity.Low,
|
|
61
|
+
regscale_models.IssueSeverity.Moderate,
|
|
62
|
+
regscale_models.IssueSeverity.High,
|
|
63
|
+
regscale_models.IssueSeverity.Critical,
|
|
64
|
+
],
|
|
65
|
+
"moderate": [regscale_models.IssueSeverity.Moderate, regscale_models.IssueSeverity.High],
|
|
66
|
+
"medium": [regscale_models.IssueSeverity.Moderate, regscale_models.IssueSeverity.High],
|
|
67
|
+
"high": [regscale_models.IssueSeverity.High, regscale_models.IssueSeverity.Critical],
|
|
68
|
+
"critical": [regscale_models.IssueSeverity.Critical],
|
|
69
|
+
}
|
|
70
|
+
return severity_map.get(
|
|
71
|
+
severity_filter,
|
|
72
|
+
[
|
|
73
|
+
regscale_models.IssueSeverity.Low,
|
|
74
|
+
regscale_models.IssueSeverity.Moderate,
|
|
75
|
+
regscale_models.IssueSeverity.High,
|
|
76
|
+
regscale_models.IssueSeverity.Critical,
|
|
77
|
+
],
|
|
78
|
+
)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""Tenable Variables"""
|
|
4
|
+
|
|
5
|
+
from regscale.core.app.utils.variables import RsVariableType, RsVariablesMeta
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TenableVariables(metaclass=RsVariablesMeta):
|
|
9
|
+
"""
|
|
10
|
+
Tenable Variables class to define class-level attributes with type annotations and examples
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
# Define class-level attributes with type annotations and examples
|
|
14
|
+
tenableAccessKey: RsVariableType(str, "xxxxxxxxxxxxxxxxxxxxxx", sensitive=True) # type: ignore # noqa: F722,F821
|
|
15
|
+
tenableSecretKey: RsVariableType(str, "xxxxxxxxxxxxxxxxxxxxxx", sensitive=True) # type: ignore # noqa: F722,F821
|
|
16
|
+
tenableUrl: RsVariableType(str, "https://cloud.tenable.com") # type: ignore # noqa: F722,F821
|
|
17
|
+
tenableMinimumSeverityFilter: RsVariableType(str, "critical") # type: ignore # noqa: F722,F821
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Module for processing Trivy scan results and loading them into RegScale.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import traceback
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from typing import List, Optional, Union
|
|
9
|
+
|
|
10
|
+
import click
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
from regscale.core.app.utils.file_utils import (
|
|
14
|
+
download_from_s3,
|
|
15
|
+
find_files,
|
|
16
|
+
iterate_files,
|
|
17
|
+
move_file,
|
|
18
|
+
)
|
|
19
|
+
from regscale.models.integration_models.flat_file_importer import FlatFileImporter
|
|
20
|
+
from regscale.models.integration_models.trivy_import import TrivyImport
|
|
21
|
+
|
|
22
|
+
logger = logging.getLogger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class TrivyProcessingError(Exception):
|
|
26
|
+
"""Custom exception for Trivy processing errors."""
|
|
27
|
+
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@click.group()
|
|
32
|
+
def trivy():
|
|
33
|
+
"""Performs actions from the Trivy scanner integration."""
|
|
34
|
+
pass
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@trivy.command("import_scans")
|
|
38
|
+
@FlatFileImporter.common_scanner_options(
|
|
39
|
+
message="File path to the folder containing Trivy .json files to process to RegScale.",
|
|
40
|
+
prompt="File path for Trivy files",
|
|
41
|
+
import_name="trivy",
|
|
42
|
+
)
|
|
43
|
+
@click.option("--destination", "-d", type=click.Path(exists=True, dir_okay=True), required=False)
|
|
44
|
+
@click.option("--file_pattern", "-p", type=str, required=False, default="trivy*.json")
|
|
45
|
+
def import_scans(
|
|
46
|
+
destination: Optional[Path],
|
|
47
|
+
file_pattern: str,
|
|
48
|
+
folder_path: Path,
|
|
49
|
+
regscale_ssp_id: int,
|
|
50
|
+
scan_date: datetime,
|
|
51
|
+
mappings_path: Path,
|
|
52
|
+
disable_mapping: bool,
|
|
53
|
+
s3_bucket: str,
|
|
54
|
+
s3_prefix: str,
|
|
55
|
+
aws_profile: str,
|
|
56
|
+
upload_file: bool,
|
|
57
|
+
) -> None:
|
|
58
|
+
"""
|
|
59
|
+
Process Trivy scan results from a folder containing trivy scan files and load into RegScale.
|
|
60
|
+
"""
|
|
61
|
+
import_trivy_scans(
|
|
62
|
+
destination=destination,
|
|
63
|
+
file_pattern=file_pattern,
|
|
64
|
+
folder_path=folder_path,
|
|
65
|
+
regscale_ssp_id=regscale_ssp_id,
|
|
66
|
+
scan_date=scan_date,
|
|
67
|
+
mappings_path=mappings_path,
|
|
68
|
+
disable_mapping=disable_mapping,
|
|
69
|
+
s3_bucket=s3_bucket,
|
|
70
|
+
s3_prefix=s3_prefix,
|
|
71
|
+
aws_profile=aws_profile,
|
|
72
|
+
upload_file=upload_file,
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def import_trivy_scans(
|
|
77
|
+
folder_path: Path,
|
|
78
|
+
regscale_ssp_id: int,
|
|
79
|
+
scan_date: datetime,
|
|
80
|
+
mappings_path: Optional[Path] = None,
|
|
81
|
+
disable_mapping: Optional[bool] = False,
|
|
82
|
+
s3_bucket: Optional[str] = None,
|
|
83
|
+
s3_prefix: Optional[str] = None,
|
|
84
|
+
aws_profile: Optional[str] = None,
|
|
85
|
+
destination: Optional[Path] = None,
|
|
86
|
+
file_pattern: Optional[str] = "trivy*.json",
|
|
87
|
+
upload_file: Optional[bool] = True,
|
|
88
|
+
) -> None:
|
|
89
|
+
"""
|
|
90
|
+
Process Trivy scan results from a folder container trivy scan files and load into RegScale.
|
|
91
|
+
|
|
92
|
+
:param Path folder_path: Path to the Trivy scan results JSON file
|
|
93
|
+
:param int regscale_ssp_id: RegScale SSP ID
|
|
94
|
+
:param datetime scan_date: The date of the scan
|
|
95
|
+
:param Optional[Path] mappings_path: Path to the header mapping file, default: None
|
|
96
|
+
:param Optional[bool] disable_mapping: Disable the header mapping, default: False
|
|
97
|
+
:param Optional[str] s3_bucket: S3 bucket to download scan files from, default: None
|
|
98
|
+
:param Optional[str] s3_prefix: Prefix (folder path) within the S3 bucket, default: None
|
|
99
|
+
:param Optional[str] aws_profile: AWS profile to use for S3 access, default: None
|
|
100
|
+
:param Optional[Path] destination: The destination folder for the processed files, default: None
|
|
101
|
+
:param Optional[str] file_pattern: The file pattern to search for in the file path Default: trivy*.json
|
|
102
|
+
:param Optional[bool] upload_file: Whether to upload the file to RegScale after processing, default: True
|
|
103
|
+
"""
|
|
104
|
+
from regscale.exceptions import ValidationException
|
|
105
|
+
from regscale.core.app.application import Application
|
|
106
|
+
|
|
107
|
+
try:
|
|
108
|
+
if s3_bucket and s3_prefix and aws_profile:
|
|
109
|
+
download_from_s3(bucket=s3_bucket, prefix=s3_prefix, local_path=destination, aws_profile=aws_profile)
|
|
110
|
+
files = find_files(path=destination, pattern=file_pattern)
|
|
111
|
+
logger.info("Downloaded all Trivy scan files from S3. Processing...")
|
|
112
|
+
elif destination and not s3_bucket:
|
|
113
|
+
logger.info("Moving Trivy scan files to %s", destination)
|
|
114
|
+
stored_file_collection = find_files(path=folder_path, pattern=file_pattern)
|
|
115
|
+
move_all_files(stored_file_collection, destination)
|
|
116
|
+
files = find_files(path=destination, pattern=file_pattern)
|
|
117
|
+
logger.info("Done moving files")
|
|
118
|
+
else:
|
|
119
|
+
stored_file_collection = find_files(path=folder_path, pattern=file_pattern)
|
|
120
|
+
files = stored_file_collection
|
|
121
|
+
if not files:
|
|
122
|
+
logger.error("No Trivy scan results found in the specified directory")
|
|
123
|
+
return
|
|
124
|
+
except Exception as e:
|
|
125
|
+
logger.error(f"Error processing Trivy results: {str(e)}")
|
|
126
|
+
logger.error(traceback.format_exc())
|
|
127
|
+
raise TrivyProcessingError(f"Failed to process Trivy results: {str(e)}")
|
|
128
|
+
|
|
129
|
+
for file in files:
|
|
130
|
+
try:
|
|
131
|
+
TrivyImport(
|
|
132
|
+
name="Trivy",
|
|
133
|
+
app=Application(),
|
|
134
|
+
file_path=str(file),
|
|
135
|
+
file_type=file.suffix,
|
|
136
|
+
parent_id=regscale_ssp_id,
|
|
137
|
+
parent_module="securityplans",
|
|
138
|
+
scan_date=scan_date,
|
|
139
|
+
mappings_path=mappings_path,
|
|
140
|
+
disable_mapping=disable_mapping,
|
|
141
|
+
upload_file=upload_file,
|
|
142
|
+
file_name=file.name,
|
|
143
|
+
)
|
|
144
|
+
except ValidationException as e:
|
|
145
|
+
logger.error(f"Validation error on {file}: {e}")
|
|
146
|
+
continue
|
|
147
|
+
logger.info("Completed Trivy processing.")
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def move_all_files(file_collection: List[Union[Path, str]], destination: Union[Path, str]) -> None:
|
|
151
|
+
"""
|
|
152
|
+
Move all Trivy files in the current directory to a folder called 'processed'.
|
|
153
|
+
|
|
154
|
+
:param List[Union[Path, str]] file_collection: A list of file paths or S3 URIs
|
|
155
|
+
:param Union[Path, str] destination: The destination folder
|
|
156
|
+
:rtype: None
|
|
157
|
+
"""
|
|
158
|
+
for file in iterate_files(file_collection):
|
|
159
|
+
file_path = Path(file)
|
|
160
|
+
new_filename = f"{file_path.stem}{file_path.suffix}"
|
|
161
|
+
new_file_path = Path(destination) / new_filename
|
|
162
|
+
move_file(file, new_file_path)
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""Veracode RegScale integration"""
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from os import PathLike
|
|
6
|
+
from typing import Optional
|
|
7
|
+
|
|
8
|
+
import click
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
from regscale.models.integration_models.flat_file_importer import FlatFileImporter
|
|
12
|
+
from regscale.models.integration_models.veracode import Veracode
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@click.group()
|
|
16
|
+
def veracode():
|
|
17
|
+
"""Performs actions on Veracode export files."""
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
FlatFileImporter.show_mapping(
|
|
21
|
+
group=veracode,
|
|
22
|
+
import_name="veracode",
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@veracode.command(name="import_veracode")
|
|
27
|
+
@FlatFileImporter.common_scanner_options(
|
|
28
|
+
message="File path to the folder containing Veracode .xlsx files to process to RegScale.",
|
|
29
|
+
prompt="File path for Veracode files",
|
|
30
|
+
import_name="veracode",
|
|
31
|
+
)
|
|
32
|
+
def import_veracode(
|
|
33
|
+
folder_path: PathLike[str],
|
|
34
|
+
regscale_ssp_id: int,
|
|
35
|
+
scan_date: datetime,
|
|
36
|
+
mappings_path: Path,
|
|
37
|
+
disable_mapping: bool,
|
|
38
|
+
s3_bucket: str,
|
|
39
|
+
s3_prefix: str,
|
|
40
|
+
aws_profile: str,
|
|
41
|
+
upload_file: bool,
|
|
42
|
+
):
|
|
43
|
+
"""
|
|
44
|
+
Import scans, vulnerabilities and assets to RegScale from Veracode export files
|
|
45
|
+
"""
|
|
46
|
+
import_veracode_data(
|
|
47
|
+
folder_path=folder_path,
|
|
48
|
+
regscale_ssp_id=regscale_ssp_id,
|
|
49
|
+
scan_date=scan_date,
|
|
50
|
+
mappings_path=mappings_path,
|
|
51
|
+
disable_mapping=disable_mapping,
|
|
52
|
+
s3_bucket=s3_bucket,
|
|
53
|
+
s3_prefix=s3_prefix,
|
|
54
|
+
aws_profile=aws_profile,
|
|
55
|
+
upload_file=upload_file,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def import_veracode_data(
|
|
60
|
+
folder_path: PathLike[str],
|
|
61
|
+
regscale_ssp_id: int,
|
|
62
|
+
scan_date: datetime,
|
|
63
|
+
mappings_path: Path,
|
|
64
|
+
s3_bucket: str,
|
|
65
|
+
s3_prefix: str,
|
|
66
|
+
aws_profile: str,
|
|
67
|
+
disable_mapping: Optional[bool] = False,
|
|
68
|
+
upload_file: Optional[bool] = True,
|
|
69
|
+
) -> None:
|
|
70
|
+
"""Import scans, vulnerabilities and assets to RegScale from Veracode export files"
|
|
71
|
+
|
|
72
|
+
:param os.PathLike[str] folder_path: Path to the folder containing Veracode files
|
|
73
|
+
:param int regscale_ssp_id: RegScale SSP ID
|
|
74
|
+
:param datetime scan_date: Scan date
|
|
75
|
+
:param os.PathLike[str] mappings_path: Path to the header mapping file
|
|
76
|
+
:param str s3_bucket: S3 bucket to download the files from
|
|
77
|
+
:param str s3_prefix: S3 prefix to download the files from
|
|
78
|
+
:param str aws_profile: AWS profile to use for S3 access
|
|
79
|
+
:param bool disable_mapping: Disable mapping
|
|
80
|
+
:param Optional[bool] upload_file: Whether to upload the file to RegScale after processing, defaults to True
|
|
81
|
+
:rtype: None
|
|
82
|
+
"""
|
|
83
|
+
FlatFileImporter.import_files(
|
|
84
|
+
import_type=Veracode,
|
|
85
|
+
import_name="Veracode",
|
|
86
|
+
file_types=[".xml", ".xlsx"],
|
|
87
|
+
folder_path=folder_path,
|
|
88
|
+
regscale_ssp_id=regscale_ssp_id,
|
|
89
|
+
scan_date=scan_date,
|
|
90
|
+
mappings_path=mappings_path,
|
|
91
|
+
disable_mapping=disable_mapping,
|
|
92
|
+
s3_bucket=s3_bucket,
|
|
93
|
+
s3_prefix=s3_prefix,
|
|
94
|
+
aws_profile=aws_profile,
|
|
95
|
+
upload_file=upload_file,
|
|
96
|
+
)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
from datetime import datetime, timedelta
|
|
5
|
+
from typing import Optional, Dict, Any, List
|
|
6
|
+
|
|
7
|
+
from regscale.core.app.utils.app_utils import error_and_exit, check_file_path
|
|
8
|
+
from regscale.integrations.commercial.wizv2.constants import CONTENT_TYPE
|
|
9
|
+
from regscale.core.app.application import Application
|
|
10
|
+
from regscale.utils import PaginatedGraphQLClient
|
|
11
|
+
|
|
12
|
+
logger = logging.getLogger("regscale")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class WizMixin(Application):
|
|
16
|
+
def fetch_data_if_needed(
|
|
17
|
+
self,
|
|
18
|
+
file_path: str,
|
|
19
|
+
query: str,
|
|
20
|
+
topic_key: str,
|
|
21
|
+
interval_hours: int,
|
|
22
|
+
variables: Optional[Dict[str, Any]] = None,
|
|
23
|
+
) -> List[Dict]:
|
|
24
|
+
"""
|
|
25
|
+
Fetches data if the file is not present or is older than the fetch interval
|
|
26
|
+
:param str file_path: File path to write to
|
|
27
|
+
:param str query: GraphQL Query
|
|
28
|
+
:param str topic_key: Topic Key
|
|
29
|
+
:param int interval_hours: Interval in hours to fetch new data
|
|
30
|
+
:param Optional[Dict[str, Any]] variables: Variables
|
|
31
|
+
:returns: List[Dict] of data nodes
|
|
32
|
+
:rtype: List[Dict]
|
|
33
|
+
"""
|
|
34
|
+
fetch_interval = timedelta(hours=interval_hours) # Interval to fetch new data
|
|
35
|
+
current_time = datetime.now()
|
|
36
|
+
|
|
37
|
+
# Check if the file exists and its last modified time
|
|
38
|
+
if os.path.exists(file_path):
|
|
39
|
+
file_mod_time = datetime.fromtimestamp(os.path.getmtime(file_path))
|
|
40
|
+
if current_time - file_mod_time < fetch_interval:
|
|
41
|
+
nodes = self.load_file(file_path)
|
|
42
|
+
return nodes
|
|
43
|
+
nodes = self.fetch_data(query, topic_key, variables)
|
|
44
|
+
self.write_to_file(file_path, nodes)
|
|
45
|
+
return nodes
|
|
46
|
+
|
|
47
|
+
@staticmethod
|
|
48
|
+
def write_to_file(file_path: str, nodes: List[Dict]):
|
|
49
|
+
"""
|
|
50
|
+
Writes the nodes to a file
|
|
51
|
+
:param str file_path: File path to write to
|
|
52
|
+
:param List[Dict] nodes: List of nodes to write
|
|
53
|
+
"""
|
|
54
|
+
check_file_path("artifacts")
|
|
55
|
+
with open(file_path, "w") as file:
|
|
56
|
+
json.dump(nodes, file)
|
|
57
|
+
|
|
58
|
+
@staticmethod
|
|
59
|
+
def load_file(file_path: str) -> List[Dict]:
|
|
60
|
+
"""
|
|
61
|
+
Loads the file and maps the nodes to Vulnerability objects
|
|
62
|
+
:param str file_path: File path to load
|
|
63
|
+
Returns: List of Dict
|
|
64
|
+
:rtype: List[Dict]
|
|
65
|
+
"""
|
|
66
|
+
check_file_path("artifacts")
|
|
67
|
+
with open(file_path, "r") as file:
|
|
68
|
+
return json.load(file)
|
|
69
|
+
|
|
70
|
+
def fetch_data(self, query: str, topic_key: str, variables: Optional[Dict[str, Any]] = None) -> List[Dict]:
|
|
71
|
+
"""
|
|
72
|
+
Fetches data from Wiz
|
|
73
|
+
:param str query: GraphQL Query
|
|
74
|
+
:param str topic_key: Topic Key
|
|
75
|
+
:param Optional[Dict[str, Any]] variables: Variables
|
|
76
|
+
:returns: List of nodes
|
|
77
|
+
:rtype: List[Dict]
|
|
78
|
+
"""
|
|
79
|
+
client = None
|
|
80
|
+
api_endpoint_url = self.config.get("wizUrl")
|
|
81
|
+
if not api_endpoint_url:
|
|
82
|
+
logger.error("Wiz API endpoint not configured")
|
|
83
|
+
error_and_exit("Wiz API endpoint not configured")
|
|
84
|
+
if token := self.config.get("wizAccessToken"):
|
|
85
|
+
client = PaginatedGraphQLClient(
|
|
86
|
+
endpoint=api_endpoint_url,
|
|
87
|
+
query=query,
|
|
88
|
+
headers={
|
|
89
|
+
"Content-Type": CONTENT_TYPE,
|
|
90
|
+
"Authorization": "Bearer " + token,
|
|
91
|
+
},
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
logger.info(f"Fetching data from Wiz on topic key for {topic_key}")
|
|
95
|
+
# Fetch all results using the client's pagination logic
|
|
96
|
+
data = client.fetch_all(variables=variables, topic_key=topic_key) if client else []
|
|
97
|
+
return data
|
|
File without changes
|