#!/usr/bin/env bash # ============================================================================= # preflight.sh — OSVauco Operator Preflight Dashboard # Provides immediate situational awareness of the OPAX ecosystem on GCP. # Usage: bash scripts/preflight.sh # ============================================================================= set -uo pipefail # Colors GREEN='\033[0;32m' RED='\033[0;31m' YELLOW='\033[1;33m' CYAN='\033[0;36m' DIM='\033[2m' BOLD='\033[1m' NC='\033[0m' # Icons OK="${GREEN}\u2713${NC}" WARN="${YELLOW}\u26a0\ufe0f${NC}" FAIL="${RED}\u2718${NC}" INFO="${CYAN}\u2139${NC}" # 1. Context Discovery PROJECT_ID=$(gcloud config get-value project 2>/dev/null | tr -d '\r' || echo "NOT_SET") ACCOUNT=$(gcloud config get-value account 2>/dev/null | tr -d '\r' || echo "NOT_SET") # Region fallback if not set in environment REGION="${RAG_LOCATION:-${REGION:-us-central1}}" REGION=$(echo "$REGION" | tr -d '\r') clear echo -e "${CYAN}${BOLD}==========================================================${NC}" echo -e "${CYAN}${BOLD} OSVauco OPAX PREFLIGHT DASHBOARD${NC}" echo -e "${CYAN}${BOLD}==========================================================${NC}" echo -e "${DIM}Time : $(date '+%Y-%m-%d %H:%M %Z')${NC}" echo -e "${DIM}Project : ${PROJECT_ID}${NC}" echo -e "${DIM}Identity: ${ACCOUNT}${NC}" echo -e "${CYAN}${BOLD}----------------------------------------------------------${NC}" # --- 1. Infrastructure Status (Cloud Run) --- echo -e "${BOLD}[1] Infrastructure (Cloud Run)${NC}" SERVICE_NAME="opax-mcp-core" # Check if service exists and its state SERVICE_DATA=$(gcloud run services describe "${SERVICE_NAME}" --region="${REGION}" --project="${PROJECT_ID}" --format="value(status.conditions[0].status,status.url)" 2>/dev/null | tr -d '\r' || echo "NOT_FOUND -") SERVICE_STATUS=$(echo "$SERVICE_DATA" | awk '{print $1}') SERVICE_URL=$(echo "$SERVICE_DATA" | awk '{print $2}') if [ "$SERVICE_STATUS" = "True" ]; then echo -e " ${OK} ${SERVICE_NAME}: ${GREEN}ACTIVE${NC}" echo -e " ${DIM}URL: ${SERVICE_URL}${NC}" elif [ "$SERVICE_STATUS" = "NOT_FOUND" ]; then echo -e " ${FAIL} ${SERVICE_NAME}: ${RED}NOT DEPLOYED${NC}" echo -e " ${DIM}Action: bash infrastructure/05-cloudrun-deploy.sh${NC}" else echo -e " ${WARN} ${SERVICE_NAME}: ${YELLOW}INACTIVE / UNHEALTHY${NC} (Status: ${SERVICE_STATUS})" echo -e " ${DIM}Check console for deployment errors${NC}" fi echo "" # --- 2. Knowledge Base Status (RAG Engine) --- echo -e "${BOLD}[2] Knowledge Base (RAG Engine)${NC}" CORPUS_DISPLAY_NAME="osvauco-knowledge-base" # Note: gcloud ai rag-corpora might not be available in all SDK versions. if gcloud ai rag-corpora --help &>/dev/null; then RAG_DATA=$(gcloud ai rag-corpora list --project="${PROJECT_ID}" --format="value(name,location)" 2>/dev/null | tr -d '\r' | grep "${CORPUS_DISPLAY_NAME}" || true) if [ -n "$RAG_DATA" ]; then FULL_NAME=$(echo "$RAG_DATA" | awk '{print $1}') RAG_LOC=$(echo "$RAG_DATA" | awk '{print $2}') # Get count of files FILE_COUNT=$(gcloud ai rag-files list --corpus="${FULL_NAME}" --project="${PROJECT_ID}" --location="${RAG_LOC}" --format="value(name)" 2>/dev/null | wc -l | tr -dc '0-9') FILE_COUNT=${FILE_COUNT:-0} echo -e " ${OK} Corpus: ${GREEN}FOUND${NC} in ${RAG_LOC}" echo -e " ${DIM}Files: ${FILE_COUNT} documents indexed${NC}" else echo -e " ${WARN} Corpus: ${YELLOW}NOT FOUND${NC}" echo -e " ${DIM}Action: python3 agents/rag/setup_corpus.py${NC}" fi else # Fallback: Try a lightweight python check echo -e " ${INFO} Corpus check: ${DIM}gcloud ai rag commands missing. Checking via SDK...${NC}" RAG_CHECK=$(python3 -c " import os try: from vertexai import rag import vertexai vertexai.init(project='${PROJECT_ID}') # Check common regions for loc in ['${REGION}', 'europe-west4']: vertexai.init(project='${PROJECT_ID}', location=loc) for c in rag.list_corpora(): if c.display_name == '${CORPUS_DISPLAY_NAME}': print(f'FOUND|{loc}|{c.name}') exit(0) print('MISSING') except Exception: print('ERROR') " 2>/dev/null | tr -d '\r' || echo "ERROR") if [[ "$RAG_CHECK" == FOUND* ]]; then LOC=$(echo "$RAG_CHECK" | cut -d'|' -f2) echo -e " ${OK} Corpus: ${GREEN}FOUND${NC} in ${LOC}" elif [ "$RAG_CHECK" = "MISSING" ]; then echo -e " ${WARN} Corpus: ${YELLOW}NOT FOUND${NC}" echo -e " ${DIM}Action: python3 agents/rag/setup_corpus.py${NC}" else echo -e " ${WARN} Corpus: ${DIM}Unable to verify (Vertex AI SDK issues)${NC}" fi fi echo "" # --- 3. Resource & Cost Risk Audit --- echo -e "${BOLD}[3] Resource & Cost Risk Audit${NC}" # Resources that incur cost even when idle VM_COUNT=$(gcloud compute instances list --project="${PROJECT_ID}" --filter="status=RUNNING" --format="value(name)" 2>/dev/null | wc -l | tr -dc '0-9') SQL_COUNT=$(gcloud sql instances list --project="${PROJECT_ID}" --filter="state=RUNNABLE" --format="value(name)" 2>/dev/null | wc -l | tr -dc '0-9') # Reasoning Engines (Memory Bank) are common cost leaks RB_COUNT=$(gcloud ai reasoning-engines list --project="${PROJECT_ID}" --format="value(name)" 2>/dev/null | wc -l | tr -dc '0-9') # Initialize defaults VM_COUNT=${VM_COUNT:-0} SQL_COUNT=${SQL_COUNT:-0} RB_COUNT=${RB_COUNT:-0} if [ "$VM_COUNT" -eq 0 ] && [ "$SQL_COUNT" -eq 0 ] && [ "$RB_COUNT" -eq 0 ]; then echo -e " ${OK} No expensive idle resources detected." else if [ "$VM_COUNT" -gt 0 ]; then echo -e " ${RED}${FAIL} Running VMs: ${VM_COUNT}${NC} (Always-on cost!)" fi if [ "$SQL_COUNT" -gt 0 ]; then echo -e " ${RED}${FAIL} Running SQL: ${SQL_COUNT}${NC} (Always-on cost!)" fi if [ "$RB_COUNT" -gt 0 ]; then echo -e " ${RED}${FAIL} Memory Bank: ${RB_COUNT}${NC} (Idle cost!)" fi echo -e " ${DIM}Tip: Run bash infrastructure/03-teardown.sh at end of day.${NC}" fi echo "" # --- 4. Security & Integrations --- echo -e "${BOLD}[4] Security & Secrets${NC}" SECRETS=("github-token" "webhook-url" "rag-corpus-name") for s in "${SECRETS[@]}"; do if gcloud secrets describe "$s" --project="${PROJECT_ID}" &>/dev/null; then echo -e " ${OK} Secret: ${GREEN}${s}${NC}" else if [ "$s" = "rag-corpus-name" ]; then echo -e " ${INFO} Secret: ${DIM}${s}${NC} (Auto-populated by setup_corpus.py)" else echo -e " ${WARN} Secret: ${YELLOW}${s}${NC} (MISSING)" echo -e " ${DIM}Action: gcloud secrets create ${s} --data-file=...${NC}" fi fi done echo "" echo -e "${CYAN}${BOLD}==========================================================${NC}" echo -e " ${BOLD}Next Step:${NC} Run ${DIM}bash scripts/osvauco-opax-boot.sh${NC} to start OPAX." echo -e "${CYAN}${BOLD}==========================================================${NC}"