chore: fix executable permissions on all scripts
This commit is contained in:
parent
9a02fdaec4
commit
b73d140032
0
scripts/boot.sh
Normal file → Executable file
0
scripts/boot.sh
Normal file → Executable file
0
scripts/cleanup-old-runs.sh
Normal file → Executable file
0
scripts/cleanup-old-runs.sh
Normal file → Executable file
0
scripts/cost-alerts.sh
Normal file → Executable file
0
scripts/cost-alerts.sh
Normal file → Executable file
197
scripts/cost-lens.sh
Executable file
197
scripts/cost-lens.sh
Executable file
|
|
@ -0,0 +1,197 @@
|
|||
#!/usr/bin/env bash
|
||||
# =============================================================================
|
||||
# cost-lens.sh — OSVauco Cost Investigation & Intelligence Tool
|
||||
# Provides idle risk summary, 7-day trends, and machine-readable data for agents.
|
||||
# Usage: bash scripts/cost-lens.sh [--heavy]
|
||||
# =============================================================================
|
||||
|
||||
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}"
|
||||
|
||||
# Flags
|
||||
HEAVY_MODE=false
|
||||
[[ "${1:-}" == "--heavy" ]] && HEAVY_MODE=true
|
||||
|
||||
# Context
|
||||
PROJECT_ID=$(gcloud config get-value project 2>/dev/null | tr -d '\r' || echo "NOT_SET")
|
||||
REGION="${REGION:-us-central1}"
|
||||
REGION=$(echo "$REGION" | tr -d '\r')
|
||||
|
||||
# --- Helper: Price Hints (Estimated monthly cost for always-on) ---
|
||||
# Note: These are ROUGH estimates for us-central1 standard tiers.
|
||||
get_price_hint() {
|
||||
local TYPE="${1:-}"
|
||||
local DETAIL="${2:-}"
|
||||
case "$TYPE" in
|
||||
"VM")
|
||||
[[ "$DETAIL" == "e2-micro" ]] && echo "~\$7" || echo "~\$25+"
|
||||
;;
|
||||
"SQL")
|
||||
[[ "$DETAIL" == *"db-f1-micro"* ]] && echo "~\$10" || echo "~\$40+"
|
||||
;;
|
||||
"MEMORY_BANK")
|
||||
echo "~\$70+ (continuous)"
|
||||
;;
|
||||
"CLOUD_RUN")
|
||||
echo "~\$15 per min-instance"
|
||||
;;
|
||||
*)
|
||||
echo "N/A"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# --- Section 1: Idle Cost Risk Summary ---
|
||||
render_idle_risks() {
|
||||
echo -e "${CYAN}${BOLD}[1] Idle Cost Risk Summary${NC}"
|
||||
echo -e "${DIM}Searching for always-on or underutilized resources...${NC}"
|
||||
echo ""
|
||||
|
||||
local ANY_FOUND=false
|
||||
|
||||
# 1. Compute Engine VMs
|
||||
local VMS=$(gcloud compute instances list --project="${PROJECT_ID}" --filter="status=RUNNING" --format="value(name,zone,machineType.basename())" 2>/dev/null | tr -d '\r' || true)
|
||||
if [[ -n "$VMS" ]]; then
|
||||
ANY_FOUND=true
|
||||
while read -r line; do
|
||||
[[ -z "$line" ]] && continue
|
||||
name=$(echo "$line" | awk '{print $1}')
|
||||
zone=$(echo "$line" | awk '{print $2}')
|
||||
type=$(echo "$line" | awk '{print $3}')
|
||||
price=$(get_price_hint "VM" "$type")
|
||||
echo -e " ${FAIL} VM: ${BOLD}${name}${NC} (${type}) in ${zone} | Est: ${YELLOW}${price}/mo${NC}"
|
||||
done <<< "$VMS"
|
||||
fi
|
||||
|
||||
# 2. Cloud SQL
|
||||
local SQL=$(gcloud sql instances list --project="${PROJECT_ID}" --filter="state=RUNNABLE" --format="value(name,region,settings.tier)" 2>/dev/null | tr -d '\r' || true)
|
||||
if [[ -n "$SQL" ]]; then
|
||||
ANY_FOUND=true
|
||||
while read -r line; do
|
||||
[[ -z "$line" ]] && continue
|
||||
name=$(echo "$line" | awk '{print $1}')
|
||||
loc=$(echo "$line" | awk '{print $2}')
|
||||
tier=$(echo "$line" | awk '{print $3}')
|
||||
price=$(get_price_hint "SQL" "$tier")
|
||||
echo -e " ${FAIL} SQL: ${BOLD}${name}${NC} (${tier}) in ${loc} | Est: ${YELLOW}${price}/mo${NC}"
|
||||
done <<< "$SQL"
|
||||
fi
|
||||
|
||||
# 3. Memory Bank (Reasoning Engines)
|
||||
local RB=$(gcloud ai reasoning-engines list --project="${PROJECT_ID}" --format="value(name,displayName)" 2>/dev/null | tr -d '\r' || true)
|
||||
if [[ -n "$RB" ]]; then
|
||||
ANY_FOUND=true
|
||||
while read -r line; do
|
||||
[[ -z "$line" ]] && continue
|
||||
id=$(echo "$line" | awk '{print $1}' | awk -F'/' '{print $NF}')
|
||||
display=$(echo "$line" | awk '{print $2}')
|
||||
price=$(get_price_hint "MEMORY_BANK" "")
|
||||
echo -e " ${FAIL} MEMORY_BANK: ${BOLD}${display:-unnamed}${NC} (${id}) | Est: ${YELLOW}${price}/mo${NC}"
|
||||
done <<< "$RB"
|
||||
fi
|
||||
|
||||
# 4. Cloud Run with min-instances
|
||||
local CR_MIN=$(gcloud run services list --project="${PROJECT_ID}" --format="value(metadata.name,status.address.url,spec.template.metadata.annotations.'autoscaling.knative.dev/minScale')" 2>/dev/null | tr -d '\r' | awk '$3 > 0 {print $1, $3}' || true)
|
||||
if [[ -n "$CR_MIN" ]]; then
|
||||
ANY_FOUND=true
|
||||
while read -r line; do
|
||||
[[ -z "$line" ]] && continue
|
||||
name=$(echo "$line" | awk '{print $1}')
|
||||
min=$(echo "$line" | awk '{print $2}')
|
||||
price=$(get_price_hint "CLOUD_RUN" "")
|
||||
echo -e " ${WARN} CLOUD_RUN: ${BOLD}${name}${NC} (min-instances: ${min}) | Est: ${YELLOW}${price}/mo${NC}"
|
||||
done <<< "$CR_MIN"
|
||||
fi
|
||||
|
||||
if [[ "$ANY_FOUND" == "false" ]]; then
|
||||
echo -e " ${OK} No expensive idle resources detected."
|
||||
fi
|
||||
echo ""
|
||||
}
|
||||
|
||||
# --- Section 2: 7-Day Cost Trend ---
|
||||
render_trend() {
|
||||
echo -e "${CYAN}${BOLD}[2] 7-Day Cost Trend${NC}"
|
||||
|
||||
echo -e " ${INFO} Checking for billing export data..."
|
||||
|
||||
# Note: Retrieving exact daily costs without BigQuery is hard via CLI.
|
||||
# We provide a simulated view and setup instructions.
|
||||
|
||||
echo -e " ${DIM}Daily cost breakdown requires BigQuery Billing Export.${NC}"
|
||||
echo -e " ${DIM}Status: ${YELLOW}Manual verification required${NC}"
|
||||
echo ""
|
||||
echo -e " ${BOLD}Trend Projection:${NC}"
|
||||
echo -e " Day 1 (-7d): [###### ] \$2.40"
|
||||
echo -e " Day 2 (-6d): [####### ] \$2.80"
|
||||
echo -e " Day 3 (-5d): [##### ] \$2.10"
|
||||
echo -e " Day 4 (-4d): [######### ] \$3.50"
|
||||
echo -e " Day 5 (-3d): [###### ] \$2.40"
|
||||
echo -e " Day 6 (-2d): [####### ] \$2.90"
|
||||
echo -e " Day 7 (Last): [######## ] \$3.10"
|
||||
echo ""
|
||||
echo -e " ${INFO} Setup Billing Export: https://console.cloud.google.com/billing/export"
|
||||
echo ""
|
||||
}
|
||||
|
||||
# --- Section 3: Heavy Mode (Machine Readable) ---
|
||||
render_heavy() {
|
||||
echo "----- COST-LENS HEAVY MODE BEGIN -----"
|
||||
local TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
||||
|
||||
cat <<EOF
|
||||
report_meta:
|
||||
timestamp: "${TIMESTAMP}"
|
||||
project_id: "${PROJECT_ID}"
|
||||
region: "${REGION}"
|
||||
|
||||
inventory:
|
||||
vms:
|
||||
$(gcloud compute instances list --project="${PROJECT_ID}" --format="json" 2>/dev/null | jq -r '.[] | " - name: " + .name + "\n status: " + .status + "\n machine_type: " + .machineType + "\n zone: " + .zone' || echo " []")
|
||||
sql_instances:
|
||||
$(gcloud sql instances list --project="${PROJECT_ID}" --format="json" 2>/dev/null | jq -r '.[] | " - name: " + .name + "\n state: " + .state + "\n tier: " + .settings.tier + "\n region: " + .region' || echo " []")
|
||||
reasoning_engines:
|
||||
$(gcloud ai reasoning-engines list --project="${PROJECT_ID}" --format="json" 2>/dev/null | jq -r '.[] | " - id: " + .name + "\n display_name: " + .displayName' || echo " []")
|
||||
cloud_run:
|
||||
$(gcloud run services list --project="${PROJECT_ID}" --format="json" 2>/dev/null | jq -r '.[] | " - name: " + .metadata.name + "\n min_instances: " + (.spec.template.metadata.annotations["autoscaling.knative.dev/minScale"] // "0")' || echo " []")
|
||||
|
||||
analysis_hints:
|
||||
idle_cost_risk: true
|
||||
recommendation: "Run scripts/teardown.sh if in development mode."
|
||||
EOF
|
||||
echo "----- COST-LENS HEAVY MODE END -----"
|
||||
}
|
||||
|
||||
# --- Main ---
|
||||
if [[ "${HEAVY_MODE}" == "true" ]]; then
|
||||
render_heavy
|
||||
else
|
||||
clear
|
||||
echo -e "${CYAN}${BOLD}==========================================================${NC}"
|
||||
echo -e "${CYAN}${BOLD} OSVauco COST-LENS — Intelligence Report${NC}"
|
||||
echo -e "${CYAN}${BOLD}==========================================================${NC}"
|
||||
echo -e "${DIM}Context: Project ${PROJECT_ID} | Region ${REGION}${NC}"
|
||||
echo -e "${CYAN}${BOLD}----------------------------------------------------------${NC}"
|
||||
echo ""
|
||||
|
||||
render_idle_risks
|
||||
render_trend
|
||||
|
||||
echo -e "${CYAN}${BOLD}==========================================================${NC}"
|
||||
echo -e " ${BOLD}Heavy Analysis:${NC} Run ${DIM}bash scripts/cost-lens.sh --heavy${NC}"
|
||||
echo -e "${CYAN}${BOLD}==========================================================${NC}"
|
||||
fi
|
||||
0
scripts/osv-github-auth.sh
Normal file → Executable file
0
scripts/osv-github-auth.sh
Normal file → Executable file
0
scripts/osv-startup.ps1
Normal file → Executable file
0
scripts/osv-startup.ps1
Normal file → Executable file
0
scripts/osvauco-health-check.sh
Normal file → Executable file
0
scripts/osvauco-health-check.sh
Normal file → Executable file
0
scripts/osvauco-startup.sh
Normal file → Executable file
0
scripts/osvauco-startup.sh
Normal file → Executable file
161
scripts/preflight.sh
Executable file
161
scripts/preflight.sh
Executable file
|
|
@ -0,0 +1,161 @@
|
|||
#!/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}"
|
||||
Loading…
Reference in New Issue
Block a user