# Wazuh agent DaemonSet for Kubernetes.
#
# Reproduced VERBATIM from the Wazuh 5.0 beta5 documentation, "Other cluster
# types" variant (the EKS variant is identical except that it omits the
# /var/run/docker.sock volume and its mount):
# https://documentation.wazuh.com/5.0-beta/deployment-options/deploying-with-kubernetes/kubernetes-deployment.html
#
# Nothing below this header has been edited. Replace the two placeholders
# before applying:
#   <EXTERNAL_IP_WAZUH_EVENTS>        external IP of the wazuh-events load balancer
#   <EXTERNAL_IP_WAZUH_REGISTRATION>  external IP of the wazuh-registration load balancer
#
# CAUTION: this manifest writes a 4.x-shaped ossec.conf using <client><server>
# with port 1514 for events and 1515 for enrolment. The rest of the Wazuh 5.0
# documentation describes agent-to-manager communication over HTTPS on port
# 1517 with an <agent><manager> block, and the wazuh/wazuh-agent Docker image
# expects WAZUH_MANAGER_ENDPOINT of the form host:1517/wazuh-manager/. The
# Kubernetes manifests, services and network policies in the beta still carry
# the legacy ports. Apply as published, confirm the agent reaches Active, and
# re-check at GA. Do not change the ports here without also changing the
# service definitions and network policies.
#
# Before applying:
#   kubectl create namespace wazuh-daemonset
#   kubectl create secret generic wazuh-authd-pass \
#     -n wazuh-daemonset \
#     --from-literal=authd.pass=<PASSWORD_FROM_MANAGER>
# The manager's value is in /var/wazuh-manager/etc/authd.pass. The documented
# default in a fresh Kubernetes deployment is "password".
#
# Apply and verify:
#   kubectl apply -f wazuh-agent-daemonset.yaml
#   kubectl get pods -n wazuh-daemonset -o wide
#
# Create any agent group on the manager BEFORE the agents enrol. In Wazuh 5.0
# enrolment into a group that does not exist is rejected.

apiVersion: v1
kind: Namespace
metadata:
  name: wazuh-daemonset
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: wazuh-agent
  namespace: wazuh-daemonset
