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,116 @@
|
|
|
1
|
+
"""Tasks for interacting with the RegScale-CLI."""
|
|
2
|
+
|
|
3
|
+
from typing import Union
|
|
4
|
+
from uuid import uuid4
|
|
5
|
+
|
|
6
|
+
from airflow.operators.python import PythonOperator
|
|
7
|
+
|
|
8
|
+
from regscale.utils.shell import run_command
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def construct_regscale_login_command(rg_un: str, rg_pw: str) -> str:
|
|
12
|
+
"""Construct the RegScale-CLI login command
|
|
13
|
+
|
|
14
|
+
:param str rg_un: a string representing the RegScale User
|
|
15
|
+
:param str rg_pw: a string representing the RegScale User's password
|
|
16
|
+
:return: a str of the login command
|
|
17
|
+
:rtype: str
|
|
18
|
+
"""
|
|
19
|
+
return f"regscale login --username {rg_un} --password {rg_pw}"
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def run_login_command(rg_un: str, rg_pw: str) -> bool:
|
|
23
|
+
"""Execute the CLI login command
|
|
24
|
+
|
|
25
|
+
:param str rg_un: a string representing the RegScale User
|
|
26
|
+
:param str rg_pw: a string representing the RegScale User's password
|
|
27
|
+
:return: a bool indicating success or failure
|
|
28
|
+
:rtype: bool
|
|
29
|
+
"""
|
|
30
|
+
return run_command(cmd=construct_regscale_login_command(rg_un=rg_un, rg_pw=rg_pw))
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def make_cli_task(task_id: str, cmd: Union[str, list], **kwargs: dict) -> PythonOperator:
|
|
34
|
+
"""Construct a cli task
|
|
35
|
+
|
|
36
|
+
:param str task_id: a task id to assign to the operator
|
|
37
|
+
:param Union[str, list] cmd: a str or list of commands to invoke in the cli
|
|
38
|
+
:param dict **kwargs: additional keyword arguments
|
|
39
|
+
:return: a PythonOperator task configured to execute run_command
|
|
40
|
+
:rtype: PythonOperator
|
|
41
|
+
"""
|
|
42
|
+
return PythonOperator(
|
|
43
|
+
task_id=task_id,
|
|
44
|
+
python_callable=run_command,
|
|
45
|
+
op_kwargs={"cmd": cmd},
|
|
46
|
+
**kwargs,
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def make_login_task(**kwargs: dict) -> PythonOperator:
|
|
51
|
+
"""Construct the regscale login task
|
|
52
|
+
This login task uses the dag_run.conf keys
|
|
53
|
+
* `regscale-username`
|
|
54
|
+
* `regscale-password`
|
|
55
|
+
|
|
56
|
+
:param dict **kwargs: additional keyword arguments
|
|
57
|
+
:return: a PythonOperator task configured to execute run_login_command
|
|
58
|
+
:rtype: PythonOperator
|
|
59
|
+
"""
|
|
60
|
+
return PythonOperator(
|
|
61
|
+
task_id=f"regscale_login_{str(uuid4())[:8]}",
|
|
62
|
+
python_callable=run_command,
|
|
63
|
+
op_kwargs={
|
|
64
|
+
"cmd": 'regscale login --username {{ dag_run.conf["regscale-username"] }}'
|
|
65
|
+
' --password {{ dag_run.conf["regscale-password"] }}'
|
|
66
|
+
},
|
|
67
|
+
**kwargs,
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def make_config_task(key: str, value: str, **kwargs: dict) -> PythonOperator:
|
|
72
|
+
"""Construct a config task to set key to value
|
|
73
|
+
|
|
74
|
+
:param str key: str representing the key to set in the config
|
|
75
|
+
:param str value: str representing the value to set for the key in the config
|
|
76
|
+
:param dict **kwargs: additional keyword arguments
|
|
77
|
+
:return: a PythonOperator task configured to execute the run_command to set a value in config
|
|
78
|
+
:rtype: PythonOperator
|
|
79
|
+
"""
|
|
80
|
+
return PythonOperator(
|
|
81
|
+
task_id=f"regscale_config_{key}_{str(uuid4())[:8]}",
|
|
82
|
+
python_callable=run_command,
|
|
83
|
+
op_kwargs={"cmd": f"regscale config --param {key} --val {value}"},
|
|
84
|
+
**kwargs,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def make_set_domain_task(**kwargs: dict) -> PythonOperator:
|
|
89
|
+
"""Construct as config to set the domain, this uses the dag_run.conf["domain"] key
|
|
90
|
+
|
|
91
|
+
:param dict **kwargs: additional keyword arguments
|
|
92
|
+
:return: a PythonOperator that sets the domain
|
|
93
|
+
:rtype: PythonOperator
|
|
94
|
+
"""
|
|
95
|
+
return PythonOperator(
|
|
96
|
+
task_id=f"set_domain_{str(uuid4())[:8]}",
|
|
97
|
+
python_callable=run_command,
|
|
98
|
+
op_kwargs={"cmd": 'regscale config --param domain --val {{ dag_run.conf["domain"] }}'},
|
|
99
|
+
**kwargs,
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def make_azure_config_task(**context: dict) -> None:
|
|
104
|
+
"""Construct azure config tasks
|
|
105
|
+
|
|
106
|
+
:param dict **context: an airflow context
|
|
107
|
+
:rtype: None
|
|
108
|
+
"""
|
|
109
|
+
keys = dict(
|
|
110
|
+
domain=context["dag_run"].conf.get("domain"),
|
|
111
|
+
azure365ClientId=context["dag_run"].conf.get("azure365ClientId"),
|
|
112
|
+
azure365Secret=context["dag_run"].conf.get("azure365Secret"),
|
|
113
|
+
azure365TenantId=context["dag_run"].conf.get("azure365TenantId"),
|
|
114
|
+
)
|
|
115
|
+
for key, value in keys.items():
|
|
116
|
+
run_command(cmd=f"regscale config --param {key} --val {value}")
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module contains functions to help Airflow execute a click command.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
|
|
7
|
+
from pydantic import ValidationError
|
|
8
|
+
|
|
9
|
+
from regscale.models.click_models import ClickCommand
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def execute_click_command_old(command: ClickCommand, **context: dict) -> None:
|
|
13
|
+
"""Execute a click command
|
|
14
|
+
|
|
15
|
+
:param ClickCommand command: a click command to execute
|
|
16
|
+
:param dict **context: get dag_run from conf
|
|
17
|
+
:raises ValueError: If required parameters are missing
|
|
18
|
+
:rtype: None
|
|
19
|
+
"""
|
|
20
|
+
dag_run = context["dag_run"]
|
|
21
|
+
try:
|
|
22
|
+
command_model = command.model_validate(dag_run.conf)
|
|
23
|
+
except ValidationError as exc:
|
|
24
|
+
# This will raise a ValidationError if any required parameters are missing
|
|
25
|
+
raise ValueError(f"Invalid parameters for command '{command.name}': {str(exc)}") from exc
|
|
26
|
+
valid_params = {name: value for name, value in command_model.dict().items() if name in command.params}
|
|
27
|
+
command.callback(**valid_params)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def execute_click_command(command: ClickCommand, **context: dict) -> None:
|
|
31
|
+
"""Execute a click command
|
|
32
|
+
|
|
33
|
+
:param ClickCommand command: a click command to execute
|
|
34
|
+
:param dict **context: get dag_run from conf
|
|
35
|
+
:raises ValueError: if no dag_run in context
|
|
36
|
+
:rtype: None
|
|
37
|
+
"""
|
|
38
|
+
# Get the dag_run from the context, or raise an error if it's not present
|
|
39
|
+
dag_run = context.get("dag_run")
|
|
40
|
+
parameters = command.parameters
|
|
41
|
+
logging.debug(f"{parameters=}")
|
|
42
|
+
op_kwargs = {param: context.get(param) for param in parameters}
|
|
43
|
+
logging.debug(f"{op_kwargs.keys()}")
|
|
44
|
+
if dag_run is None:
|
|
45
|
+
raise ValueError("No dag_run in context")
|
|
46
|
+
if dag_run.conf is None:
|
|
47
|
+
dag_run.conf = {}
|
|
48
|
+
# merge the dictionaries, giving precedence to op_kwargs
|
|
49
|
+
command_defaults = command.defaults
|
|
50
|
+
command_parameters = {**command_defaults, **dag_run.conf, **op_kwargs}
|
|
51
|
+
for key, value in command_parameters.items():
|
|
52
|
+
logging.debug(f"{key=}, {value=}")
|
|
53
|
+
try:
|
|
54
|
+
valid_params = {key: value for key, value in command_parameters.items() if key in command.parameters}
|
|
55
|
+
logging.debug(f"{valid_params=}")
|
|
56
|
+
except Exception as exc:
|
|
57
|
+
# Catch any other exceptions that might be raised
|
|
58
|
+
logging.error(f"Error parsing command {command.name} parameters: {str(exc)}")
|
|
59
|
+
raise
|
|
60
|
+
try:
|
|
61
|
+
if dag_run.conf:
|
|
62
|
+
from regscale.core.app.application import Application
|
|
63
|
+
|
|
64
|
+
_ = Application(config=dag_run.conf)
|
|
65
|
+
command.context_settings["CONFIG"] = dag_run.conf
|
|
66
|
+
command.call(**valid_params)
|
|
67
|
+
except UnboundLocalError as exc:
|
|
68
|
+
if "callback_results" in str(exc):
|
|
69
|
+
return None
|
|
70
|
+
# Catch any exceptions that might be raised by the command callback
|
|
71
|
+
logging.error(f"Error executing command '{command.name}': {str(exc)}")
|
|
72
|
+
raise
|
|
73
|
+
return None
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""Define pre-made TaskGroups for usage across DAGs."""
|
|
2
|
+
|
|
3
|
+
from uuid import uuid4
|
|
4
|
+
|
|
5
|
+
from airflow import AirflowException, DAG
|
|
6
|
+
from airflow.models import TaskInstance
|
|
7
|
+
from airflow.operators.python import PythonOperator
|
|
8
|
+
from airflow.utils.db import provide_session
|
|
9
|
+
from airflow.utils.state import State
|
|
10
|
+
from airflow.utils.task_group import TaskGroup
|
|
11
|
+
from airflow.utils.trigger_rule import TriggerRule
|
|
12
|
+
|
|
13
|
+
from regscale.airflow.hierarchy import AIRFLOW_CLICK_OPERATORS as OPERATORS
|
|
14
|
+
from regscale.airflow.tasks.click import execute_click_command
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def generate_name(name: str, tag: str = None) -> str:
|
|
18
|
+
"""Generate a unique name for a TaskGroup
|
|
19
|
+
|
|
20
|
+
:param str name: the name of the TaskGroup
|
|
21
|
+
:param str tag: a unique identifier for the TaskGroup
|
|
22
|
+
:return: a unique name for the TaskGroup
|
|
23
|
+
:rtype: str
|
|
24
|
+
"""
|
|
25
|
+
if not tag:
|
|
26
|
+
tag = str(uuid4())[:8] # give the task group a unique name for tracking
|
|
27
|
+
return f"{name}-{tag}"
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def setup_task_group(
|
|
31
|
+
dag: DAG,
|
|
32
|
+
setup_tag: str = None,
|
|
33
|
+
) -> TaskGroup:
|
|
34
|
+
"""Create a TaskGroup for setting up the init.yaml and initialization of the DAG
|
|
35
|
+
|
|
36
|
+
:param DAG dag: an Airflow DAG
|
|
37
|
+
:param str setup_tag: a unique identifier for the task
|
|
38
|
+
:return: a setup TaskGroup
|
|
39
|
+
:rtype: TaskGroup
|
|
40
|
+
"""
|
|
41
|
+
setup_name = generate_name("setup", setup_tag)
|
|
42
|
+
with TaskGroup(setup_name, dag=dag) as setup:
|
|
43
|
+
login = PythonOperator(
|
|
44
|
+
task_id=f"login-{setup_tag}",
|
|
45
|
+
task_group=setup,
|
|
46
|
+
python_callable=execute_click_command,
|
|
47
|
+
op_kwargs={
|
|
48
|
+
"command": OPERATORS["login"]["command"],
|
|
49
|
+
"token": '{{ dag_run.conf.get("token") }}',
|
|
50
|
+
"domain": '{{ dag_run.conf.get("domain") }}',
|
|
51
|
+
},
|
|
52
|
+
)
|
|
53
|
+
login
|
|
54
|
+
return setup
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@provide_session
|
|
58
|
+
def _email_on_fail(task, execution_date, dag, session=None, **kwargs):
|
|
59
|
+
"""
|
|
60
|
+
Send an email if any of the upstream DAGs failed
|
|
61
|
+
|
|
62
|
+
:param DAG dag: The DAG to add the operator to
|
|
63
|
+
:param execution_date: The execution date of the DAG
|
|
64
|
+
:param session: DAG session
|
|
65
|
+
:return: The PythonOperator to send an email if any of the DAG tasks fail
|
|
66
|
+
:rtype: TaskGroup
|
|
67
|
+
"""
|
|
68
|
+
from regscale.core.app.application import Application
|
|
69
|
+
from regscale.models import Email
|
|
70
|
+
|
|
71
|
+
upstream_task_instances = (
|
|
72
|
+
session.query(TaskInstance)
|
|
73
|
+
.filter(
|
|
74
|
+
TaskInstance.dag_id == dag.dag_id,
|
|
75
|
+
TaskInstance.execution_date == execution_date,
|
|
76
|
+
TaskInstance.task_id.in_(task.upstream_task_ids),
|
|
77
|
+
)
|
|
78
|
+
.all()
|
|
79
|
+
)
|
|
80
|
+
upstream_states = [ti.state for ti in upstream_task_instances]
|
|
81
|
+
fail_this_task = State.FAILED in upstream_states
|
|
82
|
+
dag_config = kwargs["dag_run"].conf
|
|
83
|
+
app = Application(config=dag_config)
|
|
84
|
+
|
|
85
|
+
if email := kwargs["dag_run"].conf.get("email"):
|
|
86
|
+
email = Email(
|
|
87
|
+
fromEmail="Support@RegScale.com",
|
|
88
|
+
emailSenderId=app.config["userId"],
|
|
89
|
+
to=email,
|
|
90
|
+
subject=f"An Automated Job Has Failed: {dag_config['jobName']} ({dag_config['cadence']})",
|
|
91
|
+
body=f"{dag.dag_id} with ID: {dag_config['dag_run_id']} job has failed. "
|
|
92
|
+
+ f"Please check the logs for more information: {dag_config['job_url']}",
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
if fail_this_task:
|
|
96
|
+
if email.send():
|
|
97
|
+
print(f"Email sent to {email} about {dag.dag_id} job failure.")
|
|
98
|
+
raise AirflowException("Failing task because one or more upstream tasks failed.")
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def email_on_fail_operator(dag, email_tag: str = None) -> PythonOperator:
|
|
102
|
+
"""
|
|
103
|
+
Create a PythonOperator to send an email if any of the DAGs fail
|
|
104
|
+
|
|
105
|
+
:param DAG dag: The DAG to add the operator to
|
|
106
|
+
:param str email_tag: A unique identifier for the task, if not provided one will be generated
|
|
107
|
+
:return: The PythonOperator to send an email if any of the DAG tasks fail
|
|
108
|
+
:rtype: TaskGroup
|
|
109
|
+
"""
|
|
110
|
+
return PythonOperator(
|
|
111
|
+
task_id=generate_name("email", email_tag),
|
|
112
|
+
python_callable=_email_on_fail,
|
|
113
|
+
trigger_rule=TriggerRule.ALL_DONE,
|
|
114
|
+
provide_context=True,
|
|
115
|
+
dag=dag,
|
|
116
|
+
)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"""Initialize init.yaml and set shared keys as variables for the DAG."""
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import Optional, Union
|
|
6
|
+
|
|
7
|
+
import yaml
|
|
8
|
+
from airflow.exceptions import AirflowException
|
|
9
|
+
|
|
10
|
+
from regscale.airflow.hierarchy import AIRFLOW_CLICK_OPERATORS as OPERATORS
|
|
11
|
+
from regscale.airflow.tasks.click import execute_click_command
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def get_shared_keys(
|
|
15
|
+
yaml_file_path: Optional[Union[str, Path]] = Path("init.yaml"),
|
|
16
|
+
**context,
|
|
17
|
+
) -> list:
|
|
18
|
+
"""Get shared keys between init.yaml and a dag_run_conf obj
|
|
19
|
+
|
|
20
|
+
:param Optional[Union[str, Path]] yaml_file_path: the Path to where the yaml file is expected, defaults to Path("init.yaml")
|
|
21
|
+
:param context: context from Airflow DAG
|
|
22
|
+
:return: a list of shared keys
|
|
23
|
+
:rtype: list
|
|
24
|
+
"""
|
|
25
|
+
if "dag_run" not in context:
|
|
26
|
+
logging.error(f"context contains {list(context.keys())}")
|
|
27
|
+
if isinstance(yaml_file_path, str):
|
|
28
|
+
yaml_file_path = Path(yaml_file_path)
|
|
29
|
+
yaml_keys = list(yaml.safe_load(yaml_file_path.open("r")).keys())
|
|
30
|
+
dag_run_conf = context["dag_run"].conf
|
|
31
|
+
if shared_keys := list(set(list(dag_run_conf.keys())).intersection(set(yaml_keys))):
|
|
32
|
+
for key in shared_keys:
|
|
33
|
+
logging.info(f"Shared key: {key}")
|
|
34
|
+
value = dag_run_conf[key]
|
|
35
|
+
temp_context = context | {"param": key, "val": value}
|
|
36
|
+
execute_click_command(command=OPERATORS["config"]["command"], **temp_context)
|
|
37
|
+
return shared_keys
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def set_shared_config_values(shared_keys_task: str = None, **context: dict) -> None:
|
|
41
|
+
"""Get the shared keys and set them as a variable
|
|
42
|
+
|
|
43
|
+
:param str shared_keys_task: the task_id of the task that will get the shared keys, defaults to None
|
|
44
|
+
:param dict **context: context from Airflow DAG
|
|
45
|
+
:raises AirflowException: if no dag_run or dag.conf found or setup_tag specified
|
|
46
|
+
:rtype: None
|
|
47
|
+
"""
|
|
48
|
+
logging.info(f"Initial shared_keys_task: {shared_keys_task=}")
|
|
49
|
+
dag_run_conf = context["dag_run"].conf
|
|
50
|
+
if not shared_keys_task:
|
|
51
|
+
if "op_kwargs" not in dag_run_conf:
|
|
52
|
+
raise AirflowException("No dag_run or dag.conf found or setup_tag specified")
|
|
53
|
+
shared_keys_task = dag_run_conf["op_kwargs"]["shared_keys_task"]
|
|
54
|
+
if shared_keys := context["ti"].xcom_pull(key="shared_keys", task_ids=shared_keys_task):
|
|
55
|
+
for key in shared_keys:
|
|
56
|
+
value = dag_run_conf[key]
|
|
57
|
+
temp_context = context | {"param": key, "val": value}
|
|
58
|
+
execute_click_command(command=OPERATORS["config"]["command"], **temp_context)
|
|
59
|
+
else:
|
|
60
|
+
logging.warning(f"No shared keys found: {shared_keys=}")
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module contains functions to change the state of a DAG run or a task instance.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
from airflow.exceptions import AirflowException
|
|
8
|
+
from airflow.models import DagRun, TaskInstance
|
|
9
|
+
from airflow.utils.state import State
|
|
10
|
+
|
|
11
|
+
from airflow import settings
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def mark_dag_run_as_success(dag_id: Any, execution_date: Any):
|
|
15
|
+
"""
|
|
16
|
+
This function marks a DAG run as successful.
|
|
17
|
+
|
|
18
|
+
:param Any dag_id: the id of the dag
|
|
19
|
+
:param Any execution_date: the execution date of the dag run
|
|
20
|
+
"""
|
|
21
|
+
session = settings.Session()
|
|
22
|
+
|
|
23
|
+
dag_run = (
|
|
24
|
+
session.query(DagRun)
|
|
25
|
+
.filter(
|
|
26
|
+
DagRun.dag_id == dag_id,
|
|
27
|
+
DagRun.execution_date == execution_date,
|
|
28
|
+
)
|
|
29
|
+
.one_or_none()
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
if dag_run:
|
|
33
|
+
dag_run.state = State.SUCCESS
|
|
34
|
+
|
|
35
|
+
# Update state of the tasks of this dag run
|
|
36
|
+
session.query(TaskInstance).filter(
|
|
37
|
+
TaskInstance.dag_id == dag_id,
|
|
38
|
+
TaskInstance.execution_date == execution_date,
|
|
39
|
+
).update({TaskInstance.state: State.SUCCESS})
|
|
40
|
+
|
|
41
|
+
session.commit()
|
|
42
|
+
session.close()
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def fail_dag_run():
|
|
46
|
+
"""Fail a DAG run on purpose."""
|
|
47
|
+
raise AirflowException("Failed DAGRun on Purpose")
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"""Tasks for the workflows to do the following"""
|
|
2
|
+
|
|
3
|
+
from airflow import DAG
|
|
4
|
+
from airflow.operators.python import PythonOperator
|
|
5
|
+
|
|
6
|
+
from regscale.airflow.tasks.states import mark_dag_run_as_success, fail_dag_run
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def build_complete(uid: str, dag: DAG) -> PythonOperator:
|
|
10
|
+
"""Build a complete task
|
|
11
|
+
|
|
12
|
+
:param str uid: a unique identifier for the task
|
|
13
|
+
:param DAG dag: the DAG to add the task to
|
|
14
|
+
:return: a complete task
|
|
15
|
+
:rtype: PythonOperator
|
|
16
|
+
"""
|
|
17
|
+
return PythonOperator(
|
|
18
|
+
task_id=uid,
|
|
19
|
+
python_callable=mark_dag_run_as_success,
|
|
20
|
+
dag=dag,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def build_rejected(uid: str, dag: DAG) -> PythonOperator:
|
|
25
|
+
"""Reject the workflow
|
|
26
|
+
|
|
27
|
+
:param str uid: a unique identifier for the task
|
|
28
|
+
:param DAG dag: the DAG to add the task to
|
|
29
|
+
:return: a rejected task
|
|
30
|
+
:rtype: PythonOperator
|
|
31
|
+
"""
|
|
32
|
+
return PythonOperator(
|
|
33
|
+
task_id=uid,
|
|
34
|
+
python_callable=fail_dag_run,
|
|
35
|
+
dag=dag,
|
|
36
|
+
)
|
|
File without changes
|