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,88 @@
|
|
|
1
|
+
"""Generate a hierarchy for Airflow based on Click."""
|
|
2
|
+
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
from regscale.regscale import cli
|
|
6
|
+
from regscale.models.click_models import ClickCommand
|
|
7
|
+
from regscale.airflow.click_mixins import AirflowClickGroup
|
|
8
|
+
|
|
9
|
+
AIRFLOW_CLICK_GROUP = AirflowClickGroup.from_group(cli, prefix="regscale")
|
|
10
|
+
AIRFLOW_CLICK_OPERATORS = AIRFLOW_CLICK_GROUP.flatten_operator()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def iter_operators(operators: dict = AIRFLOW_CLICK_OPERATORS) -> dict:
|
|
14
|
+
"""Iterate over the operators and create a structured dict"""
|
|
15
|
+
|
|
16
|
+
def _nested_dict(data: tuple, value: ClickCommand, result: dict = None) -> Optional[dict]:
|
|
17
|
+
"""Create a single dict from a nested dict."""
|
|
18
|
+
if result is None:
|
|
19
|
+
result = {}
|
|
20
|
+
if len(data) > 1:
|
|
21
|
+
key = data[0]
|
|
22
|
+
if key not in result:
|
|
23
|
+
result[key] = {}
|
|
24
|
+
_nested_dict(data=data[1:], value=value, result=result[key])
|
|
25
|
+
else:
|
|
26
|
+
if data[0] in result:
|
|
27
|
+
if isinstance(result[data[0]], dict):
|
|
28
|
+
result[data[0]].update(_make_platform_params(value))
|
|
29
|
+
else:
|
|
30
|
+
result[data[0]] = [result[data[0]], _make_platform_params(value)]
|
|
31
|
+
else:
|
|
32
|
+
result[data[0]] = _make_platform_params(value)
|
|
33
|
+
return result
|
|
34
|
+
|
|
35
|
+
def _make_platform_params(command: ClickCommand) -> dict:
|
|
36
|
+
"""Create a dict from a command of what platform would need."""
|
|
37
|
+
return {
|
|
38
|
+
"name": command.name,
|
|
39
|
+
"params": command.parameters,
|
|
40
|
+
"parameters": {**command.params},
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
new_dict = {}
|
|
44
|
+
for operator, op_dict in operators.items():
|
|
45
|
+
if "__" in operator:
|
|
46
|
+
operator_split = operator.split("__")
|
|
47
|
+
new_dict = _nested_dict(data=operator_split, value=op_dict["command"], result=new_dict)
|
|
48
|
+
else:
|
|
49
|
+
if operator in new_dict:
|
|
50
|
+
if isinstance(new_dict[operator], dict):
|
|
51
|
+
new_dict[operator].update(_make_platform_params(op_dict["command"]))
|
|
52
|
+
else:
|
|
53
|
+
new_dict[operator] = [
|
|
54
|
+
new_dict[operator],
|
|
55
|
+
_make_platform_params(op_dict["command"]),
|
|
56
|
+
]
|
|
57
|
+
else:
|
|
58
|
+
new_dict[operator] = _make_platform_params(op_dict["command"])
|
|
59
|
+
return new_dict
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
AIRFLOW_CLI_HIERARCHY = iter_operators()
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def get_command_params(cmd: str) -> list:
|
|
66
|
+
"""Get the parameters for a command
|
|
67
|
+
|
|
68
|
+
:param str cmd: the command to get the parameters for
|
|
69
|
+
:return: a list of parameters
|
|
70
|
+
:rtype: list
|
|
71
|
+
"""
|
|
72
|
+
cmd_split = cmd.split(" ")
|
|
73
|
+
if len(cmd_split) == 1:
|
|
74
|
+
return AIRFLOW_CLI_HIERARCHY[cmd_split[0]]["params"]
|
|
75
|
+
elif len(cmd_split) == 2:
|
|
76
|
+
return AIRFLOW_CLI_HIERARCHY[cmd_split[0]][cmd_split[1]]["params"]
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def return_all_commands_and_params() -> dict:
|
|
80
|
+
"""Return all commands and parameters
|
|
81
|
+
|
|
82
|
+
:return: a dict of commands and parameters
|
|
83
|
+
:rtype: dict
|
|
84
|
+
"""
|
|
85
|
+
dct = {}
|
|
86
|
+
for operator in AIRFLOW_CLICK_OPERATORS:
|
|
87
|
+
click_name = " ".join(operator.split("__"))
|
|
88
|
+
dct[click_name] = {"parameters": AIRFLOW_CLICK_OPERATORS[operator]["command"].parameters}
|
|
File without changes
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""Generate PythonOperators based on a click.Command."""
|
|
2
|
+
|
|
3
|
+
from typing import Union, Optional
|
|
4
|
+
|
|
5
|
+
import click
|
|
6
|
+
from airflow.operators.python import PythonOperator
|
|
7
|
+
|
|
8
|
+
from airflow import DAG
|
|
9
|
+
from regscale.airflow.tasks.click import execute_click_command
|
|
10
|
+
from regscale.models.click_models import ClickCommand
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def generate_operator_for_command(
|
|
14
|
+
command: Union[click.Command, ClickCommand],
|
|
15
|
+
command_name: Optional[str] = None,
|
|
16
|
+
dag: Optional[DAG] = None,
|
|
17
|
+
**kwargs: dict,
|
|
18
|
+
) -> PythonOperator:
|
|
19
|
+
"""Generate a PythonOperator for a Click Command
|
|
20
|
+
|
|
21
|
+
:param Union[click.Command, ClickCommand] command: the command to generate the operator for
|
|
22
|
+
:param Optional[str] command_name: optional command name to specify as task_id, defaults to None
|
|
23
|
+
:param Optional[DAG] dag: an Optional airflow DAG to pass, defaults to None
|
|
24
|
+
:param dict **kwargs: additional named parameters to pass to PythonOperator
|
|
25
|
+
:return: a PythonOperator configured to execute the Click Command
|
|
26
|
+
:rtype: PythonOperator
|
|
27
|
+
"""
|
|
28
|
+
if isinstance(command, click.Command):
|
|
29
|
+
command = ClickCommand.from_command(command)
|
|
30
|
+
return PythonOperator(
|
|
31
|
+
task_id=command_name or command.name,
|
|
32
|
+
python_callable=execute_click_command,
|
|
33
|
+
op_kwargs={"command": command.callback},
|
|
34
|
+
dag=dag,
|
|
35
|
+
**kwargs,
|
|
36
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
"""SQL Sensors for Airflow"""
|
|
2
|
+
|
|
3
|
+
from typing import Literal
|
|
4
|
+
from uuid import uuid4
|
|
5
|
+
|
|
6
|
+
from airflow.sensors.sql import SqlSensor
|
|
7
|
+
|
|
8
|
+
from regscale.airflow.sessions.sql import SQLQuery
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class SqlSensorXcon(SqlSensor):
|
|
12
|
+
def __init__(self, step_name: str = "sql_sensor_xcon", **kwargs):
|
|
13
|
+
super().__init__(**kwargs)
|
|
14
|
+
self.step_name = step_name
|
|
15
|
+
|
|
16
|
+
def poke(self, context):
|
|
17
|
+
self.log.info(f"Poking: {self.sql}")
|
|
18
|
+
records = self._get_hook().get_first(self.sql, parameters=self.parameters)
|
|
19
|
+
if not records:
|
|
20
|
+
return False
|
|
21
|
+
context["task_instance"].xcom_push(key=self.step_name, value=records)
|
|
22
|
+
return True
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def build_sql_sensor_xcon(
|
|
26
|
+
sql: SQLQuery,
|
|
27
|
+
name: str = None,
|
|
28
|
+
conn_id: str = "platform_db",
|
|
29
|
+
unique: bool = False,
|
|
30
|
+
mode: Literal["reschedule", "poke"] = "poke",
|
|
31
|
+
step_name: str = "sql_sensor_xcon",
|
|
32
|
+
timeout: int = 60 * 60 * 24 * 7,
|
|
33
|
+
poke_interval: int = 60 * 5,
|
|
34
|
+
**kwargs: dict,
|
|
35
|
+
) -> SqlSensorXcon:
|
|
36
|
+
"""Build a SQL Sensor that will push its results to XCom
|
|
37
|
+
|
|
38
|
+
:param SQLQuery sql: the SQL query to run
|
|
39
|
+
:param str name: the name of the sensor, defaults to None
|
|
40
|
+
:param str conn_id: the connection id to use, defaults to "platform_db"
|
|
41
|
+
:param bool unique: whether to make the sensor unique, defaults to False
|
|
42
|
+
:param Literal["reschedule", "poke"] mode: the mode of the sensor, defaults to "poke"
|
|
43
|
+
:param str step_name: the name of the step, defaults to "sql_sensor_xcon"
|
|
44
|
+
:param int timeout: the timeout of the sensor, defaults to 60 * 60 * 24 * 7
|
|
45
|
+
:param int poke_interval: the poke interval of the sensor, defaults to 60 * 5
|
|
46
|
+
:param dict kwargs: keyword arguments to pass to the sensor
|
|
47
|
+
:return: the SQL Sensor
|
|
48
|
+
:rtype: SqlSensorXcon
|
|
49
|
+
"""
|
|
50
|
+
dag_run_dict = dict(zip(sql.dag_run_vars, sql.dag_run_vars))
|
|
51
|
+
params_dict = dict(zip(sql.params, sql.params))
|
|
52
|
+
if unique and name is not None:
|
|
53
|
+
name = f"{name}-{str(uuid4())[:8]}"
|
|
54
|
+
|
|
55
|
+
return SqlSensorXcon(
|
|
56
|
+
task_id=name or f"sql_sensor-{name or str(uuid4())[:8]}",
|
|
57
|
+
sql=sql.raw,
|
|
58
|
+
conn_id=conn_id,
|
|
59
|
+
params=params_dict or dag_run_dict,
|
|
60
|
+
mode=mode,
|
|
61
|
+
step_name=step_name,
|
|
62
|
+
timeout=timeout,
|
|
63
|
+
poke_interval=poke_interval,
|
|
64
|
+
**kwargs,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def build_sql_sensor(
|
|
69
|
+
sql: SQLQuery,
|
|
70
|
+
name: str = None,
|
|
71
|
+
conn_id: str = "platform_db",
|
|
72
|
+
unique: bool = False,
|
|
73
|
+
mode: Literal["reschedule", "poke"] = "poke",
|
|
74
|
+
timeout: int = 60 * 60 * 24 * 7,
|
|
75
|
+
poke_interval: int = 60 * 5,
|
|
76
|
+
**kwargs: dict,
|
|
77
|
+
) -> SqlSensor:
|
|
78
|
+
"""Build a SQL Sensor from a SQLQuery object
|
|
79
|
+
|
|
80
|
+
:param SQLQuery sql: the SQL query to run
|
|
81
|
+
:param str name: the name of the sensor, defaults to None
|
|
82
|
+
:param str conn_id: the connection id to use, defaults to "platform_db"
|
|
83
|
+
:param bool unique: whether to make the sensor unique, defaults to False
|
|
84
|
+
:param Literal["reschedule", "poke"] mode: the mode of the sensor, defaults to "poke"
|
|
85
|
+
:param int timeout: the timeout of the sensor, defaults to 60 * 60 * 24 * 7
|
|
86
|
+
:param int poke_interval: the poke interval of the sensor, defaults to 60 * 5
|
|
87
|
+
:param dict **kwargs: additional keyword arguments
|
|
88
|
+
:return: the SQL Sensor
|
|
89
|
+
:rtype: SqlSensor
|
|
90
|
+
"""
|
|
91
|
+
dag_run_dict = dict(zip(sql.dag_run_vars, sql.dag_run_vars))
|
|
92
|
+
params_dict = dict(zip(sql.params, sql.params))
|
|
93
|
+
if unique and name:
|
|
94
|
+
name = f"{name}-{str(uuid4())[:8]}"
|
|
95
|
+
if unique and name is None:
|
|
96
|
+
name = f"sql_sensor-{str(uuid4())[:8]}"
|
|
97
|
+
|
|
98
|
+
return SqlSensor(
|
|
99
|
+
task_id=name,
|
|
100
|
+
sql=sql.raw,
|
|
101
|
+
conn_id=conn_id,
|
|
102
|
+
params=params_dict or dag_run_dict,
|
|
103
|
+
mode=mode,
|
|
104
|
+
timeout=timeout,
|
|
105
|
+
poke_interval=poke_interval,
|
|
106
|
+
**kwargs,
|
|
107
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"""Provide SQL Queries to be used in Airflow DAGs related to SQL Server."""
|
|
2
|
+
|
|
3
|
+
from typing import List
|
|
4
|
+
|
|
5
|
+
from regscale.utils.string import (
|
|
6
|
+
replace_unknown_spaces_and_newlines,
|
|
7
|
+
extract_double_curly_braces_contents,
|
|
8
|
+
extract_dag_run_conf_key,
|
|
9
|
+
extract_param,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class SQLQuery:
|
|
14
|
+
"""
|
|
15
|
+
A class to represent a SQL Query
|
|
16
|
+
|
|
17
|
+
:param str query: a SQL query
|
|
18
|
+
:param dict **kwargs: additional keyword arguments
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, query: str = "", **kwargs: dict):
|
|
22
|
+
self.raw = query
|
|
23
|
+
self.query = replace_unknown_spaces_and_newlines(query)
|
|
24
|
+
self.kwargs = kwargs
|
|
25
|
+
self.vars: List[str] = []
|
|
26
|
+
self.dag_run_vars: List[str] = []
|
|
27
|
+
self.params: List[str] = []
|
|
28
|
+
self.jinja_kwargs = {}
|
|
29
|
+
self._populate_jinja_vars(**kwargs)
|
|
30
|
+
|
|
31
|
+
def __repr__(self) -> str:
|
|
32
|
+
"""Return the SQLQuery object
|
|
33
|
+
|
|
34
|
+
:return: the SQLQuery object as a string
|
|
35
|
+
:rtype: str
|
|
36
|
+
"""
|
|
37
|
+
return f"SQLQuery(query={self.query}, kwargs={self.kwargs})"
|
|
38
|
+
|
|
39
|
+
def __str__(self) -> str:
|
|
40
|
+
"""Return the SQLQuery object
|
|
41
|
+
|
|
42
|
+
:return: the SQLQuery object as a string
|
|
43
|
+
:rtype: str
|
|
44
|
+
"""
|
|
45
|
+
return f"{self.dag_run_vars=}\n{self.params=}\n{self.unique_vars=}"
|
|
46
|
+
|
|
47
|
+
def _populate_jinja_vars(self, **kwargs: dict):
|
|
48
|
+
"""Populate the SQLQuery object with Jinja variables
|
|
49
|
+
|
|
50
|
+
:param dict **kwargs: keyword arguments
|
|
51
|
+
"""
|
|
52
|
+
self.jinja_kwargs = kwargs
|
|
53
|
+
self.vars = extract_double_curly_braces_contents(self.query)
|
|
54
|
+
self.dag_run_vars = [extract_dag_run_conf_key(__) for __ in self.vars]
|
|
55
|
+
self.params = [extract_param(_) for _ in self.vars]
|
|
56
|
+
|
|
57
|
+
@property
|
|
58
|
+
def unique_vars(self) -> List[str]:
|
|
59
|
+
"""Return a list of unique Jinja variables
|
|
60
|
+
|
|
61
|
+
:return: a list of unique Jinja variables as strings
|
|
62
|
+
:rtype: List[str]
|
|
63
|
+
"""
|
|
64
|
+
return list(set(self.dag_run_vars + self.params))
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"""SQL Server Platform Queries."""
|
|
2
|
+
|
|
3
|
+
from regscale.airflow.sessions.sql.queries import SQLQuery
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
CHECK_WORKFLOW_STATUS_QUERY: str = """
|
|
7
|
+
SELECT
|
|
8
|
+
CASE
|
|
9
|
+
WHEN EXISTS (
|
|
10
|
+
SELECT 1
|
|
11
|
+
FROM dbo.WorkflowInstance wi
|
|
12
|
+
WHERE wi.id = {{ dag_run.conf['workflow_id'] if dag_run and dag_run.conf and 'workflow_id' in dag_run.conf else params.workflow_id }}
|
|
13
|
+
AND NOT EXISTS (
|
|
14
|
+
SELECT 1
|
|
15
|
+
FROM dbo.WorkflowInstanceSteps wis
|
|
16
|
+
WHERE wis.WorkflowInstanceId = wi.id
|
|
17
|
+
AND wis.[Status] <> 'Rejected'
|
|
18
|
+
)
|
|
19
|
+
) THEN -1
|
|
20
|
+
WHEN EXISTS (
|
|
21
|
+
SELECT 1
|
|
22
|
+
FROM dbo.WorkflowInstance wi
|
|
23
|
+
WHERE wi.id = {{ dag_run.conf['workflow_id'] if dag_run and dag_run.conf and 'workflow_id' in dag_run.conf else params.workflow_id }}
|
|
24
|
+
AND NOT EXISTS (
|
|
25
|
+
SELECT 1
|
|
26
|
+
FROM dbo.WorkflowInstanceSteps wis
|
|
27
|
+
WHERE wis.WorkflowInstanceId = wi.id
|
|
28
|
+
AND wis.[Status] <> 'Approved'
|
|
29
|
+
)
|
|
30
|
+
) THEN 1
|
|
31
|
+
WHEN EXISTS(
|
|
32
|
+
SELECT 1
|
|
33
|
+
FROM dbo.WorkflowInstance wi
|
|
34
|
+
WHERE wi.id = {{ dag_run.conf['workflow_id'] if dag_run and dag_run.conf and 'workflow_id' in dag_run.conf else params.workflow_id }}
|
|
35
|
+
AND NOT EXISTS (
|
|
36
|
+
SELECT 1
|
|
37
|
+
FROM dbo.WorkflowInstanceSteps wis
|
|
38
|
+
WHERE wis.WorkflowInstanceId = wi.id
|
|
39
|
+
AND wis.[Status] <> 'Pending'
|
|
40
|
+
) THEN 0
|
|
41
|
+
ELSE NULL
|
|
42
|
+
END AS OverallStatus;
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
NEW_CHECK_WORKFLOW_STATUS_QUERY: str = """
|
|
46
|
+
declare @workflowInstanceId int = {{ dag_run.conf['workflow_id'] if dag_run and dag_run.conf and 'workflow_id' in dag_run.conf else params.workflow_id }}
|
|
47
|
+
declare @workflowStepId int = -1
|
|
48
|
+
;WITH orderedWorkFlowSteps AS
|
|
49
|
+
(
|
|
50
|
+
SELECT
|
|
51
|
+
id, ROW_NUMBER() OVER(ORDER BY [Order] DESC) AS 'RowNum'
|
|
52
|
+
FROM WorkflowInstanceSteps where WorkflowInstanceId = @workflowInstanceId
|
|
53
|
+
)
|
|
54
|
+
SELECT @workflowStepId = id
|
|
55
|
+
FROM orderedWorkFlowSteps
|
|
56
|
+
WHERE RowNum = 2
|
|
57
|
+
SELECT
|
|
58
|
+
case
|
|
59
|
+
when exists
|
|
60
|
+
(select wis.id from dbo.WorkflowInstanceSteps wis
|
|
61
|
+
where wis.Id = @workflowStepId and wis.WorkflowInstanceId = @workflowInstanceId and wis.[Status] = 'Rejected')
|
|
62
|
+
then -1
|
|
63
|
+
when exists
|
|
64
|
+
(select wis.id from dbo.WorkflowInstanceSteps wis
|
|
65
|
+
where wis.Id = @workflowStepId and wis.WorkflowInstanceId = @workflowInstanceId and wis.[Status] = 'Approved')
|
|
66
|
+
then 1
|
|
67
|
+
when exists
|
|
68
|
+
(select wis.id from dbo.WorkflowInstanceSteps wis
|
|
69
|
+
where wis.Id = @workflowStepId and wis.WorkflowInstanceId = @workflowInstanceId and wis.[Status] = 'Pending')
|
|
70
|
+
then 0
|
|
71
|
+
else
|
|
72
|
+
null
|
|
73
|
+
end as OverallStatus;
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
NEWER_CHECK_WORKFLOW_STATUS_QUERY: str = """
|
|
77
|
+
declare @workflowInstanceId int = {{ dag_run.conf['workflow_id'] if dag_run and dag_run.conf and 'workflow_id' in dag_run.conf else params.workflow_id }}
|
|
78
|
+
;select * from WorkflowInstanceSteps
|
|
79
|
+
where WorkflowInstanceId = @workflowInstanceId and [Order] not in (0, 1000) order by [order] -- this is for validating results only
|
|
80
|
+
select top 1
|
|
81
|
+
case when wis.status = 'Rejected' then -1
|
|
82
|
+
when wis.status = 'Approved' then 1
|
|
83
|
+
when wis.status = 'Pending' then 0
|
|
84
|
+
else null
|
|
85
|
+
end as OverallStatus,
|
|
86
|
+
*
|
|
87
|
+
from WorkflowInstanceSteps wis
|
|
88
|
+
where wis.WorkflowInstanceId = @workflowInstanceId
|
|
89
|
+
and status in ('Rejected', 'Approved', 'Pending' )
|
|
90
|
+
order by [Order] DESC;
|
|
91
|
+
"""
|
|
92
|
+
|
|
93
|
+
CHECK_IF_COMPLETED_QUERY: str = """
|
|
94
|
+
DECLARE @workflowInstanceId INT = '{{ dag_run.conf['workflow_id'] if dag_run and dag_run.conf and 'workflow_id' in dag_run.conf else params.workflow_id }}';
|
|
95
|
+
WITH OrderedSteps AS (
|
|
96
|
+
SELECT
|
|
97
|
+
wis.*,
|
|
98
|
+
LEAD(wis.[Order]) OVER (ORDER BY wis.[Order] DESC) AS NextOrder,
|
|
99
|
+
LEAD(wis.[Status]) OVER (ORDER BY wis.[Order] DESC) AS NextStatus
|
|
100
|
+
FROM WorkflowInstanceSteps wis
|
|
101
|
+
WHERE wis.WorkflowInstanceId = @workflowInstanceId
|
|
102
|
+
)
|
|
103
|
+
SELECT
|
|
104
|
+
CASE
|
|
105
|
+
WHEN [Order] = 1000 AND NextStatus = 'Approved' THEN 1
|
|
106
|
+
ELSE NULL
|
|
107
|
+
END AS Result
|
|
108
|
+
FROM OrderedSteps
|
|
109
|
+
WHERE [Order] = 1000;
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
WATCH_WORFKLOW_QUERY: str = """
|
|
113
|
+
DECLARE @workflowInstanceId INT = {{ dag_run.conf['workflow_id'] if dag_run and dag_run.conf and 'workflow_id' in dag_run.conf else params.workflow_id }};
|
|
114
|
+
WITH OrderedSteps AS (
|
|
115
|
+
SELECT
|
|
116
|
+
wis.*,
|
|
117
|
+
LEAD(wis.[Order]) OVER (ORDER BY wis.[Order] DESC) AS NextOrder,
|
|
118
|
+
ROW_NUMBER() OVER (ORDER BY wis.[Order] DESC) AS Rn
|
|
119
|
+
FROM WorkflowInstanceSteps wis
|
|
120
|
+
WHERE wis.WorkflowInstanceId = @workflowInstanceId
|
|
121
|
+
AND status IN ('Rejected', 'Approved', 'Pending')
|
|
122
|
+
)
|
|
123
|
+
SELECT TOP 1
|
|
124
|
+
CASE
|
|
125
|
+
WHEN NextOrder = 1000 THEN 1
|
|
126
|
+
ELSE 0
|
|
127
|
+
END AS Result,
|
|
128
|
+
wis.*
|
|
129
|
+
FROM OrderedSteps wis
|
|
130
|
+
WHERE Rn = 1;
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
GET_WORKFLOW_STEPS_QUERY: str = """
|
|
134
|
+
SELECT COUNT(*) as Steps
|
|
135
|
+
FROM WorkflowInstanceSteps as wis
|
|
136
|
+
WHERE wis.WorkflowInstanceId = {{ dag_run.conf['workflow_id'] if dag_run and dag_run.conf and 'workflow_id' in dag_run.conf else params.workflow_id }}
|
|
137
|
+
GROUP BY WorkflowInstanceId;
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
BETTER_GET_WORKFLOW_STEPS_QUERY: str = """
|
|
141
|
+
declare @workflowInstanceId int = {{ dag_run.conf['workflow_id'] if dag_run and dag_run.conf and 'workflow_id' in dag_run.conf else params.workflow_id }}
|
|
142
|
+
;select
|
|
143
|
+
stepCount.Steps,
|
|
144
|
+
FROM
|
|
145
|
+
(
|
|
146
|
+
SELECT
|
|
147
|
+
@workflowInstanceId WorkflowinstanceId) as t1
|
|
148
|
+
left JOIN (
|
|
149
|
+
SELECT
|
|
150
|
+
@workflowInstanceId ID,
|
|
151
|
+
COUNT(*) as Steps
|
|
152
|
+
FROM
|
|
153
|
+
WorkflowInstanceSteps as wis
|
|
154
|
+
WHERE
|
|
155
|
+
wis.WorkflowInstanceId = @workflowInstanceId
|
|
156
|
+
group by
|
|
157
|
+
WorkflowInstanceId) as stepCount on
|
|
158
|
+
t1.workflowInstanceId = stepCount.ID
|
|
159
|
+
LEFT JOIN (
|
|
160
|
+
select
|
|
161
|
+
top 1
|
|
162
|
+
wis.WorkflowinstanceId,
|
|
163
|
+
case
|
|
164
|
+
when wis.status = 'Rejected' then -1
|
|
165
|
+
when wis.status = 'Approved' then 1
|
|
166
|
+
when wis.status = 'Pending' then 0
|
|
167
|
+
else null
|
|
168
|
+
end as OverallStatus
|
|
169
|
+
from
|
|
170
|
+
WorkflowInstanceSteps as wis
|
|
171
|
+
where
|
|
172
|
+
wis.WorkflowInstanceId = @workflowInstanceId
|
|
173
|
+
and status in ('Rejected', 'Approved', 'Pending' )
|
|
174
|
+
order by
|
|
175
|
+
[Order] DESC) as status on
|
|
176
|
+
t1.WorkflowinstanceId = status.WorkflowinstanceId
|
|
177
|
+
"""
|
|
178
|
+
|
|
179
|
+
GET_STATUS_WORKFLOW_QUERY: str = """
|
|
180
|
+
declare @workflowInstanceId int = {{ dag_run.conf['workflow_id'] if dag_run and dag_run.conf and 'workflow_id' in dag_run.conf else params.workflow_id }};
|
|
181
|
+
select
|
|
182
|
+
t1.WorkflowinstanceId,
|
|
183
|
+
stepCount.Steps,
|
|
184
|
+
status.OverallStatus
|
|
185
|
+
FROM
|
|
186
|
+
(
|
|
187
|
+
SELECT
|
|
188
|
+
@workflowInstanceId WorkflowinstanceId) as t1
|
|
189
|
+
left JOIN (
|
|
190
|
+
SELECT
|
|
191
|
+
@workflowInstanceId ID,
|
|
192
|
+
COUNT(*) as Steps
|
|
193
|
+
FROM
|
|
194
|
+
WorkflowInstanceSteps as wis
|
|
195
|
+
WHERE
|
|
196
|
+
wis.WorkflowInstanceId = @workflowInstanceId
|
|
197
|
+
group by
|
|
198
|
+
WorkflowInstanceId) as stepCount on
|
|
199
|
+
t1.workflowInstanceId = stepCount.ID
|
|
200
|
+
LEFT JOIN (
|
|
201
|
+
select
|
|
202
|
+
top 1
|
|
203
|
+
wis.WorkflowinstanceId,
|
|
204
|
+
case
|
|
205
|
+
when wis.status = 'Rejected' then -1
|
|
206
|
+
when wis.status = 'Approved' then 1
|
|
207
|
+
when wis.status = 'Pending' then 0
|
|
208
|
+
else null
|
|
209
|
+
end as OverallStatus
|
|
210
|
+
from
|
|
211
|
+
WorkflowInstanceSteps as wis
|
|
212
|
+
where
|
|
213
|
+
wis.WorkflowInstanceId = @workflowInstanceId
|
|
214
|
+
and status in ('Rejected', 'Approved', 'Pending' )
|
|
215
|
+
order by
|
|
216
|
+
[Order] DESC) as status on
|
|
217
|
+
t1.WorkflowinstanceId = status.WorkflowinstanceId;
|
|
218
|
+
"""
|
|
219
|
+
|
|
220
|
+
GET_STEPS_QUERY: str = """
|
|
221
|
+
declare @workflowInstanceId int = {{ dag_run.conf['workflow_id'] if dag_run and dag_run.conf and 'workflow_id' in dag_run.conf else params.workflow_id }};
|
|
222
|
+
select
|
|
223
|
+
stepCount.Steps
|
|
224
|
+
FROM
|
|
225
|
+
(
|
|
226
|
+
SELECT
|
|
227
|
+
@workflowInstanceId WorkflowinstanceId) as t1
|
|
228
|
+
left JOIN (
|
|
229
|
+
SELECT
|
|
230
|
+
@workflowInstanceId ID,
|
|
231
|
+
COUNT(*) as Steps
|
|
232
|
+
FROM
|
|
233
|
+
WorkflowInstanceSteps as wis
|
|
234
|
+
WHERE
|
|
235
|
+
wis.WorkflowInstanceId = @workflowInstanceId
|
|
236
|
+
group by
|
|
237
|
+
WorkflowInstanceId) as stepCount on
|
|
238
|
+
t1.workflowInstanceId = stepCount.ID;
|
|
239
|
+
"""
|
|
240
|
+
|
|
241
|
+
NEW_WORKFLOW_SQL_QUERY: SQLQuery = SQLQuery(query=NEWER_CHECK_WORKFLOW_STATUS_QUERY)
|
|
242
|
+
WORKFLOW_SQL_QUERY: SQLQuery = SQLQuery(query=NEW_CHECK_WORKFLOW_STATUS_QUERY)
|
|
243
|
+
CHECK_IF_COMPLETED_SQL_QUERY: SQLQuery = SQLQuery(query=CHECK_IF_COMPLETED_QUERY)
|
|
244
|
+
WATCH_WORKFLOW_SQL_QUERY: SQLQuery = SQLQuery(query=WATCH_WORFKLOW_QUERY)
|
|
245
|
+
GET_WORKFLOW_STEPS_SQL_QUERY: SQLQuery = SQLQuery(query=GET_WORKFLOW_STEPS_QUERY)
|
|
246
|
+
BETTER_GET_WORFKLOW_STEPS_SQL_QUERY: SQLQuery = SQLQuery(query=BETTER_GET_WORKFLOW_STEPS_QUERY)
|
|
247
|
+
GET_STATUS_WORKFLOW_SQL_QUERY: SQLQuery = SQLQuery(query=GET_STATUS_WORKFLOW_QUERY)
|
|
248
|
+
GET_STEPS_SQL_QUERY: SQLQuery = SQLQuery(query=GET_STEPS_QUERY)
|
|
File without changes
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""Provide information related to branches in python."""
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def tri_branch_func(pull_from: str, negative_task: str, neutral_task: str, positive_task: str, **kwargs: dict) -> str:
|
|
5
|
+
"""Return the branch name
|
|
6
|
+
|
|
7
|
+
:param str pull_from: the task_id to pull from
|
|
8
|
+
:param str negative_task: the task_id to go to if the pull_from task returns -1
|
|
9
|
+
:param str neutral_task: the task_id to go to if the pull_from task returns 0
|
|
10
|
+
:param str positive_task: the task_id to go to if the pull_from task returns 1
|
|
11
|
+
:param dict **kwargs: additional keyword arguments
|
|
12
|
+
:return: the task_id to go to
|
|
13
|
+
:rtype: str
|
|
14
|
+
"""
|
|
15
|
+
ti = kwargs["ti"]
|
|
16
|
+
var = ti.xcom_pull(task_ids=pull_from)
|
|
17
|
+
if var == -1:
|
|
18
|
+
return negative_task
|
|
19
|
+
elif var == 0:
|
|
20
|
+
return neutral_task
|
|
21
|
+
else:
|
|
22
|
+
return positive_task
|