spec:
  selector:
    matchLabels:
      app: wazuh-agent
  template:
    metadata:
      labels:
        app: wazuh-agent
    spec:
      serviceAccountName: default
      terminationGracePeriodSeconds: 20

      #        INIT CONTAINERS
      initContainers:
        # 1) Clean stale PID / lock files
        - name: cleanup-ossec-stale
          image: busybox:1.36
          imagePullPolicy: IfNotPresent
          command: ["/bin/sh", "-lc"]
          args:
            - |
              set -e
              echo "[init] Cleaning old locks..."
              mkdir -p /agent/var/run /agent/queue/ossec
              rm -f /agent/var/run/*.pid || true
              rm -f /agent/queue/ossec/*.lock || true
          volumeMounts:
            - name: ossec-data
              mountPath: /agent

        # 2) Seed /var/ossec into hostPath (first run only)
        - name: seed-ossec-tree
          image: wazuh/wazuh-agent:5.0.0-beta5-latest
          imagePullPolicy: IfNotPresent
          command: ["/bin/sh", "-lc"]
          args:
            - |
              set -e
              echo "[init] Checking if seeding is required..."
              if [ ! -d /agent/bin ]; then
                echo "[init] Seeding /var/ossec to hostPath..."
                tar -C /var/ossec -cf - . | tar -C /agent -xpf -
              else
                echo "[init] Existing data found, skipping seed"
              fi
          volumeMounts:
            - name: ossec-data
              mountPath: /agent

        # 3) Fix ownership/permissions
        - name: fix-permissions
          image: busybox:1.36
          imagePullPolicy: IfNotPresent
          command: ["/bin/sh", "-lc"]
          args:
            - |
              set -e
              echo "[init] Fixing permissions..."
              for d in etc logs queue var rids tmp "active-response"; do
                [ -d "/agent/$d" ] && chown -R 999:999 "/agent/$d"
              done
              chown -R 0:0 /agent/bin /agent/lib || true
              find /agent/bin -type f -exec chmod 0755 {} \; || true
          volumeMounts:
            - name: ossec-data
              mountPath: /agent

        # 4) Write ossec.conf with PASSWORD ENROLLMENT
        - name: write-ossec-config
          image: busybox:1.36
          imagePullPolicy: IfNotPresent
          env:
            - name: WAZUH_MANAGER
              value: "<EXTERNAL_IP_WAZUH_EVENTS>"
            - name: WAZUH_PORT
              value: "1514"
            - name: WAZUH_PROTOCOL
              value: "tcp"
            - name: WAZUH_REGISTRATION_SERVER
              value: "<EXTERNAL_IP_WAZUH_REGISTRATION>"
            - name: WAZUH_REGISTRATION_PORT
              value: "1515"
            - name: NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
          command: ["/bin/sh", "-lc"]
          args:
            - |
              set -e
              echo "[init] Writing ossec.conf..."
              mkdir -p /agent/etc


              cat > /agent/etc/ossec.conf <<EOF
              <ossec_config>
                <client>
                  <server>
                    <address>${WAZUH_MANAGER}</address>
                    <port>${WAZUH_PORT}</port>
                    <protocol>${WAZUH_PROTOCOL}</protocol>
                  </server>

                  <enrollment>
                    <enabled>yes</enabled>
                    <agent_name>${NODE_NAME}</agent_name>
                    <manager_address>${WAZUH_REGISTRATION_SERVER}</manager_address>
                    <port>${WAZUH_REGISTRATION_PORT}</port>
                    <authorization_pass_path>/var/ossec/etc/authd.pass</authorization_pass_path>
                  </enrollment>
                </client>
              </ossec_config>
              EOF

              chown 999:999 /agent/etc/ossec.conf
              chmod 0640 /agent/etc/ossec.conf
          volumeMounts:
            - name: ossec-data
              mountPath: /agent

        # 5) Copy authd.pass from Secret and fix ownership
        - name: fix-authd-pass-perms
          image: busybox:1.36
          imagePullPolicy: IfNotPresent
          command: ["/bin/sh", "-lc"]
          args:
            - |
              set -e
              echo "[init] Copying authd.pass from Secret..."
              mkdir -p /agent/etc
              cp /secret/authd.pass /agent/etc/authd.pass
              chown 0:999 /agent/etc/authd.pass
              chmod 0640 /agent/etc/authd.pass
              ls -l /agent/etc/authd.pass
          volumeMounts:
            - name: ossec-data
              mountPath: /agent
            - name: wazuh-authd-pass
              mountPath: /secret/authd.pass
              subPath: authd.pass
              readOnly: true


      #        MAIN CONTAINER
      containers:
        - name: wazuh-agent
          image: wazuh/wazuh-agent:5.0.0-beta5-latest
          imagePullPolicy: IfNotPresent
          command: ["/bin/sh", "-lc"]
          args:
            - |
              set -e
              ln -sf /var/ossec/etc/ossec.conf /etc/ossec.conf || true
              exec /init
          env:
            - name: WAZUH_MANAGER
              value: "<EXTERNAL_IP_WAZUH_EVENTS>"
            - name: NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
          securityContext:
            runAsUser: 0
            allowPrivilegeEscalation: true
            capabilities:
              add: ["SETGID","SETUID"]
          volumeMounts:
            - name: varlog
              mountPath: /var/log
              readOnly: true
            - name: dockersock
              mountPath: /var/run/docker.sock
              readOnly: true
            - name: ossec-data
              mountPath: /var/ossec


      #            VOLUMES
      volumes:
        - name: varlog
          hostPath:
            path: /var/log
            type: Directory
        - name: dockersock
          hostPath:
            path: /var/run/docker.sock
            type: Socket
        - name: ossec-data
          hostPath:
            path: /var/lib/wazuh
            type: DirectoryOrCreate
        - name: wazuh-authd-pass
          secret:
            secretName: wazuh-authd-pass
