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,358 @@
|
|
|
1
|
+
"""
|
|
2
|
+
API Handler class to handle API requests using API class
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
import time
|
|
9
|
+
from typing import Any, Dict, List, Optional, Union
|
|
10
|
+
from urllib import parse
|
|
11
|
+
from urllib.parse import urljoin
|
|
12
|
+
|
|
13
|
+
from regscale.core.app.api import Api
|
|
14
|
+
from regscale.core.app.application import Application
|
|
15
|
+
from regscale.core.app.internal.login import parse_user_id_from_jwt
|
|
16
|
+
|
|
17
|
+
logger = logging.getLogger()
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class APIRetrieveError(Exception):
|
|
21
|
+
"""Exception raised when there is an error retrieving data via API."""
|
|
22
|
+
|
|
23
|
+
pass
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class APIInsertionError(Exception):
|
|
27
|
+
"""Exception raised when there is an error inserting data into the API."""
|
|
28
|
+
|
|
29
|
+
pass
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class APIUpdateError(Exception):
|
|
33
|
+
"""Exception raised when there is an error updating data in the API."""
|
|
34
|
+
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class APIResponseError(Exception):
|
|
39
|
+
"""Exception raised when there is an error in the API response."""
|
|
40
|
+
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class APIHandler(Application):
|
|
45
|
+
"""Class to handle API requests."""
|
|
46
|
+
|
|
47
|
+
def __init__(self):
|
|
48
|
+
logger.debug("Instantiating APIHandler")
|
|
49
|
+
super().__init__()
|
|
50
|
+
|
|
51
|
+
if self.api_handler is None:
|
|
52
|
+
self.api: Api = Api()
|
|
53
|
+
self.domain: str = self.api.config["domain"]
|
|
54
|
+
self.endpoint_tracker: Dict[str, Dict[str, Union[int, float, set]]] = {} # Initialize the endpoint tracker
|
|
55
|
+
self.api_handler: APIHandler = self # type: ignore
|
|
56
|
+
else:
|
|
57
|
+
logger.warning("APIHandler already set for Application. Not initializing a new instance.")
|
|
58
|
+
return
|
|
59
|
+
|
|
60
|
+
self._regscale_version: Optional[str] = None # Initialize version as None
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def regscale_version(self) -> str:
|
|
64
|
+
"""
|
|
65
|
+
Get the version from the API endpoint.
|
|
66
|
+
|
|
67
|
+
:return: The version string
|
|
68
|
+
:rtype: str
|
|
69
|
+
"""
|
|
70
|
+
if self._regscale_version is None:
|
|
71
|
+
try:
|
|
72
|
+
response = self.get("/assets/json/version.json")
|
|
73
|
+
if response.status_code == 200:
|
|
74
|
+
version_data = response.json()
|
|
75
|
+
self._regscale_version = version_data.get("version", "Unknown")
|
|
76
|
+
else:
|
|
77
|
+
logger.error(f"Failed to fetch version. Status code: {response.status_code}")
|
|
78
|
+
self._regscale_version = "Unknown"
|
|
79
|
+
except Exception as e:
|
|
80
|
+
logger.error(f"Error fetching version: {e}")
|
|
81
|
+
self._regscale_version = "Unknown"
|
|
82
|
+
return self._regscale_version
|
|
83
|
+
|
|
84
|
+
def _make_request(
|
|
85
|
+
self,
|
|
86
|
+
method: str,
|
|
87
|
+
endpoint: str,
|
|
88
|
+
headers: Optional[Dict[str, Any]] = None,
|
|
89
|
+
data: Optional[Union[Dict[str, Any], List[Any]]] = None,
|
|
90
|
+
query: Optional[str] = None,
|
|
91
|
+
files: Optional[List[Any]] = None,
|
|
92
|
+
params: Optional[Any] = None,
|
|
93
|
+
retry_login: bool = True,
|
|
94
|
+
) -> Any:
|
|
95
|
+
"""
|
|
96
|
+
Generic function to make API requests.
|
|
97
|
+
|
|
98
|
+
:param str method: HTTP method ('get', 'post', 'put')
|
|
99
|
+
:param str endpoint: API endpoint, domain is added automatically
|
|
100
|
+
:param Dict[str, Any] headers: Optional headers
|
|
101
|
+
:param Union[Dict[str, Any], List[Any]] data: Data to send
|
|
102
|
+
:param str query: Optional GraphQL query
|
|
103
|
+
:param List[Any] files: Optional files to send
|
|
104
|
+
:param Any params: Optional query parameters
|
|
105
|
+
:param bool retry_login: Whether to retry login on 401, defaults to True
|
|
106
|
+
:return: Response data or None
|
|
107
|
+
:rtype: Any
|
|
108
|
+
"""
|
|
109
|
+
start_time = time.time()
|
|
110
|
+
self._update_endpoint_tracker(endpoint, method)
|
|
111
|
+
|
|
112
|
+
url = self._get_url(endpoint)
|
|
113
|
+
if not url:
|
|
114
|
+
return None
|
|
115
|
+
|
|
116
|
+
logger.debug("[API_HANDLER] - Making %s request to %s", method.upper(), url)
|
|
117
|
+
response = None
|
|
118
|
+
try:
|
|
119
|
+
response = self._send_request(method, url, headers, data, query, files, params, retry_login)
|
|
120
|
+
return response
|
|
121
|
+
except Exception as e:
|
|
122
|
+
self._log_error(e, response)
|
|
123
|
+
return response
|
|
124
|
+
finally:
|
|
125
|
+
self._update_endpoint_time(endpoint, start_time)
|
|
126
|
+
|
|
127
|
+
def _update_endpoint_tracker(self, endpoint: str, method: str) -> None:
|
|
128
|
+
"""
|
|
129
|
+
Update the endpoint tracker with the current request.
|
|
130
|
+
|
|
131
|
+
:param str endpoint: The API endpoint
|
|
132
|
+
:param str method: The HTTP method used
|
|
133
|
+
"""
|
|
134
|
+
if endpoint not in self.endpoint_tracker:
|
|
135
|
+
self.endpoint_tracker[endpoint] = {
|
|
136
|
+
"count": 0,
|
|
137
|
+
"methods": set(),
|
|
138
|
+
"time": 0,
|
|
139
|
+
"get": 0,
|
|
140
|
+
"put": 0,
|
|
141
|
+
"post": 0,
|
|
142
|
+
"delete": 0,
|
|
143
|
+
"graph": 0,
|
|
144
|
+
}
|
|
145
|
+
self.endpoint_tracker[endpoint]["count"] += 1
|
|
146
|
+
self.endpoint_tracker[endpoint]["methods"].add(method)
|
|
147
|
+
self.endpoint_tracker[endpoint][method.lower()] += 1
|
|
148
|
+
|
|
149
|
+
def _get_url(self, endpoint: str) -> Optional[str]:
|
|
150
|
+
"""
|
|
151
|
+
Get the full URL for the given endpoint.
|
|
152
|
+
|
|
153
|
+
:param str endpoint: The API endpoint
|
|
154
|
+
:return: The full URL or None if it couldn't be constructed
|
|
155
|
+
:rtype: Optional[str]
|
|
156
|
+
"""
|
|
157
|
+
url = urljoin(self.domain, parse.quote(str(endpoint))) # type: ignore
|
|
158
|
+
if not url:
|
|
159
|
+
logger.error("[API_HANDLER] - URL is empty or None")
|
|
160
|
+
return url
|
|
161
|
+
|
|
162
|
+
def _send_request(
|
|
163
|
+
self,
|
|
164
|
+
method: str,
|
|
165
|
+
url: str,
|
|
166
|
+
headers: Optional[Dict[str, Any]],
|
|
167
|
+
data: Any,
|
|
168
|
+
query: Optional[str],
|
|
169
|
+
files: Optional[List[Any]],
|
|
170
|
+
params: Any,
|
|
171
|
+
retry_login: Optional[bool] = True,
|
|
172
|
+
) -> Any:
|
|
173
|
+
"""
|
|
174
|
+
Send the actual HTTP request.
|
|
175
|
+
|
|
176
|
+
:param str method: The HTTP method
|
|
177
|
+
:param str url: The full URL
|
|
178
|
+
:param Dict[str, Any] headers: The request headers
|
|
179
|
+
:param Any data: The request data
|
|
180
|
+
:param str query: The GraphQL query (if applicable)
|
|
181
|
+
:param List[Any] files: The files to send (if applicable)
|
|
182
|
+
:param Any params: The query parameters
|
|
183
|
+
:param Optional[bool] retry_login: Whether to retry login on 401, defaults to True
|
|
184
|
+
:return: The API response
|
|
185
|
+
:rtype: Any
|
|
186
|
+
"""
|
|
187
|
+
if method == "get":
|
|
188
|
+
return self.api.get(url=url, headers=headers, params=params, retry_login=retry_login, merge_headers=True)
|
|
189
|
+
elif method == "delete":
|
|
190
|
+
return self.api.delete(url=url, headers=headers, retry_login=retry_login, merge_headers=True)
|
|
191
|
+
elif method == "post" and files:
|
|
192
|
+
return self.api.post(
|
|
193
|
+
url, headers=headers, data=data, params=params, files=files, retry_login=retry_login, merge_headers=True
|
|
194
|
+
)
|
|
195
|
+
elif method == "graph":
|
|
196
|
+
return self.api.graph(query=query, headers=headers, merge_headers=True)
|
|
197
|
+
else:
|
|
198
|
+
return getattr(self.api, method)(
|
|
199
|
+
url, headers=headers, json=data, params=params, retry_login=retry_login, merge_headers=True
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
@staticmethod
|
|
203
|
+
def _log_error(e: Exception, response: Any) -> None:
|
|
204
|
+
"""
|
|
205
|
+
Log errors that occur during API requests.
|
|
206
|
+
|
|
207
|
+
:param Exception e: The exception that occurred
|
|
208
|
+
:param Any response: The API response (if available)
|
|
209
|
+
"""
|
|
210
|
+
logger.error(f"An error occurred: {e}", exc_info=True)
|
|
211
|
+
if response is not None:
|
|
212
|
+
logger.error(f"Response Code: {response.status_code} - {response.text}")
|
|
213
|
+
|
|
214
|
+
def _update_endpoint_time(self, endpoint: str, start_time: float) -> None:
|
|
215
|
+
"""
|
|
216
|
+
Update the total time spent on an endpoint.
|
|
217
|
+
|
|
218
|
+
:param str endpoint: The API endpoint
|
|
219
|
+
:param float start_time: The start time of the request
|
|
220
|
+
"""
|
|
221
|
+
total_time = time.time() - start_time
|
|
222
|
+
self.endpoint_tracker[endpoint]["time"] += total_time
|
|
223
|
+
|
|
224
|
+
def get(
|
|
225
|
+
self,
|
|
226
|
+
endpoint: str,
|
|
227
|
+
headers: Optional[Dict[str, Any]] = None,
|
|
228
|
+
params: Optional[Any] = None,
|
|
229
|
+
) -> Any:
|
|
230
|
+
"""
|
|
231
|
+
Fetch a record from RegScale.
|
|
232
|
+
|
|
233
|
+
:param str endpoint: API endpoint
|
|
234
|
+
:param Dict[str, Any] headers: Optional headers
|
|
235
|
+
:param Any params: Optional query parameters
|
|
236
|
+
:return: Response data or None
|
|
237
|
+
:rtype: Any
|
|
238
|
+
"""
|
|
239
|
+
return self._make_request("get", endpoint, headers=headers, params=params)
|
|
240
|
+
|
|
241
|
+
def post(
|
|
242
|
+
self,
|
|
243
|
+
endpoint: str,
|
|
244
|
+
headers: Optional[Dict[str, Any]] = None,
|
|
245
|
+
data: Optional[Union[Dict[str, Any], List[Any]]] = None,
|
|
246
|
+
files: Optional[List[Any]] = None,
|
|
247
|
+
params: Optional[Any] = None,
|
|
248
|
+
) -> Any:
|
|
249
|
+
"""
|
|
250
|
+
Insert new data into an API endpoint.
|
|
251
|
+
|
|
252
|
+
:param str endpoint: API endpoint
|
|
253
|
+
:param Dict[str, Any] headers: Optional headers
|
|
254
|
+
:param Union[Dict[str, Any], List[Any]] data: Data to send
|
|
255
|
+
:param List[Any] files: Files to send
|
|
256
|
+
:param Any params: Optional query parameters
|
|
257
|
+
:return: Response data or None
|
|
258
|
+
:rtype: Any
|
|
259
|
+
"""
|
|
260
|
+
return self._make_request(
|
|
261
|
+
"post",
|
|
262
|
+
endpoint,
|
|
263
|
+
headers=headers,
|
|
264
|
+
data=data,
|
|
265
|
+
params=params,
|
|
266
|
+
files=files,
|
|
267
|
+
)
|
|
268
|
+
|
|
269
|
+
def put(
|
|
270
|
+
self,
|
|
271
|
+
endpoint: str,
|
|
272
|
+
headers: Optional[Dict[str, Any]] = None,
|
|
273
|
+
data: Union[Optional[Dict[str, Any]], Optional[List[Dict[str, Any]]]] = None,
|
|
274
|
+
params: Optional[Any] = None,
|
|
275
|
+
) -> Any:
|
|
276
|
+
"""
|
|
277
|
+
Update existing data in an API endpoint.
|
|
278
|
+
|
|
279
|
+
:param str endpoint: API endpoint
|
|
280
|
+
:param Dict[str, Any] headers: Optional headers
|
|
281
|
+
:param Union[Optional[Dict[str, Any]], Optional[List[Dict[str, Any]]]] data: Data to send
|
|
282
|
+
:param Any params: Optional query parameters
|
|
283
|
+
:return: Response data or None
|
|
284
|
+
:rtype: Any
|
|
285
|
+
"""
|
|
286
|
+
return self._make_request("put", endpoint, headers=headers, data=data, params=params)
|
|
287
|
+
|
|
288
|
+
def delete(
|
|
289
|
+
self,
|
|
290
|
+
endpoint: str,
|
|
291
|
+
headers: Optional[Dict[str, Any]] = None,
|
|
292
|
+
params: Optional[Any] = None,
|
|
293
|
+
) -> Any:
|
|
294
|
+
"""
|
|
295
|
+
Delete existing data in an API endpoint.
|
|
296
|
+
|
|
297
|
+
:param str endpoint: API endpoint
|
|
298
|
+
:param Dict[str, Any] headers: Optional headers
|
|
299
|
+
:param Any params: Optional query parameters
|
|
300
|
+
:return: Response data or None
|
|
301
|
+
:rtype: Any
|
|
302
|
+
"""
|
|
303
|
+
return self._make_request("delete", endpoint, headers=headers, params=params)
|
|
304
|
+
|
|
305
|
+
def graph(self, query: str) -> Any:
|
|
306
|
+
"""
|
|
307
|
+
Fetch data from the graph API.
|
|
308
|
+
|
|
309
|
+
:param str query: GraphQL query
|
|
310
|
+
:return: Response data or None
|
|
311
|
+
:rtype: Any
|
|
312
|
+
"""
|
|
313
|
+
return self._make_request("graph", "/graphql", query=query)
|
|
314
|
+
|
|
315
|
+
def get_user_id(self) -> str:
|
|
316
|
+
"""
|
|
317
|
+
Get the user ID of the current user.
|
|
318
|
+
|
|
319
|
+
:return: The user ID of the current user.
|
|
320
|
+
:rtype: str
|
|
321
|
+
"""
|
|
322
|
+
return parse_user_id_from_jwt(self, self.config["token"])
|
|
323
|
+
|
|
324
|
+
def get_config_user_id(self) -> str:
|
|
325
|
+
"""
|
|
326
|
+
Get the user ID of the current user.
|
|
327
|
+
|
|
328
|
+
:return: The user ID of the current user.
|
|
329
|
+
:rtype: str
|
|
330
|
+
"""
|
|
331
|
+
return self.config.get("userId", "")
|
|
332
|
+
|
|
333
|
+
def log_api_summary(self) -> None:
|
|
334
|
+
"""
|
|
335
|
+
Log a summary of API calls made during the lifetime of this APIHandler instance.
|
|
336
|
+
"""
|
|
337
|
+
logger.info("APIHandler instance is being destroyed. Summary of API calls:")
|
|
338
|
+
|
|
339
|
+
total_calls = 0
|
|
340
|
+
total_time = 0.0
|
|
341
|
+
|
|
342
|
+
for endpoint, details in sorted(
|
|
343
|
+
self.endpoint_tracker.items(),
|
|
344
|
+
key=lambda item: item[1]["time"],
|
|
345
|
+
reverse=False,
|
|
346
|
+
):
|
|
347
|
+
methods = ", ".join(details["methods"])
|
|
348
|
+
count = details["count"]
|
|
349
|
+
total_calls += count
|
|
350
|
+
total_time += details["time"]
|
|
351
|
+
logger.debug(
|
|
352
|
+
f"Endpoint '{endpoint}' was called {count} times with methods: {methods} and total time: "
|
|
353
|
+
f"{details['time']:.2f}s "
|
|
354
|
+
f"gets: {details['get']} puts: {details['put']} posts: {details['post']} deletes: {details['delete']} graphs: {details['graph']}"
|
|
355
|
+
)
|
|
356
|
+
|
|
357
|
+
logger.info(f"Total API calls: {total_calls}")
|
|
358
|
+
logger.info(f"Total time spent on API calls: {total_time:.2f}s")
|