#!/usr/bin/env bash # host-validate.sh — Quest-specific host validation probe. # # Usage: bash host-validate.sh # Output: JSON to stdout # # This is a supplementary probe. ValidationService uses SSH-based checks # as the authoritative path; this probe provides higher-level summaries # for quests that need them. # # AGENT RULES: # - Read-only. Never modify VM state. # - Output valid JSON always, even on error. # - Quest-specific logic should be minimal — prefer generic rule evaluation. set -euo pipefail DOMAIN="${1:-}" QUEST_ID="${2:-}" ssh_login_user() { case "$1" in sc-workstation) printf '%s\n' "opsbridge" ;; *) printf '%s\n' "player" ;; esac } LOGIN_USER="$(ssh_login_user "$DOMAIN")" if [ -z "$DOMAIN" ] || [ -z "$QUEST_ID" ]; then echo '{"error": "Usage: host-validate.sh "}' exit 0 fi VM_IP=$(virsh domifaddr "$DOMAIN" --source agent 2>/dev/null \ | grep ipv4 | awk '{print $4}' | cut -d/ -f1 | head -1) if [ -z "$VM_IP" ]; then echo '{"error": "Cannot get VM IP", "domain": "'"$DOMAIN"'", "quest_id": "'"$QUEST_ID"'"}' exit 0 fi SSH_OPTS="-o StrictHostKeyChecking=no -o BatchMode=yes -o ConnectTimeout=5 -i $HOME/.ssh/sc_host_key" SSH="ssh $SSH_OPTS $LOGIN_USER@$VM_IP" case "$QUEST_ID" in Q002) # nginx config validity check NGINX_OK=$($SSH "nginx -t 2>&1 | grep -c 'syntax is ok'" 2>/dev/null || echo "0") NGINX_ACTIVE=$($SSH "systemctl is-active nginx 2>/dev/null" || echo "inactive") echo "{\"quest_id\": \"Q002\", \"nginx_config_valid\": $([ "$NGINX_OK" -gt 0 ] && echo true || echo false), \"nginx_state\": \"$NGINX_ACTIVE\"}" ;; Q003) # Disk and logrotate check LOG_SIZE=$($SSH "du -sm /var/log/nginx/access.log 2>/dev/null | awk '{print \$1}'" || echo "0") HAS_LOGROTATE=$($SSH "test -f /etc/logrotate.d/nginx && echo true || echo false" 2>/dev/null || echo "false") DISK_PCT=$($SSH "df -P /var/log | tail -1 | awk '{print \$5}'" | tr -d '%' || echo "-1") echo "{\"quest_id\": \"Q003\", \"access_log_size_mb\": $LOG_SIZE, \"logrotate_configured\": $HAS_LOGROTATE, \"disk_usage_pct\": $DISK_PCT}" ;; Q004) # Web root ownership check OWNER=$($SSH "stat -c '%U:%G' /var/www/axiomworks 2>/dev/null" || echo "unknown:unknown") echo "{\"quest_id\": \"Q004\", \"webroot_owner\": \"$OWNER\", \"correct\": $([ "$OWNER" = "player:player" ] && echo true || echo false)}" ;; *) # Generic state for unknown quests echo "{\"quest_id\": \"$QUEST_ID\", \"domain\": \"$DOMAIN\", \"note\": \"No specific probe for this quest — use generic validation rules\"}" ;; esac