chore(sdk): migrate from poetry to uv (#11162)

This commit is contained in:
Adrián Peña
2026-05-14 12:51:57 +02:00
committed by GitHub
parent 5f92989492
commit 7d3ed62e90
43 changed files with 4878 additions and 7288 deletions
+5 -6
View File
@@ -2,20 +2,19 @@
# Runs automatically on `wt switch --create`. # Runs automatically on `wt switch --create`.
# Block 1: setup + copy gitignored env files (.envrc, ui/.env.local) # Block 1: setup + copy gitignored env files (.envrc, ui/.env.local)
# from the primary worktree patterns selected via .worktreeinclude. # from the primary worktree - patterns selected via .worktreeinclude.
[[pre-start]] [[pre-start]]
skills = "./skills/setup.sh --claude" skills = "./skills/setup.sh --claude"
python = "poetry env use python3.12"
envs = "wt step copy-ignored" envs = "wt step copy-ignored"
# Block 2: install Python deps (requires `poetry env use` from block 1). # Block 2: install Python deps (uv manages the venv on `uv sync`).
[[pre-start]] [[pre-start]]
deps = "poetry install --with dev" deps = "uv sync"
# Block 3: reminder last visible output before `wt switch` returns. # Block 3: reminder - last visible output before `wt switch` returns.
# Hooks can't mutate the parent shell, so venv activation is manual. # Hooks can't mutate the parent shell, so venv activation is manual.
[[pre-start]] [[pre-start]]
reminder = "echo '>> Reminder: activate the venv in this shell with: eval $(poetry env activate)'" reminder = "echo '>> Reminder: activate the venv in this shell with: source .venv/bin/activate'"
# Background: pnpm install runs while you start working. # Background: pnpm install runs while you start working.
# Tail logs via `wt config state logs`. # Tail logs via `wt config state logs`.
@@ -1,100 +0,0 @@
name: 'Setup Python with Poetry'
description: 'Setup Python environment with Poetry and install dependencies'
author: 'Prowler'
inputs:
python-version:
description: 'Python version to use'
required: true
working-directory:
description: 'Working directory for Poetry'
required: false
default: '.'
poetry-version:
description: 'Poetry version to install'
required: false
default: '2.3.4'
install-dependencies:
description: 'Install Python dependencies with Poetry'
required: false
default: 'true'
update-lock:
description: 'Run `poetry lock` during setup. Only enable when a prior step mutates pyproject.toml (e.g. API `@master` VCS rewrite). Default: false.'
required: false
default: 'false'
enable-cache:
description: 'Whether to enable Poetry dependency caching via actions/setup-python'
required: false
default: 'true'
runs:
using: 'composite'
steps:
- name: Replace @master with current branch in pyproject.toml (prowler repo only)
if: github.event_name == 'pull_request' && github.base_ref == 'master' && github.repository == 'prowler-cloud/prowler'
shell: bash
working-directory: ${{ inputs.working-directory }}
env:
HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }}
run: |
BRANCH_NAME="${GITHUB_HEAD_REF:-${GITHUB_REF_NAME}}"
UPSTREAM="prowler-cloud/prowler"
if [ "$HEAD_REPO" != "$UPSTREAM" ]; then
echo "Fork PR detected (${HEAD_REPO}), rewriting VCS URL to fork"
sed -i "s|git+https://github.com/prowler-cloud/prowler\([^@]*\)@master|git+https://github.com/${HEAD_REPO}\1@$BRANCH_NAME|g" pyproject.toml
else
echo "Same-repo PR, using branch: $BRANCH_NAME"
sed -i "s|\(git+https://github.com/prowler-cloud/prowler[^@]*\)@master|\1@$BRANCH_NAME|g" pyproject.toml
fi
- name: Install poetry
shell: bash
run: |
python -m pip install --upgrade pip
pipx install poetry==${INPUTS_POETRY_VERSION}
env:
INPUTS_POETRY_VERSION: ${{ inputs.poetry-version }}
- name: Update poetry.lock with latest Prowler commit
if: github.repository_owner == 'prowler-cloud' && github.repository != 'prowler-cloud/prowler'
shell: bash
working-directory: ${{ inputs.working-directory }}
run: |
LATEST_COMMIT=$(curl -s "https://api.github.com/repos/prowler-cloud/prowler/commits/master" | jq -r '.sha')
echo "Latest commit hash: $LATEST_COMMIT"
sed -i '/url = "https:\/\/github\.com\/prowler-cloud\/prowler\.git"/,/resolved_reference = / {
s/resolved_reference = "[a-f0-9]\{40\}"/resolved_reference = "'"$LATEST_COMMIT"'"/
}' poetry.lock
echo "Updated resolved_reference:"
grep -A2 -B2 "resolved_reference" poetry.lock
- name: Update poetry.lock (prowler repo only)
if: github.repository == 'prowler-cloud/prowler' && inputs.update-lock == 'true'
shell: bash
working-directory: ${{ inputs.working-directory }}
run: poetry lock
- name: Set up Python ${{ inputs.python-version }}
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
with:
python-version: ${{ inputs.python-version }}
# Disable cache when callers skip dependency install: Poetry 2.3.4 creates
# the venv in a path setup-python can't hash, breaking the post-step save-cache.
cache: ${{ inputs.enable-cache == 'true' && 'poetry' || '' }}
cache-dependency-path: ${{ inputs.enable-cache == 'true' && format('{0}/poetry.lock', inputs.working-directory) || '' }}
- name: Install Python dependencies
if: inputs.install-dependencies == 'true'
shell: bash
working-directory: ${{ inputs.working-directory }}
run: |
poetry install --no-root
poetry run pip list
- name: Update Prowler Cloud API Client
if: github.repository_owner == 'prowler-cloud' && github.repository != 'prowler-cloud/prowler'
shell: bash
working-directory: ${{ inputs.working-directory }}
run: |
poetry remove prowler-cloud-api-client
poetry add ./prowler-cloud-api-client
+1 -1
View File
@@ -49,7 +49,7 @@ Please add a detailed description of how to review this PR.
- [ ] Performance test results (if applicable) - [ ] Performance test results (if applicable)
- [ ] Any other relevant evidence of the implementation (if applicable) - [ ] Any other relevant evidence of the implementation (if applicable)
- [ ] Verify if API specs need to be regenerated. - [ ] Verify if API specs need to be regenerated.
- [ ] Check if version updates are required (e.g., specs, Poetry, etc.). - [ ] Check if version updates are required (e.g., specs, uv, etc.).
- [ ] Ensure new entries are added to [CHANGELOG.md](https://github.com/prowler-cloud/prowler/blob/master/api/CHANGELOG.md), if applicable. - [ ] Ensure new entries are added to [CHANGELOG.md](https://github.com/prowler-cloud/prowler/blob/master/api/CHANGELOG.md), if applicable.
### License ### License
+3 -3
View File
@@ -59,7 +59,7 @@ jobs:
ui/** ui/**
prowler/** prowler/**
mcp_server/** mcp_server/**
poetry.lock uv.lock
pyproject.toml pyproject.toml
- name: Check for folder changes and changelog presence - name: Check for folder changes and changelog presence
@@ -84,9 +84,9 @@ jobs:
fi fi
done done
# Check root-level dependency files (poetry.lock, pyproject.toml) # Check root-level dependency files (uv.lock, pyproject.toml)
# These are associated with the prowler folder changelog # These are associated with the prowler folder changelog
root_deps_changed=$(echo "${STEPS_CHANGED_FILES_OUTPUTS_ALL_CHANGED_FILES}" | tr ' ' '\n' | grep -E "^(poetry\.lock|pyproject\.toml)$" || true) root_deps_changed=$(echo "${STEPS_CHANGED_FILES_OUTPUTS_ALL_CHANGED_FILES}" | tr ' ' '\n' | grep -E "^(uv\.lock|pyproject\.toml)$" || true)
if [ -n "$root_deps_changed" ]; then if [ -n "$root_deps_changed" ]; then
echo "Detected changes in root dependency files: $root_deps_changed" echo "Detected changes in root dependency files: $root_deps_changed"
# Check if prowler/CHANGELOG.md was already updated (might have been caught above) # Check if prowler/CHANGELOG.md was already updated (might have been caught above)
+2 -3
View File
@@ -40,12 +40,11 @@ jobs:
token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }} token: ${{ secrets.PROWLER_BOT_ACCESS_TOKEN }}
persist-credentials: false persist-credentials: false
- name: Setup Python with Poetry - name: Setup Python with uv
uses: ./.github/actions/setup-python-poetry uses: ./.github/actions/setup-python-uv
with: with:
python-version: '3.12' python-version: '3.12'
install-dependencies: 'false' install-dependencies: 'false'
enable-cache: 'false'
- name: Configure Git - name: Configure Git
run: | run: |
+7 -7
View File
@@ -71,26 +71,26 @@ jobs:
contrib/** contrib/**
**/AGENTS.md **/AGENTS.md
- name: Setup Python with Poetry - name: Setup Python with uv
if: steps.check-changes.outputs.any_changed == 'true' if: steps.check-changes.outputs.any_changed == 'true'
uses: ./.github/actions/setup-python-poetry uses: ./.github/actions/setup-python-uv
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
- name: Check Poetry lock file - name: Check uv lock file
if: steps.check-changes.outputs.any_changed == 'true' if: steps.check-changes.outputs.any_changed == 'true'
run: poetry check --lock run: uv lock --check
- name: Lint with flake8 - name: Lint with flake8
if: steps.check-changes.outputs.any_changed == 'true' if: steps.check-changes.outputs.any_changed == 'true'
run: poetry run flake8 . --ignore=E266,W503,E203,E501,W605,E128 --exclude contrib,ui,api,skills,mcp_server run: uv run flake8 . --ignore=E266,W503,E203,E501,W605,E128 --exclude .venv,contrib,ui,api,skills,mcp_server
- name: Check format with black - name: Check format with black
if: steps.check-changes.outputs.any_changed == 'true' if: steps.check-changes.outputs.any_changed == 'true'
# mcp_server has its own pyproject and uses ruff format, exclude it so SDK black # mcp_server has its own pyproject and uses ruff format, exclude it so SDK black
# does not fight ruff over rules it never formatted. # does not fight ruff over rules it never formatted.
run: poetry run black --exclude "api|ui|skills|mcp_server" --check . run: uv run black --exclude "\.venv|api|ui|skills|mcp_server" --check .
- name: Lint with pylint - name: Lint with pylint
if: steps.check-changes.outputs.any_changed == 'true' if: steps.check-changes.outputs.any_changed == 'true'
run: poetry run pylint --disable=W,C,R,E -j 0 -rn -sn prowler/ run: uv run pylint --disable=W,C,R,E -j 0 -rn -sn prowler/
+1 -11
View File
@@ -73,20 +73,10 @@ jobs:
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Python with Poetry
uses: ./.github/actions/setup-python-poetry
with:
python-version: ${{ env.PYTHON_VERSION }}
install-dependencies: 'false'
enable-cache: 'false'
- name: Inject poetry-bumpversion plugin
run: pipx inject poetry poetry-bumpversion
- name: Get Prowler version and set tags - name: Get Prowler version and set tags
id: get-prowler-version id: get-prowler-version
run: | run: |
PROWLER_VERSION="$(poetry version -s 2>/dev/null)" PROWLER_VERSION="$(grep -E '^version = ' pyproject.toml | sed -E 's/version = "([^"]+)"/\1/' | tr -d '[:space:]')"
echo "prowler_version=${PROWLER_VERSION}" >> "${GITHUB_OUTPUT}" echo "prowler_version=${PROWLER_VERSION}" >> "${GITHUB_OUTPUT}"
PROWLER_VERSION_MAJOR="${PROWLER_VERSION%%.*}" PROWLER_VERSION_MAJOR="${PROWLER_VERSION%%.*}"
+2 -2
View File
@@ -9,7 +9,7 @@ on:
- 'prowler/**' - 'prowler/**'
- 'Dockerfile*' - 'Dockerfile*'
- 'pyproject.toml' - 'pyproject.toml'
- 'poetry.lock' - 'uv.lock'
- '.github/workflows/sdk-container-checks.yml' - '.github/workflows/sdk-container-checks.yml'
pull_request: pull_request:
branches: branches:
@@ -19,7 +19,7 @@ on:
- 'prowler/**' - 'prowler/**'
- 'Dockerfile*' - 'Dockerfile*'
- 'pyproject.toml' - 'pyproject.toml'
- 'poetry.lock' - 'uv.lock'
- '.github/workflows/sdk-container-checks.yml' - '.github/workflows/sdk-container-checks.yml'
concurrency: concurrency:
+6 -8
View File
@@ -75,15 +75,14 @@ jobs:
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Python with Poetry - name: Setup Python with uv
uses: ./.github/actions/setup-python-poetry uses: ./.github/actions/setup-python-uv
with: with:
python-version: ${{ env.PYTHON_VERSION }} python-version: ${{ env.PYTHON_VERSION }}
install-dependencies: 'false' install-dependencies: 'false'
enable-cache: 'false'
- name: Build Prowler package - name: Build Prowler package
run: poetry build run: uv build
- name: Publish Prowler package to PyPI - name: Publish Prowler package to PyPI
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
@@ -112,12 +111,11 @@ jobs:
with: with:
persist-credentials: false persist-credentials: false
- name: Setup Python with Poetry - name: Setup Python with uv
uses: ./.github/actions/setup-python-poetry uses: ./.github/actions/setup-python-uv
with: with:
python-version: ${{ env.PYTHON_VERSION }} python-version: ${{ env.PYTHON_VERSION }}
install-dependencies: 'false' install-dependencies: 'false'
enable-cache: 'false'
- name: Install toml package - name: Install toml package
run: pip install toml run: pip install toml
@@ -128,7 +126,7 @@ jobs:
python util/replicate_pypi_package.py python util/replicate_pypi_package.py
- name: Build prowler-cloud package - name: Build prowler-cloud package
run: poetry build run: uv build
- name: Publish prowler-cloud package to PyPI - name: Publish prowler-cloud package to PyPI
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
+9 -9
View File
@@ -9,10 +9,10 @@ on:
- 'prowler/**' - 'prowler/**'
- 'tests/**' - 'tests/**'
- 'pyproject.toml' - 'pyproject.toml'
- 'poetry.lock' - 'uv.lock'
- '.github/workflows/sdk-tests.yml' - '.github/workflows/sdk-tests.yml'
- '.github/workflows/sdk-security.yml' - '.github/workflows/sdk-security.yml'
- '.github/actions/setup-python-poetry/**' - '.github/actions/setup-python-uv/**'
pull_request: pull_request:
branches: branches:
- 'master' - 'master'
@@ -21,10 +21,10 @@ on:
- 'prowler/**' - 'prowler/**'
- 'tests/**' - 'tests/**'
- 'pyproject.toml' - 'pyproject.toml'
- 'poetry.lock' - 'uv.lock'
- '.github/workflows/sdk-tests.yml' - '.github/workflows/sdk-tests.yml'
- '.github/workflows/sdk-security.yml' - '.github/workflows/sdk-security.yml'
- '.github/actions/setup-python-poetry/**' - '.github/actions/setup-python-uv/**'
concurrency: concurrency:
group: ${{ github.workflow }}-${{ github.ref }} group: ${{ github.workflow }}-${{ github.ref }}
@@ -87,21 +87,21 @@ jobs:
contrib/** contrib/**
**/AGENTS.md **/AGENTS.md
- name: Setup Python with Poetry - name: Setup Python with uv
if: steps.check-changes.outputs.any_changed == 'true' if: steps.check-changes.outputs.any_changed == 'true'
uses: ./.github/actions/setup-python-poetry uses: ./.github/actions/setup-python-uv
with: with:
python-version: '3.12' python-version: '3.12'
- name: Security scan with Bandit - name: Security scan with Bandit
if: steps.check-changes.outputs.any_changed == 'true' if: steps.check-changes.outputs.any_changed == 'true'
run: poetry run bandit -q -lll -x '*_test.py,./contrib/,./api/,./ui' -r . run: uv run bandit -q -lll -x '*_test.py,./.venv/,./contrib/,./api/,./ui' -r .
- name: Security scan with Safety - name: Security scan with Safety
if: steps.check-changes.outputs.any_changed == 'true' if: steps.check-changes.outputs.any_changed == 'true'
# Accepted CVEs, severity threshold, and ignore expirations live in .safety-policy.yml # Accepted CVEs, severity threshold, and ignore expirations live in .safety-policy.yml
run: poetry run safety check -r pyproject.toml --policy-file .safety-policy.yml run: uv run safety check -r pyproject.toml --policy-file .safety-policy.yml
- name: Dead code detection with Vulture - name: Dead code detection with Vulture
if: steps.check-changes.outputs.any_changed == 'true' if: steps.check-changes.outputs.any_changed == 'true'
run: poetry run vulture --exclude "contrib,api,ui" --min-confidence 100 . run: uv run vulture --exclude ".venv,contrib,api,ui" --min-confidence 100 .
+35 -35
View File
@@ -92,9 +92,9 @@ jobs:
contrib/** contrib/**
**/AGENTS.md **/AGENTS.md
- name: Setup Python with Poetry - name: Setup Python with uv
if: steps.check-changes.outputs.any_changed == 'true' if: steps.check-changes.outputs.any_changed == 'true'
uses: ./.github/actions/setup-python-poetry uses: ./.github/actions/setup-python-uv
with: with:
python-version: ${{ matrix.python-version }} python-version: ${{ matrix.python-version }}
@@ -107,7 +107,7 @@ jobs:
files: | files: |
./prowler/**/aws/** ./prowler/**/aws/**
./tests/**/aws/** ./tests/**/aws/**
./poetry.lock ./uv.lock
- name: Resolve AWS services under test - name: Resolve AWS services under test
if: steps.changed-aws.outputs.any_changed == 'true' if: steps.changed-aws.outputs.any_changed == 'true'
@@ -209,11 +209,11 @@ jobs:
echo "AWS service_paths='${STEPS_AWS_SERVICES_OUTPUTS_SERVICE_PATHS}'" echo "AWS service_paths='${STEPS_AWS_SERVICES_OUTPUTS_SERVICE_PATHS}'"
if [ "${STEPS_AWS_SERVICES_OUTPUTS_RUN_ALL}" = "true" ]; then if [ "${STEPS_AWS_SERVICES_OUTPUTS_RUN_ALL}" = "true" ]; then
poetry run pytest -n auto --cov=./prowler/providers/aws --cov-report=xml:aws_coverage.xml tests/providers/aws uv run pytest -n auto --cov=./prowler/providers/aws --cov-report=xml:aws_coverage.xml tests/providers/aws
elif [ -z "${STEPS_AWS_SERVICES_OUTPUTS_SERVICE_PATHS}" ]; then elif [ -z "${STEPS_AWS_SERVICES_OUTPUTS_SERVICE_PATHS}" ]; then
echo "No AWS service paths detected; skipping AWS tests." echo "No AWS service paths detected; skipping AWS tests."
else else
poetry run pytest -n auto --cov=./prowler/providers/aws --cov-report=xml:aws_coverage.xml ${STEPS_AWS_SERVICES_OUTPUTS_SERVICE_PATHS} uv run pytest -n auto --cov=./prowler/providers/aws --cov-report=xml:aws_coverage.xml ${STEPS_AWS_SERVICES_OUTPUTS_SERVICE_PATHS}
fi fi
env: env:
STEPS_AWS_SERVICES_OUTPUTS_RUN_ALL: ${{ steps.aws-services.outputs.run_all }} STEPS_AWS_SERVICES_OUTPUTS_RUN_ALL: ${{ steps.aws-services.outputs.run_all }}
@@ -237,11 +237,11 @@ jobs:
files: | files: |
./prowler/**/azure/** ./prowler/**/azure/**
./tests/**/azure/** ./tests/**/azure/**
./poetry.lock ./uv.lock
- name: Run Azure tests - name: Run Azure tests
if: steps.changed-azure.outputs.any_changed == 'true' if: steps.changed-azure.outputs.any_changed == 'true'
run: poetry run pytest -n auto --cov=./prowler/providers/azure --cov-report=xml:azure_coverage.xml tests/providers/azure run: uv run pytest -n auto --cov=./prowler/providers/azure --cov-report=xml:azure_coverage.xml tests/providers/azure
- name: Upload Azure coverage to Codecov - name: Upload Azure coverage to Codecov
if: steps.changed-azure.outputs.any_changed == 'true' if: steps.changed-azure.outputs.any_changed == 'true'
@@ -261,11 +261,11 @@ jobs:
files: | files: |
./prowler/**/gcp/** ./prowler/**/gcp/**
./tests/**/gcp/** ./tests/**/gcp/**
./poetry.lock ./uv.lock
- name: Run GCP tests - name: Run GCP tests
if: steps.changed-gcp.outputs.any_changed == 'true' if: steps.changed-gcp.outputs.any_changed == 'true'
run: poetry run pytest -n auto --cov=./prowler/providers/gcp --cov-report=xml:gcp_coverage.xml tests/providers/gcp run: uv run pytest -n auto --cov=./prowler/providers/gcp --cov-report=xml:gcp_coverage.xml tests/providers/gcp
- name: Upload GCP coverage to Codecov - name: Upload GCP coverage to Codecov
if: steps.changed-gcp.outputs.any_changed == 'true' if: steps.changed-gcp.outputs.any_changed == 'true'
@@ -285,11 +285,11 @@ jobs:
files: | files: |
./prowler/**/kubernetes/** ./prowler/**/kubernetes/**
./tests/**/kubernetes/** ./tests/**/kubernetes/**
./poetry.lock ./uv.lock
- name: Run Kubernetes tests - name: Run Kubernetes tests
if: steps.changed-kubernetes.outputs.any_changed == 'true' if: steps.changed-kubernetes.outputs.any_changed == 'true'
run: poetry run pytest -n auto --cov=./prowler/providers/kubernetes --cov-report=xml:kubernetes_coverage.xml tests/providers/kubernetes run: uv run pytest -n auto --cov=./prowler/providers/kubernetes --cov-report=xml:kubernetes_coverage.xml tests/providers/kubernetes
- name: Upload Kubernetes coverage to Codecov - name: Upload Kubernetes coverage to Codecov
if: steps.changed-kubernetes.outputs.any_changed == 'true' if: steps.changed-kubernetes.outputs.any_changed == 'true'
@@ -309,11 +309,11 @@ jobs:
files: | files: |
./prowler/**/github/** ./prowler/**/github/**
./tests/**/github/** ./tests/**/github/**
./poetry.lock ./uv.lock
- name: Run GitHub tests - name: Run GitHub tests
if: steps.changed-github.outputs.any_changed == 'true' if: steps.changed-github.outputs.any_changed == 'true'
run: poetry run pytest -n auto --cov=./prowler/providers/github --cov-report=xml:github_coverage.xml tests/providers/github run: uv run pytest -n auto --cov=./prowler/providers/github --cov-report=xml:github_coverage.xml tests/providers/github
- name: Upload GitHub coverage to Codecov - name: Upload GitHub coverage to Codecov
if: steps.changed-github.outputs.any_changed == 'true' if: steps.changed-github.outputs.any_changed == 'true'
@@ -333,11 +333,11 @@ jobs:
files: | files: |
./prowler/**/okta/** ./prowler/**/okta/**
./tests/**/okta/** ./tests/**/okta/**
./poetry.lock ./uv.lock
- name: Run Okta tests - name: Run Okta tests
if: steps.changed-okta.outputs.any_changed == 'true' if: steps.changed-okta.outputs.any_changed == 'true'
run: poetry run pytest -n auto --cov=./prowler/providers/okta --cov-report=xml:okta_coverage.xml tests/providers/okta run: uv run pytest -n auto --cov=./prowler/providers/okta --cov-report=xml:okta_coverage.xml tests/providers/okta
- name: Upload Okta coverage to Codecov - name: Upload Okta coverage to Codecov
if: steps.changed-okta.outputs.any_changed == 'true' if: steps.changed-okta.outputs.any_changed == 'true'
@@ -357,11 +357,11 @@ jobs:
files: | files: |
./prowler/**/nhn/** ./prowler/**/nhn/**
./tests/**/nhn/** ./tests/**/nhn/**
./poetry.lock ./uv.lock
- name: Run NHN tests - name: Run NHN tests
if: steps.changed-nhn.outputs.any_changed == 'true' if: steps.changed-nhn.outputs.any_changed == 'true'
run: poetry run pytest -n auto --cov=./prowler/providers/nhn --cov-report=xml:nhn_coverage.xml tests/providers/nhn run: uv run pytest -n auto --cov=./prowler/providers/nhn --cov-report=xml:nhn_coverage.xml tests/providers/nhn
- name: Upload NHN coverage to Codecov - name: Upload NHN coverage to Codecov
if: steps.changed-nhn.outputs.any_changed == 'true' if: steps.changed-nhn.outputs.any_changed == 'true'
@@ -381,11 +381,11 @@ jobs:
files: | files: |
./prowler/**/m365/** ./prowler/**/m365/**
./tests/**/m365/** ./tests/**/m365/**
./poetry.lock ./uv.lock
- name: Run M365 tests - name: Run M365 tests
if: steps.changed-m365.outputs.any_changed == 'true' if: steps.changed-m365.outputs.any_changed == 'true'
run: poetry run pytest -n auto --cov=./prowler/providers/m365 --cov-report=xml:m365_coverage.xml tests/providers/m365 run: uv run pytest -n auto --cov=./prowler/providers/m365 --cov-report=xml:m365_coverage.xml tests/providers/m365
- name: Upload M365 coverage to Codecov - name: Upload M365 coverage to Codecov
if: steps.changed-m365.outputs.any_changed == 'true' if: steps.changed-m365.outputs.any_changed == 'true'
@@ -405,11 +405,11 @@ jobs:
files: | files: |
./prowler/**/iac/** ./prowler/**/iac/**
./tests/**/iac/** ./tests/**/iac/**
./poetry.lock ./uv.lock
- name: Run IaC tests - name: Run IaC tests
if: steps.changed-iac.outputs.any_changed == 'true' if: steps.changed-iac.outputs.any_changed == 'true'
run: poetry run pytest -n auto --cov=./prowler/providers/iac --cov-report=xml:iac_coverage.xml tests/providers/iac run: uv run pytest -n auto --cov=./prowler/providers/iac --cov-report=xml:iac_coverage.xml tests/providers/iac
- name: Upload IaC coverage to Codecov - name: Upload IaC coverage to Codecov
if: steps.changed-iac.outputs.any_changed == 'true' if: steps.changed-iac.outputs.any_changed == 'true'
@@ -429,11 +429,11 @@ jobs:
files: | files: |
./prowler/**/mongodbatlas/** ./prowler/**/mongodbatlas/**
./tests/**/mongodbatlas/** ./tests/**/mongodbatlas/**
./poetry.lock ./uv.lock
- name: Run MongoDB Atlas tests - name: Run MongoDB Atlas tests
if: steps.changed-mongodbatlas.outputs.any_changed == 'true' if: steps.changed-mongodbatlas.outputs.any_changed == 'true'
run: poetry run pytest -n auto --cov=./prowler/providers/mongodbatlas --cov-report=xml:mongodbatlas_coverage.xml tests/providers/mongodbatlas run: uv run pytest -n auto --cov=./prowler/providers/mongodbatlas --cov-report=xml:mongodbatlas_coverage.xml tests/providers/mongodbatlas
- name: Upload MongoDB Atlas coverage to Codecov - name: Upload MongoDB Atlas coverage to Codecov
if: steps.changed-mongodbatlas.outputs.any_changed == 'true' if: steps.changed-mongodbatlas.outputs.any_changed == 'true'
@@ -453,11 +453,11 @@ jobs:
files: | files: |
./prowler/**/oraclecloud/** ./prowler/**/oraclecloud/**
./tests/**/oraclecloud/** ./tests/**/oraclecloud/**
./poetry.lock ./uv.lock
- name: Run OCI tests - name: Run OCI tests
if: steps.changed-oraclecloud.outputs.any_changed == 'true' if: steps.changed-oraclecloud.outputs.any_changed == 'true'
run: poetry run pytest -n auto --cov=./prowler/providers/oraclecloud --cov-report=xml:oraclecloud_coverage.xml tests/providers/oraclecloud run: uv run pytest -n auto --cov=./prowler/providers/oraclecloud --cov-report=xml:oraclecloud_coverage.xml tests/providers/oraclecloud
- name: Upload OCI coverage to Codecov - name: Upload OCI coverage to Codecov
if: steps.changed-oraclecloud.outputs.any_changed == 'true' if: steps.changed-oraclecloud.outputs.any_changed == 'true'
@@ -477,11 +477,11 @@ jobs:
files: | files: |
./prowler/**/openstack/** ./prowler/**/openstack/**
./tests/**/openstack/** ./tests/**/openstack/**
./poetry.lock ./uv.lock
- name: Run OpenStack tests - name: Run OpenStack tests
if: steps.changed-openstack.outputs.any_changed == 'true' if: steps.changed-openstack.outputs.any_changed == 'true'
run: poetry run pytest -n auto --cov=./prowler/providers/openstack --cov-report=xml:openstack_coverage.xml tests/providers/openstack run: uv run pytest -n auto --cov=./prowler/providers/openstack --cov-report=xml:openstack_coverage.xml tests/providers/openstack
- name: Upload OpenStack coverage to Codecov - name: Upload OpenStack coverage to Codecov
if: steps.changed-openstack.outputs.any_changed == 'true' if: steps.changed-openstack.outputs.any_changed == 'true'
@@ -501,11 +501,11 @@ jobs:
files: | files: |
./prowler/**/googleworkspace/** ./prowler/**/googleworkspace/**
./tests/**/googleworkspace/** ./tests/**/googleworkspace/**
./poetry.lock ./uv.lock
- name: Run Google Workspace tests - name: Run Google Workspace tests
if: steps.changed-googleworkspace.outputs.any_changed == 'true' if: steps.changed-googleworkspace.outputs.any_changed == 'true'
run: poetry run pytest -n auto --cov=./prowler/providers/googleworkspace --cov-report=xml:googleworkspace_coverage.xml tests/providers/googleworkspace run: uv run pytest -n auto --cov=./prowler/providers/googleworkspace --cov-report=xml:googleworkspace_coverage.xml tests/providers/googleworkspace
- name: Upload Google Workspace coverage to Codecov - name: Upload Google Workspace coverage to Codecov
if: steps.changed-googleworkspace.outputs.any_changed == 'true' if: steps.changed-googleworkspace.outputs.any_changed == 'true'
@@ -525,11 +525,11 @@ jobs:
files: | files: |
./prowler/**/vercel/** ./prowler/**/vercel/**
./tests/**/vercel/** ./tests/**/vercel/**
./poetry.lock ./uv.lock
- name: Run Vercel tests - name: Run Vercel tests
if: steps.changed-vercel.outputs.any_changed == 'true' if: steps.changed-vercel.outputs.any_changed == 'true'
run: poetry run pytest -n auto --cov=./prowler/providers/vercel --cov-report=xml:vercel_coverage.xml tests/providers/vercel run: uv run pytest -n auto --cov=./prowler/providers/vercel --cov-report=xml:vercel_coverage.xml tests/providers/vercel
- name: Upload Vercel coverage to Codecov - name: Upload Vercel coverage to Codecov
if: steps.changed-vercel.outputs.any_changed == 'true' if: steps.changed-vercel.outputs.any_changed == 'true'
@@ -549,11 +549,11 @@ jobs:
files: | files: |
./prowler/lib/** ./prowler/lib/**
./tests/lib/** ./tests/lib/**
./poetry.lock ./uv.lock
- name: Run Lib tests - name: Run Lib tests
if: steps.changed-lib.outputs.any_changed == 'true' if: steps.changed-lib.outputs.any_changed == 'true'
run: poetry run pytest -n auto --cov=./prowler/lib --cov-report=xml:lib_coverage.xml tests/lib run: uv run pytest -n auto --cov=./prowler/lib --cov-report=xml:lib_coverage.xml tests/lib
- name: Upload Lib coverage to Codecov - name: Upload Lib coverage to Codecov
if: steps.changed-lib.outputs.any_changed == 'true' if: steps.changed-lib.outputs.any_changed == 'true'
@@ -573,11 +573,11 @@ jobs:
files: | files: |
./prowler/config/** ./prowler/config/**
./tests/config/** ./tests/config/**
./poetry.lock ./uv.lock
- name: Run Config tests - name: Run Config tests
if: steps.changed-config.outputs.any_changed == 'true' if: steps.changed-config.outputs.any_changed == 'true'
run: poetry run pytest -n auto --cov=./prowler/config --cov-report=xml:config_coverage.xml tests/config run: uv run pytest -n auto --cov=./prowler/config --cov-report=xml:config_coverage.xml tests/config
- name: Upload Config coverage to Codecov - name: Upload Config coverage to Codecov
if: steps.changed-config.outputs.any_changed == 'true' if: steps.changed-config.outputs.any_changed == 'true'
+2 -2
View File
@@ -132,8 +132,8 @@ jobs:
- name: Build API image from current code - name: Build API image from current code
# docker-compose.yml references prowlercloud/prowler-api:latest from the registry, # docker-compose.yml references prowlercloud/prowler-api:latest from the registry,
# which lags behind PR changes (e.g. the poetry -> uv migration); build locally so # which lags behind PR changes; build locally so E2E exercises the API image
# E2E exercises the API image produced by this PR. # produced by this PR.
run: docker build -t prowlercloud/prowler-api:latest ./api run: docker build -t prowlercloud/prowler-api:latest ./api
- name: Start API services - name: Start API services
+6 -17
View File
@@ -107,7 +107,7 @@ repos:
files: { glob: ["{api,mcp_server}/**/*.py"] } files: { glob: ["{api,mcp_server}/**/*.py"] }
priority: 20 priority: 20
## PYTHON — uv (API) ## PYTHON — uv (API + SDK)
- repo: https://github.com/astral-sh/uv-pre-commit - repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.11.14 rev: 0.11.14
hooks: hooks:
@@ -118,21 +118,10 @@ repos:
pass_filenames: false pass_filenames: false
priority: 50 priority: 50
## PYTHON — Poetry (SDK) - id: uv-lock
- repo: https://github.com/python-poetry/poetry name: SDK - uv-lock
rev: 2.3.4 args: ["--check", "--project=./"]
hooks: files: { glob: ["{pyproject.toml,uv.lock}"] }
- id: poetry-check
name: SDK - poetry-check
args: ["--directory=./"]
files: { glob: ["{pyproject.toml,poetry.lock}"] }
pass_filenames: false
priority: 50
- id: poetry-lock
name: SDK - poetry-lock
args: ["--directory=./"]
files: { glob: ["{pyproject.toml,poetry.lock}"] }
pass_filenames: false pass_filenames: false
priority: 50 priority: 50
@@ -183,7 +172,7 @@ repos:
entry: safety check --policy-file .safety-policy.yml entry: safety check --policy-file .safety-policy.yml
language: system language: system
pass_filenames: false pass_filenames: false
files: { glob: ["**/pyproject.toml", "**/poetry.lock", "**/uv.lock", "**/requirements*.txt", ".safety-policy.yml"] } files: { glob: ["**/pyproject.toml", "**/uv.lock", "**/requirements*.txt", ".safety-policy.yml"] }
priority: 40 priority: 40
- id: vulture - id: vulture
+2 -6
View File
@@ -11,15 +11,11 @@ build:
python: "3.11" python: "3.11"
jobs: jobs:
post_create_environment: post_create_environment:
# Install poetry - python -m pip install uv==0.11.14
# https://python-poetry.org/docs/#installing-manually
- python -m pip install poetry==2.3.4
post_install: post_install:
# Install dependencies with 'docs' dependency group
# https://python-poetry.org/docs/managing-dependencies/#dependency-groups
# VIRTUAL_ENV needs to be set manually for now. # VIRTUAL_ENV needs to be set manually for now.
# See https://github.com/readthedocs/readthedocs.org/pull/11152/ # See https://github.com/readthedocs/readthedocs.org/pull/11152/
- VIRTUAL_ENV=${READTHEDOCS_VIRTUALENV_PATH} python -m poetry install --only=docs - VIRTUAL_ENV=${READTHEDOCS_VIRTUALENV_PATH} uv sync --group docs --no-install-project
mkdocs: mkdocs:
configuration: mkdocs.yml configuration: mkdocs.yml
+2 -2
View File
@@ -2,10 +2,10 @@
# Applied in: .pre-commit-config.yaml, .github/workflows/api-security.yml, # Applied in: .pre-commit-config.yaml, .github/workflows/api-security.yml,
# .github/workflows/sdk-security.yml via `--policy-file`. # .github/workflows/sdk-security.yml via `--policy-file`.
# #
# Validate: poetry run safety validate policy_file --path .safety-policy.yml # Validate: uv run safety validate policy_file --path .safety-policy.yml
security: security:
# Scan unpinned requirements too. Prowler pins via poetry.lock, so this is # Scan unpinned requirements too. Prowler pins via uv.lock, so this is
# defensive against accidental unpinned entries. # defensive against accidental unpinned entries.
ignore-unpinned-requirements: False ignore-unpinned-requirements: False
+6 -6
View File
@@ -148,7 +148,7 @@ Prowler is an open-source cloud security assessment tool supporting AWS, Azure,
| Component | Location | Tech Stack | | Component | Location | Tech Stack |
|-----------|----------|------------| |-----------|----------|------------|
| SDK | `prowler/` | Python 3.10+, Poetry 2.3+ | | SDK | `prowler/` | Python 3.10+, uv |
| API | `api/` | Django 5.1, DRF, Celery | | API | `api/` | Django 5.1, DRF, Celery |
| UI | `ui/` | Next.js 16, React 19, Tailwind 4 | | UI | `ui/` | Next.js 16, React 19, Tailwind 4 |
| MCP Server | `mcp_server/` | FastMCP, Python 3.12+ | | MCP Server | `mcp_server/` | FastMCP, Python 3.12+ |
@@ -160,13 +160,13 @@ Prowler is an open-source cloud security assessment tool supporting AWS, Azure,
```bash ```bash
# Setup # Setup
poetry install --with dev uv sync
poetry run prek install uv run prek install
# Code quality # Code quality
poetry run make lint uv run make lint
poetry run make format uv run make format
poetry run prek run --all-files uv run prek run --all-files
``` ```
--- ---
+6 -6
View File
@@ -78,7 +78,7 @@ WORKDIR /home/prowler
# Copy necessary files # Copy necessary files
COPY prowler/ /home/prowler/prowler/ COPY prowler/ /home/prowler/prowler/
COPY dashboard/ /home/prowler/dashboard/ COPY dashboard/ /home/prowler/dashboard/
COPY pyproject.toml /home/prowler COPY pyproject.toml uv.lock /home/prowler/
COPY README.md /home/prowler/ COPY README.md /home/prowler/
COPY prowler/providers/m365/lib/powershell/m365_powershell.py /home/prowler/prowler/providers/m365/lib/powershell/m365_powershell.py COPY prowler/providers/m365/lib/powershell/m365_powershell.py /home/prowler/prowler/providers/m365/lib/powershell/m365_powershell.py
@@ -87,17 +87,17 @@ ENV HOME='/home/prowler'
ENV PATH="${HOME}/.local/bin:${PATH}" ENV PATH="${HOME}/.local/bin:${PATH}"
#hadolint ignore=DL3013 #hadolint ignore=DL3013
RUN pip install --no-cache-dir --upgrade pip && \ RUN pip install --no-cache-dir --upgrade pip && \
pip install --no-cache-dir poetry==2.3.4 pip install --no-cache-dir uv==0.11.14
RUN poetry install --compile && \ RUN uv sync --compile-bytecode && \
rm -rf ~/.cache/pip rm -rf ~/.cache/uv
# Install PowerShell modules # Install PowerShell modules
RUN poetry run python prowler/providers/m365/lib/powershell/m365_powershell.py RUN .venv/bin/python prowler/providers/m365/lib/powershell/m365_powershell.py
# Remove deprecated dash dependencies # Remove deprecated dash dependencies
RUN pip uninstall dash-html-components -y && \ RUN pip uninstall dash-html-components -y && \
pip uninstall dash-core-components -y pip uninstall dash-core-components -y
USER prowler USER prowler
ENTRYPOINT ["poetry", "run", "prowler"] ENTRYPOINT [".venv/bin/prowler"]
+2 -3
View File
@@ -23,7 +23,7 @@ format: ## Format Code
lint: ## Lint Code lint: ## Lint Code
@echo "Running flake8..." @echo "Running flake8..."
flake8 . --ignore=E266,W503,E203,E501,W605,E128 --exclude contrib flake8 . --ignore=E266,W503,E203,E501,W605,E128 --exclude .venv,contrib
@echo "Running black... " @echo "Running black... "
black --check . black --check .
@echo "Running pylint..." @echo "Running pylint..."
@@ -35,7 +35,7 @@ pypi-clean: ## Delete the distribution files
pypi-build: ## Build package pypi-build: ## Build package
$(MAKE) pypi-clean && \ $(MAKE) pypi-clean && \
poetry build uv build
pypi-upload: ## Upload package pypi-upload: ## Upload package
python3 -m twine upload --repository pypi dist/* python3 -m twine upload --repository pypi dist/*
@@ -56,4 +56,3 @@ run-api-dev: ## Start development environment with API, PostgreSQL, Valkey, MCP,
##@ Development Environment ##@ Development Environment
build-and-run-api-dev: build-no-cache-dev run-api-dev build-and-run-api-dev: build-no-cache-dev run-api-dev
+10 -21
View File
@@ -177,7 +177,7 @@ You can find more information in the [Troubleshooting](./docs/troubleshooting.md
**Requirements** **Requirements**
* `git` installed. * `git` installed.
* `poetry` v2 installed: [poetry installation](https://python-poetry.org/docs/#installation). * `uv` installed: [uv installation](https://docs.astral.sh/uv/getting-started/installation/).
* `pnpm` installed: [pnpm installation](https://pnpm.io/installation). * `pnpm` installed: [pnpm installation](https://pnpm.io/installation).
* `Docker Compose` installed: https://docs.docker.com/compose/install/. * `Docker Compose` installed: https://docs.docker.com/compose/install/.
@@ -186,8 +186,8 @@ You can find more information in the [Troubleshooting](./docs/troubleshooting.md
``` console ``` console
git clone https://github.com/prowler-cloud/prowler git clone https://github.com/prowler-cloud/prowler
cd prowler/api cd prowler/api
poetry install uv sync
eval $(poetry env activate) source .venv/bin/activate
set -a set -a
source .env source .env
docker compose up postgres valkey -d docker compose up postgres valkey -d
@@ -195,11 +195,6 @@ cd src/backend
python manage.py migrate --database admin python manage.py migrate --database admin
gunicorn -c config/guniconf.py config.wsgi:application gunicorn -c config/guniconf.py config.wsgi:application
``` ```
> [!IMPORTANT]
> As of Poetry v2.0.0, the `poetry shell` command has been deprecated. Use `poetry env activate` instead for environment activation.
>
> If your Poetry version is below v2.0.0, continue using `poetry shell` to activate your environment.
> For further guidance, refer to the Poetry Environment Activation Guide https://python-poetry.org/docs/managing-environments/#activating-the-environment.
> After completing the setup, access the API documentation at http://localhost:8080/api/v1/docs. > After completing the setup, access the API documentation at http://localhost:8080/api/v1/docs.
@@ -208,8 +203,8 @@ gunicorn -c config/guniconf.py config.wsgi:application
``` console ``` console
git clone https://github.com/prowler-cloud/prowler git clone https://github.com/prowler-cloud/prowler
cd prowler/api cd prowler/api
poetry install uv sync
eval $(poetry env activate) source .venv/bin/activate
set -a set -a
source .env source .env
cd src/backend cd src/backend
@@ -221,8 +216,8 @@ python -m celery -A config.celery worker -l info -E
``` console ``` console
git clone https://github.com/prowler-cloud/prowler git clone https://github.com/prowler-cloud/prowler
cd prowler/api cd prowler/api
poetry install uv sync
eval $(poetry env activate) source .venv/bin/activate
set -a set -a
source .env source .env
cd src/backend cd src/backend
@@ -283,24 +278,18 @@ The container images are available here:
### From GitHub ### From GitHub
Python >=3.10, <3.13 is required with pip and Poetry: Python >=3.10, <3.13 is required with [uv](https://docs.astral.sh/uv/):
``` console ``` console
git clone https://github.com/prowler-cloud/prowler git clone https://github.com/prowler-cloud/prowler
cd prowler cd prowler
eval $(poetry env activate) uv sync
poetry install source .venv/bin/activate
python prowler-cli.py -v python prowler-cli.py -v
``` ```
> [!IMPORTANT] > [!IMPORTANT]
> To clone Prowler on Windows, configure Git to support long file paths by running the following command: `git config core.longpaths true`. > To clone Prowler on Windows, configure Git to support long file paths by running the following command: `git config core.longpaths true`.
> [!IMPORTANT]
> As of Poetry v2.0.0, the `poetry shell` command has been deprecated. Use `poetry env activate` instead for environment activation.
>
> If your Poetry version is below v2.0.0, continue using `poetry shell` to activate your environment.
> For further guidance, refer to the Poetry Environment Activation Guide https://python-poetry.org/docs/managing-environments/#activating-the-environment.
# 🛡️ GitHub Action # 🛡️ GitHub Action
The official **Prowler GitHub Action** runs Prowler scans in your GitHub workflows using the official [`prowlercloud/prowler`](https://hub.docker.com/r/prowlercloud/prowler) Docker image. Scans run on any [supported provider](https://docs.prowler.com/user-guide/providers/), with optional [`--push-to-cloud`](https://docs.prowler.com/user-guide/tutorials/prowler-app-import-findings) to send findings to Prowler Cloud and optional SARIF upload so findings show up in the repo's **Security → Code scanning** tab and as inline PR annotations. The official **Prowler GitHub Action** runs Prowler scans in your GitHub workflows using the official [`prowlercloud/prowler`](https://hub.docker.com/r/prowlercloud/prowler) Docker image. Scans run on any [supported provider](https://docs.prowler.com/user-guide/providers/), with optional [`--push-to-cloud`](https://docs.prowler.com/user-guide/tutorials/prowler-app-import-findings) to send findings to Prowler Cloud and optional SARIF upload so findings show up in the repo's **Security → Code scanning** tab and as inline PR annotations.
@@ -1,8 +1,9 @@
#!/bin/bash #!/bin/bash
# Run Prowler against All AWS Accounts in an AWS Organization # Run Prowler against All AWS Accounts in an AWS Organization
# Activate Poetry Environment # Activate uv-managed virtualenv
eval "$(poetry env activate)" # shellcheck disable=SC1091
source .venv/bin/activate
# Show Prowler Version # Show Prowler Version
prowler -v prowler -v
+1 -1
View File
@@ -467,7 +467,7 @@ Effective headers and section titles enhance document readability and structure,
* **Example:** * **Example:**
* How to Clone and Install Prowler from GitHub (header: Title case) * How to Clone and Install Prowler from GitHub (header: Title case)
* How to install poetry dependencies (subheading: Sentence case) * How to install uv dependencies (subheading: Sentence case)
5. **Using Keywords in Headers** 5. **Using Keywords in Headers**
Headers should include relevant keywords to improve document searchability: Headers should include relevant keywords to improve document searchability:
* **Good:** Scanning AWS Accounts in Parallel * **Good:** Scanning AWS Accounts in Parallel
+2 -2
View File
@@ -20,8 +20,8 @@ The most common high level steps to create a new check are:
3. Create a check-specific folder. The path should follow this pattern: `prowler/providers/<provider>/services/<service>/<check_name_want_to_implement>`. Adhere to the [Naming Format for Checks](#naming-format-for-checks). 3. Create a check-specific folder. The path should follow this pattern: `prowler/providers/<provider>/services/<service>/<check_name_want_to_implement>`. Adhere to the [Naming Format for Checks](#naming-format-for-checks).
4. Populate the folder with files as specified in [File Creation](#file-creation). 4. Populate the folder with files as specified in [File Creation](#file-creation).
5. Run the check locally to ensure it works as expected. For checking you can use the CLI in the next way: 5. Run the check locally to ensure it works as expected. For checking you can use the CLI in the next way:
- To ensure the check has been detected by Prowler: `poetry run python prowler-cli.py <provider> --list-checks | grep <check_name>`. - To ensure the check has been detected by Prowler: `uv run python prowler-cli.py <provider> --list-checks | grep <check_name>`.
- To run the check, to find possible issues: `poetry run python prowler-cli.py <provider> --log-level ERROR --verbose --check <check_name>`. - To run the check, to find possible issues: `uv run python prowler-cli.py <provider> --log-level ERROR --verbose --check <check_name>`.
6. Create comprehensive tests for the check that cover multiple scenarios including both PASS (compliant) and FAIL (non-compliant) cases. For detailed information about test structure and implementation guidelines, refer to the [Testing](/developer-guide/unit-testing) documentation. 6. Create comprehensive tests for the check that cover multiple scenarios including both PASS (compliant) and FAIL (non-compliant) cases. For detailed information about test structure and implementation guidelines, refer to the [Testing](/developer-guide/unit-testing) documentation.
7. If the check and its corresponding tests are working as expected, you can submit a PR to Prowler. 7. If the check and its corresponding tests are working as expected, you can submit a PR to Prowler.
+9 -16
View File
@@ -80,7 +80,7 @@ Before proceeding, ensure the following:
- Git is installed. - Git is installed.
- Python 3.10 or higher is installed. - Python 3.10 or higher is installed.
- `poetry` is installed to manage dependencies. - `uv` is installed to manage dependencies.
### Forking the Prowler Repository ### Forking the Prowler Repository
@@ -97,28 +97,21 @@ cd prowler
### Dependency Management and Environment Isolation ### Dependency Management and Environment Isolation
To prevent conflicts between environments, we recommend using `poetry`, a Python dependency management solution. Install it by following the [instructions](https://python-poetry.org/docs/#installation). To prevent conflicts between environments, we recommend using [`uv`](https://docs.astral.sh/uv/), a fast Python package and project manager. Install it by following the [official instructions](https://docs.astral.sh/uv/getting-started/installation/).
### Installing Dependencies ### Installing Dependencies
To install all required dependencies, including those needed for development, run: To install all required dependencies, including those needed for development, run:
``` ```
poetry install --with dev uv sync
eval $(poetry env activate) source .venv/bin/activate
``` ```
<Warning>
Starting from Poetry v2.0.0, `poetry shell` has been deprecated in favor of `poetry env activate`.
If your poetry version is below 2.0.0 you must keep using `poetry shell` to activate your environment.
In case you have any doubts, consult the [Poetry environment activation guide](https://python-poetry.org/docs/managing-environments/#activating-the-environment).
</Warning>
### Pre-Commit Hooks ### Pre-Commit Hooks
This repository uses Git pre-commit hooks managed by the [prek](https://prek.j178.dev/) tool, it is installed with `poetry install --with dev`. Next, run the following command in the root of this repository: This repository uses Git pre-commit hooks managed by the [prek](https://prek.j178.dev/) tool, it is installed with `uv sync`. Next, run the following command in the root of this repository:
```shell ```shell
prek install prek install
@@ -155,7 +148,7 @@ Once installed, TruffleHog runs before each push and blocks the operation when v
Before merging pull requests, several automated checks and utilities ensure code security and updated dependencies: Before merging pull requests, several automated checks and utilities ensure code security and updated dependencies:
<Note> <Note>
These should have been already installed if `poetry install --with dev` was already run. These should have been already installed if `uv sync` was already run.
</Note> </Note>
- [`bandit`](https://pypi.org/project/bandit/) for code security review. - [`bandit`](https://pypi.org/project/bandit/) for code security review.
@@ -183,7 +176,7 @@ These resources help ensure that AI-assisted contributions maintain consistency
All dependencies are listed in the `pyproject.toml` file. All dependencies are listed in the `pyproject.toml` file.
The SDK keeps direct dependencies pinned to exact versions, while `poetry.lock` records the full resolved dependency tree and the artifact hashes for every package. Use `poetry install` from the lock file instead of ad-hoc `pip` installs when you need a reproducible environment. The SDK keeps direct dependencies pinned to exact versions, while `uv.lock` records the full resolved dependency tree and the artifact hashes for every package. Use `uv sync` from the lock file instead of ad-hoc `pip` installs when you need a reproducible environment.
For proper code documentation, refer to the following and follow the code documentation practices presented there: [Google Python Style Guide - Comments and Docstrings](https://github.com/google/styleguide/blob/gh-pages/pyguide.md#38-comments-and-docstrings). For proper code documentation, refer to the following and follow the code documentation practices presented there: [Google Python Style Guide - Comments and Docstrings](https://github.com/google/styleguide/blob/gh-pages/pyguide.md#38-comments-and-docstrings).
@@ -209,8 +202,8 @@ prowler/
├── contrib/ # Community-contributed scripts or modules ├── contrib/ # Community-contributed scripts or modules
├── kubernetes/ # Kubernetes deployment files ├── kubernetes/ # Kubernetes deployment files
├── .github/ # GitHub-related files (workflows, issue templates, etc.) ├── .github/ # GitHub-related files (workflows, issue templates, etc.)
├── pyproject.toml # Python project configuration (Poetry) ├── pyproject.toml # Python project configuration (uv)
├── poetry.lock # Poetry lock file ├── uv.lock # uv lock file
├── README.md # Project overview and getting started ├── README.md # Project overview and getting started
├── Makefile # Common development commands ├── Makefile # Common development commands
├── Dockerfile # SDK Docker container ├── Dockerfile # SDK Docker container
+6 -4
View File
@@ -1277,10 +1277,12 @@ Dependencies ensure that your provider's required libraries are available when P
**File:** `pyproject.toml` **File:** `pyproject.toml`
```toml ```toml
[tool.poetry.dependencies] [project]
python = ">=3.10,<3.13" requires-python = ">=3.10,<3.13"
# ... other dependencies dependencies = [
your-sdk-library = "^1.0.0" # Add your SDK dependency # ... other dependencies
"your-sdk-library>=1.0.0,<2.0.0", # Add your SDK dependency
]
``` ```
#### Step 18: Create Tests #### Step 18: Create Tests
@@ -228,7 +228,7 @@ Each requirement links to the Prowler checks that, together, produce a PASS or F
To discover available checks, run: To discover available checks, run:
```bash ```bash
poetry run python prowler-cli.py <provider> --list-checks uv run python prowler-cli.py <provider> --list-checks
``` ```
## Supporting Multiple Providers ## Supporting Multiple Providers
@@ -295,7 +295,7 @@ Follow the steps below before opening a pull request.
### 1. Run the Compliance Model Validator ### 1. Run the Compliance Model Validator
```bash ```bash
poetry run python prowler-cli.py <provider> --list-compliance uv run python prowler-cli.py <provider> --list-compliance
``` ```
The framework must appear in the output. A validation error indicates a schema mismatch between the JSON file and the attribute model. The framework must appear in the output. A validation error indicates a schema mismatch between the JSON file and the attribute model.
@@ -303,7 +303,7 @@ The framework must appear in the output. A validation error indicates a schema m
### 2. Run a Scan Filtered by the Framework ### 2. Run a Scan Filtered by the Framework
```bash ```bash
poetry run python prowler-cli.py <provider> \ uv run python prowler-cli.py <provider> \
--compliance <framework>_<version>_<provider> \ --compliance <framework>_<version>_<provider> \
--log-level ERROR --log-level ERROR
``` ```
@@ -336,7 +336,7 @@ Compliance contributions require two layers of tests.
Run the suite with: Run the suite with:
```bash ```bash
poetry run pytest -n auto tests/lib/check/universal_compliance_models_test.py \ uv run pytest -n auto tests/lib/check/universal_compliance_models_test.py \
tests/lib/outputs/compliance/ tests/lib/outputs/compliance/
``` ```
@@ -348,8 +348,8 @@ Before opening the pull request:
1. Run the complete QA pipeline: 1. Run the complete QA pipeline:
```bash ```bash
poetry run pre-commit run --all-files uv run pre-commit run --all-files
poetry run pytest -n auto uv run pytest -n auto
``` ```
2. Add a changelog entry under the `### 🚀 Added` section of `prowler/CHANGELOG.md`, describing the new framework and the providers it covers. 2. Add a changelog entry under the `### 🚀 Added` section of `prowler/CHANGELOG.md`, describing the new framework and the providers it covers.
3. Follow the [Pull Request Template](https://github.com/prowler-cloud/prowler/blob/master/.github/pull_request_template.md) and set the PR title using Conventional Commits, for example `feat(compliance): add My Framework 1.0 for AWS`. 3. Follow the [Pull Request Template](https://github.com/prowler-cloud/prowler/blob/master/.github/pull_request_template.md) and set the PR title using Conventional Commits, for example `feat(compliance): add My Framework 1.0 for AWS`.
+1 -1
View File
@@ -23,7 +23,7 @@ Within this folder the following files are also to be created:
- `<new_service_name>_service.py` Contains all the logic and API calls of the service. - `<new_service_name>_service.py` Contains all the logic and API calls of the service.
- `<new_service_name>_client_.py` Contains the initialization of the freshly created service's class so that the checks can use it. - `<new_service_name>_client_.py` Contains the initialization of the freshly created service's class so that the checks can use it.
Once the files are create, you can check that the service has been created by running the following command: `poetry run python prowler-cli.py <provider> --list-services | grep <new_service_name>`. Once the files are create, you can check that the service has been created by running the following command: `uv run python prowler-cli.py <provider> --list-services | grep <new_service_name>`.
## Service Structure and Initialisation ## Service Structure and Initialisation
@@ -37,7 +37,7 @@ Refer to the [Prowler App Tutorial](/user-guide/tutorials/prowler-app) for detai
_Requirements_: _Requirements_:
- `git` installed. - `git` installed.
- `poetry` installed: [poetry installation](https://python-poetry.org/docs/#installation). - `uv` installed: [uv installation](https://docs.astral.sh/uv/getting-started/installation/).
- `pnpm` installed through [Corepack](https://pnpm.io/installation#using-corepack) or the standalone [pnpm installation](https://pnpm.io/installation). - `pnpm` installed through [Corepack](https://pnpm.io/installation#using-corepack) or the standalone [pnpm installation](https://pnpm.io/installation).
- `Docker Compose` installed: https://docs.docker.com/compose/install/. - `Docker Compose` installed: https://docs.docker.com/compose/install/.
@@ -49,8 +49,8 @@ Refer to the [Prowler App Tutorial](/user-guide/tutorials/prowler-app) for detai
```bash ```bash
git clone https://github.com/prowler-cloud/prowler \ git clone https://github.com/prowler-cloud/prowler \
cd prowler/api \ cd prowler/api \
poetry install \ uv sync \
eval $(poetry env activate) \ source .venv/bin/activate \
set -a \ set -a \
source .env \ source .env \
docker compose up postgres valkey -d \ docker compose up postgres valkey -d \
@@ -59,11 +59,6 @@ Refer to the [Prowler App Tutorial](/user-guide/tutorials/prowler-app) for detai
gunicorn -c config/guniconf.py config.wsgi:application gunicorn -c config/guniconf.py config.wsgi:application
``` ```
<Warning>
Starting from Poetry v2.0.0, `poetry shell` has been deprecated in favor of `poetry env activate`.
If your poetry version is below 2.0.0 you must keep using `poetry shell` to activate your environment. In case you have any doubts, consult the Poetry environment activation guide: https://python-poetry.org/docs/managing-environments/#activating-the-environment
</Warning>
> Now, you can access the API documentation at http://localhost:8080/api/v1/docs. > Now, you can access the API documentation at http://localhost:8080/api/v1/docs.
_Commands to run the API Worker_: _Commands to run the API Worker_:
@@ -71,8 +66,8 @@ Refer to the [Prowler App Tutorial](/user-guide/tutorials/prowler-app) for detai
```bash ```bash
git clone https://github.com/prowler-cloud/prowler \ git clone https://github.com/prowler-cloud/prowler \
cd prowler/api \ cd prowler/api \
poetry install \ uv sync \
eval $(poetry env activate) \ source .venv/bin/activate \
set -a \ set -a \
source .env \ source .env \
cd src/backend \ cd src/backend \
@@ -84,8 +79,8 @@ Refer to the [Prowler App Tutorial](/user-guide/tutorials/prowler-app) for detai
```bash ```bash
git clone https://github.com/prowler-cloud/prowler \ git clone https://github.com/prowler-cloud/prowler \
cd prowler/api \ cd prowler/api \
poetry install \ uv sync \
eval $(poetry env activate) \ source .venv/bin/activate \
set -a \ set -a \
source .env \ source .env \
cd src/backend \ cd src/backend \
@@ -68,7 +68,7 @@ To install Prowler as a Python package, use `Python >= 3.10, <= 3.12`. Prowler i
_Requirements for Developers_: _Requirements for Developers_:
* `git` * `git`
* `poetry` installed: [poetry installation](https://python-poetry.org/docs/#installation). * `uv` installed: [uv installation](https://docs.astral.sh/uv/getting-started/installation/).
* AWS, GCP, Azure and/or Kubernetes credentials * AWS, GCP, Azure and/or Kubernetes credentials
_Commands_: _Commands_:
@@ -76,8 +76,8 @@ To install Prowler as a Python package, use `Python >= 3.10, <= 3.12`. Prowler i
```bash ```bash
git clone https://github.com/prowler-cloud/prowler git clone https://github.com/prowler-cloud/prowler
cd prowler cd prowler
poetry install uv sync
poetry run python prowler-cli.py -v uv run python prowler-cli.py -v
``` ```
<Note> <Note>
+5 -13
View File
@@ -27,7 +27,7 @@ To download results from AWS CloudShell:
## Cloning Prowler from GitHub ## Cloning Prowler from GitHub
Due to the limited storage in AWS CloudShell's home directory, installing Poetry dependencies for running Prowler from GitHub can be problematic. Due to the limited storage in AWS CloudShell's home directory, installing uv dependencies for running Prowler from GitHub can be problematic.
The following workaround ensures successful installation: The following workaround ensures successful installation:
@@ -37,17 +37,9 @@ adduser prowler
su prowler su prowler
git clone https://github.com/prowler-cloud/prowler.git git clone https://github.com/prowler-cloud/prowler.git
cd prowler cd prowler
pip install poetry pip install uv
mkdir /tmp/poetry mkdir /tmp/uv-cache
poetry config cache-dir /tmp/poetry UV_CACHE_DIR=/tmp/uv-cache uv sync
eval $(poetry env activate) source .venv/bin/activate
poetry install
python prowler-cli.py -v python prowler-cli.py -v
``` ```
<Warning>
Starting from Poetry v2.0.0, `poetry shell` has been deprecated in favor of `poetry env activate`.
If your Poetry version is below v2.0.0, continue using `poetry shell` to activate your environment. For further guidance, refer to the Poetry Environment Activation Guide https://python-poetry.org/docs/managing-environments/#activating-the-environment.
</Warning>
@@ -153,8 +153,8 @@ Before running Prowler CLI for GitHub, ensure you have:
# Install via pip # Install via pip
pip install prowler pip install prowler
# Or via poetry # Or via uv (from the cloned repo)
poetry install uv sync
``` ```
2. **Authentication Credentials** 2. **Authentication Credentials**
@@ -46,7 +46,7 @@ Before you begin, ensure you have:
```bash ```bash
pip install prowler pip install prowler
# or for development: # or for development:
poetry install uv sync
``` ```
2. **OCI Python SDK** (automatically installed with Prowler): 2. **OCI Python SDK** (automatically installed with Prowler):
@@ -133,7 +133,7 @@ export OKTA_PRIVATE_KEY="$(cat /secure/path/to/prowler-okta.pem)"
# Optional — defaults to "okta.policies.read" # Optional — defaults to "okta.policies.read"
export OKTA_SCOPES="okta.policies.read" export OKTA_SCOPES="okta.policies.read"
poetry run python prowler-cli.py okta uv run python prowler-cli.py okta
``` ```
### Non-Secret CLI Flags ### Non-Secret CLI Flags
@@ -149,7 +149,7 @@ Non-secret values are also available as CLI flags for ergonomic overrides:
Run a single check directly: Run a single check directly:
```bash ```bash
poetry run python prowler-cli.py okta --check signon_global_session_idle_timeout_15min uv run python prowler-cli.py okta --check signon_global_session_idle_timeout_15min
``` ```
## Troubleshooting ## Troubleshooting
Generated
-6888
View File
File diff suppressed because it is too large Load Diff
+11 -11
View File
@@ -85,7 +85,7 @@ class {check_name}(Check):
## TECH STACK ## TECH STACK
Python 3.10+ | Poetry 2.3+ | pytest | moto (AWS mocking) | Pre-commit hooks (black, flake8, pylint, bandit) Python 3.10+ | uv | pytest | moto (AWS mocking) | Pre-commit hooks (black, flake8, pylint, bandit)
--- ---
@@ -112,20 +112,20 @@ prowler/
```bash ```bash
# Setup # Setup
poetry install --with dev uv sync
poetry run pre-commit install uv run pre-commit install
# Run Prowler # Run Prowler
poetry run python prowler-cli.py {provider} uv run python prowler-cli.py {provider}
poetry run python prowler-cli.py {provider} --check {check_name} uv run python prowler-cli.py {provider} --check {check_name}
poetry run python prowler-cli.py {provider} --list-checks uv run python prowler-cli.py {provider} --list-checks
# Testing # Testing
poetry run pytest -n auto -vvv tests/ uv run pytest -n auto -vvv tests/
poetry run pytest tests/providers/{provider}/services/{service}/ -v uv run pytest tests/providers/{provider}/services/{service}/ -v
# Code Quality # Code Quality
poetry run pre-commit run --all-files uv run pre-commit run --all-files
``` ```
--- ---
@@ -145,8 +145,8 @@ poetry run pre-commit run --all-files
## QA CHECKLIST ## QA CHECKLIST
- [ ] `poetry run pytest` passes - [ ] `uv run pytest` passes
- [ ] `poetry run pre-commit run --all-files` passes - [ ] `uv run pre-commit run --all-files` passes
- [ ] Check metadata JSON is valid - [ ] Check metadata JSON is valid
- [ ] Tests cover PASS, FAIL, and empty resource scenarios - [ ] Tests cover PASS, FAIL, and empty resource scenarios
- [ ] Docstrings follow Google style - [ ] Docstrings follow Google style
+36 -36
View File
@@ -1,6 +1,30 @@
[build-system] [build-system]
build-backend = "poetry.core.masonry.api" build-backend = "hatchling.build"
requires = ["poetry-core>=2.0"] requires = ["hatchling"]
[dependency-groups]
dev = [
"bandit==1.8.3",
"black==25.1.0",
"coverage==7.6.12",
"docker==7.1.0",
"filelock==3.20.3",
"flake8==7.1.2",
"freezegun==1.5.1",
"mock==5.2.0",
"moto[all]==5.1.11",
"openapi-schema-validator==0.6.3",
"openapi-spec-validator==0.7.1",
"prek==0.3.9",
"pylint==3.3.4",
"pytest==8.3.5",
"pytest-cov==6.0.0",
"pytest-env==1.1.5",
"pytest-randomly==3.16.0",
"pytest-xdist==3.6.1",
"safety==3.7.0",
"vulture==2.14"
]
# https://peps.python.org/pep-0621/ # https://peps.python.org/pep-0621/
[project] [project]
@@ -107,41 +131,11 @@ prowler = "prowler.__main__:prowler"
"Homepage" = "https://github.com/prowler-cloud/prowler" "Homepage" = "https://github.com/prowler-cloud/prowler"
"Issue tracker" = "https://github.com/prowler-cloud/prowler/issues" "Issue tracker" = "https://github.com/prowler-cloud/prowler/issues"
[tool.poetry] [tool.hatch.build.targets.sdist]
packages = [ include = ["prowler", "dashboard"]
{include = "prowler"},
{include = "dashboard"}
]
requires-poetry = ">=2.0"
[tool.poetry.group.dev.dependencies] [tool.hatch.build.targets.wheel]
bandit = "1.8.3" packages = ["prowler", "dashboard"]
black = "25.1.0"
coverage = "7.6.12"
docker = "7.1.0"
filelock = "3.20.3"
flake8 = "7.1.2"
freezegun = "1.5.1"
mock = "5.2.0"
moto = {extras = ["all"], version = "5.1.11"}
openapi-schema-validator = "0.6.3"
openapi-spec-validator = "0.7.1"
prek = "0.3.9"
pylint = "3.3.4"
pytest = "8.3.5"
pytest-cov = "6.0.0"
pytest-env = "1.1.5"
pytest-randomly = "3.16.0"
pytest-xdist = "3.6.1"
safety = "3.7.0"
vulture = "2.14"
[tool.poetry-version-plugin]
source = "init"
[tool.poetry_bumpversion.file."prowler/config/config.py"]
replace = 'prowler_version = "{new_version}"'
search = 'prowler_version = "{current_version}"'
[tool.pytest.ini_options] [tool.pytest.ini_options]
pythonpath = [ pythonpath = [
@@ -155,3 +149,9 @@ AWS_DEFAULT_REGION = 'us-east-1'
AWS_SECRET_ACCESS_KEY = 'testing' AWS_SECRET_ACCESS_KEY = 'testing'
AWS_SECURITY_TOKEN = 'testing' AWS_SECURITY_TOKEN = 'testing'
AWS_SESSION_TOKEN = 'testing' AWS_SESSION_TOKEN = 'testing'
[tool.uv]
# cartography (pulled in via the API) still pins okta<1.0.0 for its (unused-by-prowler)
# intel.okta integration; the SDK Okta provider needs okta==3.4.2 (PR #11079). Force the
# version prowler needs; cartography's okta module is not imported here.
override-dependencies = ["okta==3.4.2"]
+10 -10
View File
@@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
# Setup Git Hooks for Prowler # Setup Git Hooks for Prowler
# This script installs prek hooks using the project's Poetry environment # This script installs prek hooks using the project's uv-managed environment
# or a system-wide prek installation # or a system-wide prek installation
set -e set -e
@@ -32,27 +32,27 @@ fi
echo "" echo ""
# Full setup requires Poetry for system hooks (pylint, bandit, safety, vulture, trufflehog) # Full setup requires uv for system hooks (pylint, bandit, safety, vulture, trufflehog)
# These are installed as Python dev dependencies and used by local hooks in .pre-commit-config.yaml # These are installed as Python dev dependencies and used by local hooks in .pre-commit-config.yaml
if command -v poetry &>/dev/null && [ -f "pyproject.toml" ]; then if command -v uv &>/dev/null && [ -f "pyproject.toml" ]; then
if poetry run prek --version &>/dev/null 2>&1; then if uv run prek --version &>/dev/null 2>&1; then
echo -e "${GREEN}${NC} prek and dependencies found via Poetry" echo -e "${GREEN}${NC} prek and dependencies found via uv"
else else
echo -e "${YELLOW}📦 Installing project dependencies (including prek)...${NC}" echo -e "${YELLOW}📦 Installing project dependencies (including prek)...${NC}"
poetry install --with dev uv sync
fi fi
echo -e "${YELLOW}🔗 Installing prek hooks...${NC}" echo -e "${YELLOW}🔗 Installing prek hooks...${NC}"
poetry run prek install --overwrite uv run prek install --overwrite
elif command -v prek &>/dev/null; then elif command -v prek &>/dev/null; then
# prek is available system-wide but without Poetry dev deps # prek is available system-wide but without uv dev deps
echo -e "${GREEN}${NC} prek found in PATH" echo -e "${GREEN}${NC} prek found in PATH"
echo -e "${YELLOW}🔗 Installing prek hooks...${NC}" echo -e "${YELLOW}🔗 Installing prek hooks...${NC}"
prek install --overwrite prek install --overwrite
echo "" echo ""
echo -e "${YELLOW}⚠️ Warning: Some hooks require Python tools installed via Poetry:${NC}" echo -e "${YELLOW}⚠️ Warning: Some hooks require Python tools installed via uv:${NC}"
echo -e " pylint, bandit, safety, vulture, trufflehog" echo -e " pylint, bandit, safety, vulture, trufflehog"
echo -e " These hooks will be skipped unless you install them or run:" echo -e " These hooks will be skipped unless you install them or run:"
echo -e " ${GREEN}poetry install --with dev${NC}" echo -e " ${GREEN}uv sync${NC}"
else else
echo -e "${RED}❌ prek is not installed${NC}" echo -e "${RED}❌ prek is not installed${NC}"
echo -e "${YELLOW} Install prek using one of these methods:${NC}" echo -e "${YELLOW} Install prek using one of these methods:${NC}"
+4 -4
View File
@@ -168,16 +168,16 @@ After validation passes, test the framework with Prowler:
```bash ```bash
# Verify framework is detected # Verify framework is detected
poetry run python prowler-cli.py {provider} --list-compliance | grep {framework} uv run python prowler-cli.py {provider} --list-compliance | grep {framework}
# Run a quick test with a single check from the framework # Run a quick test with a single check from the framework
poetry run python prowler-cli.py {provider} --compliance {framework} --check {check_name} uv run python prowler-cli.py {provider} --compliance {framework} --check {check_name}
# Run full compliance scan (dry-run with limited checks) # Run full compliance scan (dry-run with limited checks)
poetry run python prowler-cli.py {provider} --compliance {framework} --checks-limit 5 uv run python prowler-cli.py {provider} --compliance {framework} --checks-limit 5
# Generate compliance report in multiple formats # Generate compliance report in multiple formats
poetry run python prowler-cli.py {provider} --compliance {framework} -M csv json html uv run python prowler-cli.py {provider} --compliance {framework} -M csv json html
``` ```
--- ---
+5 -5
View File
@@ -155,19 +155,19 @@ Current providers:
```bash ```bash
# Run provider # Run provider
poetry run python prowler-cli.py {provider} uv run python prowler-cli.py {provider}
# List services for provider # List services for provider
poetry run python prowler-cli.py {provider} --list-services uv run python prowler-cli.py {provider} --list-services
# List checks for provider # List checks for provider
poetry run python prowler-cli.py {provider} --list-checks uv run python prowler-cli.py {provider} --list-checks
# Run specific service # Run specific service
poetry run python prowler-cli.py {provider} --services {service} uv run python prowler-cli.py {provider} --services {service}
# Debug mode # Debug mode
poetry run python prowler-cli.py {provider} --log-level DEBUG uv run python prowler-cli.py {provider} --log-level DEBUG
``` ```
## Resources ## Resources
+6 -6
View File
@@ -73,13 +73,13 @@ For detailed field documentation, see `references/metadata-docs.md`.
### 5. Verify Check Detection ### 5. Verify Check Detection
```bash ```bash
poetry run python prowler-cli.py {provider} --list-checks | grep {check_name} uv run python prowler-cli.py {provider} --list-checks | grep {check_name}
``` ```
### 6. Run Check Locally ### 6. Run Check Locally
```bash ```bash
poetry run python prowler-cli.py {provider} --log-level ERROR --verbose --check {check_name} uv run python prowler-cli.py {provider} --log-level ERROR --verbose --check {check_name}
``` ```
### 7. Create Tests ### 7. Create Tests
@@ -243,16 +243,16 @@ class ec2_instance_hardened(Check):
```bash ```bash
# Verify detection # Verify detection
poetry run python prowler-cli.py {provider} --list-checks | grep {check_name} uv run python prowler-cli.py {provider} --list-checks | grep {check_name}
# Run check # Run check
poetry run python prowler-cli.py {provider} --log-level ERROR --verbose --check {check_name} uv run python prowler-cli.py {provider} --log-level ERROR --verbose --check {check_name}
# Run with specific profile/credentials # Run with specific profile/credentials
poetry run python prowler-cli.py aws --profile myprofile --check {check_name} uv run python prowler-cli.py aws --profile myprofile --check {check_name}
# Run multiple checks # Run multiple checks
poetry run python prowler-cli.py {provider} --check {check1} {check2} {check3} uv run python prowler-cli.py {provider} --check {check1} {check2} {check3}
``` ```
## Resources ## Resources
+4 -4
View File
@@ -309,16 +309,16 @@ assert result[0].project_id == GCP_PROJECT_ID # GCP
```bash ```bash
# All SDK tests # All SDK tests
poetry run pytest -n auto -vvv tests/ uv run pytest -n auto -vvv tests/
# Specific provider # Specific provider
poetry run pytest tests/providers/{provider}/ -v uv run pytest tests/providers/{provider}/ -v
# Specific check # Specific check
poetry run pytest tests/providers/{provider}/services/{service}/{check_name}/ -v uv run pytest tests/providers/{provider}/services/{service}/{check_name}/ -v
# Stop on first failure # Stop on first failure
poetry run pytest -x tests/ uv run pytest -x tests/
``` ```
## Resources ## Resources
+4 -4
View File
@@ -16,7 +16,7 @@ allowed-tools: Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
| Component | Stack | Location | | Component | Stack | Location |
|-----------|-------|----------| |-----------|-------|----------|
| SDK | Python 3.10+, Poetry | `prowler/` | | SDK | Python 3.10+, uv | `prowler/` |
| API | Django 5.1, DRF, Celery | `api/` | | API | Django 5.1, DRF, Celery | `api/` |
| UI | Next.js 16, React 19, Tailwind 4 | `ui/` | | UI | Next.js 16, React 19, Tailwind 4 | `ui/` |
| MCP | FastMCP 2.13.1 | `mcp_server/` | | MCP | FastMCP 2.13.1 | `mcp_server/` |
@@ -25,9 +25,9 @@ allowed-tools: Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
```bash ```bash
# SDK # SDK
poetry install --with dev uv sync
poetry run python prowler-cli.py aws --check check_name uv run python prowler-cli.py aws --check check_name
poetry run pytest tests/ uv run pytest tests/
# API # API
cd api && uv run python src/backend/manage.py runserver cd api && uv run python src/backend/manage.py runserver
+7 -7
View File
@@ -75,7 +75,7 @@ pnpm test:coverage -- components/feature/
fd "*_test.py" tests/providers/aws/services/ec2/ fd "*_test.py" tests/providers/aws/services/ec2/
# 2. Run specific test # 2. Run specific test
poetry run pytest tests/providers/aws/services/ec2/ec2_ami_public/ -v uv run pytest tests/providers/aws/services/ec2/ec2_ami_public/ -v
# 3. Read existing tests # 3. Read existing tests
``` ```
@@ -356,16 +356,16 @@ pnpm test ComponentName # Filter by name
### SDK (`prowler/`) ### SDK (`prowler/`)
```bash ```bash
poetry run pytest tests/path/ -v # Run specific tests uv run pytest tests/path/ -v # Run specific tests
poetry run pytest tests/path/ -v -k "test_name" # Filter by name uv run pytest tests/path/ -v -k "test_name" # Filter by name
poetry run pytest -n auto tests/ # Parallel run uv run pytest -n auto tests/ # Parallel run
poetry run pytest --cov=./prowler tests/ # Coverage uv run pytest --cov=./prowler tests/ # Coverage
``` ```
### API (`api/`) ### API (`api/`)
```bash ```bash
poetry run pytest -x --tb=short # Run all (stop on first fail) uv run pytest -x --tb=short # Run all (stop on first fail)
uv run pytest api/src/backend/api/tests/test_file.py # Specific file uv run pytest api/src/backend/api/tests/test_file.py # Specific file
poetry run pytest -k "test_name" -v # Filter by name uv run pytest -k "test_name" -v # Filter by name
``` ```
Generated
+4636
View File
File diff suppressed because it is too large Load Diff