#!/usr/bin/env bash # ============================================================================ # Example: External tool triggers maintenance via superset-tools API (bash) # # This script shows how to call the superset-tools maintenance API from any # shell environment — CI/CD pipeline, cron job, or ad-hoc debugging. # # Prerequisites: # - curl, jq (optional, for pretty-printing JSON) # - An superset-tools API key with `maintenance:start`, `maintenance:end` # # Usage: # ./maintenance-api-bash.sh start "public.messages" 4 "ss-dev" # ./maintenance-api-bash.sh end "m-abc123" # ./maintenance-api-bash.sh end-all "ss-dev" # ============================================================================ set -euo pipefail # ── Configuration ────────────────────────────────────────────────────────── # Set these via environment variables or replace inline BASE_URL="${SS_TOOLS_URL:-http://localhost:8000}" API_KEY="${SS_TOOLS_API_KEY:-}" # ── Color helpers (disabled in non-TTY) ──────────────────────────────────── if [[ -t 1 ]]; then GREEN='\033[0;32m'; RED='\033[0;31m'; YELLOW='\033[1;33m' CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m' else GREEN=''; RED=''; YELLOW=''; CYAN=''; BOLD=''; NC='' fi ok() { echo -e "${GREEN}✅${NC} $*"; } info() { echo -e "${CYAN}ℹ️ ${NC} $*"; } warn() { echo -e "${YELLOW}⚠️ ${NC} $*"; } fail() { echo -e "${RED}❌${NC} $*"; exit 1; } # ── Auth check ───────────────────────────────────────────────────────────── check_auth() { if [[ -z "$API_KEY" ]]; then fail "API key not set. Export SS_TOOLS_API_KEY or edit the script." fi } # ── API helpers ──────────────────────────────────────────────────────────── # Call the API with X-API-Key auth and handle common errors api_call() { local method="$1" # GET / POST local endpoint="$2" # /api/maintenance/start local data="$3" # JSON payload or empty string local curl_args=( -X "$method" -sS -H "X-API-Key: $API_KEY" -H "Content-Type: application/json" ) if [[ -n "$data" ]]; then curl_args+=(-d "$data") fi local http_code local response_file response_file=$(mktemp) http_code=$(curl -w '%{http_code}' "${curl_args[@]}" \ "${BASE_URL}${endpoint}" \ -o "$response_file" 2>/dev/null) local body body=$(<"$response_file") rm -f "$response_file" case "$http_code" in 202) echo "$body" # success return 0 ;; 400) warn "Validation error:" echo "$body" | jq . 2>/dev/null || echo "$body" return 1 ;; 401) fail "Authentication failed: invalid or revoked API key" ;; 403) fail "Permission denied: API key lacks required permission" ;; 404) local status status=$(echo "$body" | jq -r '.status // "not_found"' 2>/dev/null) if [[ "$status" == "already_completed" ]]; then info "Event was already completed (idempotent)" return 0 fi warn "Not found (404):" echo "$body" | jq . 2>/dev/null || echo "$body" return 1 ;; *) fail "Unexpected HTTP $http_code: $(echo "$body" | head -c 500)" ;; esac } # ── Commands ─────────────────────────────────────────────────────────────── cmd_start() { local tables="$1" local duration_hours="${2:-4}" local environment_id="$3" local message="${4:-}" local start_time local end_time start_time=$(date -u +"%Y-%m-%dT%H:%M:%SZ") end_time=$(date -u -d "+${duration_hours} hours" +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null \ || date -u -v "+${duration_hours}H" +"%Y-%m-%dT%H:%M:%SZ") # Build JSON payload local payload payload=$(cat </dev/null || echo "unknown") local task_id task_id=$(echo "$response" | jq -r '.task_id' 2>/dev/null || echo "unknown") ok "Maintenance event created: ${BOLD}${event_id}${NC}" info "Task: ${task_id}" echo "$response" | jq . 2>/dev/null || echo "$response" fi } cmd_end() { local event_id="$1" info "Ending maintenance event: ${event_id}" local response if response=$(api_call POST "/api/maintenance/${event_id}/end" ""); then ok "Maintenance event end scheduled" echo "$response" | jq . 2>/dev/null || echo "$response" fi } cmd_end_all() { local environment_id="${1:-}" warn "This will remove banners from ALL affected dashboards!" if [[ -n "$environment_id" ]]; then info "Scope: environment=${environment_id}" else info "Scope: all environments (API key default)" fi # Prompt for confirmation in interactive mode if [[ -t 0 ]]; then echo -n "Continue? [y/N] " read -r confirm if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then info "Cancelled." exit 0 fi fi local payload="{}" if [[ -n "$environment_id" ]]; then payload=$(cat </dev/null || echo "$response" fi } # ── Main ─────────────────────────────────────────────────────────────────── check_auth case "${1:-help}" in start) if [[ $# -lt 3 ]]; then echo "Usage: $0 start [duration_hours] [message]" echo "" echo "Examples:" echo " $0 start public.messages 4 ss-dev" echo " $0 start public.messages,public.users 4 ss-prod \"Scheduled ETL\"" exit 1 fi cmd_start "$2" "${3:-4}" "${4:-}" "${5:-}" ;; end) if [[ $# -lt 2 ]]; then echo "Usage: $0 end " exit 1 fi cmd_end "$2" ;; end-all) cmd_end_all "${2:-}" ;; *) cat < [hours=4] [message] Start maintenance on tables (comma-separated) $0 end End a specific maintenance event $0 end-all [environment] End ALL maintenance (use with caution) Examples: $0 start public.messages 4 ss-dev $0 end m-abc123 $0 end-all ss-dev Environment: SS_TOOLS_URL superset-tools base URL (default: http://localhost:8000) SS_TOOLS_API_KEY API key with required permissions (required) EOF exit 0 ;; esac