Merge branch '5.0.0' into bug/2477-bumper-script-issue-when-the-tag-is-set-to-false

This commit is contained in:
Carlos Anguita
2026-07-02 11:54:09 +02:00
committed by GitHub
8 changed files with 460 additions and 1780 deletions
@@ -155,6 +155,12 @@ jobs:
with:
ref: ${{ inputs.docker_reference }}
- name: Log in to Docker Hub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
@@ -172,12 +178,6 @@ jobs:
if: ${{ inputs.dev == true }}
uses: aws-actions/amazon-ecr-login@v2
- name: Log in to Docker Hub
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Build Wazuh images
run: |
IMAGE_TAG="${{ inputs.image_tag }}"
@@ -81,6 +81,8 @@ on:
permissions:
id-token: write
contents: read
env:
LOCAL_ARTIFACT_URLS_FILEPATH: /tmp/${{ vars.ARTIFACT_URL_FILE_NAME }}
jobs:
setup:
@@ -166,7 +168,6 @@ jobs:
WORKFLOW_VENV: "${{ github.workspace }}/workflow_venv"
GENERATE_PRESIGNED_URLS_SCRIPT_PATH: ${{ github.workspace }}/wazuh-automation/tools/sign_urls/generate_presigned_dev_urls.py
PRESIGNED_URLS_SCRIPT_PROCESS: "build_docker"
LOCAL_ARTIFACT_URLS_FILEPATH: /tmp/${{ vars.ARTIFACT_URL_FILE_NAME }}
COMMIT_LIST: ${{ inputs.commit_list }}
ASSISTANT_REVISION: ${{ inputs.assistant_revision }}
@@ -284,10 +285,9 @@ jobs:
- name: Save presigned URLs file to artifact
if: ${{ inputs.dev == true }}
uses: actions/upload-artifact@v4
with:
name: presigned-artifact-urls-${{ github.run_id }}
path: ${{ env.LOCAL_ARTIFACT_URLS_FILEPATH }}
run: |
echo "Uploading presigned URLs artifact..."
aws s3 cp "${{ env.LOCAL_ARTIFACT_URLS_FILEPATH }}" "s3://${{ secrets.CI_DEV_INTERNAL_S3_BUCKET }}/wazuh-docker/5_build_and_push_images/${{ github.run_id }}/${{ vars.ARTIFACT_URL_FILE_NAME }}"
build-and-push:
runs-on: codebuild-github-actions-codebuild-runner-devops-amd-${{ github.run_id }}-${{ github.run_attempt }}
@@ -337,10 +337,10 @@ jobs:
- name: Download artifact_urls.yaml (dev)
if: ${{ inputs.dev == true }}
uses: actions/download-artifact@v4
with:
name: presigned-artifact-urls-${{ github.run_id }}
path: ./build-docker-images
run: |
echo "Downloading presigned URLs artifact..."
aws s3 cp "s3://${{ secrets.CI_DEV_INTERNAL_S3_BUCKET }}/wazuh-docker/5_build_and_push_images/${{ github.run_id }}/${{ vars.ARTIFACT_URL_FILE_NAME }}" "${{ env.LOCAL_ARTIFACT_URLS_FILEPATH }}"
mv "${{ env.LOCAL_ARTIFACT_URLS_FILEPATH }}" ./build-docker-images/${{ vars.ARTIFACT_URL_FILE_NAME }}
- name: Compute component reference (dev)
if: ${{ inputs.dev == true }}
+16 -2
View File
@@ -37,6 +37,11 @@ on:
default: false
required: false
type: boolean
bump-issue-link:
description: 'Issue link used in the original bump (required for revert if different from issue-link)'
required: false
type: string
jobs:
bump:
name: Repository bumper 5.x
@@ -152,9 +157,18 @@ jobs:
id: revert_step
if: inputs.revert == true
run: |
# 1. Get the current issue number (for the new revert branch/PR)
ISSUE_NUMBER=$(echo "${{ inputs.issue-link }}" | awk -F'/' '{print $NF}')
BUMP_BRANCH="enhancement/wqa${ISSUE_NUMBER}-bump-${{ github.ref_name }}"
# 2. Get the issue number from the original bump (if provided; otherwise, defaults to the current one)
if [ -n "${{ inputs.bump-issue-link }}" ]; then
BUMP_ISSUE_NUMBER=$(echo "${{ inputs.bump-issue-link }}" | awk -F'/' '{print $NF}')
else
BUMP_ISSUE_NUMBER=$ISSUE_NUMBER
fi
# 3. Search for the original bump branch using the obtained BUMP ISSUE number
BUMP_BRANCH="enhancement/wqa${BUMP_ISSUE_NUMBER}-bump-${{ github.ref_name }}"
PR_NUMBER=$(gh pr list --head "$BUMP_BRANCH" --base "${{ github.ref_name }}" --state merged --json number --jq '.[0].number')
@@ -173,7 +187,7 @@ jobs:
# Remove the files to prevent them from being included in the revert commit
git checkout HEAD -- VERSION.json 2>/dev/null || true
git checkout HEAD -- CHANGELOG.md 2>/dev/null || true
# Add any other repository-specific version files here
# [!] ADD ANY OTHER REPOSITORY-SPECIFIC VERSION FILES HERE [!]
if git diff --staged --quiet; then
echo "No references to revert. Skipping commit."
+33 -24
View File
@@ -53,6 +53,7 @@ env:
AUTOMATION_REFERENCE: ${{ inputs.automation_reference || 'main' }}
ALLOCATOR_PATH: /tmp/allocator_instance
REGION: us-east-1
LOGS_ARTIFACT_ZIP_FILE: "docker_logs_artifacts_${{ github.run_id }}.zip"
jobs:
# -------------------------------------------------------------------------
@@ -176,8 +177,8 @@ jobs:
echo "deployment_matrix=[\"${DEPLOY_TYPE}\"]" >> $GITHUB_OUTPUT
fi
else
echo "pr_head_ref=${{ needs.get_pr_info.outputs.pr_head_ref }}" >> $GITHUB_OUTPUT
echo "deployment_matrix=${{ needs.get_pr_info.outputs.deployment_matrix }}" >> $GITHUB_OUTPUT
echo 'pr_head_ref=${{ needs.get_pr_info.outputs.pr_head_ref }}' >> $GITHUB_OUTPUT
echo 'deployment_matrix=${{ needs.get_pr_info.outputs.deployment_matrix }}' >> $GITHUB_OUTPUT
fi
- name: Checkout wazuh-docker PR branch (VERSION.json only)
@@ -409,6 +410,7 @@ jobs:
pip install -r wazuh-automation/deployability/deps/requirements.txt
pip install -r wazuh-automation/integration-test-module/requirements.txt
pip install -e wazuh-automation/integration-test-module/
pip install pyyaml
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
@@ -417,6 +419,19 @@ jobs:
role-session-name: docker-test-${{ github.run_id }}-${{ matrix.deployment_type }}
aws-region: ${{ env.REGION }}
- name: Generate presigned cert tool URL
run: |
python wazuh-automation/tools/sign_urls/generate_presigned_dev_urls.py \
--process build_docker \
--wazuh-version "${{ env.DOCKER_VERSION }}" \
--aws-s3-bucket-dev "${{ vars.AWS_S3_BUCKET_DEV }}"
python3 -c "
import yaml
data = yaml.safe_load(open('/tmp/artifact_urls.yaml'))
print(f'wazuh_certs_tool={data[\"wazuh_certs_tool\"]}')
" >> "$GITHUB_ENV"
# -----------------------------------------------------------------------
# Provision: allocate VM and extract SSH credentials
# -----------------------------------------------------------------------
@@ -502,20 +517,10 @@ jobs:
- name: Prepare cert tool and config
run: |
DEPLOYMENT="${{ matrix.deployment_type }}"
VERSION="${{ env.WAZUH_VERSION }}"
STAGE="${{ env.WAZUH_STAGE }}"
MAJOR=$(echo "$VERSION" | cut -d. -f1)
echo "Cert tool: ${VERSION}-${STAGE} Docker image: ${{ env.DOCKER_TAG }}"
echo "Cert tool: ${{ env.wazuh_certs_tool }} Docker image: ${{ env.DOCKER_TAG }}"
# Download cert tool once on the runner
if [ -n "$STAGE" ]; then
CERT_TOOL_URL="https://packages-staging.xdrsiem.wazuh.info/pre-release/${MAJOR}.x/installation-assistant/wazuh-certs-tool-${VERSION}-${STAGE}.sh"
else
CERT_TOOL_URL="https://packages.wazuh.com/${MAJOR}.$(echo "$VERSION" | cut -d. -f2)/wazuh-certs-tool-${VERSION}-1.sh"
fi
echo "Downloading cert tool: $CERT_TOOL_URL"
curl -fsSL -o "wazuh-docker/${DEPLOYMENT}/wazuh-certs-tool.sh" "$CERT_TOOL_URL"
curl --output "wazuh-docker/${DEPLOYMENT}/wazuh-certs-tool.sh" "${{ env.wazuh_certs_tool }}"
chmod +x "wazuh-docker/${DEPLOYMENT}/wazuh-certs-tool.sh"
echo "Downloaded OK"
@@ -732,11 +737,10 @@ jobs:
- name: Upload Docker logs
if: failure() || steps.run_tests.outcome == 'failure'
uses: actions/upload-artifact@v4
with:
name: docker-logs-${{ matrix.deployment_type }}-${{ github.run_id }}
path: docker-logs-*.txt
retention-days: 7
run: |
echo "Uploading Docker logs artifact..."
zip "${{ env.LOGS_ARTIFACT_ZIP_FILE }}" docker-logs-*.txt
aws s3 cp "${{ env.LOGS_ARTIFACT_ZIP_FILE }}" "s3://${{ secrets.CI_DEV_INTERNAL_S3_BUCKET }}/wazuh-docker/5_check_integration_tools/${{ github.run_id }}/${{ env.LOGS_ARTIFACT_ZIP_FILE }}"
# -----------------------------------------------------------------------
# Reporting
@@ -810,11 +814,16 @@ jobs:
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: test-results-docker-${{ matrix.deployment_type }}-${{ github.run_id }}
path: test-results-docker-${{ matrix.deployment_type }}.github
retention-days: 7
env:
S3_ARTIFACTS_PATH: s3://${{ secrets.CI_DEV_INTERNAL_S3_BUCKET }}/wazuh-docker/5_check_integration_tools/${{ github.run_id }}
LOCAL_RESULTS_PATH: test-results-docker-${{ matrix.deployment_type }}.github
run: |
if [ -f "${LOCAL_RESULTS_PATH}" ]; then
echo "Uploading test results to S3..."
aws s3 cp "${LOCAL_RESULTS_PATH}" "${S3_ARTIFACTS_PATH}/test-results-docker-${{ matrix.deployment_type }}/"
else
echo "::warning::No test results file found - skipping upload (an earlier step likely failed before test_runner produced output)."
fi
# -----------------------------------------------------------------------
# Cleanup: always stop stack and deallocate VM
-664
View File
@@ -1,664 +0,0 @@
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 <<EOF
nodes:
# Wazuh indexer server nodes
indexer:
- name: wazuh.indexer
dns: "wazuh.indexer"
# Wazuh manager nodes
# Use node_type only with more than one Wazuh manager
manager:
- name: wazuh.manager
dns: "wazuh.manager"
# Wazuh dashboard node
dashboard:
- name: wazuh.dashboard
dns: "wazuh.dashboard"
EOF
cat config.yml
sudo bash ../tools/utils/deployment/certificates-conf.sh --cert --copy --priv
sudo sysctl -w vm.max_map_count=262144
working-directory: ./single-node
- name: Edit single node docker-compose file
shell: bash
env:
WAZUH_REGISTRY: ${{ env.WAZUH_REGISTRY }}
run: |
TARGET_FILE="single-node/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 single node stack
id: start_single_node_stack
run: docker compose up -d
working-directory: ./single-node
- name: Check Wazuh indexer start
if: ${{ always() && steps.start_single_node_stack.outcome == 'success' }}
run: |
for i in {1..20}; do
echo "Checking Wazuh indexer health (Attempt $i/20)"
RESPONSE=$(curl -XGET "https://127.0.0.1:9200/_cluster/health?pretty" -u ${{ env.INDEXER_USERNAME }}:${{ env.INDEXER_PASSWORD }} -k -s --retry 2 || true)
INDEXER_CONTAINERS=$(docker ps --format '{{.Names}}' | grep "indexer")
if echo "$RESPONSE" | grep -qE "green|yellow"; then
echo "Cluster Online"
echo "$RESPONSE"
exit 0
fi
echo "Waiting for cluster to be online"
for CONTAINER_NAME in $INDEXER_CONTAINERS; do
echo ""
echo "========================================================="
echo "Container logs for $CONTAINER_NAME"
echo "========================================================="
docker logs --tail 30 "$CONTAINER_NAME"
echo "---------------------------------------------------------"
done
[ $i -lt 20 ] && sleep 60
done
status_index="`curl -XGET "https://127.0.0.1:9200/_cat/indices" -u ${{ env.INDEXER_USERNAME }}:${{ env.INDEXER_PASSWORD }} -k -s | wc -l`"
status_index_green="`curl -XGET "https://127.0.0.1:9200/_cat/indices" -u ${{ env.INDEXER_USERNAME }}:${{ env.INDEXER_PASSWORD }} -k -s | grep -E "green|yellow" | wc -l`"
if [[ $status_index_green -eq $status_index ]]; then
curl -XGET "https://127.0.0.1:9200/_cat/indices" -u ${{ env.INDEXER_USERNAME }}:${{ env.INDEXER_PASSWORD }} -k -s
else
curl -XGET "https://127.0.0.1:9200/_cat/indices" -u ${{ env.INDEXER_USERNAME }}:${{ env.INDEXER_PASSWORD }} -k -s
exit 1
fi
- name: Check Wazuh indexer nodes
if: ${{ always() && steps.start_single_node_stack.outcome == 'success' }}
run: |
nodes="`curl -XGET "https://127.0.0.1:9200/_cat/nodes" -u ${{ env.INDEXER_USERNAME }}:${{ env.INDEXER_PASSWORD }} -k -s | grep -E "indexer" | wc -l`"
echo "Wazuh indexer nodes: ${nodes}"
- name: Check Wazuh templates
if: ${{ always() && steps.start_single_node_stack.outcome == 'success' }}
run: |
qty_templates="`curl -XGET "https://127.0.0.1:9200/_cat/templates" -u ${{ env.INDEXER_USERNAME }}:${{ env.INDEXER_PASSWORD }} -k -s | grep -P "wazuh|wazuh-agent|wazuh-statistics" | wc -l`"
templates="`curl -XGET "https://127.0.0.1:9200/_cat/templates" -u ${{ env.INDEXER_USERNAME }}:${{ env.INDEXER_PASSWORD }} -k -s | grep -P "wazuh|wazuh-agent|wazuh-statistics"`"
if [[ $qty_templates -gt 3 ]]; then
echo "wazuh templates:"
echo "${templates}"
else
echo "wazuh templates:"
echo "${templates}"
exit 1
fi
- name: Check Wazuh manager start
if: ${{ always() && steps.start_single_node_stack.outcome == 'success' }}
run: |
for NODE in "${{ env.MANAGER_NODES }}"; do
ok=false
for i in {1..20}; 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")
services="`curl -k -s -X GET "https://127.0.0.1:55000/cluster/$NODE/status?pretty=true" -H "Authorization: Bearer ${TOKEN}" | jq -r .data.affected_items | grep running | wc -l`"
if [[ $services -gt 7 ]]; then
echo "Wazuh Manager $NODE Services: ${services}"
echo "OK"
ok=true
break
else
curl -k -X GET "https://127.0.0.1:55000/cluster/$NODE/status?pretty=true" -H "Authorization: Bearer ${TOKEN}" | jq -r .data.affected_items
echo "Wazuh Manager $NODE Services: ${services}. Retrying in 30s"
[ $i -lt 20 ] && sleep 30
fi
done
if [[ "$ok" != "true" ]]; then
echo "Error: Wazuh Manager $NODE did not reach expected running services threshold"
exit 1
fi
done
- name: Check Wazuh dashboard service URL
if: ${{ always() && steps.start_single_node_stack.outcome == 'success' }}
run: |
for i in {1..20}; do
echo "Checking Wazuh dashboard (Attempt $i/20)"
STATUS=$(curl -k -s -o /dev/null -w "%{http_code}" -u ${{ env.INDEXER_USERNAME }}:${{ env.INDEXER_PASSWORD }} "https://127.0.0.1:443/app/status" || true)
echo "Current status: $STATUS"
if [[ "$STATUS" == "200" ]]; then
echo "Wazuh dashboard is UP"
exit 0
elif [[ "$STATUS" == "429" || "$STATUS" == "503" ]]; then
echo "Dashboard is busy or initializing (Status $STATUS). Retrying in 30s"
else
echo "Unexpected status $STATUS. Retrying in 30s"
fi
sleep 30
done
echo "Error: Dashboard did not reach 200 status in time."
exit 1
- name: Modify Docker endpoint into Wazuh agent docker-compose.yml file
if: ${{ always() && steps.start_single_node_stack.outcome == 'success' }}
run: sed -i "s/<WAZUH_MANAGER_IP>/$(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 <<EOF
nodes:
# Wazuh indexer server nodes
indexer:
- name: wazuh1.indexer
dns: "wazuh1.indexer"
- name: wazuh2.indexer
dns: "wazuh2.indexer"
- name: wazuh3.indexer
dns: "wazuh3.indexer"
# Wazuh manager nodes
# Use node_type only with more than one Wazuh manager
manager:
- name: wazuh.master
dns: "wazuh.master"
node_type: master
- name: wazuh.worker
dns: "wazuh.worker"
node_type: worker
# Wazuh dashboard node
dashboard:
- name: wazuh.dashboard
dns: "wazuh.dashboard"
EOF
cat config.yml
sudo bash ../tools/utils/deployment/certificates-conf.sh --cert --copy --priv
sudo sysctl -w vm.max_map_count=262144
working-directory: ./multi-node
- name: Edit multi node docker-compose file
shell: bash
run: |
TARGET_FILE="multi-node/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 multi node stack
id: start_multi_node_stack
run: docker compose up -d
working-directory: ./multi-node
- name: Check Wazuh indexer start
if: ${{ always() && steps.start_multi_node_stack.outcome == 'success' }}
run: |
for i in {1..20}; do
echo "Checking Wazuh indexer health (Attempt $i/20)"
RESPONSE=$(curl -XGET "https://127.0.0.1:9200/_cluster/health?pretty" -u ${{ env.INDEXER_USERNAME }}:${{ env.INDEXER_PASSWORD }} -k -s --retry 2 || true)
INDEXER_CONTAINERS=$(docker ps --format '{{.Names}}' | grep "indexer")
if echo "$RESPONSE" | grep -qE "green|yellow"; then
echo "Cluster Online"
echo "$RESPONSE"
exit 0
fi
echo "Waiting for cluster to be online"
for CONTAINER_NAME in $INDEXER_CONTAINERS; do
echo ""
echo "========================================================="
echo "Container logs for $CONTAINER_NAME"
echo "========================================================="
docker logs --tail 30 "$CONTAINER_NAME"
echo "---------------------------------------------------------"
done
[ $i -lt 20 ] && sleep 60
done
status_index="`curl -XGET "https://127.0.0.1:9200/_cat/indices" -u ${{ env.INDEXER_USERNAME }}:${{ env.INDEXER_PASSWORD }} -k -s | wc -l`"
status_index_green="`curl -XGET "https://127.0.0.1:9200/_cat/indices" -u ${{ env.INDEXER_USERNAME }}:${{ env.INDEXER_PASSWORD }} -k -s | grep -E "green" | wc -l`"
if [[ $status_index_green -eq $status_index ]]; then
curl -XGET "https://127.0.0.1:9200/_cat/indices" -u ${{ env.INDEXER_USERNAME }}:${{ env.INDEXER_PASSWORD }} -k -s
else
curl -XGET "https://127.0.0.1:9200/_cat/indices" -u ${{ env.INDEXER_USERNAME }}:${{ env.INDEXER_PASSWORD }} -k -s
exit 1
fi
- name: Check Wazuh indexer nodes
if: ${{ always() && steps.start_multi_node_stack.outcome == 'success' }}
run: |
nodes="`curl -XGET "https://127.0.0.1:9200/_cat/nodes" -u ${{ env.INDEXER_USERNAME }}:${{ env.INDEXER_PASSWORD }} -k -s | grep -E "indexer" | wc -l`"
if [[ $nodes -eq 3 ]]; then
echo "Wazuh indexer nodes: ${nodes}"
else
echo "Wazuh indexer nodes: ${nodes}"
exit 1
fi
- name: Check Wazuh templates
if: ${{ always() && steps.start_multi_node_stack.outcome == 'success' }}
run: |
qty_templates="`curl -XGET "https://127.0.0.1:9200/_cat/templates" -u ${{ env.INDEXER_USERNAME }}:${{ env.INDEXER_PASSWORD }} -k -s | grep "wazuh" | wc -l`"
templates="`curl -XGET "https://127.0.0.1:9200/_cat/templates" -u ${{ env.INDEXER_USERNAME }}:${{ env.INDEXER_PASSWORD }} -k -s | grep "wazuh"`"
if [[ $qty_templates -gt 3 ]]; then
echo "wazuh templates:"
echo "${templates}"
else
echo "wazuh templates:"
echo "${templates}"
exit 1
fi
- name: Check Wazuh manager start
if: ${{ always() && steps.start_multi_node_stack.outcome == 'success' }}
run: |
IFS=',' read -r -a NODES <<< "${{ env.MANAGER_NODES }}"
for NODE in "${NODES[@]}"; do
if [[ "$NODE" == "master" ]]; then
THRESHOLD=8
else
THRESHOLD=7
fi
ok=false
for i in {1..20}; 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")
services="`curl -k -s -X GET "https://127.0.0.1:55000/cluster/$NODE/status?pretty=true" -H "Authorization: Bearer ${TOKEN}" | jq -r .data.affected_items | grep running | wc -l`"
if [[ $services -ge $THRESHOLD ]]; then
echo "Wazuh Manager $NODE Services: ${services}"
echo "OK"
ok=true
break
else
curl -k -X GET "https://127.0.0.1:55000/cluster/$NODE/status?pretty=true" -H "Authorization: Bearer ${TOKEN}" | jq -r .data.affected_items
echo "Wazuh Manager $NODE Services: ${services}. Retrying in 30s"
[ $i -lt 20 ] && sleep 30
fi
done
if [[ "$ok" != "true" ]]; then
echo "Error: Wazuh Manager $NODE did not reach expected running services threshold"
exit 1
fi
done
- name: Check Wazuh dashboard service URL
if: ${{ always() && steps.start_multi_node_stack.outcome == 'success' }}
run: |
for i in {1..20}; do
echo "Checking Wazuh dashboard (Attempt $i/20)"
STATUS=$(curl -k -s -o /dev/null -w "%{http_code}" -u ${{ env.INDEXER_USERNAME }}:${{ env.INDEXER_PASSWORD }} "https://127.0.0.1:443/app/status" || true)
echo "Current status: $STATUS"
if [[ "$STATUS" == "200" ]]; then
echo "Wazuh dashboard is UP"
exit 0
elif [[ "$STATUS" == "429" || "$STATUS" == "503" ]]; then
echo "Dashboard is busy or initializing (Status $STATUS). Retrying in 30s"
else
echo "Unexpected status $STATUS. Retrying in 30s"
fi
sleep 30
done
echo "Error: Dashboard did not reach 200 status in time."
exit 1
- name: Modify Docker endpoint into Wazuh agent docker-compose.yml file
if: ${{ always() && steps.start_multi_node_stack.outcome == 'success' }}
run: sed -i "s/<WAZUH_MANAGER_IP>/$(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