Dotfiles/setup/modules/FreeipaAnsible/image/ansipa-checkmk-setup.sh

163 lines
6.9 KiB
Bash

#!/bin/bash
# ansipa-checkmk-setup.sh — CheckMK CE integration for the IPA container.
#
# Phase 1 (one-time, guarded by /data/ansipa-checkmk.done):
# Creates /ansipa folder, IPA monitoring groups, stores CMK credentials.
#
# Phase 2 (runs every invocation after phase 1):
# Writes push-mode requests for all hosts in dev_mon_base to /cmk-creds/.
# The CheckMK container polls /cmk-creds/push-mode-*.req and updates hosts.mk.
# This lets clients in NAT environments push agent data without pull reachability.
#
# Credential format in IPA dev_mon_base description:
# cmk://<host>:<port>/<site>:automation:<secret>
set -euo pipefail
LOG_TAG="ansipa-checkmk-setup"
DONE_FLAG="/data/ansipa-checkmk.done"
CMK_CREDS_FILE="/cmk-creds/automation.secret"
log() { echo "[$LOG_TAG] $*"; }
warn() { echo "[$LOG_TAG][WARN] $*" >&2; }
# ── Phase 2: write push-mode requests for enrolled monitoring hosts ───────────
# Runs on EVERY invocation (not guarded by done flag). The CheckMK container
# polls /cmk-creds/push-mode-*.req and adds explicit_host_conf push-agent entries.
_write_push_requests() {
[[ -d /cmk-creds ]] || return 0
local _hosts _h
_hosts=$(ipa hostgroup-show dev_mon_base --all 2>/dev/null \
| awk '/Member hosts:/{p=1; next} /^$/{p=0} p{print}' \
| grep -oE '[a-zA-Z0-9._-]+\.[a-zA-Z]{2,}' | sort -u || true)
[[ -z "$_hosts" ]] && return 0
while IFS= read -r _h; do
[[ -z "$_h" ]] && continue
_req="/cmk-creds/push-mode-${_h}.req"
[[ -f "$_req" ]] && continue
echo "$_h" > "$_req" && log "Push-mode request created for ${_h}"
done <<< "$_hosts"
}
# Skip re-initialization but still run push-mode requests if already set up
if [[ -f "$DONE_FLAG" ]]; then
[[ -f /etc/ipa/default.conf ]] && \
echo "$IPA_ADMIN_PASS" | kinit "admin@${IPA_REALM}" &>/dev/null && \
_write_push_requests 2>/dev/null; \
kdestroy &>/dev/null || true
log "Already configured (delete $DONE_FLAG to force re-initialization)"
exit 0
fi
# ── Resolve configuration ──────────────────────────────────────────────────────
# docker-env.service writes container env to /etc/container.env; source it.
[[ -f /etc/container.env ]] && source /etc/container.env || true
CMK_URL="${CMK_URL:-http://172.30.0.12:5000}"
CMK_SITE="${CMK_SITE_ID:-cmk}"
CMK_API="${CMK_URL}/${CMK_SITE}/check_mk/api/1.0"
IPA_REALM="${IPA_REALM:-}"
IPA_ADMIN_PASS="${IPA_ADMIN_PASSWORD:-}"
if [[ -z "$IPA_REALM" || -z "$IPA_ADMIN_PASS" ]]; then
warn "IPA_REALM or IPA_ADMIN_PASSWORD not set — cannot configure IPA side"
exit 1
fi
# ── Wait for IPA to be fully configured ──────────────────────────────────────
if [[ ! -f /etc/ipa/default.conf ]]; then
warn "IPA not yet configured — waiting for ipa-first-boot to complete"
exit 1
fi
# ── Wait for CheckMK automation secret (written by checkmk container) ─────────
if [[ ! -f "$CMK_CREDS_FILE" ]]; then
warn "CheckMK automation secret not yet available at $CMK_CREDS_FILE"
warn " (CheckMK container writes it after site init — will retry)"
exit 1
fi
CMK_SECRET=$(tr -d '[:space:]' < "$CMK_CREDS_FILE")
if [[ -z "$CMK_SECRET" ]]; then
warn "CheckMK automation secret is empty — CheckMK not ready yet"
exit 1
fi
# ── Wait for CheckMK web API (use automation secret — no admin password needed) ──
log "Waiting for CheckMK API at ${CMK_API}..."
_wait=0
until curl -sf \
-H "Authorization: Bearer automation ${CMK_SECRET}" \
"${CMK_API}/version" >/dev/null 2>&1; do
_wait=$(( _wait + 15 ))
if [[ $_wait -ge 300 ]]; then
warn "CheckMK API not reachable after 5 minutes — will retry on next start"
exit 1
fi
sleep 15
done
log "CheckMK API is up"
# ── Create /ansipa folder in CheckMK ─────────────────────────────────────────
_folder_result=$(curl -sf -o /dev/null -w '%{http_code}' \
-X POST "${CMK_API}/domain-types/folder_config/collections/all" \
-H "Authorization: Bearer automation ${CMK_SECRET}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"name":"ansipa","title":"Ansipa Managed Hosts","parent":"/"}' \
2>/dev/null || echo "000")
if [[ "$_folder_result" =~ ^2 ]]; then
log "Created /ansipa folder in CheckMK"
elif [[ "$_folder_result" == "422" ]]; then
log "/ansipa folder already exists"
else
warn "Unexpected response creating /ansipa folder: HTTP $_folder_result"
fi
# ── Activate changes in CheckMK ───────────────────────────────────────────────
curl -sf \
-X POST "${CMK_API}/domain-types/activation_run/actions/activate-changes/invoke" \
-H "Authorization: Bearer automation ${CMK_SECRET}" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"redirect":false,"sites":[],"force_foreign_changes":false}' \
>/dev/null 2>&1 && log "Changes activated" || warn "Activation failed (non-fatal)"
# ── Store CheckMK credentials in IPA host-group descriptions ─────────────────
# Format: cmk://<host>:<port>/<site>:automation:<secret>
CMK_HOST=$(echo "$CMK_URL" | sed 's|http://||')
CMK_DESC="cmk://${CMK_HOST}/${CMK_SITE}:automation:${CMK_SECRET}"
echo "$IPA_ADMIN_PASS" | kinit "admin@${IPA_REALM}" &>/dev/null || {
warn "kinit admin failed"
exit 1
}
# dev_mon_base stores the credentials; clients parse them to register.
if ipa hostgroup-show dev_mon_base &>/dev/null 2>&1; then
ipa hostgroup-mod dev_mon_base --desc="$CMK_DESC" &>/dev/null \
&& log "Updated dev_mon_base description with CMK credentials"
else
ipa hostgroup-add dev_mon_base --desc="$CMK_DESC" &>/dev/null \
&& log "Created IPA hostgroup dev_mon_base with CMK credentials"
fi
# Create supplementary monitoring host-groups (no credentials needed in description).
for _hgrp in dev_mon_malware dev_mon_timeshift dev_mon_power; do
ipa hostgroup-show "$_hgrp" &>/dev/null 2>&1 || \
ipa hostgroup-add "$_hgrp" &>/dev/null || true
done
# usr_mon_logins is a USER group (monitoring follows the user, not the device).
ipa group-show usr_mon_logins &>/dev/null 2>&1 || \
ipa group-add usr_mon_logins \
--desc="Members: SSH login monitoring enabled on enrolled devices" &>/dev/null || true
kdestroy &>/dev/null || true
touch "$DONE_FLAG"
log "CheckMK setup complete."
log " Phase 2 (push-mode requests) will run on next invocation."
log " Web UI: ${CMK_URL}/${CMK_SITE}/"
log " Login: cmkadmin / (CMK_ADMIN_PASSWORD from .env)"
log " Clients: add to dev_mon_base hostgroup — agent self-registers via ansipa"