name: (5.x) Docker PR check permissions: contents: read id-token: write on: pull_request: types: [opened, synchronize, reopened, ready_for_review] branches: - 5.* - main paths: - 'build-docker-images/**' - 'multi-node/**' - 'single-node/**' - 'wazuh-agent/**' - '.github/**' workflow_dispatch: inputs: docker_reference: description: 'Branch or tag to build from' required: true type: string jobs: prepare-variables: if: ${{ !github.event.pull_request.draft }} runs-on: codebuild-github-actions-codebuild-runner-devops-amd-${{ github.run_id }}-${{ github.run_attempt }} outputs: WAZUH_VERSION: ${{ steps.dotenv.outputs.WAZUH_VERSION }} WAZUH_IMAGE_VERSION: ${{ steps.dotenv.outputs.WAZUH_IMAGE_VERSION }} WAZUH_REGISTRY: ${{ vars.IMAGE_REGISTRY_DEV }} IMAGE_TAG: ${{ steps.dotenv.outputs.IMAGE_TAG }} WAZUH_MINOR_VERSION: ${{ steps.dotenv.outputs.WAZUH_MINOR_VERSION }} steps: - name: Checkout repository uses: actions/checkout@v4 - name: Export .env variables id: dotenv shell: bash run: | if [ ! -f .env ]; then echo "::error::.env missing"; exit 1; fi grep -v '^#' .env | grep -v '^\s*$' >> "$GITHUB_OUTPUT" FULL_VERSION=$(grep "^WAZUH_VERSION=" .env | cut -d'=' -f2) MINOR_VERSION=$(echo "$FULL_VERSION" | cut -d'.' -f1,2) echo "WAZUH_MINOR_VERSION=$MINOR_VERSION" >> "$GITHUB_OUTPUT" build-images: needs: prepare-variables uses: ./.github/workflows/5_build_and_push_images.yml secrets: inherit with: image_tag: ${{ needs.prepare-variables.outputs.WAZUH_IMAGE_VERSION }} docker_reference: ${{ github.head_ref || inputs.docker_reference }} wazuh_automation_reference: '5.0.0' commit_list: '["latest", "latest", "latest", "latest"]' assistant_revision: 'latest' id: ${{ github.run_id }} dev: true Execute-Goss-tests: needs: [prepare-variables, build-images] runs-on: codebuild-github-actions-codebuild-runner-devops-amd-${{ github.run_id }}-${{ github.run_attempt }} env: WAZUH_IMAGE_VERSION: ${{ needs.prepare-variables.outputs.WAZUH_IMAGE_VERSION }} WAZUH_REGISTRY: ${{ needs.prepare-variables.outputs.WAZUH_REGISTRY }} steps: - name: Check out code uses: actions/checkout@v4 - name: Install Goss uses: e1himself/goss-installation-action@v1.0.3 with: version: 'v0.4.4' - name: Configure aws credentials uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ secrets.AWS_IAM_DOCKER_ROLE }} aws-region: "${{ secrets.AWS_REGION }}" - name: Log in to Amazon ECR uses: aws-actions/amazon-ecr-login@v2 - name: Execute Goss tests (wazuh-manager) run: dgoss run ${{ env.WAZUH_REGISTRY }}/wazuh/wazuh-manager:${{ env.WAZUH_IMAGE_VERSION }}-latest env: GOSS_SLEEP: 30 GOSS_FILE: .github/.goss.yaml check-single-node: name: Check single node on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: matrix: os: ["codebuild-github-actions-codebuild-runner-devops-amd-${{ github.run_id }}-${{ github.run_attempt }}", "codebuild-github-actions-codebuild-runner-devops-arm-${{ github.run_id }}-${{ github.run_attempt }}"] fail-fast: false needs: [prepare-variables, Execute-Goss-tests] env: WAZUH_IMAGE_VERSION: ${{ needs.prepare-variables.outputs.WAZUH_IMAGE_VERSION }} WAZUH_MINOR_VERSION: ${{ needs.prepare-variables.outputs.WAZUH_MINOR_VERSION }} WAZUH_REGISTRY: ${{ needs.prepare-variables.outputs.WAZUH_REGISTRY }} INDEXER_USERNAME: admin INDEXER_PASSWORD: admin MANAGER_NODES: "manager" API_USERNAME: wazuh-wui API_PASSWORD: wazuh-wui steps: - name: Check out code uses: actions/checkout@v4 - name: Configure aws credentials uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ secrets.AWS_IAM_DOCKER_ROLE }} aws-region: "${{ secrets.AWS_REGION }}" - name: Log in to Amazon ECR uses: aws-actions/amazon-ecr-login@v2 - name: Download artifact_urls.yaml uses: actions/download-artifact@v4 with: name: presigned-artifact-urls-${{ github.run_id }} path: ./single-node/ - name: Log in to Docker Hub uses: docker/login-action@v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - name: Add environment variables into GITHUB_ENV run: | # Export variables to the environment awk -F':' '!/^#/ && NF>1 {name=$1; val=substr($0,length(name)+3); gsub(/[-.]/,"_",name); print name "=" val}' ${{ vars.ARTIFACT_URL_FILE_NAME }} >> "$GITHUB_ENV" working-directory: ./single-node/ - name: Create single node certficates run: | curl --output ./wazuh-certs-tool.sh "${{ env.wazuh_certs_tool }}" cat > config.yml </$(ip addr show docker0 | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1)/g" wazuh-agent/docker-compose.yml - name: Edit Wazuh agent docker-compose file if: ${{ always() && steps.start_single_node_stack.outcome == 'success' }} shell: bash env: WAZUH_REGISTRY: ${{ env.WAZUH_REGISTRY }} run: | TARGET_FILE="wazuh-agent/docker-compose.yml" if [ -f "$TARGET_FILE" ]; then echo "Updating registry in $TARGET_FILE to: ${{ env.WAZUH_REGISTRY }}" sed -i "s|wazuh/wazuh-|${{ env.WAZUH_REGISTRY }}/wazuh/wazuh-|g" "$TARGET_FILE" sed -i "s/\(.*wazuh\/wazuh-.*:\)${{ env.WAZUH_IMAGE_VERSION }}/\1${{ env.WAZUH_IMAGE_VERSION }}-latest/g" "$TARGET_FILE" else echo "File $TARGET_FILE not found" exit 1 fi - name: Start Wazuh agent if: ${{ always() && steps.start_single_node_stack.outcome == 'success' }} run: docker compose up -d working-directory: ./wazuh-agent - name: Check Wazuh agent enrollment if: ${{ always() && steps.start_single_node_stack.outcome == 'success' }} run: | enrolled=false for i in {1..5}; do TOKEN=$(curl -s -u ${{ env.API_USERNAME }}:${{ env.API_PASSWORD }} -k -X POST "https://127.0.0.1:55000/security/user/authenticate?raw=true") agents="`curl -k -s -X GET "https://127.0.0.1:55000/agents?pretty=true" -H "Authorization: Bearer ${TOKEN}" | jq -r .data.affected_items | grep active | wc -l`" if [[ $agents -gt 0 ]]; then echo "Wazuh agents: ${agents}" echo "OK" enrolled=true break else curl -k -s -X GET "https://127.0.0.1:55000/agents?pretty=true" -H "Authorization: Bearer ${TOKEN}" echo "Wazuh agents: ${agents}. Retrying in 10s" [ $i -lt 5 ] && sleep 10 fi done if [[ "$enrolled" != "true" ]]; then echo "Error: Wazuh agent enrollment did not reach expected active agents threshold" exit 1 fi - name: Check errors in wazuh-manager.log for Wazuh manager if: ${{ always() && steps.start_single_node_stack.outcome == 'success' }} run: ./.github/single-node-log-check.sh - name: Check documents into wazuh-states index if: ${{ always() && steps.start_single_node_stack.outcome == 'success' }} run: | for i in {1..20}; do echo "Checking documents in wazuh-states (Attempt $i/20)..." RESPONSE=$(curl -XGET "https://127.0.0.1:9200/wazuh-states*/_count" -u ${{ env.INDEXER_USERNAME }}:${{ env.INDEXER_PASSWORD }} -k -s || echo "{}") DOCS=$(echo "$RESPONSE" | jq -r '.count // 0') if [[ "$DOCS" -gt 0 ]]; then echo "wazuh-states index has documents: ${DOCS}" exit 0 fi echo "The index is empty or does not exist yet (Count: $DOCS). Waiting 60s" [ $i -lt 20 ] && sleep 60 done echo "Error: No documents found in wazuh-states after 20 attempts." echo "Last response: $RESPONSE" exit 1 - name: Docker logs if: always() continue-on-error: true run: | INDEXER_CONTAINERS=$(docker ps --format '{{.Names}}') for CONTAINER_NAME in $INDEXER_CONTAINERS; do echo "" echo "=========================================================" echo "Container logs for $CONTAINER_NAME" echo "=========================================================" docker logs "$CONTAINER_NAME" echo "---------------------------------------------------------" done working-directory: ./single-node check-multi-node: name: Check multi node on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: matrix: os: ["codebuild-github-actions-codebuild-runner-devops-amd-${{ github.run_id }}-${{ github.run_attempt }}", "codebuild-github-actions-codebuild-runner-devops-arm-${{ github.run_id }}-${{ github.run_attempt }}"] fail-fast: false needs: [prepare-variables, Execute-Goss-tests] env: WAZUH_IMAGE_VERSION: ${{ needs.prepare-variables.outputs.WAZUH_IMAGE_VERSION }} WAZUH_MINOR_VERSION: ${{ needs.prepare-variables.outputs.WAZUH_MINOR_VERSION }} WAZUH_REGISTRY: ${{ needs.prepare-variables.outputs.WAZUH_REGISTRY }} INDEXER_USERNAME: admin INDEXER_PASSWORD: admin MANAGER_NODES: "master,worker01" API_USERNAME: wazuh-wui API_PASSWORD: wazuh-wui steps: - name: Check out code uses: actions/checkout@v4 - name: Configure aws credentials uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: ${{ secrets.AWS_IAM_DOCKER_ROLE }} aws-region: "${{ secrets.AWS_REGION }}" - name: Log in to Amazon ECR uses: aws-actions/amazon-ecr-login@v2 - name: Download artifact_urls.yaml uses: actions/download-artifact@v4 with: name: presigned-artifact-urls-${{ github.run_id }} path: ./multi-node/ - name: Log in to Docker Hub uses: docker/login-action@v4 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_PASSWORD }} - name: Add environment variables into GITHUB_ENV run: | # Export variables to the environment awk -F':' '!/^#/ && NF>1 {name=$1; val=substr($0,length(name)+3); gsub(/[-.]/,"_",name); print name "=" val}' ${{ vars.ARTIFACT_URL_FILE_NAME }} >> "$GITHUB_ENV" working-directory: ./multi-node/ - name: Create multi node certficates run: | curl --output ./wazuh-certs-tool.sh "${{ env.wazuh_certs_tool }}" cat > config.yml </$(ip addr show docker0 | grep 'inet ' | awk '{print $2}' | cut -d'/' -f1)/g" wazuh-agent/docker-compose.yml - name: Edit Wazuh agent docker-compose file if: ${{ always() && steps.start_multi_node_stack.outcome == 'success' }} shell: bash env: WAZUH_REGISTRY: ${{ env.WAZUH_REGISTRY }} run: | TARGET_FILE="wazuh-agent/docker-compose.yml" if [ -f "$TARGET_FILE" ]; then echo "Updating registry in $TARGET_FILE to: ${{ env.WAZUH_REGISTRY }}" sed -i "s|wazuh/wazuh-|${{ env.WAZUH_REGISTRY }}/wazuh/wazuh-|g" "$TARGET_FILE" sed -i "s/\(.*wazuh\/wazuh-.*:\)${{ env.WAZUH_IMAGE_VERSION }}/\1${{ env.WAZUH_IMAGE_VERSION }}-latest/g" "$TARGET_FILE" else echo "File $TARGET_FILE not found" exit 1 fi - name: Start Wazuh agent if: ${{ always() && steps.start_multi_node_stack.outcome == 'success' }} run: docker compose -f wazuh-agent/docker-compose.yml up -d - name: Check Wazuh agent enrollment if: ${{ always() && steps.start_multi_node_stack.outcome == 'success' }} run: | enrolled=false for i in {1..5}; do TOKEN=$(curl -s -u ${{ env.API_USERNAME }}:${{ env.API_PASSWORD }} -k -X POST "https://127.0.0.1:55000/security/user/authenticate?raw=true") agents="`curl -k -s -X GET "https://127.0.0.1:55000/agents?pretty=true" -H "Authorization: Bearer ${TOKEN}" | jq -r .data.affected_items | grep active | wc -l`" if [[ $agents -gt 0 ]]; then echo "Wazuh agents: ${agents}" echo "OK" enrolled=true break else curl -k -s -X GET "https://127.0.0.1:55000/agents?pretty=true" -H "Authorization: Bearer ${TOKEN}" echo "Wazuh agents: ${agents}. Retrying in 10s" [ $i -lt 5 ] && sleep 10 fi done if [[ "$enrolled" != "true" ]]; then echo "Error: Wazuh agent enrollment did not reach expected active agents threshold" exit 1 fi - name: Check errors in wazuh-manager.log for Wazuh manager if: ${{ always() && steps.start_multi_node_stack.outcome == 'success' }} run: ./.github/multi-node-log-check.sh - name: Check documents into wazuh-states index if: ${{ always() && steps.start_multi_node_stack.outcome == 'success' }} run: | for i in {1..20}; do echo "Checking documents in wazuh-states (Attempt $i/20)..." RESPONSE=$(curl -XGET "https://127.0.0.1:9200/wazuh-states*/_count" -u ${{ env.INDEXER_USERNAME }}:${{ env.INDEXER_PASSWORD }} -k -s || echo "{}") DOCS=$(echo "$RESPONSE" | jq -r '.count // 0') if [[ "$DOCS" -gt 0 ]]; then echo "wazuh-states index has documents: ${DOCS}" exit 0 fi echo "The index is empty or does not exist yet (Count: $DOCS). Waiting 60s" [ $i -lt 20 ] && sleep 60 done echo "Error: No documents found in wazuh-states after 20 attempts." echo "Last response: $RESPONSE" exit 1 - name: Docker logs if: always() continue-on-error: true run: | INDEXER_CONTAINERS=$(docker ps --format '{{.Names}}') for CONTAINER_NAME in $INDEXER_CONTAINERS; do echo "" echo "=========================================================" echo "Container logs for $CONTAINER_NAME" echo "=========================================================" docker logs "$CONTAINER_NAME" echo "---------------------------------------------------------" done working-directory: ./multi-node