thothctl 0.13.0__tar.gz → 0.13.2__tar.gz
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.
- {thothctl-0.13.0 → thothctl-0.13.2}/PKG-INFO +1 -1
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/scan/commands/iac.py +14 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/inventory/inventory_service.py +34 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/scan/scan_service.py +60 -39
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/scan/scanners/checkov.py +3 -3
- thothctl-0.13.2/src/thothctl/version.py +2 -0
- thothctl-0.13.2/tests/test_parallel_scan.py +193 -0
- thothctl-0.13.0/src/thothctl/version.py +0 -2
- {thothctl-0.13.0 → thothctl-0.13.2}/.devcontainer/Dockerfile +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/.devcontainer/README.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/.devcontainer/devcontainer.json +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/.github/workflows/python-publish.yml +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/.gitignore +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/.pre-commit-config.yaml +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/.readthedocs.yaml +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/AWS_PRICING_API_FINAL_REPORT.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/AWS_PRICING_API_IMPLEMENTATION_PLAN.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/AWS_PRICING_REFACTOR_REPORT.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/Dockerfile +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/LICENSE +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/README.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/TECHNICAL_DEBT_METRICS.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/catalog/catalog-info.yaml +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/dashboard/README.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/ai-review/README.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/check/blast-radius.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/check/check_environment.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/check/check_iac.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/check/check_overview.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/check/check_project_iac.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/check/check_space.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/check/cost-analysis-quick-reference.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/check/cost-analysis.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/check/deps-advanced.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/check/deps.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/check/drift-detection.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/check/plan.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/document/document_iac.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/document/document_overview.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/document/iac.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/document/use_cases.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/generate/generate_components.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/generate/generate_stacks.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/init/init.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/init/init_space.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/inventory/CHANGELOG.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/inventory/frameworks/terraform.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/inventory/frameworks/terragrunt.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/inventory/iac.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/inventory/inventory_iac.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/inventory/inventory_overview.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/list/list_overview.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/list/list_projects.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/list/list_spaces.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/mcp/mcp.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/project/iac.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/project/project_cleanup.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/project/project_convert.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/project/project_overview.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/project/project_upgrade.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/project/use_cases.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/remove/remove_overview.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/remove/remove_project.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/remove/remove_space.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/scan/iac.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/scan/scan_iac.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/scan/scan_overview.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/scan/use_cases.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/upgrade/upgrade_overview.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/concepts.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/cross_platform_support.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/framework_architecture.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/infrasctructure_composition.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/software_architecture.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/space_configuration.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/use_cases/README.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/use_cases/ai_dlc.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/use_cases/check_command.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/use_cases/devsecops_quickstart.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/use_cases/devsecops_sdlc.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/use_cases/inventory_command.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/use_cases/platform_engineering_templates.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/use_cases/space_management.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/use_cases/tasks/create_template.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/iac_devsecops_use_case.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/automate_tasks_command.png +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/commnad_init.png +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/create_component.gif +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/create_inventory.gif +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/doc_command.png +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/document_project_code.gif +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/framework/thothforge-framework.svg +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/framework/thothfr.png +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/iacpeerbot_summary.png +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/init_project.gif +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/inventory_command.png +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/notification_img.png +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/report_dependencies.png +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/report_dependencies_summary.png +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/restore_inventory_version.gif +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/reuse_project_pattern.gif +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/scan_code.gif +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/scan_command.png +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/sync_wk_command.png +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/transform_command.png +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/update_inventory_version.gif +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/validate_command.png +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/validate_environment.gif +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/img/validate_project.gif +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/includes/abbreviations.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/index.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/installation/windows_installation.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/javascripts/tablesort.js +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/mcp.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/navigation.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/quick_start.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/requirements.txt +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/stylesheets/extra-enhanced.css +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/stylesheets/extra.css +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/telemetry.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/template_engine/github_templates.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/template_engine/template_engine.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/troubleshooting/linux_troubleshooting.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/troubleshooting/macos_troubleshooting.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/troubleshooting/troubleshooting.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/docs/troubleshooting/windows_troubleshooting.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/mkdocs.yaml +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/pyproject.toml +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/scripts/run_mcp_server.sh +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/application/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/autocomplete.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/cli.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/ai_review/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/ai_review/cli.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/ai_review/commands/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/ai_review/commands/analyze.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/ai_review/commands/apply_fix.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/ai_review/commands/configure.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/ai_review/commands/configure_decisions.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/ai_review/commands/decide.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/ai_review/commands/history.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/ai_review/commands/improve.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/ai_review/commands/orchestrate.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/ai_review/commands/override.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/ai_review/commands/report.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/ai_review/commands/serve.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/check/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/check/cli.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/check/commands/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/check/commands/environment.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/check/commands/iac.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/check/commands/project/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/check/commands/project/iac.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/check/commands/project.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/dashboard/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/dashboard/cli.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/dashboard/commands/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/dashboard/commands/launch.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/document/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/document/cli.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/document/commands/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/document/commands/iac.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/generate/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/generate/cli.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/generate/commands/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/generate/commands/component.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/generate/commands/stacks.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/init/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/init/cli.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/init/commands/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/init/commands/env.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/init/commands/project.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/init/commands/space.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/inventory/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/inventory/cli.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/inventory/commands/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/inventory/commands/check.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/inventory/commands/iac.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/list/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/list/cli.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/list/commands/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/list/commands/projects.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/list/commands/spaces.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/mcp/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/mcp/cli.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/mcp/commands/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/mcp/commands/register.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/mcp/commands/server.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/mcp/commands/status.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/mcp/commands/stop.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/project/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/project/cli.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/project/commands/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/project/commands/bootstrap.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/project/commands/cleanup.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/project/commands/convert.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/project/commands/upgrade.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/remove/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/remove/cli.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/remove/project.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/remove/space.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/scan/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/scan/cli.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/scan/commands/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/commands/upgrade/cli.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/common/.thothcf.setup.toml +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/common/.thothcf_home.toml +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/common/.thothcf_module.toml +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/common/.thothcf_project.toml +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/common/.thothcf_template_parameters.toml +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/common/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/common/common.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/common/terragrunt/.thothcf_project.toml +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/config/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/config/constants.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/config/default_values.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/config/defaults.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/config/models.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/config/settings.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/config/template_config.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/config/template_configs.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/config/templates.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/config/validation.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/core/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/core/cli_ui.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/core/commands.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/core/config.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/core/integrations/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/core/integrations/azure_devops/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/core/integrations/azure_devops/get_azure_devops.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/core/integrations/azure_devops/pull_request_comments.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/core/integrations/github/get_github.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/core/integrations/github/pull_request_comments.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/core/integrations/integrate_messages_services/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/core/integrations/integrate_messages_services/microsoft_teams.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/core/integrations/integrate_messages_services/sent_message_teams.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/core/integrations/pattern_names.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/core/integrations/pr_comments/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/core/integrations/pr_comments/pr_comment_publisher.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/core/logger.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/core/telemetry.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/core/version_tools.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/domain/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/domain/interfaces/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/domain/models/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/mcp/README.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/mcp/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/mcp/server.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/ai_agent.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/analyzers/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/analyzers/code_reviewer.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/analyzers/context_builder.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/analyzers/report_analyzer.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/analyzers/risk_assessor.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/bedrock_agent_api.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/config/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/config/ai_settings.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/config/decision_rules.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/decision_engine.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/memory.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/orchestrator.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/pr_decision_publisher.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/providers/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/providers/azure_provider.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/providers/bedrock_agent_provider.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/providers/bedrock_provider.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/providers/ollama_provider.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/providers/openai_provider.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/safety/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/safety/safety_guard.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/utils/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/utils/cost_tracker.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/utils/fix_patterns.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/utils/fix_prompts.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/utils/formatters.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/ai_review/utils/prompts.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/environment/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/environment/check_environment.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/blast_radius_service.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/check_origin_version.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/check_project_structure.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/cost_analyzer.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/models/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/models/cloudformation_mapper.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/models/cost_models.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/aws_pricing_client.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/base_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/providers/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/providers/apigateway_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/providers/bedrock_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/providers/cloudwatch_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/providers/dynamodb_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/providers/ebs_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/providers/ec2_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/providers/ecs_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/providers/eip_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/providers/eks_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/providers/elb_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/providers/free_resources_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/providers/kms_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/providers/lambda_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/providers/msk_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/providers/rds_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/providers/s3_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/providers/secrets_manager_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/pricing/providers/vpc_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/cost/unified_cost_report.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/drift/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/drift/drift_ai.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/drift/drift_history.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/drift/drift_policy.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/drift/drift_report.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/drift/drift_service.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/drift/models.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/risk_assessment.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/check/project/validate_project_structure.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/dashboard/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/dashboard/dashboard_service.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/dashboard/data_loader.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/document/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/document/create_documentation.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/document/files_content.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/document/files_scan.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/document/iac_documentation.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/document/iac_grunt_graph.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/document/iac_grunt_info.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/generate/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/generate/create_stacks/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/generate/create_stacks/config_generator.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/generate/create_stacks/remote_config_generation.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/generate/create_stacks/stack_service.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/generate/create_stacks/templates/terragrunt.hcl.j2 +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/generate/create_template/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/generate/create_template/config.yaml +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/generate/create_template/create_code.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/generate/create_template/create_component.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/generate/create_template/create_component_service.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/generate/create_template/create_stacks.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/generate/create_template/create_template.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/generate/create_template/files_content.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/generate/create_template/github_template_loader.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/generate/create_template/project_templates.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/init/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/init/environment/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/init/environment/install_tools.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/init/project/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/init/project/project.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/init/space/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/init/space/example_space.toml +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/init/space/local_registry.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/init/space/space.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/init/space/space_config.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/init/space/space_service.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/inventory/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/inventory/changelog_parser.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/inventory/models.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/inventory/module_compatibility_service.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/inventory/report_service.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/inventory/schema_compatibility_service.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/inventory/terragrunt_parser.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/inventory/update_versions.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/inventory/version_service.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/mcp/README.md +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/mcp/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/mcp/amazon_q_server.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/mcp/example.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/mcp/service.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/mcp/simple_http_server.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/project/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/project/bootstrap/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/project/bootstrap/bootstrap_service.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/project/cleanup/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/project/cleanup/clean_project.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/project/cleanup/clean_space.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/project/convert/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/project/convert/conversion_service.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/project/convert/get_project_data.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/project/convert/post_init.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/project/convert/project_converter.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/project/convert/project_defaults.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/project/convert/set_project_parameters.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/project/create_terramate/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/project/create_terramate/create_terramate_stacks.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/project/create_terramate/detect_changes_stacks.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/project/create_terramate/manage_terramate_stacks.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/project/upgrade/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/project/upgrade/upgrade_service.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/scan/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/scan/compliance_review.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/scan/import_reports.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/scan/scanners/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/scan/scanners/kics.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/scan/scanners/opa.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/scan/scanners/scan_reports.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/scan/scanners/scanners.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/scan/scanners/terraform_compliance.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/scan/scanners/tfsec.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/services/scan/scanners/trivy.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/templates/reports/inventory_report.html +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/templates/reports/inventory_report.js +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/templates/unified_report_styles.css +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/banner.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/common/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/common/create_compliance_html_reports.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/common/create_html_reports.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/common/delete_directory.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/common/fix_report_styling.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/common/report_html_utils.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/common/templates/dashboard.html +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/common/templates/index_report.html +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/common/templates/individual_report.html +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/common/templates/simple_report.html +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/common/templates/unified_report_styles.css +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/common/templates/unified_simple_report.html +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/common/templates/xunit_report.html +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/crypto.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/manage_backend_resources/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/manage_backend_resources/manage_backend_resources.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/modules_ops/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/modules_ops/terraform_module_details.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/modules_ops/terraform_modules_fetcher.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/platform_utils.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/process_hcl/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/process_hcl/analyze_terraform_plan.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/process_hcl/graph_manager.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/process_hcl/graph_terragrunt_dependencies.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/process_hcl/process_terraform_file.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/process_hcl/risk_analyzing_terraform_plan.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/sync_workspaces/__init__.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/sync_workspaces/sync_terraform_workspaces.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/sync_workspaces/sync_terragrunt_workspaces.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/template_loader.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/utils/thoth_colors.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/src/thothctl/wellcome_banner.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/conftest.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_aws_pricing_client.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_azure_devops_pr_comments.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_bedrock_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_cost_analyzer.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_cost_models.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_cost_pr_comments.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_dashboard_loading_fix.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_dashboard_service.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_drift.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_drift_detection.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_ec2_pricing.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_github_pr_comments.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_iac_cost_integration.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_inventory_pr_comments.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_kics_scanner.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_mermaid_edge_labels.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_new_cost_providers.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_platform_utils.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_pr_comment_publisher.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_scan_pr_comments.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_space_command.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_space_config.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tests/test_terragrunt_parser.py +0 -0
- {thothctl-0.13.0 → thothctl-0.13.2}/tox.ini +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: thothctl
|
|
3
|
-
Version: 0.13.
|
|
3
|
+
Version: 0.13.2
|
|
4
4
|
Summary: A CLI for Developer Control Plane. Accelerate your cloud IaC deployments.
|
|
5
5
|
Project-URL: Homepage, https://github.com/thothforge/thothctl
|
|
6
6
|
Author-email: Alejandro Velez <velez94@pm.me>
|
|
@@ -88,6 +88,8 @@ class RestoredIaCScanCommand(ClickCommand):
|
|
|
88
88
|
options=self._parse_options(options) if options else {},
|
|
89
89
|
tftool=tftool,
|
|
90
90
|
html_reports_format=html_reports_format,
|
|
91
|
+
max_workers=max_workers,
|
|
92
|
+
compact=compact,
|
|
91
93
|
)
|
|
92
94
|
|
|
93
95
|
# Enhanced data extraction and validation
|
|
@@ -640,4 +642,16 @@ cli = RestoredIaCScanCommand.as_click_command(
|
|
|
640
642
|
default="soft",
|
|
641
643
|
help="Enforcement mode: 'soft' reports violations (exit 0), 'hard' fails the pipeline (exit 1) when any tool finds violations",
|
|
642
644
|
),
|
|
645
|
+
click.option(
|
|
646
|
+
"--max-workers",
|
|
647
|
+
type=int,
|
|
648
|
+
default=2,
|
|
649
|
+
help="Max parallel checkov scans (default: 2, reduce to 1 on low-memory agents)",
|
|
650
|
+
),
|
|
651
|
+
click.option(
|
|
652
|
+
"--compact",
|
|
653
|
+
is_flag=True,
|
|
654
|
+
default=False,
|
|
655
|
+
help="Use checkov --compact mode to reduce memory usage on constrained CI agents",
|
|
656
|
+
),
|
|
643
657
|
)
|
|
@@ -663,6 +663,15 @@ class InventoryService:
|
|
|
663
663
|
logger.warning(f"Stack path does not exist or is not a directory: {stack_path}")
|
|
664
664
|
return providers
|
|
665
665
|
|
|
666
|
+
# Pre-check: skip if stack has module references but hasn't been initialized
|
|
667
|
+
if self._has_uninitialized_modules(abs_stack_path):
|
|
668
|
+
logger.warning(
|
|
669
|
+
f"Skipping provider check for {stack_path}: "
|
|
670
|
+
"module references found but modules not initialized. "
|
|
671
|
+
"Run 'tofu init' or 'terraform init' to install modules first."
|
|
672
|
+
)
|
|
673
|
+
return providers
|
|
674
|
+
|
|
666
675
|
# Determine the command to use based on project type
|
|
667
676
|
# Check if this specific stack has a terragrunt.hcl (not just the global project flag)
|
|
668
677
|
stack_has_terragrunt = (abs_stack_path / "terragrunt.hcl").exists()
|
|
@@ -795,6 +804,31 @@ class InventoryService:
|
|
|
795
804
|
# Fallback: assume hashicorp
|
|
796
805
|
return ('hashicorp', source)
|
|
797
806
|
|
|
807
|
+
def _has_uninitialized_modules(self, stack_path: Path) -> bool:
|
|
808
|
+
"""Check if a stack references external modules but hasn't been initialized."""
|
|
809
|
+
# Terragrunt manages its own init, skip this check
|
|
810
|
+
if (stack_path / "terragrunt.hcl").exists():
|
|
811
|
+
return False
|
|
812
|
+
|
|
813
|
+
# Look for module blocks in .tf files
|
|
814
|
+
has_module_refs = False
|
|
815
|
+
for tf_file in stack_path.glob("*.tf"):
|
|
816
|
+
try:
|
|
817
|
+
with open(tf_file, "r") as f:
|
|
818
|
+
content = f.read()
|
|
819
|
+
# Quick check for module blocks with non-local sources
|
|
820
|
+
if re.search(r'\bmodule\s+"[^"]+"\s*\{', content):
|
|
821
|
+
has_module_refs = True
|
|
822
|
+
break
|
|
823
|
+
except (IOError, UnicodeDecodeError):
|
|
824
|
+
continue
|
|
825
|
+
|
|
826
|
+
if not has_module_refs:
|
|
827
|
+
return False
|
|
828
|
+
|
|
829
|
+
# Modules referenced but .terraform/modules not present = not initialized
|
|
830
|
+
return not (stack_path / ".terraform" / "modules").exists()
|
|
831
|
+
|
|
798
832
|
def _parse_providers_output(self, output: str, stack_path: str = "") -> List[Provider]:
|
|
799
833
|
"""
|
|
800
834
|
Parse the output of terraform/tofu providers command.
|
|
@@ -58,6 +58,8 @@ class ScanService:
|
|
|
58
58
|
options: Dict[str, Dict],
|
|
59
59
|
tftool: str = "tofu",
|
|
60
60
|
html_reports_format: Literal["simple", "xunit"] = "simple",
|
|
61
|
+
max_workers: int = 2,
|
|
62
|
+
compact: bool = False,
|
|
61
63
|
) -> Dict[str, Dict]:
|
|
62
64
|
"""Execute selected security scans."""
|
|
63
65
|
try:
|
|
@@ -110,6 +112,8 @@ class ScanService:
|
|
|
110
112
|
reports_dir=reports_dir,
|
|
111
113
|
options=options.get("checkov", {}),
|
|
112
114
|
tftool=tftool,
|
|
115
|
+
max_workers=max_workers,
|
|
116
|
+
compact=compact,
|
|
113
117
|
)
|
|
114
118
|
|
|
115
119
|
# Process the directory to generate reports
|
|
@@ -607,59 +611,76 @@ class ScanService:
|
|
|
607
611
|
return results
|
|
608
612
|
|
|
609
613
|
def _recursive_terraform_scan(
|
|
610
|
-
self, directory: str, reports_dir: str, options: Dict, tftool: str
|
|
614
|
+
self, directory: str, reports_dir: str, options: Dict, tftool: str,
|
|
615
|
+
max_workers: int = 2, compact: bool = False,
|
|
611
616
|
) -> Dict[str, Dict]:
|
|
612
617
|
"""
|
|
613
618
|
Recursively scan directories for Terraform files and run Checkov.
|
|
619
|
+
|
|
620
|
+
Optimized for memory-constrained CI agents (4 CPU / 8 GB):
|
|
621
|
+
- Parallel execution with controlled concurrency (max_workers)
|
|
622
|
+
- GC runs after each completed scan to free memory
|
|
623
|
+
- compact flag reduces checkov output memory usage
|
|
614
624
|
"""
|
|
625
|
+
import gc
|
|
626
|
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
627
|
+
|
|
615
628
|
results = {}
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
raise ValueError("Checkov scanner not available")
|
|
629
|
+
scanner = self.available_scanners.get("checkov")
|
|
630
|
+
if not scanner:
|
|
631
|
+
raise ValueError("Checkov scanner not available")
|
|
620
632
|
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
Path(directory) / "tfplan.json"
|
|
624
|
-
).exists():
|
|
625
|
-
print(f"{Fore.MAGENTA} \n 🔎 {directory}")
|
|
626
|
-
self.logger.debug(f"Found terraform files in {directory}")
|
|
633
|
+
# Collect all scannable stack directories
|
|
634
|
+
stacks = self._find_terraform_stacks(directory)
|
|
627
635
|
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
reports_dir=str(reports_dir),
|
|
632
|
-
options=options,
|
|
633
|
-
tftool=tftool,
|
|
634
|
-
)
|
|
635
|
-
results[directory] = result
|
|
636
|
-
except Exception as e:
|
|
637
|
-
self.logger.error(f"Error scanning {directory}: {e}")
|
|
638
|
-
results[directory] = {"status": "FAIL", "error": str(e)}
|
|
639
|
-
|
|
640
|
-
# Recursively scan subdirectories
|
|
641
|
-
subdirs = [
|
|
642
|
-
d
|
|
643
|
-
for d in Path(directory).iterdir()
|
|
644
|
-
if d.is_dir() and not d.name.startswith(".")
|
|
645
|
-
]
|
|
636
|
+
if not stacks:
|
|
637
|
+
self.logger.info(f"No terraform stacks found in {directory}")
|
|
638
|
+
return results
|
|
646
639
|
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
640
|
+
self.logger.info(f"Found {len(stacks)} terraform stacks to scan (workers={max_workers})")
|
|
641
|
+
print(f"{Fore.MAGENTA}\n \U0001f50e Found {len(stacks)} stacks to scan (parallel={max_workers})")
|
|
642
|
+
|
|
643
|
+
scan_options = dict(options)
|
|
644
|
+
if compact:
|
|
645
|
+
scan_options["compact"] = True
|
|
646
|
+
|
|
647
|
+
def _scan_stack(stack_dir: str) -> Tuple[str, Dict]:
|
|
648
|
+
print(f"{Fore.MAGENTA} \n \U0001f50e {stack_dir}")
|
|
649
|
+
try:
|
|
650
|
+
result = scanner.execute_scan(
|
|
651
|
+
directory=str(stack_dir),
|
|
652
|
+
reports_dir=str(reports_dir),
|
|
653
|
+
options=scan_options,
|
|
652
654
|
tftool=tftool,
|
|
653
655
|
)
|
|
654
|
-
|
|
656
|
+
return (stack_dir, result)
|
|
657
|
+
except Exception as e:
|
|
658
|
+
self.logger.error(f"Error scanning {stack_dir}: {e}")
|
|
659
|
+
return (stack_dir, {"status": "FAIL", "error": str(e)})
|
|
655
660
|
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
661
|
+
with ThreadPoolExecutor(max_workers=max_workers) as executor:
|
|
662
|
+
futures = {executor.submit(_scan_stack, s): s for s in stacks}
|
|
663
|
+
for future in as_completed(futures):
|
|
664
|
+
stack_dir, result = future.result()
|
|
665
|
+
results[stack_dir] = result
|
|
666
|
+
gc.collect()
|
|
659
667
|
|
|
660
668
|
return results
|
|
661
669
|
|
|
662
|
-
|
|
670
|
+
def _find_terraform_stacks(self, directory: str) -> List[str]:
|
|
671
|
+
"""Find all directories containing main.tf or tfplan.json."""
|
|
672
|
+
stacks = []
|
|
673
|
+
root = Path(directory)
|
|
674
|
+
if (root / "main.tf").exists() or (root / "tfplan.json").exists():
|
|
675
|
+
stacks.append(str(root))
|
|
676
|
+
for d in sorted(root.rglob("*")):
|
|
677
|
+
if not d.is_dir():
|
|
678
|
+
continue
|
|
679
|
+
if any(part.startswith(".") for part in d.relative_to(root).parts):
|
|
680
|
+
continue
|
|
681
|
+
if (d / "main.tf").exists() or (d / "tfplan.json").exists():
|
|
682
|
+
stacks.append(str(d))
|
|
683
|
+
return stacks
|
|
663
684
|
def recursive_scan(
|
|
664
685
|
directory: str,
|
|
665
686
|
tool: str,
|
|
@@ -262,11 +262,11 @@ class CheckovScanner(ScannerPort):
|
|
|
262
262
|
Returns:
|
|
263
263
|
List of command components
|
|
264
264
|
"""
|
|
265
|
-
|
|
266
|
-
cmd = ["checkov"] # No timeout
|
|
265
|
+
cmd = ["checkov"]
|
|
267
266
|
|
|
268
267
|
if options:
|
|
269
|
-
|
|
268
|
+
if options.get("compact"):
|
|
269
|
+
cmd.append("--compact")
|
|
270
270
|
if "additional_args" in options:
|
|
271
271
|
if isinstance(options["additional_args"], list):
|
|
272
272
|
cmd.extend(options["additional_args"])
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"""Unit tests for parallel checkov scan and memory optimization."""
|
|
2
|
+
|
|
3
|
+
import gc
|
|
4
|
+
import tempfile
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
from unittest.mock import Mock, patch, MagicMock
|
|
7
|
+
|
|
8
|
+
import pytest
|
|
9
|
+
|
|
10
|
+
from thothctl.services.scan.scan_service import ScanService
|
|
11
|
+
from thothctl.services.scan.scanners.checkov import CheckovScanner
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class TestFindTerraformStacks:
|
|
15
|
+
"""Test _find_terraform_stacks discovery."""
|
|
16
|
+
|
|
17
|
+
def test_finds_root_stack(self, tmp_path):
|
|
18
|
+
svc = ScanService()
|
|
19
|
+
(tmp_path / "main.tf").write_text("")
|
|
20
|
+
stacks = svc._find_terraform_stacks(str(tmp_path))
|
|
21
|
+
assert str(tmp_path) in stacks
|
|
22
|
+
|
|
23
|
+
def test_finds_nested_stacks(self, tmp_path):
|
|
24
|
+
for name in ["stack-a", "stack-b", "modules/vpc"]:
|
|
25
|
+
d = tmp_path / name
|
|
26
|
+
d.mkdir(parents=True)
|
|
27
|
+
(d / "main.tf").write_text("")
|
|
28
|
+
stacks = svc = ScanService()
|
|
29
|
+
stacks = svc._find_terraform_stacks(str(tmp_path))
|
|
30
|
+
assert len(stacks) == 3
|
|
31
|
+
|
|
32
|
+
def test_finds_tfplan_json_stacks(self, tmp_path):
|
|
33
|
+
d = tmp_path / "plan-stack"
|
|
34
|
+
d.mkdir()
|
|
35
|
+
(d / "tfplan.json").write_text("{}")
|
|
36
|
+
svc = ScanService()
|
|
37
|
+
stacks = svc._find_terraform_stacks(str(tmp_path))
|
|
38
|
+
assert len(stacks) == 1
|
|
39
|
+
assert "plan-stack" in stacks[0]
|
|
40
|
+
|
|
41
|
+
def test_skips_hidden_dirs(self, tmp_path):
|
|
42
|
+
hidden = tmp_path / ".terraform" / "modules" / "inner"
|
|
43
|
+
hidden.mkdir(parents=True)
|
|
44
|
+
(hidden / "main.tf").write_text("")
|
|
45
|
+
(tmp_path / "main.tf").write_text("")
|
|
46
|
+
svc = ScanService()
|
|
47
|
+
stacks = svc._find_terraform_stacks(str(tmp_path))
|
|
48
|
+
assert len(stacks) == 1
|
|
49
|
+
|
|
50
|
+
def test_empty_dir_returns_empty(self, tmp_path):
|
|
51
|
+
svc = ScanService()
|
|
52
|
+
assert svc._find_terraform_stacks(str(tmp_path)) == []
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class TestRecursiveTerraformScanParallel:
|
|
56
|
+
"""Test _recursive_terraform_scan with parallel execution."""
|
|
57
|
+
|
|
58
|
+
def _make_stacks(self, tmp_path, count):
|
|
59
|
+
for i in range(count):
|
|
60
|
+
d = tmp_path / f"stack-{i}"
|
|
61
|
+
d.mkdir()
|
|
62
|
+
(d / "main.tf").write_text(f'resource "null_resource" "r{i}" {{}}')
|
|
63
|
+
return tmp_path
|
|
64
|
+
|
|
65
|
+
@patch.object(ScanService, '_find_terraform_stacks')
|
|
66
|
+
def test_parallel_scans_all_stacks(self, mock_find):
|
|
67
|
+
"""All discovered stacks are scanned and results collected."""
|
|
68
|
+
stacks = ["/a/stack-0", "/a/stack-1", "/a/stack-2"]
|
|
69
|
+
mock_find.return_value = stacks
|
|
70
|
+
|
|
71
|
+
svc = ScanService()
|
|
72
|
+
mock_scanner = Mock()
|
|
73
|
+
mock_scanner.execute_scan.return_value = {"status": "COMPLETE"}
|
|
74
|
+
svc.available_scanners["checkov"] = Mock()
|
|
75
|
+
svc.available_scanners["checkov"].execute_scan = mock_scanner.execute_scan
|
|
76
|
+
|
|
77
|
+
results = svc._recursive_terraform_scan(
|
|
78
|
+
directory="/a", reports_dir="/r", options={}, tftool="tofu",
|
|
79
|
+
max_workers=2,
|
|
80
|
+
)
|
|
81
|
+
|
|
82
|
+
assert len(results) == 3
|
|
83
|
+
assert mock_scanner.execute_scan.call_count == 3
|
|
84
|
+
for s in stacks:
|
|
85
|
+
assert s in results
|
|
86
|
+
assert results[s]["status"] == "COMPLETE"
|
|
87
|
+
|
|
88
|
+
@patch.object(ScanService, '_find_terraform_stacks')
|
|
89
|
+
def test_single_worker_sequential(self, mock_find):
|
|
90
|
+
"""max_workers=1 still scans all stacks (sequential fallback)."""
|
|
91
|
+
mock_find.return_value = ["/a/s1", "/a/s2"]
|
|
92
|
+
|
|
93
|
+
svc = ScanService()
|
|
94
|
+
mock_scanner = Mock()
|
|
95
|
+
mock_scanner.execute_scan.return_value = {"status": "COMPLETE"}
|
|
96
|
+
svc.available_scanners["checkov"] = Mock()
|
|
97
|
+
svc.available_scanners["checkov"].execute_scan = mock_scanner.execute_scan
|
|
98
|
+
|
|
99
|
+
results = svc._recursive_terraform_scan(
|
|
100
|
+
directory="/a", reports_dir="/r", options={}, tftool="tofu",
|
|
101
|
+
max_workers=1,
|
|
102
|
+
)
|
|
103
|
+
assert len(results) == 2
|
|
104
|
+
|
|
105
|
+
@patch.object(ScanService, '_find_terraform_stacks')
|
|
106
|
+
def test_failed_stack_does_not_block_others(self, mock_find):
|
|
107
|
+
"""A failing stack returns FAIL but other stacks still complete."""
|
|
108
|
+
mock_find.return_value = ["/a/good", "/a/bad"]
|
|
109
|
+
|
|
110
|
+
svc = ScanService()
|
|
111
|
+
mock_scanner = Mock()
|
|
112
|
+
|
|
113
|
+
def side_effect(directory, **kw):
|
|
114
|
+
if "bad" in directory:
|
|
115
|
+
raise RuntimeError("boom")
|
|
116
|
+
return {"status": "COMPLETE"}
|
|
117
|
+
|
|
118
|
+
mock_scanner.execute_scan.side_effect = side_effect
|
|
119
|
+
svc.available_scanners["checkov"] = Mock()
|
|
120
|
+
svc.available_scanners["checkov"].execute_scan = mock_scanner.execute_scan
|
|
121
|
+
|
|
122
|
+
results = svc._recursive_terraform_scan(
|
|
123
|
+
directory="/a", reports_dir="/r", options={}, tftool="tofu",
|
|
124
|
+
)
|
|
125
|
+
assert results["/a/good"]["status"] == "COMPLETE"
|
|
126
|
+
assert results["/a/bad"]["status"] == "FAIL"
|
|
127
|
+
assert "boom" in results["/a/bad"]["error"]
|
|
128
|
+
|
|
129
|
+
@patch.object(ScanService, '_find_terraform_stacks')
|
|
130
|
+
def test_no_stacks_returns_empty(self, mock_find):
|
|
131
|
+
mock_find.return_value = []
|
|
132
|
+
svc = ScanService()
|
|
133
|
+
results = svc._recursive_terraform_scan(
|
|
134
|
+
directory="/a", reports_dir="/r", options={}, tftool="tofu",
|
|
135
|
+
)
|
|
136
|
+
assert results == {}
|
|
137
|
+
|
|
138
|
+
@patch.object(ScanService, '_find_terraform_stacks')
|
|
139
|
+
def test_compact_flag_passed_to_scanner(self, mock_find):
|
|
140
|
+
"""compact=True adds compact key to options passed to scanner."""
|
|
141
|
+
mock_find.return_value = ["/a/s1"]
|
|
142
|
+
|
|
143
|
+
svc = ScanService()
|
|
144
|
+
mock_scanner = Mock()
|
|
145
|
+
mock_scanner.execute_scan.return_value = {"status": "COMPLETE"}
|
|
146
|
+
svc.available_scanners["checkov"] = Mock()
|
|
147
|
+
svc.available_scanners["checkov"].execute_scan = mock_scanner.execute_scan
|
|
148
|
+
|
|
149
|
+
svc._recursive_terraform_scan(
|
|
150
|
+
directory="/a", reports_dir="/r", options={}, tftool="tofu",
|
|
151
|
+
compact=True,
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
call_opts = mock_scanner.execute_scan.call_args
|
|
155
|
+
assert call_opts.kwargs.get("options", {}).get("compact") is True or \
|
|
156
|
+
call_opts[1].get("options", {}).get("compact") is True
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
class TestCheckovBuildCommand:
|
|
160
|
+
"""Test checkov _build_command handles compact flag."""
|
|
161
|
+
|
|
162
|
+
def test_compact_adds_flag(self):
|
|
163
|
+
scanner = CheckovScanner()
|
|
164
|
+
cmd = scanner._build_command("/dir", {"compact": True})
|
|
165
|
+
assert "--compact" in cmd
|
|
166
|
+
|
|
167
|
+
def test_no_compact_by_default(self):
|
|
168
|
+
scanner = CheckovScanner()
|
|
169
|
+
cmd = scanner._build_command("/dir", {})
|
|
170
|
+
assert "--compact" not in cmd
|
|
171
|
+
|
|
172
|
+
def test_compact_false_no_flag(self):
|
|
173
|
+
scanner = CheckovScanner()
|
|
174
|
+
cmd = scanner._build_command("/dir", {"compact": False})
|
|
175
|
+
assert "--compact" not in cmd
|
|
176
|
+
|
|
177
|
+
def test_additional_args_string(self):
|
|
178
|
+
scanner = CheckovScanner()
|
|
179
|
+
cmd = scanner._build_command("/dir", {"additional_args": "--skip-check CKV_AWS_1"})
|
|
180
|
+
assert "--skip-check" in cmd
|
|
181
|
+
assert "CKV_AWS_1" in cmd
|
|
182
|
+
|
|
183
|
+
def test_additional_args_list(self):
|
|
184
|
+
scanner = CheckovScanner()
|
|
185
|
+
cmd = scanner._build_command("/dir", {"additional_args": ["--framework", "terraform"]})
|
|
186
|
+
assert "--framework" in cmd
|
|
187
|
+
assert "terraform" in cmd
|
|
188
|
+
|
|
189
|
+
def test_compact_with_additional_args(self):
|
|
190
|
+
scanner = CheckovScanner()
|
|
191
|
+
cmd = scanner._build_command("/dir", {"compact": True, "additional_args": "--quiet"})
|
|
192
|
+
assert "--compact" in cmd
|
|
193
|
+
assert "--quiet" in cmd
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/check/cost-analysis-quick-reference.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/inventory/frameworks/terraform.md
RENAMED
|
File without changes
|
{thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/commands/inventory/frameworks/terragrunt.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{thothctl-0.13.0 → thothctl-0.13.2}/docs/framework/use_cases/platform_engineering_templates.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|