Resolving conflicts

This commit is contained in:
Victor Carlos Erenu
2026-04-17 01:37:11 +07:00
116 changed files with 5706 additions and 4669 deletions
+4 -4
View File
@@ -1,4 +1,4 @@
name: Repository bumper
name: Repository bumper 4.x
run-name: Bump ${{ github.ref_name }} (${{ inputs.id }})
on:
@@ -30,8 +30,8 @@ on:
jobs:
bump:
name: Repository bumper
runs-on: ubuntu-22.04
name: Repository bumper 4.x
runs-on: ubuntu-24.04
permissions:
contents: write
pull-requests: write
@@ -139,4 +139,4 @@ jobs:
echo "Branch: ${{ steps.vars.outputs.branch_name }}"
echo "PR: ${{ steps.create_pr.outputs.pull_request_url }}"
echo "Bumper scripts logs:"
cat ${BUMP_LOG_PATH}/repository_bumper*log
cat ${BUMP_LOG_PATH}/repository_bumper*log
+153
View File
@@ -0,0 +1,153 @@
name: Repository bumper 5.x
run-name: Bump ${{ github.ref_name }} (${{ inputs.id }})
on:
workflow_dispatch:
inputs:
version:
description: 'Target version (e.g. 1.2.3)'
default: ''
required: false
type: string
stage:
description: 'Version stage (e.g. alpha0)'
default: ''
required: false
type: string
tag:
description: 'Change branches references to tag-like references (e.g. v4.12.0-alpha7)'
default: false
required: false
type: boolean
set_as_main:
description: "Enable main branch mode: bump version values only, keep branch references pointing to main"
required: false
type: boolean
default: false
issue-link:
description: 'Issue link in format https://github.com/wazuh/<REPO>/issues/<ISSUE-NUMBER>'
required: true
type: string
id:
description: 'Optional identifier for the run'
required: false
type: string
jobs:
bump:
name: Repository bumper 5.x
runs-on: ubuntu-24.04
permissions:
contents: write
pull-requests: write
env:
CI_COMMIT_AUTHOR: wazuhci
CI_COMMIT_EMAIL: 22834044+wazuhci@users.noreply.github.com
CI_GPG_PRIVATE_KEY: ${{ secrets.CI_WAZUHCI_GPG_PRIVATE }}
GH_TOKEN: ${{ secrets.CI_WAZUHCI_BUMPER_TOKEN }}
BUMP_SCRIPT_PATH: tools/repository_bumper.sh
BUMP_LOG_PATH: tools
steps:
- name: Dump event payload
run: |
cat $GITHUB_EVENT_PATH | jq '.inputs'
- name: Set up GPG key
id: signing_setup
run: |
echo "${{ env.CI_GPG_PRIVATE_KEY }}" | gpg --batch --import
KEY_ID=$(gpg --list-secret-keys --with-colons | awk -F: '/^sec/ {print $5; exit}')
echo "gpg_key_id=$KEY_ID" >> $GITHUB_OUTPUT
- name: Set up git
run: |
git config --global user.name "${{ env.CI_COMMIT_AUTHOR }}"
git config --global user.email "${{ env.CI_COMMIT_EMAIL }}"
git config --global commit.gpgsign true
git config --global user.signingkey "${{ steps.signing_setup.outputs.gpg_key_id }}"
echo "use-agent" >> ~/.gnupg/gpg.conf
echo "pinentry-mode loopback" >> ~/.gnupg/gpg.conf
echo "allow-loopback-pinentry" >> ~/.gnupg/gpg-agent.conf
echo RELOADAGENT | gpg-connect-agent
export DEBIAN_FRONTEND=noninteractive
export GPG_TTY=$(tty)
- name: Checkout repository
uses: actions/checkout@v6
with:
# Using workflow-specific GITHUB_TOKEN because currently CI_WAZUHCI_BUMPER_TOKEN
# doesn't have all the necessary permissions
token: ${{ env.GH_TOKEN }}
- name: Determine branch name
id: vars
env:
VERSION: ${{ inputs.version }}
STAGE: ${{ inputs.stage }}
TAG: ${{ inputs.tag }}
run: |
script_params=""
version=${{ env.VERSION }}
stage=${{ env.STAGE }}
tag=${{ env.TAG }}
set_as_main=${{ inputs.set_as_main }}
if [[ "$set_as_main" == "true" ]]; then
script_params="--set-as-main"
fi
# Both version and stage provided
if [[ -n "$version" && -n "$stage" && "$tag" != "true" ]]; then
script_params+=" --version ${version} --stage ${stage}"
elif [[ -n "$version" && -n "$stage" && "$tag" == "true" ]]; then
script_params+=" --version ${version} --stage ${stage} --tag ${tag}"
fi
issue_number=$(echo "${{ inputs.issue-link }}" | awk -F'/' '{print $NF}')
BRANCH_NAME="enhancement/wqa${issue_number}-bump-${{ github.ref_name }}"
echo "branch_name=$BRANCH_NAME" >> $GITHUB_OUTPUT
echo "script_params=${script_params}" >> $GITHUB_OUTPUT
- name: Create and switch to bump branch
run: |
git checkout -b ${{ steps.vars.outputs.branch_name }}
- name: Make version bump changes
run: |
echo "Running bump script"
bash ${{ env.BUMP_SCRIPT_PATH }} ${{ steps.vars.outputs.script_params }}
- name: Commit and push changes
run: |
git add .
git commit -m "feat: bump ${{ github.ref_name }}"
git push origin ${{ steps.vars.outputs.branch_name }}
- name: Create pull request
id: create_pr
run: |
gh auth setup-git
PR_URL=$(gh pr create \
--title "Bump ${{ github.ref_name }} branch" \
--body "Issue: ${{ inputs.issue-link }}" \
--base ${{ github.ref_name }} \
--head ${{ steps.vars.outputs.branch_name }})
echo "Pull request created: ${PR_URL}"
echo "pull_request_url=${PR_URL}" >> $GITHUB_OUTPUT
- name: Merge pull request
run: |
# Any checks for the PR are bypassed since the branch is expected to be functional (i.e. the bump process does not introduce any bugs)
gh pr merge "${{ steps.create_pr.outputs.pull_request_url }}" --merge --admin
- name: Show logs
run: |
echo "Bump complete."
echo "Branch: ${{ steps.vars.outputs.branch_name }}"
echo "PR: ${{ steps.create_pr.outputs.pull_request_url }}"
echo "Bumper scripts logs:"
cat ${BUMP_LOG_PATH}/repository_bumper*log
+643
View File
@@ -0,0 +1,643 @@
name: Wazuh Docker pipeline
permissions:
contents: read
id-token: write
on:
pull_request:
workflow_dispatch:
inputs:
docker_reference:
description: 'Branch or tag to build from'
required: true
type: string
jobs:
prepare-variables:
runs-on: ubuntu-latest
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/Procedure_push_docker_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: 'main'
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: ubuntu-22.04
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 }}
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: [ubuntu-22.04, ubuntu-22.04-arm]
fail-fast: false
needs: [prepare-variables, Execute-Goss-tests, build-images]
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: free disk space
uses: ./.github/free-disk-space
- 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: 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"
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"
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: [ubuntu-22.04, ubuntu-22.04-arm]
fail-fast: false
needs: [prepare-variables, Execute-Goss-tests, build-images]
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: free disk space
uses: ./.github/free-disk-space
- 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: 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"
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"
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
@@ -6,25 +6,29 @@ on:
inputs:
image_tag:
description: 'Docker image tag'
default: '4.14.6'
default: '5.0.0'
required: true
docker_reference:
description: 'wazuh-docker reference'
required: true
filebeat_module_version:
description: 'Filebeat module version'
default: '0.5'
required: true
type: string
wazuh_automation_reference:
description: 'Branch or tag of the wazuh-automation repository'
required: false
default: 'main'
products:
description: 'Comma-separated list of the image names to build and push'
default: 'wazuh-manager,wazuh-dashboard,wazuh-indexer,wazuh-agent'
required: false
type: string
revision:
description: 'Package revision'
default: '1'
required: true
commit_list:
description: 'Wazuh components revisions (only for dev): json array with commit-hash for each product'
type: string
default: '["latest", "latest", "latest", "latest"]'
assistant_revision:
description: 'Revision for Wazuh installation assistant tools like Wazuh password tool (only for dev)'
type: string
default: 'latest'
required: false
id:
description: "ID used to identify the workflow uniquely."
type: string
@@ -38,28 +42,32 @@ on:
inputs:
image_tag:
description: 'Docker image tag'
default: '4.14.6'
default: '5.0.0'
required: true
type: string
docker_reference:
description: 'wazuh-docker reference'
required: false
type: string
filebeat_module_version:
description: 'Filebeat module version'
default: '0.5'
required: true
wazuh_automation_reference:
description: 'Branch or tag of the wazuh-automation repository'
required: false
default: 'main'
type: string
products:
description: 'Comma-separated list of the image names to build and push'
default: 'wazuh-manager,wazuh-dashboard,wazuh-indexer,wazuh-agent'
required: false
type: string
revision:
description: 'Package revision'
default: '1'
required: true
commit_list:
description: 'Wazuh components revisions (only for dev): json array with commit-hash for each product'
type: string
default: '["latest", "latest", "latest", "latest"]'
assistant_revision:
description: 'Revision for Wazuh installation assistant tools like Wazuh password tool (only for dev)'
type: string
default: 'latest'
required: false
id:
description: "ID used to identify the workflow uniquely."
type: string
@@ -70,23 +78,18 @@ on:
default: false
required: false
jobs:
setup:
runs-on: ubuntu-22.04
permissions:
permissions:
id-token: write
contents: read
env:
IMAGE_REGISTRY: ${{ inputs.dev && vars.IMAGE_REGISTRY_DEV || vars.IMAGE_REGISTRY_PROD }}
IMAGE_TAG: ${{ inputs.image_tag }}
FILEBEAT_MODULE_VERSION: ${{ inputs.filebeat_module_version }}
REVISION: ${{ inputs.revision }}
jobs:
setup:
runs-on:
group: wz-linux-amd64
outputs:
WAZUH_COMPONENTS: ${{ steps.compute-outputs.outputs.WAZUH_COMPONENTS }}
ALL_PRODUCTS_SELECTED: ${{ steps.compute-outputs.outputs.ALL_PRODUCTS_SELECTED }}
COMMIT_LIST: ${{ steps.compute-outputs.outputs.COMMIT_LIST }}
steps:
- name: Print inputs
@@ -102,42 +105,191 @@ jobs:
echo "* id: ${{ inputs.id }}"
echo "* image_tag: ${{ inputs.image_tag }}"
echo "* docker_reference: ${{ inputs.docker_reference }}"
echo "* filebeat_module_version: ${{ inputs.filebeat_module_version }}"
echo "* wazuh_automation_reference: ${{ inputs.wazuh_automation_reference }}"
echo "* products: ${{ inputs.products }}"
echo "* revision: ${{ inputs.revision }}"
echo "* dev: ${{ inputs.dev }}"
echo "* commit_list: ${{ inputs.commit_list }}"
echo "* assistant_revision: ${{ inputs.assistant_revision }}"
echo "---------------------------------------------"
- name: Set up variables
id: compute-outputs
run: |
# Use the default list if products is empty
PRODUCTS="${{ inputs.products }}"
if [[ -z "$PRODUCTS" || "$PRODUCTS" == "null" ]]; then
PRODUCTS="wazuh-manager,wazuh-dashboard,wazuh-indexer,wazuh-agent"
# Set WAZUH_COMPONENTS
WC_JSON_ARRAY=""
if [[ "${{ inputs.products }}" != "null" && "${{ inputs.products }}" != "" ]]; then
# Convert comma-separated list to JSON array format
IFS=',' read -ra COMPONENTS <<< "${{ inputs.products }}"
WC_JSON_ARRAY="["
for i in "${!COMPONENTS[@]}"; do
if [ $i -gt 0 ]; then
WC_JSON_ARRAY+=","
fi
WC_JSON_ARRAY+="\"${COMPONENTS[$i]}\""
done
WC_JSON_ARRAY+="]"
else
WC_JSON_ARRAY='["wazuh-manager","wazuh-dashboard","wazuh-indexer","wazuh-agent"]'
fi
echo "Products to build: $WC_JSON_ARRAY"
echo "WAZUH_COMPONENTS=$WC_JSON_ARRAY" >> $GITHUB_OUTPUT
# Check if all 4 core components are present in the string
if [[ "$PRODUCTS" == *"wazuh-manager"* && "$PRODUCTS" == *"wazuh-dashboard"* && "$PRODUCTS" == *"wazuh-indexer"* && "$PRODUCTS" == *"wazuh-agent"* ]]; then
echo "ALL_PRODUCTS_SELECTED=true" >> $GITHUB_OUTPUT
# Set COMMIT_LIST
WC_COMMIT_LIST=""
if [[ "${{ inputs.dev }}" == "true" ]]; then
if [[ "${{ inputs.commit_list }}" != "null" && "${{ inputs.commit_list }}" != "" ]]; then
WC_COMMIT_LIST='${{ inputs.commit_list }}'
else
echo "ALL_PRODUCTS_SELECTED=false" >> $GITHUB_OUTPUT
# Set commit list to "latest" for all components using WAZUH_COMPONENTS
COMPONENTS=($(echo "$WC_JSON_ARRAY" | jq -r '.[]'))
WC_COMMIT_LIST="["
for i in "${!COMPONENTS[@]}"; do
if [ $i -gt 0 ]; then
WC_COMMIT_LIST+=" ,"
fi
WC_COMMIT_LIST+="\"latest\""
done
WC_COMMIT_LIST+="]"
fi
echo "Revision list: $WC_COMMIT_LIST"
fi
echo "COMMIT_LIST=$WC_COMMIT_LIST" >> $GITHUB_OUTPUT
package-urls:
name: generate package urls
runs-on:
group: wz-linux-amd64
needs: setup
env:
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 }}
steps:
- name: Checkout repository
if: ${{ inputs.dev == true }}
uses: actions/checkout@v4
with:
ref: ${{ inputs.docker_reference }}
- name: Checkout wazuh/wazuh-automation repository
if: ${{ inputs.dev == true }}
uses: actions/checkout@v4
with:
repository: wazuh/wazuh-automation
ref: ${{ inputs.wazuh_automation_reference }}
token: ${{ secrets.GH_CLONE_TOKEN }}
path: wazuh-automation
- name: Configure AWS credentials
if: ${{ inputs.dev == true }}
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_IAM_DOCKER_ROLE }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Set up Python
if: ${{ inputs.dev == true }}
uses: actions/setup-python@v6
with:
python-version: '3.12'
- name: Install and configure python and workflow dependencies
if: ${{ inputs.dev == true }}
run: |
sudo apt-get update
sudo apt-get install -y jq
# Install yq
sudo curl -sL "https://github.com/mikefarah/yq/releases/download/v4.44.3/yq_linux_amd64" -o /usr/local/bin/yq
sudo chmod +x /usr/local/bin/yq
sudo apt-get install -y python3-venv
python3 -m venv ${{ env.WORKFLOW_VENV }}
source ${{ env.WORKFLOW_VENV }}/bin/activate
pip install --upgrade pip
pip install pyyaml
- name: Get Wazuh version
if: ${{ inputs.dev == true }}
run: |
WAZUH_VERSION=$(jq -r '.version' VERSION.json)
WAZUH_MAJOR=$(echo "$WAZUH_VERSION" | cut -d '.' -f 1)
WAZUH_MINOR=$(echo "$WAZUH_VERSION" | cut -d '.' -f 1-2)
echo WAZUH_VERSION=$WAZUH_VERSION >> $GITHUB_ENV
echo WAZUH_MAJOR=$WAZUH_MAJOR >> $GITHUB_ENV
echo WAZUH_MINOR=$WAZUH_MINOR >> $GITHUB_ENV
- name: Get artifacts URLs file
if: ${{ inputs.dev == true }}
run: |
LOCAL_AWS_S3_BUCKET_DEV=${{ vars.AWS_S3_BUCKET_DEV }}
echo LOCAL_AWS_S3_BUCKET_DEV=$LOCAL_AWS_S3_BUCKET_DEV >> $GITHUB_ENV
- name: Generate presigned URLs for artifacts for dev packages
if: ${{ inputs.dev == true }}
run: |
source ${{ env.WORKFLOW_VENV }}/bin/activate
WAZUH_COMPONENTS='${{ needs.setup.outputs.WAZUH_COMPONENTS }}'
COMMIT_LIST='${{ needs.setup.outputs.COMMIT_LIST }}'
# Parse components and their revisions
COMPONENTS=($(echo "$WAZUH_COMPONENTS" | jq -r '.[]'))
REVISIONS=($(echo "$COMMIT_LIST" | jq -r '.[]'))
# Ensure the number of components matches the number of revisions
if [[ ${#COMPONENTS[@]} -ne ${#REVISIONS[@]} ]]; then
echo "Error: WAZUH_COMPONENTS and COMMIT_LIST length mismatch." >&2
echo " Components: ${#COMPONENTS[@]}, Revisions: ${#REVISIONS[@]}." >&2
echo " WAZUH_COMPONENTS=${WAZUH_COMPONENTS}" >&2
echo " COMMIT_LIST=${COMMIT_LIST}" >&2
exit 1
fi
# Convert to JSON for the matrix (Your existing logic)
IFS=',' read -ra COMPONENTS <<< "$PRODUCTS"
JSON_ARRAY=$(printf '%s\n' "${COMPONENTS[@]}" | jq -R . | jq -s -c .)
echo "WAZUH_COMPONENTS=$JSON_ARRAY" >> $GITHUB_OUTPUT
# Map revisions to component names
for i in "${!COMPONENTS[@]}"; do
case "${COMPONENTS[$i]}" in
wazuh-manager)
MANAGER_REVISION="${REVISIONS[$i]}"
;;
wazuh-dashboard)
DASHBOARD_REVISION="${REVISIONS[$i]}"
;;
wazuh-indexer)
INDEXER_REVISION="${REVISIONS[$i]}"
;;
wazuh-agent)
AGENT_REVISION="${REVISIONS[$i]}"
;;
esac
done
python ${{ env.GENERATE_PRESIGNED_URLS_SCRIPT_PATH }} \
--process ${{ env.PRESIGNED_URLS_SCRIPT_PROCESS }} \
--wazuh-version ${{ env.WAZUH_VERSION }} \
--aws-s3-bucket-dev ${{ env.LOCAL_AWS_S3_BUCKET_DEV }} \
--indexer-revision $INDEXER_REVISION \
--manager-revision $MANAGER_REVISION \
--dashboard-revision $DASHBOARD_REVISION \
--agent-revision $AGENT_REVISION \
--assistant-revision $ASSISTANT_REVISION
- 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 }}
build-and-push:
runs-on: ubuntu-22.04
permissions:
id-token: write
contents: read
runs-on:
group: wz-linux-amd64
needs:
- setup
- package-urls
strategy:
fail-fast: false # all jobs will run even if one fails
@@ -147,7 +299,6 @@ jobs:
env:
IMAGE_REGISTRY: ${{ inputs.dev && vars.IMAGE_REGISTRY_DEV || vars.IMAGE_REGISTRY_PROD }}
IMAGE_TAG: ${{ inputs.image_tag }}
REVISION: ${{ inputs.revision }}
steps:
- name: Checkout repository
@@ -155,9 +306,6 @@ jobs:
with:
ref: ${{ inputs.docker_reference }}
- name: free disk space
uses: ./.github/free-disk-space
- name: Set up QEMU
uses: docker/setup-qemu-action@v4
@@ -182,12 +330,28 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- 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
- name: Compute component reference (dev)
if: ${{ inputs.dev == true }}
run: |
COMPONENT='${{ matrix.wazuh_component }}'
WAZUH_COMPONENTS='${{ needs.setup.outputs.WAZUH_COMPONENTS }}'
COMMIT_LIST='${{ needs.setup.outputs.COMMIT_LIST }}'
idx=$(jq -r --arg c "$COMPONENT" 'index($c)' <<<"$WAZUH_COMPONENTS")
ref=$(jq -r --argjson i "$idx" '.[ $i ]' <<<"$COMMIT_LIST")
echo "COMPONENT_REFS_JSON=[\"$ref\"]" >> "$GITHUB_ENV"
echo "Using component ref for $COMPONENT: $ref"
- name: Build Wazuh images
run: |
IMAGE_TAG="${{ inputs.image_tag }}"
FILEBEAT_MODULE_VERSION=${{ inputs.filebeat_module_version }}
REVISION=${{ inputs.revision }}
if [[ "$IMAGE_TAG" == *"-"* ]]; then
IFS='-' read -r -a tokens <<< "$IMAGE_TAG"
if [ -z "${tokens[1]}" ]; then
@@ -196,11 +360,40 @@ jobs:
fi
DEV_STAGE=${tokens[1]}
WAZUH_VER=${tokens[0]}
./build-images.sh -v $WAZUH_VER -r $REVISION -d $DEV_STAGE -f $FILEBEAT_MODULE_VERSION -rg $IMAGE_REGISTRY -m -c ${{ matrix.wazuh_component }}
if [ "${{ inputs.dev }}" = true ]; then
./build-images.sh \
-v $WAZUH_VER \
-d $DEV_STAGE \
-rg $IMAGE_REGISTRY \
-m \
--dev \
-refs "$COMPONENT_REFS_JSON" \
-c ${{ matrix.wazuh_component }}
else
./build-images.sh \
-v $WAZUH_VER \
-d $DEV_STAGE \
-rg $IMAGE_REGISTRY \
-m \
-c ${{ matrix.wazuh_component }}
fi
else
./build-images.sh -v $IMAGE_TAG -r $REVISION -f $FILEBEAT_MODULE_VERSION -rg $IMAGE_REGISTRY -m -c ${{ matrix.wazuh_component }}
if [ "${{ inputs.dev }}" = true ]; then
./build-images.sh \
-v $IMAGE_TAG \
-rg $IMAGE_REGISTRY \
-m \
--dev \
-refs "$COMPONENT_REFS_JSON" \
-c ${{ matrix.wazuh_component }}
else
./build-images.sh \
-v $IMAGE_TAG \
-rg $IMAGE_REGISTRY \
-m \
-c ${{ matrix.wazuh_component }}
fi
fi
# Save .env file (generated by build-images.sh) contents to $GITHUB_ENV
ENV_FILE_PATH="../.env"
-369
View File
@@ -1,369 +0,0 @@
name: Wazuh Docker pipeline
on: [pull_request]
jobs:
build-docker-images:
runs-on: ubuntu-22.04
steps:
- name: Check out code
uses: actions/checkout@v6
- name: Build Wazuh images
run: ./build-images.sh
working-directory: ./build-docker-images
- name: Create enviroment variables
run: cat .env > $GITHUB_ENV
- name: Create backup Docker images
run: |
mkdir -p /home/runner/work/wazuh-docker/wazuh-docker/docker-images/
docker save wazuh/wazuh-manager:${{env.WAZUH_IMAGE_VERSION}} -o /home/runner/work/wazuh-docker/wazuh-docker/docker-images/wazuh-manager.tar
docker save wazuh/wazuh-indexer:${{env.WAZUH_IMAGE_VERSION}} -o /home/runner/work/wazuh-docker/wazuh-docker/docker-images/wazuh-indexer.tar
docker save wazuh/wazuh-dashboard:${{env.WAZUH_IMAGE_VERSION}} -o /home/runner/work/wazuh-docker/wazuh-docker/docker-images/wazuh-dashboard.tar
docker save wazuh/wazuh-agent:${{env.WAZUH_IMAGE_VERSION}} -o /home/runner/work/wazuh-docker/wazuh-docker/docker-images/wazuh-agent.tar
- name: Temporarily save Wazuh manager Docker image
uses: actions/upload-artifact@v7
with:
name: docker-artifact-manager
path: /home/runner/work/wazuh-docker/wazuh-docker/docker-images/wazuh-manager.tar
retention-days: 1
- name: Temporarily save Wazuh indexer Docker image
uses: actions/upload-artifact@v7
with:
name: docker-artifact-indexer
path: /home/runner/work/wazuh-docker/wazuh-docker/docker-images/wazuh-indexer.tar
retention-days: 1
- name: Temporarily save Wazuh dashboard Docker image
uses: actions/upload-artifact@v7
with:
name: docker-artifact-dashboard
path: /home/runner/work/wazuh-docker/wazuh-docker/docker-images/wazuh-dashboard.tar
retention-days: 1
- name: Temporarily save Wazuh agent Docker image
uses: actions/upload-artifact@v7
with:
name: docker-artifact-agent
path: /home/runner/work/wazuh-docker/wazuh-docker/docker-images/wazuh-agent.tar
retention-days: 1
- name: Install Goss
uses: e1himself/goss-installation-action@v1.0.3
with:
version: v0.3.16
- name: Execute Goss tests (wazuh-manager)
run: dgoss run wazuh/wazuh-manager:${{env.WAZUH_IMAGE_VERSION}}
env:
GOSS_SLEEP: 30
GOSS_FILE: .github/.goss.yaml
check-single-node:
runs-on: ubuntu-22.04
needs: build-docker-images
steps:
- name: Check out code
uses: actions/checkout@v6
- name: Create enviroment variables
run: cat .env > $GITHUB_ENV
- name: Retrieve saved Wazuh indexer Docker image
uses: actions/download-artifact@v8
with:
name: docker-artifact-indexer
- name: Retrieve saved Wazuh manager Docker image
uses: actions/download-artifact@v8
with:
name: docker-artifact-manager
- name: Retrieve saved Wazuh dashboard Docker image
uses: actions/download-artifact@v8
with:
name: docker-artifact-dashboard
- name: Retrieve saved Wazuh agent Docker image
uses: actions/download-artifact@v8
with:
name: docker-artifact-agent
- name: Docker load
run: |
docker load --input ./wazuh-indexer.tar
docker load --input ./wazuh-dashboard.tar
docker load --input ./wazuh-manager.tar
docker load --input ./wazuh-agent.tar
- name: Create single node certficates
run: docker compose -f single-node/generate-indexer-certs.yml run --rm generator
- name: Start single node stack
run: docker compose -f single-node/docker-compose.yml up -d
- name: Check Wazuh indexer start
run: |
sleep 60
status_green="`curl -XGET "https://0.0.0.0:9200/_cluster/health" -u admin:SecretPassword -k -s | grep green | wc -l`"
if [[ $status_green -eq 1 ]]; then
curl -XGET "https://0.0.0.0:9200/_cluster/health" -u admin:SecretPassword -k -s
else
curl -XGET "https://0.0.0.0:9200/_cluster/health" -u admin:SecretPassword -k -s
exit 1
fi
status_index="`curl -XGET "https://0.0.0.0:9200/_cat/indices" -u admin:SecretPassword -k -s | wc -l`"
status_index_green="`curl -XGET "https://0.0.0.0:9200/_cat/indices" -u admin:SecretPassword -k -s | grep "green" | wc -l`"
if [[ $status_index_green -eq $status_index ]]; then
curl -XGET "https://0.0.0.0:9200/_cat/indices" -u admin:SecretPassword -k -s
else
curl -XGET "https://0.0.0.0:9200/_cat/indices" -u admin:SecretPassword -k -s
exit 1
fi
- name: Check Wazuh indexer nodes
run: |
nodes="`curl -XGET "https://0.0.0.0:9200/_cat/nodes" -u admin:SecretPassword -k -s | grep -E "indexer" | wc -l`"
if [[ $nodes -eq 1 ]]; then
echo "Wazuh indexer nodes: ${nodes}"
else
echo "Wazuh indexer nodes: ${nodes}"
exit 1
fi
- name: Check documents into wazuh-alerts index
run: |
sleep 120
docs="`curl -XGET "https://0.0.0.0:9200/wazuh-alerts*/_count" -u admin:SecretPassword -k -s | jq -r ".count"`"
if [[ $docs -gt 0 ]]; then
echo "wazuh-alerts index documents: ${docs}"
else
echo "wazuh-alerts index documents: ${docs}"
exit 1
fi
- name: Check Wazuh templates
run: |
qty_templates="`curl -XGET "https://0.0.0.0:9200/_cat/templates" -u admin:SecretPassword -k -s | grep -P "wazuh|wazuh-agent|wazuh-statistics" | wc -l`"
templates="`curl -XGET "https://0.0.0.0:9200/_cat/templates" -u admin:SecretPassword -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
run: |
services="`curl -k -s -X GET "https://0.0.0.0:55000/manager/status?pretty=true" -H "Authorization: Bearer ${{env.TOKEN}}" | jq -r .data.affected_items | grep running | wc -l`"
if [[ $services -gt 9 ]]; then
echo "Wazuh Manager Services: ${services}"
echo "OK"
else
echo "Wazuh indexer nodes: ${nodes}"
curl -k -X GET "https://0.0.0.0:55000/manager/status?pretty=true" -H "Authorization: Bearer ${{env.TOKEN}}" | jq -r .data.affected_items
exit 1
fi
env:
TOKEN: $(curl -s -u wazuh-wui:MyS3cr37P450r.*- -k -X GET "https://0.0.0.0:55000/security/user/authenticate?raw=true")
- name: Check filebeat output
run: ./.github/single-node-filebeat-check.sh
- name: Check Wazuh dashboard service URL
run: |
status=$(curl -XGET --silent https://0.0.0.0:443/app/status -k -u admin:SecretPassword -I -s | grep -E "^HTTP" | awk '{print $2}')
if [[ $status -eq 200 ]]; then
echo "Wazuh dashboard status: ${status}"
else
echo "Wazuh dashboard status: ${status}"
exit 1
fi
- name: Modify Docker endpoint into Wazuh agent docker-compose.yml file
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: Start Wazuh agent
run: docker compose -f wazuh-agent/docker-compose.yml up -d
- name: Check Wazuh agent enrollment
run: |
sleep 20
curl -k -s -X GET "https://localhost:55000/agents?pretty=true" -H "Authorization: Bearer ${{env.TOKEN}}"
env:
TOKEN: $(curl -s -u wazuh-wui:MyS3cr37P450r.*- -k -X GET "https://0.0.0.0:55000/security/user/authenticate?raw=true")
- name: Check errors in ossec.log for Wazuh manager
run: ./.github/single-node-log-check.sh
check-multi-node:
runs-on: ubuntu-22.04
needs: build-docker-images
steps:
- name: Check out code
uses: actions/checkout@v6
- name: Create enviroment variables
run: cat .env > $GITHUB_ENV
- name: free disk space
uses: ./.github/free-disk-space
- name: Retrieve saved Wazuh dashboard Docker image
uses: actions/download-artifact@v8
with:
name: docker-artifact-dashboard
- name: Retrieve saved Wazuh manager Docker image
uses: actions/download-artifact@v8
with:
name: docker-artifact-manager
- name: Retrieve saved Wazuh indexer Docker image
uses: actions/download-artifact@v8
with:
name: docker-artifact-indexer
- name: Retrieve saved Wazuh agent Docker image
uses: actions/download-artifact@v8
with:
name: docker-artifact-agent
- name: Docker load
run: |
docker load --input ./wazuh-manager.tar
docker load --input ./wazuh-indexer.tar
docker load --input ./wazuh-dashboard.tar
docker load --input ./wazuh-agent.tar
rm -rf wazuh-manager.tar wazuh-indexer.tar wazuh-dashboard.tar wazuh-agent.tar
- name: Create multi node certficates
run: docker compose -f multi-node/generate-indexer-certs.yml run --rm generator
- name: Start multi node stack
run: docker compose -f multi-node/docker-compose.yml up -d
- name: Check Wazuh indexer start
run: |
until [[ `curl -XGET "https://0.0.0.0:9200/_cluster/health" -u admin:SecretPassword -k -s | grep green | wc -l` -eq 1 ]]
do
echo 'Waiting for Wazuh indexer start'
free -m
df -h
sleep 120
done
status_green="`curl -XGET "https://0.0.0.0:9200/_cluster/health" -u admin:SecretPassword -k -s | grep green | wc -l`"
if [[ $status_green -eq 1 ]]; then
curl -XGET "https://0.0.0.0:9200/_cluster/health" -u admin:SecretPassword -k -s
else
curl -XGET "https://0.0.0.0:9200/_cluster/health" -u admin:SecretPassword -k -s
exit 1
fi
status_index="`curl -XGET "https://0.0.0.0:9200/_cat/indices" -u admin:SecretPassword -k -s | wc -l`"
status_index_green="`curl -XGET "https://0.0.0.0:9200/_cat/indices" -u admin:SecretPassword -k -s | grep -E "green" | wc -l`"
if [[ $status_index_green -eq $status_index ]]; then
curl -XGET "https://0.0.0.0:9200/_cat/indices" -u admin:SecretPassword -k -s
else
curl -XGET "https://0.0.0.0:9200/_cat/indices" -u admin:SecretPassword -k -s
exit 1
fi
- name: Check Wazuh indexer nodes
run: |
nodes="`curl -XGET "https://0.0.0.0:9200/_cat/nodes" -u admin:SecretPassword -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 documents into wazuh-alerts index
run: |
until [[ $(``curl -XGET "https://0.0.0.0:9200/wazuh-alerts*/_count" -u admin:SecretPassword -k -s | jq -r ".count"``) -gt 0 ]]
do
echo 'Waiting for Wazuh indexer events'
free -m
df -h
sleep 10
done
docs="`curl -XGET "https://0.0.0.0:9200/wazuh-alerts*/_count" -u admin:SecretPassword -k -s | jq -r ".count"`"
if [[ $docs -gt 0 ]]; then
echo "wazuh-alerts index documents: ${docs}"
else
echo "wazuh-alerts index documents: ${docs}"
exit 1
fi
- name: Check Wazuh templates
run: |
qty_templates="`curl -XGET "https://0.0.0.0:9200/_cat/templates" -u admin:SecretPassword -k -s | grep "wazuh" | wc -l`"
templates="`curl -XGET "https://0.0.0.0:9200/_cat/templates" -u admin:SecretPassword -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
run: |
services="`curl -k -s -X GET "https://0.0.0.0:55000/manager/status?pretty=true" -H "Authorization: Bearer ${{env.TOKEN}}" | jq -r .data.affected_items | grep running | wc -l`"
if [[ $services -gt 10 ]]; then
echo "Wazuh Manager Services: ${services}"
echo "OK"
else
echo "Wazuh indexer nodes: ${nodes}"
curl -k -s -X GET "https://0.0.0.0:55000/manager/status?pretty=true" -H "Authorization: Bearer ${{env.TOKEN}}" | jq -r .data.affected_items
exit 1
fi
nodes=$(curl -k -s -X GET "https://0.0.0.0:55000/cluster/nodes" -H "Authorization: Bearer ${{env.TOKEN}}" | jq -r ".data.affected_items[].name" | wc -l)
if [[ $nodes -eq 2 ]]; then
echo "Wazuh manager nodes: ${nodes}"
else
echo "Wazuh manager nodes: ${nodes}"
exit 1
fi
env:
TOKEN: $(curl -s -u wazuh-wui:MyS3cr37P450r.*- -k -X GET "https://0.0.0.0:55000/security/user/authenticate?raw=true")
- name: Check filebeat output
run: ./.github/multi-node-filebeat-check.sh
- name: Check Wazuh dashboard service URL
run: |
status=$(curl -XGET --silent https://0.0.0.0:443/app/status -k -u admin:SecretPassword -I | grep -E "^HTTP" | awk '{print $2}')
if [[ $status -eq 200 ]]; then
echo "Wazuh dashboard status: ${status}"
else
echo "Wazuh dashboard status: ${status}"
exit 1
fi
- name: Modify Docker endpoint into Wazuh agent docker-compose.yml file
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: Start Wazuh agent
run: docker compose -f wazuh-agent/docker-compose.yml up -d
- name: Check Wazuh agent enrollment
run: |
sleep 20
curl -k -s -X GET "https://localhost:55000/agents?pretty=true" -H "Authorization: Bearer ${{env.TOKEN}}"
env:
TOKEN: $(curl -s -u wazuh-wui:MyS3cr37P450r.*- -k -X GET "https://0.0.0.0:55000/security/user/authenticate?raw=true")
- name: Check errors in ossec.log for Wazuh manager
run: ./.github/multi-node-log-check.sh
-76
View File
@@ -1,76 +0,0 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: Trivy scan Wazuh dashboard
on:
release:
types:
- published
pull_request:
branches:
- main
schedule:
- cron: '34 2 * * 1'
workflow_dispatch:
permissions:
contents: read
jobs:
build:
permissions:
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
name: Build images and upload Trivy results
runs-on: "ubuntu-22.04"
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Installing dependencies
run: |
sudo apt-get update
sudo apt-get install -y jq
- name: Checkout latest tag
run: |
latest=$(curl -s "https://api.github.com/repos/wazuh/wazuh-docker/releases/latest" | jq -r '.tag_name')
git fetch origin
git checkout $latest
- name: Build Wazuh images
run: build-docker-images/build-images.sh
- name: Create enviroment variables
run: |
cat .env > $GITHUB_ENV
echo "GITHUB_REF_NAME="${GITHUB_REF_NAME%/*} >> $GITHUB_ENV
- name: Run Trivy vulnerability scanner for Wazuh dashboard
uses: aquasecurity/trivy-action@2a2157eb22c08c9a1fac99263430307b8d1bc7a2
with:
image-ref: 'wazuh/wazuh-dashboard:${{env.WAZUH_IMAGE_VERSION}}'
format: 'template'
template: '@/contrib/sarif.tpl'
output: 'trivy-results-dashboard.sarif'
severity: 'LOW,MEDIUM,CRITICAL,HIGH'
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results-dashboard.sarif'
- name: Slack notification
uses: rtCamp/action-slack-notify@v2
env:
SLACK_CHANNEL: cicd-monitoring
SLACK_COLOR: ${{ job.status }} # or a specific color like 'good' or '#ff00ff'
#SLACK_ICON: https://github.com/rtCamp.png?size=48
SLACK_MESSAGE: "Check the results: https://github.com/wazuh/wazuh-docker/security/code-scanning?query=is%3Aopen+branch%3A${{ env.GITHUB_REF_NAME }}"
SLACK_TITLE: Wazuh docker Trivy vulnerability scan finished.
SLACK_USERNAME: github_actions
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
-76
View File
@@ -1,76 +0,0 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: Trivy scan Wazuh indexer
on:
release:
types:
- published
pull_request:
branches:
- main
schedule:
- cron: '34 2 * * 1'
workflow_dispatch:
permissions:
contents: read
jobs:
build:
permissions:
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
name: Build images and upload Trivy results
runs-on: "ubuntu-22.04"
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Installing dependencies
run: |
sudo apt-get update
sudo apt-get install -y jq
- name: Checkout latest tag
run: |
latest=$(curl -s "https://api.github.com/repos/wazuh/wazuh-docker/releases/latest" | jq -r '.tag_name')
git fetch origin
git checkout $latest
- name: Build Wazuh images
run: build-docker-images/build-images.sh
- name: Create enviroment variables
run: |
cat .env > $GITHUB_ENV
echo "GITHUB_REF_NAME="${GITHUB_REF_NAME%/*} >> $GITHUB_ENV
- name: Run Trivy vulnerability scanner for Wazuh indexer
uses: aquasecurity/trivy-action@2a2157eb22c08c9a1fac99263430307b8d1bc7a2
with:
image-ref: 'wazuh/wazuh-indexer:${{env.WAZUH_IMAGE_VERSION}}'
format: 'template'
template: '@/contrib/sarif.tpl'
output: 'trivy-results-indexer.sarif'
severity: 'LOW,MEDIUM,CRITICAL,HIGH'
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results-indexer.sarif'
- name: Slack notification
uses: rtCamp/action-slack-notify@v2
env:
SLACK_CHANNEL: cicd-monitoring
SLACK_COLOR: ${{ job.status }} # or a specific color like 'good' or '#ff00ff'
#SLACK_ICON: https://github.com/rtCamp.png?size=48
SLACK_MESSAGE: "Check the results: https://github.com/wazuh/wazuh-docker/security/code-scanning?query=is%3Aopen+branch%3A${{ env.GITHUB_REF_NAME }}"
SLACK_TITLE: Wazuh docker Trivy vulnerability scan finished.
SLACK_USERNAME: github_actions
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
-76
View File
@@ -1,76 +0,0 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: Trivy scan Wazuh manager
on:
release:
types:
- published
pull_request:
branches:
- main
schedule:
- cron: '34 2 * * 1'
workflow_dispatch:
permissions:
contents: read
jobs:
build:
permissions:
contents: read # for actions/checkout to fetch code
security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
name: Build images and upload Trivy results
runs-on: "ubuntu-22.04"
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Installing dependencies
run: |
sudo apt-get update
sudo apt-get install -y jq
- name: Checkout latest tag
run: |
latest=$(curl -s "https://api.github.com/repos/wazuh/wazuh-docker/releases/latest" | jq -r '.tag_name')
git fetch origin
git checkout $latest
- name: Build Wazuh images
run: build-docker-images/build-images.sh
- name: Create enviroment variables
run: |
cat .env > $GITHUB_ENV
echo "GITHUB_REF_NAME="${GITHUB_REF_NAME%/*} >> $GITHUB_ENV
- name: Run Trivy vulnerability scanner for Wazuh manager
uses: aquasecurity/trivy-action@2a2157eb22c08c9a1fac99263430307b8d1bc7a2
with:
image-ref: 'wazuh/wazuh-manager:${{env.WAZUH_IMAGE_VERSION}}'
format: 'template'
template: '@/contrib/sarif.tpl'
output: 'trivy-results-manager.sarif'
severity: 'LOW,MEDIUM,CRITICAL,HIGH'
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results-manager.sarif'
- name: Slack notification
uses: rtCamp/action-slack-notify@v2
env:
SLACK_CHANNEL: cicd-monitoring
SLACK_COLOR: ${{ job.status }} # or a specific color like 'good' or '#ff00ff'
#SLACK_ICON: https://github.com/rtCamp.png?size=48
SLACK_MESSAGE: "Check the results: https://github.com/wazuh/wazuh-docker/security/code-scanning?query=is%3Aopen+branch%3A${{ env.GITHUB_REF_NAME }}"
SLACK_TITLE: Wazuh docker Trivy vulnerability scan finished.
SLACK_USERNAME: github_actions
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}