diff --git a/.github/workflows/sdk-code-quality.yml b/.github/workflows/sdk-code-quality.yml new file mode 100644 index 0000000000..fb7c13609b --- /dev/null +++ b/.github/workflows/sdk-code-quality.yml @@ -0,0 +1,99 @@ +name: 'SDK: Code Quality' + +on: + push: + branches: + - 'master' + - 'v5.*' + paths: + - 'prowler/**' + - 'tests/**' + - 'pyproject.toml' + - 'poetry.lock' + - '.github/workflows/sdk-code-quality.yml' + pull_request: + branches: + - 'master' + - 'v5.*' + paths: + - 'prowler/**' + - 'tests/**' + - 'pyproject.toml' + - 'poetry.lock' + - '.github/workflows/sdk-code-quality.yml' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + sdk-code-quality: + runs-on: ubuntu-latest + timeout-minutes: 20 + permissions: + contents: read + strategy: + matrix: + python-version: + - '3.9' + - '3.10' + - '3.11' + - '3.12' + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Check for SDK changes + id: check-changes + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files_ignore: | + prowler/CHANGELOG.md + docs/** + permissions/** + api/** + ui/** + dashboard/** + mcp_server/** + README.md + mkdocs.yml + .backportrc.json + .env + docker-compose* + examples/** + .gitignore + contrib/** + + - name: Install Poetry + if: steps.check-changes.outputs.any_changed == 'true' + run: pipx install poetry==2.1.1 + + - name: Set up Python ${{ matrix.python-version }} + if: steps.check-changes.outputs.any_changed == 'true' + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 + with: + python-version: ${{ matrix.python-version }} + cache: 'poetry' + + - name: Install dependencies + if: steps.check-changes.outputs.any_changed == 'true' + run: | + poetry install --no-root + poetry run pip list + + - name: Check Poetry lock file + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry check --lock + + - name: Lint with flake8 + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry run flake8 . --ignore=E266,W503,E203,E501,W605,E128 --exclude contrib,ui,api + + - name: Check format with black + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry run black --exclude api ui --check . + + - name: Lint with pylint + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry run pylint --disable=W,C,R,E -j 0 -rn -sn prowler/ diff --git a/.github/workflows/sdk-container-checks.yml b/.github/workflows/sdk-container-checks.yml new file mode 100644 index 0000000000..49ea98fc33 --- /dev/null +++ b/.github/workflows/sdk-container-checks.yml @@ -0,0 +1,109 @@ +name: 'SDK: Container Checks' + +on: + push: + branches: + - 'master' + - 'v5.*' + paths: + - 'prowler/**' + - 'tests/**' + - 'Dockerfile' + - '.github/workflows/sdk-container-checks.yml' + pull_request: + branches: + - 'master' + - 'v5.*' + paths: + - 'prowler/**' + - 'tests/**' + - 'Dockerfile' + - '.github/workflows/sdk-container-checks.yml' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + IMAGE_NAME: prowler + +jobs: + sdk-dockerfile-lint: + runs-on: ubuntu-latest + timeout-minutes: 10 + permissions: + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Check if Dockerfile changed + id: dockerfile-changed + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files: Dockerfile + + - name: Lint Dockerfile with Hadolint + if: steps.dockerfile-changed.outputs.any_changed == 'true' + uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0 + with: + dockerfile: Dockerfile + ignore: DL3013 + + sdk-container-build-and-scan: + runs-on: ubuntu-latest + timeout-minutes: 30 + permissions: + contents: read + security-events: write + pull-requests: write + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Check for SDK changes + id: check-changes + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files_ignore: | + prowler/CHANGELOG.md + docs/** + permissions/** + api/** + ui/** + dashboard/** + mcp_server/** + README.md + mkdocs.yml + .backportrc.json + .env + docker-compose* + examples/** + .gitignore + contrib/** + + - name: Set up Docker Buildx + if: steps.check-changes.outputs.any_changed == 'true' + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 + + - name: Build SDK container + if: steps.check-changes.outputs.any_changed == 'true' + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 + with: + context: . + push: false + load: true + tags: ${{ env.IMAGE_NAME }}:${{ github.sha }} + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Scan SDK container with Trivy + if: github.repository == 'prowler-cloud/prowler' && steps.check-changes.outputs.any_changed == 'true' + uses: ./.github/actions/trivy-scan + with: + image-name: ${{ env.IMAGE_NAME }} + image-tag: ${{ github.sha }} + fail-on-critical: 'false' + severity: 'CRITICAL' diff --git a/.github/workflows/sdk-security.yml b/.github/workflows/sdk-security.yml new file mode 100644 index 0000000000..e5e8980f3f --- /dev/null +++ b/.github/workflows/sdk-security.yml @@ -0,0 +1,86 @@ +name: 'SDK: Security' + +on: + push: + branches: + - 'master' + - 'v5.*' + paths: + - 'prowler/**' + - 'tests/**' + - 'pyproject.toml' + - 'poetry.lock' + - '.github/workflows/sdk-security.yml' + pull_request: + branches: + - 'master' + - 'v5.*' + paths: + - 'prowler/**' + - 'tests/**' + - 'pyproject.toml' + - 'poetry.lock' + - '.github/workflows/sdk-security.yml' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + sdk-security-scans: + runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 + + - name: Check for SDK changes + id: check-changes + uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 + with: + files_ignore: | + prowler/CHANGELOG.md + docs/** + permissions/** + api/** + ui/** + dashboard/** + mcp_server/** + README.md + mkdocs.yml + .backportrc.json + .env + docker-compose* + examples/** + .gitignore + contrib/** + + - name: Install Poetry + if: steps.check-changes.outputs.any_changed == 'true' + run: pipx install poetry==2.1.1 + + - name: Set up Python 3.12 + if: steps.check-changes.outputs.any_changed == 'true' + uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 + with: + python-version: '3.12' + cache: 'poetry' + + - name: Install dependencies + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry install --no-root + + - name: Security scan with Bandit + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry run bandit -q -lll -x '*_test.py,./contrib/,./api/,./ui' -r . + + - name: Security scan with Safety + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry run safety check --ignore 70612 -r pyproject.toml + + - name: Dead code detection with Vulture + if: steps.check-changes.outputs.any_changed == 'true' + run: poetry run vulture --exclude "contrib,api,ui" --min-confidence 100 . diff --git a/.github/workflows/sdk-pull-request.yml b/.github/workflows/sdk-tests.yml similarity index 70% rename from .github/workflows/sdk-pull-request.yml rename to .github/workflows/sdk-tests.yml index c63520b6b7..c8252bec02 100644 --- a/.github/workflows/sdk-pull-request.yml +++ b/.github/workflows/sdk-tests.yml @@ -1,4 +1,4 @@ -name: 'SDK: Pull Request' +name: 'SDK: Tests' on: push: @@ -10,8 +10,7 @@ on: - 'tests/**' - 'pyproject.toml' - 'poetry.lock' - - 'Dockerfile' - - '.github/workflows/sdk-pull-request.yml' + - '.github/workflows/sdk-tests.yml' pull_request: branches: - 'master' @@ -21,29 +20,32 @@ on: - 'tests/**' - 'pyproject.toml' - 'poetry.lock' - - 'Dockerfile' - - '.github/workflows/sdk-pull-request.yml' + - '.github/workflows/sdk-tests.yml' concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true -env: - IMAGE_NAME: prowler - jobs: - check-changes: - if: github.repository == 'prowler-cloud/prowler' + sdk-tests: runs-on: ubuntu-latest - timeout-minutes: 5 - outputs: - sdk-changed: ${{ steps.filter.outputs.sdk }} + timeout-minutes: 120 + permissions: + contents: read + strategy: + matrix: + python-version: + - '3.9' + - '3.10' + - '3.11' + - '3.12' + steps: - name: Checkout repository uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - name: Check for SDK changes - id: filter + id: check-changes uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 with: files_ignore: | @@ -63,126 +65,24 @@ jobs: .gitignore contrib/** - - name: Set output - id: set-output - run: | - if [[ "${{ steps.filter.outputs.any_changed }}" == "true" ]]; then - echo "sdk=true" >> $GITHUB_OUTPUT - else - echo "sdk=false" >> $GITHUB_OUTPUT - fi - - code-quality: - needs: check-changes - if: github.repository == 'prowler-cloud/prowler' && needs.check-changes.outputs.sdk-changed == 'true' - runs-on: ubuntu-latest - timeout-minutes: 20 - permissions: - contents: read - strategy: - matrix: - python-version: - - '3.9' - - '3.10' - - '3.11' - - '3.12' - - steps: - - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - - name: Install Poetry - run: pipx install poetry==2.1.1 - - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 - with: - python-version: ${{ matrix.python-version }} - cache: 'poetry' - - - name: Install dependencies - run: | - poetry install --no-root - poetry run pip list - - - name: Check Poetry lock file - run: poetry check --lock - - - name: Lint with flake8 - run: poetry run flake8 . --ignore=E266,W503,E203,E501,W605,E128 --exclude contrib,ui,api - - - name: Check format with black - run: poetry run black --exclude api ui --check . - - - name: Lint with pylint - run: poetry run pylint --disable=W,C,R,E -j 0 -rn -sn prowler/ - - security-scans: - needs: check-changes - if: github.repository == 'prowler-cloud/prowler' && needs.check-changes.outputs.sdk-changed == 'true' - runs-on: ubuntu-latest - timeout-minutes: 15 - permissions: - contents: read - - steps: - - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - - name: Install Poetry - run: pipx install poetry==2.1.1 - - - name: Set up Python 3.12 - uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 - with: - python-version: '3.12' - cache: 'poetry' - - - name: Install dependencies - run: poetry install --no-root - - - name: Security scan with Bandit - run: poetry run bandit -q -lll -x '*_test.py,./contrib/,./api/,./ui' -r . - - - name: Security scan with Safety - run: poetry run safety check --ignore 70612 -r pyproject.toml - - - name: Dead code detection with Vulture - run: poetry run vulture --exclude "contrib,api,ui" --min-confidence 100 . - - tests: - needs: check-changes - if: github.repository == 'prowler-cloud/prowler' && needs.check-changes.outputs.sdk-changed == 'true' - runs-on: ubuntu-latest - timeout-minutes: 60 - permissions: - contents: read - strategy: - matrix: - python-version: - - '3.9' - - '3.10' - - '3.11' - - '3.12' - - steps: - - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - name: Install Poetry + if: steps.check-changes.outputs.any_changed == 'true' run: pipx install poetry==2.1.1 - name: Set up Python ${{ matrix.python-version }} + if: steps.check-changes.outputs.any_changed == 'true' uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0 with: python-version: ${{ matrix.python-version }} cache: 'poetry' - name: Install dependencies + if: steps.check-changes.outputs.any_changed == 'true' run: poetry install --no-root # AWS Provider - name: Check if AWS files changed + if: steps.check-changes.outputs.any_changed == 'true' id: changed-aws uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 with: @@ -206,6 +106,7 @@ jobs: # Azure Provider - name: Check if Azure files changed + if: steps.check-changes.outputs.any_changed == 'true' id: changed-azure uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 with: @@ -229,6 +130,7 @@ jobs: # GCP Provider - name: Check if GCP files changed + if: steps.check-changes.outputs.any_changed == 'true' id: changed-gcp uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 with: @@ -252,6 +154,7 @@ jobs: # Kubernetes Provider - name: Check if Kubernetes files changed + if: steps.check-changes.outputs.any_changed == 'true' id: changed-kubernetes uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 with: @@ -275,6 +178,7 @@ jobs: # GitHub Provider - name: Check if GitHub files changed + if: steps.check-changes.outputs.any_changed == 'true' id: changed-github uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 with: @@ -298,6 +202,7 @@ jobs: # NHN Provider - name: Check if NHN files changed + if: steps.check-changes.outputs.any_changed == 'true' id: changed-nhn uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 with: @@ -321,6 +226,7 @@ jobs: # M365 Provider - name: Check if M365 files changed + if: steps.check-changes.outputs.any_changed == 'true' id: changed-m365 uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 with: @@ -344,6 +250,7 @@ jobs: # IaC Provider - name: Check if IaC files changed + if: steps.check-changes.outputs.any_changed == 'true' id: changed-iac uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 with: @@ -367,6 +274,7 @@ jobs: # MongoDB Atlas Provider - name: Check if MongoDB Atlas files changed + if: steps.check-changes.outputs.any_changed == 'true' id: changed-mongodbatlas uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 with: @@ -390,6 +298,7 @@ jobs: # OCI Provider - name: Check if OCI files changed + if: steps.check-changes.outputs.any_changed == 'true' id: changed-oraclecloud uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 with: @@ -413,6 +322,7 @@ jobs: # Lib - name: Check if Lib files changed + if: steps.check-changes.outputs.any_changed == 'true' id: changed-lib uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 with: @@ -436,6 +346,7 @@ jobs: # Config - name: Check if Config files changed + if: steps.check-changes.outputs.any_changed == 'true' id: changed-config uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 with: @@ -456,63 +367,3 @@ jobs: with: flags: prowler-py${{ matrix.python-version }}-config files: ./config_coverage.xml - - dockerfile-lint: - needs: check-changes - if: github.repository == 'prowler-cloud/prowler' && needs.check-changes.outputs.sdk-changed == 'true' - runs-on: ubuntu-latest - timeout-minutes: 10 - permissions: - contents: read - - steps: - - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - - name: Check if Dockerfile changed - id: dockerfile-changed - uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62 # v47.0.0 - with: - files: Dockerfile - - - name: Lint Dockerfile with Hadolint - if: steps.dockerfile-changed.outputs.any_changed == 'true' - uses: hadolint/hadolint-action@2332a7b74a6de0dda2e2221d575162eba76ba5e5 # v3.3.0 - with: - dockerfile: Dockerfile - ignore: DL3013 - - container-build-and-scan: - needs: check-changes - if: github.repository == 'prowler-cloud/prowler' && needs.check-changes.outputs.sdk-changed == 'true' - runs-on: ubuntu-latest - timeout-minutes: 30 - permissions: - contents: read - security-events: write - pull-requests: write - - steps: - - name: Checkout repository - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v3.11.1 - - - name: Build SDK container - uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v6.18.0 - with: - context: . - push: false - load: true - tags: ${{ env.IMAGE_NAME }}:${{ github.sha }} - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Scan SDK container with Trivy - uses: ./.github/actions/trivy-scan - with: - image-name: ${{ env.IMAGE_NAME }} - image-tag: ${{ github.sha }} - fail-on-critical: 'false' - severity: 'CRITICAL'